Shop OBEX P1 Docs P2 Docs Learn Events
Analog To Digital Converter Averaging — Parallax Forums

Analog To Digital Converter Averaging

Travis M. BestTravis M. Best Posts: 9
edited 2009-12-13 23:33 in Propeller 1
Is their a easy way to average 100+ samples from a A/D Converter without having a ton a variables???


Thanks
Travis Best

Comments

  • MacGeek117MacGeek117 Posts: 747
    edited 2009-12-13 20:48
    What's the resolution of your ADC?
    MacGeek117

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    BS2: $49


    SX48 Protoboard: $10

    Propeller Protoboard: Priceless

    www.apple.com

    www.parallax.com

    www.goldmine-elec.com

    www.expresspcb.com

    www.jameco.com
  • LeonLeon Posts: 7,620
    edited 2009-12-13 20:49
    For each 100 samples, zero the variable, add each sample to it, then divide by 100. 128 would be easier, as you can use the barrel shifter to divide by 128 in one operation.

    Leon

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Amateur radio callsign: G1HSM
  • TubularTubular Posts: 4,717
    edited 2009-12-13 20:54
    The proper way is to have a circular buffer 100 samples long. Actually 128 samples to make dividing easier. You keep a total of the sum of the 100 samples. When a new sample comes along you subtract the oldest (100 samples ago) and add the new value.

    An alternative is to use something along the lines of this algorithm which works ok when there isn't large noise
    AverageVal = AverageVal + (NewSample-AverageVal) / 128
    effectively each above/below average new sample increases/decreases the long term average by a smidge. You need to either use floating point or shift up AverageVal a few digits (like a fixed decimal point)
  • BRBR Posts: 92
    edited 2009-12-13 23:33
    Sounds like a job for a moving average filter:
    pub ma16(x_meas):x_ret
    ''16-sample moving average filter, implemented with recursion.
    ''Max filter update rate ~13000 samples/sec for 1 cog @ clkfreq=80
    
      ptr &= %00001111                         'mask off all but lower four bits
      sum := sum + x_meas - x_buf16[noparse][[/noparse]ptr]
      x_buf16[noparse][[/noparse]ptr] := x_meas
      x_ret := sum ~> 4                        'divide sum by 16
      ptr++
    dat                                
    '-----------[noparse][[/noparse] Predefined variables and constants ]-----------------------------
    x_buf16        long      0,0,0,0,0,0,0,0   '16-place filter input history buffer
                   long      0,0,0,0,0,0,0,0   
    sum            long      0
    ptr            long      0                 'pointer (set up as ring buffer)
    
    



    This particular example is for a 16 element moving average, but you could easily make it into a 128 point moving average by changing the buffer size, the mask, and and the shift arithmetic right. There are a variety of additional filter examples in this thread.

    Post Edited (BR) : 12/13/2009 11:38:26 PM GMT
Sign In or Register to comment.