Heu guys, I am currently woking on a small code which averages the distance measurements of the Ultrasonic Sensor after every 10 values. I'm having a hard time understanding how to make the averaging work and continuously display the avaerge every 10 outputs?
Think I have this right. Sometimes this simple logic does your head in! Hope you get the idea
reading9=reading8
reading8=reading7
reading7=reading6
reading6=reading5
reading5=reading4
reading4=reading3
reading3=reading2
reading2=reading1
reading1=reading0
reading0= latest_value
reading = reading0+reading1....../10
or
reading = reading0/10 + reading1/10 .....
The reason for averaging is to get a better idea of the current state of the system.
Suppose your car is approaching an obstacle. The "best" reading is the new one. Each previous reading is progressively less relevant. And introduces its own errors because an average of ten readings tells you where you were 5 clicks ago.
A better (and simpler) approach is an Exponential moving average filter - sounds complicated but the algorithm is very simple and easy to implement in software: new EMA =A * new reading + (1-A) * last EMA.
the value A controls how much weighting you give to the latest value. 0.25 is a good starting point
This graph shows the successive weighting of each reading
That's an unfortunate notation, because it implies a lot of shuffling of data, when, of course, it's the pointers that shuffle, and not the data.
And it implies you don't keep a running total, but re-sum every iteration, when all you need is one subtraction and one addition per iteration.
But, it seems you don't want to learn about arrays, so I guess that's the way to go.
Ho-hum.
This is the way to do it, and one I've done for decades. If you cleverly have A be a negative power of 2, you can implement the algorithm using only shifts and integer arithmetic which makes it particularly efficient on generally anemic microcontrollers.
Here is what I had written about averaging ADC readings:
We can easily add a filter to average the readings. Lets say each new conversion counts as 1/16 of the current result value. That means that currentResult = 15/16 lastResult + 1/16 newConversion. To make things easy, store 16 times the values. Then currentResult = lastResult - lastResult/16 + currentResult. The division by 16 is quickly done by shifting right 4 bits. Eight is added before the division to get a rounded result.
Code is: result = result - ((result+8) >> 4) + ADCW;
While you can of course use integer arithmetic (thats one reason to choose A=0.25) the rounding errors very soon become significant if you take a smaller value (or non- negative power of 2 value) for A.
Generally I prefer to use integer arithmetic with ADC values as it avoids incorrect notions of precision.
It also makes you realise the order of operations is important!