I suppose that you corrected the array definition from[6] to [5].
And then the check in the program:
to this:Code:If CounterA < 5 then goto SortLoop
IoannisCode:If CounterA < 4 then goto SortLoop
I suppose that you corrected the array definition from[6] to [5].
And then the check in the program:
to this:Code:If CounterA < 5 then goto SortLoop
IoannisCode:If CounterA < 4 then goto SortLoop
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.
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
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:@ __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
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.... 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
Not entirely sure what the problem was (I changed a few things at once & didn't retrace my steps!)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
Last edited by HankMcSpank; - 25th September 2010 at 11:03.
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
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!
Bookmarks