New software filter for adc reading


+ Reply to Thread
Results 1 to 30 of 30

Hybrid View

  1. #1
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    4,115


    Did you find this post helpful? Yes | No

    Default Re: New software filter for adc reading

    Thanks Darrel. Is that on the X-axis ... time? I guess it is and the time it takes is forever.

    OK, if we use 3/4 will sure be faster, but how accurate?

    On an experiment with touch sensors I can confirm that it could not get close to the real sample value though...

    Ioannis

  2. #2
    Join Date
    Dec 2010
    Posts
    409


    Did you find this post helpful? Yes | No

    Default Re: New software filter for adc reading

    Hey Darrel - I'm sure you don't want to make a career out of this mini-project, but can you explain that result? It's not obvious (to me at least) why it takes so long and the green line never reaches ADval. Playing with this in a spreadsheet, it can take between 100 & 150 samples to get there, but you have WAY more than that, and it's not even close! Do you think this the accumulated result of dropping LSBs, and effectively always rounding down?

    Also, to address the ramp time, when I've done something similar in practice, the first time through the loop I make RunAverage = ADval to effectively eliminate the ramp, and at least start in the right ballpark. (I'm sure you typically do as well). Wouldn't it be more fair to add that curve instead (or as well)?

  3. #3
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    4,115


    Did you find this post helpful? Yes | No

    Default Re: New software filter for adc reading

    I think with the running average will never reach the final ADC value because of rounding errors.

    E.g. for 10 bit ADC and say a RunAverage value of 1008, on next iteration 0.9375 should be added, but since PBP does only integer numbers, the RunAverage will sit at 1008 for ever. This would be the final value of the filter.

    I suppose this kind of running average routine is for floating point maths only.

    Ioannis
    Last edited by Ioannis; - 15th January 2013 at 13:46.

  4. #4
    Join Date
    May 2008
    Location
    Italy
    Posts
    825


    Did you find this post helpful? Yes | No

    Default Re: New software filter for adc reading

    Thank you Darrel for such a quick answer. I will keep thinking what else I could do for further improvment.

    As far as the running average is concerned, a way to have a faster answer could be:

    Code:
    ADCIN chan,ADVal
    
    If RAv = 0 then
    RAv = ADVal
    ELSE
    RAv = (RAv*15 + ADVal)/16
    ENDIF
    In this way you load the variable with the raw value and then you smooth it. Just thinking!

    Cheers

    Al.
    Last edited by aratti; - 15th January 2013 at 15:23.
    All progress began with an idea

  5. #5
    Join Date
    Nov 2005
    Location
    Bombay, India
    Posts
    966


    Did you find this post helpful? Yes | No

    Default Re: New software filter for adc reading

    Another running average that may be useful to all. This one will work even if you do not have floating point. However, you need to be able to handle large numbers or size the buffer appropriately that it doesn't overflow 'sum' while summing. Of course, you need way more ram than the Avg = (Avg*(n-1)+adcval)/n formula which is good for Ram Constrained systems.

    Code:
    Pseudo code.
    
    NumOfSamples   equ   16
    
    AdcVal             Word                               ' adc reading is placed here
    Samples           Word [NumOfSamples]     ' rolling buffer having NumOfSamples of AdcReading (must retain value between calls to R_Average)
    Index              var     byte                       ' next position where the sample will be put (must retain value between calls to R_Average)
    Sum                var     long                      ' gross sum of all the samples (must retain value between calls to R_Average)
    
    RA_Init:  ' initialize the running average
          Index = 0
          Sum  =0
          return
    
    ' enter with A
    R_Average:
         sum = sum - Samples[Index]                    ' remove the oldest sample from the sum
         sum = sum + AdcVal                                ' add in the latest sample             to sum
         Samples[Index] = AdcVal                          ' and save it in the buffer too
    
         Index = Index+1                                     ' move the index
         If Index > NumOfSamples then Index = 0  ' wrap around if needed
    
         return sum / NumOfSamples                     ' the running average
    Caller has to initiate with RA_Init before using the R_Average routine. I hope you will excuse my pseudo code since I am a bit rusty on my PBP at this moment.
    Last edited by Jerson; - 15th January 2013 at 15:31.

  6. #6
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default Re: New software filter for adc reading

    I agree!
    That Avg = (Avg*15 + ADval)/16 running average is only going to work with floating point math.
    It's surprising how many times we've seen it used around here in an integer only language.

    Charlie, I don't think setting it to ADval first will help, because it is likely to still be a short distance from the real value.
    And it's when it's close to the real value that it doesn't move anymore, so it would never get any closer than that first reading.
    Last edited by Darrel Taylor; - 15th January 2013 at 15:30.
    DT

  7. #7
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    4,115


    Did you find this post helpful? Yes | No

    Default Re: New software filter for adc reading

    Ehh, hmm, I think it is Al, Darrel

    It is indeed surprising how many have used it, but who thought that it needed floating? Also Microchip use it in various AN like the cap-sense routines but of course C does support floats.

    Anyway, Fast Average and Oversampling I think is the best Darrel-Soft as usual.

    Ioannis

  8. #8
    Join Date
    Dec 2010
    Posts
    409


    Did you find this post helpful? Yes | No

    Default Re: New software filter for adc reading

    Quote Originally Posted by Darrel Taylor View Post
    And it's when it's close to the real value then it doesn't move anymore.
    Well, that's sort of the objective of filtering, right?

    But I think I'm getting my head around this - it's an issue of the SIZE of change needed to make an impact on the reading. So if there is no averaging, a change is recorded when the reading changes by a whole number value of 1. If you are averaging 4 readings, then the change must be at least a whole number value of 4 before it gets included. With 16 samples, the reading has to change by at least 16 before it registers, and so on. In effect you are not integrating small changes, you are tossing them out... which is sort of where this thread started.

    I think I'd better revisit several projects where I've used a rolling average, although I don't believe I've ever used more than 4 samples.

  9. #9
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    4,115


    Did you find this post helpful? Yes | No

    Default Re: New software filter for adc reading

    You need to use floats whatever the sample are.

    Ioannis

  10. #10
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,604


    Did you find this post helpful? Yes | No

    Default Re: New software filter for adc reading

    Interesting thread!
    A while back (2+ years as it turns out) I did some work on a "general purpose" low pass filter routine which, like many projects, never really made it to the finish line.
    I based it on one of Tracy Allens filter routines and it's basically that 15/16 type filter disussed in later posts of the thread - with some adjustments. With my version you're able to select one out of 9 different filter constants and it handles negative values (two's complement). Seeing the dissusions here on that type of filter not converging properly, I tool a look at the old plots I did while testing and the output of my filter does seem to converge to the actual input value:

    Name:  LP_Filter_step.jpg
Views: 10342
Size:  76.4 KB

    It's a bit hard to see in the plot but all "traces" does end up at the actual input value when given enough time, here's a detailed view of the first step of signal:

    Name:  LP_Filter_Step_zoom.jpg
Views: 10314
Size:  69.5 KB

    Finally here's a plot that shows an "ideal" sinewave and that same sine with another sine (f=10x) on top. Then it shows what the filter output looks like at a couple of different filter constants:

    Name:  LP_Filter_sine.jpg
Views: 10310
Size:  60.8 KB

    I should probably note that all of the above tests was performed with "simulated data" ie the waveform fed to the filter was stored in the PIC so no ADC was involved. I don't think that actually makes any difference though.

    If there's any interest in it I can clean it up a bit and post it. It will not be the smallest and most likely not the fastest but it may have other benefits.

    /Henrik.

Similar Threads

  1. Help with multiple ADC inputs
    By wdmagic in forum mel PIC BASIC Pro
    Replies: 6
    Last Post: - 4th January 2013, 00:27
  2. Need help on ADC : Software R/C filter
    By luminas in forum mel PIC BASIC Pro
    Replies: 3
    Last Post: - 27th November 2010, 14:33
  3. Filter for PWM
    By Tobias in forum General
    Replies: 1
    Last Post: - 24th August 2008, 10:26
  4. Replies: 3
    Last Post: - 26th November 2006, 21:47
  5. ADC filter
    By leonel in forum mel PIC BASIC Pro
    Replies: 4
    Last Post: - 17th May 2005, 17:46

Members who have read this thread : 14

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts