Running Average

Mike February 15, 20166 comments

The running average filter is a useful way to reduce noise in a system.  One project I recently worked on required a 4 times frequency output from an encoder input.  The problem was the encoder is mounted to the wheel of an old truck and bearing noise was making the original algorithm generate way too many pulses.  The original algorithm worked, but the noise on the input made it useless.

I first implemented the moving average based on this description.  In my notation this is $$M_1=M_0+t_0-A_0$$ where $M_1$ is the next moving average, $M_0$ was the previous moving average, $t_0$ is the measured time between edges and $$A_0=M_0/8$$ is the "oldest" time value.  A flow chart of the algorithm looks like this:

The constant 4 added before the $>>3$ shift is a rounding operation.  This helps smooth out the randomness instead of pure truncation.  Sometimes it's high, sometimes it is low so that on average the time estimate is close to accurate.

Another way to look at this filter is $$M_1 = M_0 + (t_0 - A_0)$$ The running average changes by the difference between the new input and the previous average.  If the difference is small, the average doesn't change.  If the difference is big, it still takes a while to work through the filter before the change is noticed.  This is great for a noisy system because the noise does not pass through to the output.  But long term changes do make it through.  The larger the change, the longer it actually takes.

So in that sense this is not really an accurate moving average.  It does not subtract off the actual data previous to the 8 values which should be summed over.  For some applications this may not be useful, but for the an encoder mounted to a bad wheel bearing it works really well.



Previous post by Mike :
   Ancient History

Comments:

[ - ]
Comment by drjohnsmithFebruary 23, 2016
I would say what you have implemented is an exponential smoothing circuit.

https://en.wikipedia.org/wiki/Exponential_smoothing


The next output depends upon the last out put and a fraction of the new input.

[ - ]
Comment by drjohnsmithFebruary 23, 2016
Its also interesting to look at the circuit output in the frequency domain.
What you have is a low pass filter,

different frequencies going in will be attenuated by different amounts,

I found this once on a trading floor when the simple moving average filter had the effect of amplifying certain regular trades and made there values more significant to the output than the random trades.
[ - ]
Comment by drmikeFebruary 23, 2016
Yes, the whole point is to remove fast changes which is definitely a low pass filter. It isn't exactly an exponential filter, but it is definitely similar. Interesting application on the stock market!
[ - ]
Comment by odissey1March 30, 2016
Thank you for describing the filter, but can you also post a code snippet (Verilog/VHDL) for the above filter?
Also why >>2 is performed on the already truncated A1?
[ - ]
Comment by drmikeMarch 30, 2016
Unfortunately the code I have is proprietary so I can't post it. The first shift on A1 divides by 8 which is the number of terms being averaged over. The final shift gives me the 4 times frequency multiply. So the whole system averages the time between samples and divides that average by 4 so the output frequency is 4 times the input (on average). In the end, this did not solve the problem because the end user was demanding _exactly_ 4 times and that's just not possible. Especially in a noisy system.

I should point out that you can do an exact sum of 8 terms using circular buffer. For high speed this does not work too well, but if you have a lot of clocks between samples it can work fairly well.
[ - ]
Comment by tonyp12April 27, 2016
running average reading battery once an hour, don't want a intermittent voltage drop making the system thinking the battery is near death.

unsigned int temp = ADC10MEM;
battery.volt = (temp + battery.volt*3) /4; // averaging 3/4 old + 1/4 new

To post reply to a comment, click on the 'reply' button attached to each comment. To post a new comment (not a reply to a comment) check out the 'Write a Comment' tab at the top of the comments.

Registering will allow you to participate to the forums on ALL the related sites and give you access to all pdf downloads.

Sign up
or Sign in