Averaging AtoD samples


Closed Thread
Results 1 to 40 of 40

Hybrid View

  1. #1
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default

    Guy - what can I say .....I initially used random 1-6 for my numbers in the array & it sorted them & averaged them fine! (ie 1,2,3,4,5,6 was the screen output!)

    I'm puzzled why my screen output posted above doesn't look like it's working (for either the sorting or the averaging!! lol) - it was late ...that's my lame excuse for not picking up on that! The 'sorting' part of the code was a direct lift from Melanie's article.

    I'm at work now (don't tell my boss!) , so will revisit this tonight.

  2. #2
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default

    Ok, the thread title really ought to be called stripping out erroneous samples & then averaging the leftovers (vs averaging data which includes erroneous samples), I've revisited my earlier problem

    Code:
    @ __CONFIG _FCMEN_OFF & _HS_OSC & _WDT_OFF & _MCLRE_OFF & _CP_OFF & _IESO_OFF & _BOR_OFF & _PWRTE_OFF
    
    DEFINE  OSC 20          ' set Oscillator at 20Mhz.
    DEFINE  NO_CLRWDT 1   ' PBP doesn't clear WDT automatically
    DEFINE HSER_CLROERR 1
    DEFINE HSER_TXSTA 24h ' Enable transmit
    DEFINE HSER_SPBRG 129 ' set USART to 9600 baud  @20Mhz
    
    ANSEL       =  0
    ANSELH     =  0
    
        CounterA            var Byte    'A counter for sorting out the erroneous data
        DataA               var word    'A Variable used in sorting the numbers in the array 
        RawData             var word [6] 'This is the RawData gojng into the array
        Averaged            var word     'This is used to get the average.
      
        top:    
        RawData[0]  = 300
        RawData[1]  = 100
        RawData[2]  = 200
        RawData[3]  = 600
        RawData[4]  = 400
        RawData[5]  = 500
    
        pause 250
      
        hserout [27,91,72]          'home cursor
        hserout [27,91,50,74]      'clear screen  
        
       next1:
        hserout [13,10]
        hserout [13,10]
        pause 300 
        hserout ["before....", 13, 10]
        hserout [13,10]
        hserout [dec rawdata[0],13,10]
        hserout [dec rawdata[1],13,10]
        hserout [dec rawdata[2],13,10]
        hserout [dec rawdata[3],13,10]
        hserout [dec rawdata[4],13,10]
        hserout [dec rawdata[5],13,10]
        hserout [13,10]
        hserout [13,10]
    
        pause 2000
        
        CounterA =0
        gosub SortArray
        gosub Average_data
        hserout ["after....", 13, 10]
        hserout [13,10]
        hserout [dec rawdata[0],13,10]
        hserout [dec rawdata[1],13,10]
        hserout [dec rawdata[2],13,10]
        hserout [dec rawdata[3],13,10]
        hserout [dec rawdata[4],13,10]
        hserout [dec rawdata[5],13,10]
        hserout [13,10]
        hserout ["therefore, middle two samples are ", dec rawData[2]," + ", dec rawData[3], 13,10]
        pause 500
        hserout [13,10]
        hserout ["averaged middle two samples = ", dec averaged,13,10]
        pause 500
        pause 3000
        goto top
        
        
    Average_data:
        Averaged = (rawData[2]+rawData[3])/2    ' average the middle two of 6 samples
        return
    
    SortArray:
    SortLoop:
        If RawData(CounterA+1) < RawData(CounterA) then
            DataA=RawData(CounterA)
            RawData(CounterA)=RawData(CounterA+1)
            RawData(CounterA+1+0)=DataA
            If CounterA > 0 then CounterA=CounterA-2
            endif
        CounterA=CounterA+1
        If CounterA < 5 then goto SortLoop
        Return
    
        end
    And it works (basically, the code throws away all but the middle two samples of six & averages those two - ideal if your input data is all over the place.,...eg comparator counts etc!)...

    Code:
    before....
    
    300
    100
    200
    600
    400
    500
    
    
    after....
    
    100
    200
    300
    400
    500
    600
    
    therefore, middle two samples are 300 + 400
    
    averaged middle two samples = 350
    Or a more real world example (eg a comparator interrupt count jittering in or around the 200 count level but with one spurious/erroneous count of 400 in the 'sample of six' to get rid of)...

    Code:
    before....
    
    199
    400
    200
    200
    199
    200
    
    
    after....
    
    199
    199
    200
    200
    200
    400
    
    therefore, middle two samples are 200 + 200
    
    averaged middle two samples = 200
    Not entirely sure what the problem was (I changed a few things at once & didn't retrace my steps!)
    Last edited by HankMcSpank; - 25th September 2010 at 11:03.

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


    Did you find this post helpful? Yes | No

    Default

    That's better!

    Cheers

    Al.
    All progress began with an idea

  4. #4
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by aratti View Post
    That's better!

    Cheers

    Al.
    & thanks for offering up some help/support earlier!
    Last edited by HankMcSpank; - 25th September 2010 at 10:49.

  5. #5
    Join Date
    Oct 2010
    Posts
    27


    Did you find this post helpful? Yes | No

    Default

    In a different application I used a "weighted Average" where no one sample could mangle the running average.
    This is the regurgitated conversion to PBP:

    I initialize the values and add new value to the stack and subtract off the old average, giving the new value 1/weight of effect

    I leave the running average in A2D counts to avoid rounding
    Must watch (Max value * number of samples) < 65000


    Weight var byte
    WeightedAve var word
    Ave var word
    WeightedCounts
    NewAve var word
    Count var word

    AveragingComplete var word

    Incoming var word ‘incoming value from a2d
    WeightedCounts=0
    Weight = 100
    AveragingComplete = 0
    Ave=0

    If Count=0 then WeightedCounts= incoming* Weight
    If Count=0 then Ave= incoming

    If Count < Weight then Count = Count + 1
    NewAve =(incoming+ WeightedCounts-Ave
    WeightedCounts= NewAve
    Ave= WeightedCounts/ Weight
    If Count = Weight then AveragingComplete = 1
    If Count = Weight then Display “Weighted Average” ‘lcd routine
    If Count < Weight then Display “building average” ‘lcd routine

  6. #6
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by Plcguy View Post
    In a different application I used a "weighted Average" where no one sample could mangle the running average.
    This is the regurgitated conversion to PBP:

    I initialize the values and add new value to the stack and subtract off the old average, giving the new value 1/weight of effect
    It must be cos I suck at maths, but I've read that a few times & it's not sinking in. Can I use an example here to how that works in practise. Let's say six AtoD Samples are taken....

    100
    99
    100
    101
    499
    100

    You said that your weighted average stops a spurious reading skewing the overall average...can you illustrate using those six samples how the 499 would be ignored?

    Many thanks!

  7. #7
    Join Date
    Oct 2010
    Posts
    27


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by HankMcSpank View Post
    It must be cos I suck at maths, but I've read that a few times & it's not sinking in. Can I use an example here to how that works in practise. Let's say six AtoD Samples are taken....

    100
    99
    100
    101
    499
    100

    You said that your weighted average stops a spurious reading skewing the overall average...can you illustrate using those six samples how the 499 would be ignored?

    Many thanks!
    It will affect it, but only at 1/sample rate.
    so, for a 10 sample example, assume the running average = 100
    100 *10 (sample rate) = 1000 = sum of the samples

    new value 101
    101+1000 - 100 = 1001
    ave = 1001/sample rate = 100.1 0r 100 for PBP (rounds down)

    new value 99
    99+1001 - 100 = 1000
    ave = 1000/sample rate = 100.0 0r 100 for PBP (rounds down)

    new value 499
    499+1000 - 100 = 1400
    ave = 1400/sample rate = 140

    new value 101
    101+1400 - 140 = 1361
    ave = 1361/sample rate = 136.1 0r 136 for PBP (rounds down)

    far less than a (499 +100)/2 = 300

    to filter the 1st bad sample add the lines (or similar)
    if incoming > ave*10/9 AND if incoming < ave*10/9 then bad_count = 0
    if (incoming < ave*10/9 OR if incoming > ave*10/9) AND bad_count = 0 then bad_count = 1
    if (incoming < ave*10/9 OR if incoming > ave*10/9) AND bad_count = 1 then bad_count = 0

    if bad_count = 0 then gosub average
    if bad_count = 1 then Skip average routine

    This (or similar) should skip the 1st out of whack signal

Similar Threads

  1. Darrel's latest 16 bit averaging routine?
    By jellis00 in forum mel PIC BASIC Pro
    Replies: 9
    Last Post: - 17th October 2009, 01:57
  2. ADC Averaging
    By Sach_1979 in forum mel PIC BASIC Pro
    Replies: 4
    Last Post: - 21st September 2009, 06:53
  3. Atod Digital Filter
    By GeoJoe in forum mel PIC BASIC Pro
    Replies: 3
    Last Post: - 2nd April 2008, 17:04
  4. Microchip free samples in UK?
    By zoki008 in forum Off Topic
    Replies: 1
    Last Post: - 21st March 2006, 16:06
  5. Averaging & 16 maths
    By paul.mcallister in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 22nd May 2005, 18:17

Members who have read this thread : 0

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