Simple Moving Average Filter Design


There is an answer for a true moving average filter (aka “boxcar filter”) with less memory requirements, if you don’t mind downsampling. It’s called a cascaded integrator-comb filter. The idea is that you have an integrator which you take differences of over a time period, and the key memory-saving device is that by downsampling, you don’t have to store every value of the integrator. It can be implemented using the following pseudocode:

 1function out = filterInput(in)
 3   const int decimationFactor = /* 2 or 4 or 8 or whatever */;
 4   const int statesize = /* whatever */
 5   static int integrator = 0;
 6   static int downsample_count = 0;
 7   static int ringbuffer[statesize];
 8   // don't forget to initialize the ringbuffer somehow
 9   static int ringbuffer_ptr = 0;
10   static int outstate = 0;
12   integrator += in;
13   if (++downsample_count >= decimationFactor)
14   {
15     int oldintegrator = ringbuffer[ringbuffer_ptr];
16     ringbuffer[ringbuffer_ptr] = integrator;
17     ringbuffer_ptr = (ringbuffer_ptr + 1) % statesize;
18     outstate = (integrator - oldintegrator) / (statesize * decimationFactor);
19   }
20   return outstate;

Your effective moving average length is decimationFactor * statesize but you only need to keep around statesize samples. Obviously you can get better performance if your statesize and decimationFactor are powers of 2, so that the division and remainder operators get replaced by shifts and mask-ands.

Postscript: I do agree with Olin that you should always consider simple IIR filters before a moving average filter. If you don’t need the frequency-nulls of a boxcar filter, a 1-pole or 2-pole low-pass filter will probably work fine.

Add picture from clipboard (Maximum size: 1 GB)