Efficient way of buffering and averaging values

Hi!

I'm currently working with an analog medical sensor and want to apply some filtering on the signal. I want to filter the signal and combine that with the original signal. I therefore want to create a moving average that doesn't phase shift the signal.

From this link I learned that I have to create an odd sized moving average filter with an equal amount of values at both sides of the current value. I need to filter based on around 150 values and sample with 100Hz on a Teensy.

To buffer values in an array I currently use the following for loop:

int window = 149

for (int i = window - 1; i > 0 ; i--) {

                interval[i] = interval[i - 1];
                
              }

              // Add latest found interval to array
           
              interval[0] = signal;

I feel that this can be done more efficiently especially because of the rather large window.

Anyone has a suggestion how to approach this more efficiently?

don't shift all the data - read about the circular buffers coding idea

I need to filter based on around 150 values

Note that in your code above you are not dealing with interval[149] - not sure if you have actually 150 values or only 149?

Hi JML, thanks the circular buffer seems like just what I need. I implemented it using this library, if anyone else ever is looking for this information

Note that in your code above you are not dealing with interval[149] - not sure if you have actually 150 values or only 149?

In this case I indeed wanted to have 149 values. Thanks for checking!

What would be the best way to calculate the average of the whole buffer?

What would be the best way to calculate the average of the whole buffer?

  • the brute force approach is to sum it up and divide by the number of values

  • the smart approach is to do the sum only once and then - before you shift a new value in, you subtract from the sum the value that will get discarded and add the new one getting in. This way you don't have to sum 149 new values every time to get the average, it's just one addition, on subtraction and then dividing by 149.

(you need to ensure you've filled up the buffer of course first - the library you used as a isFull() method for that)

That optimization only applies when the filter coefficients are all 1, i.e. with the naive window averaging here,
but such a filter cannot have a great low-pass response however many samples you average over as its
response is inherently a sinc(x) one.

I suspect a lower order FIR filter might do a better job - so what is the sample rate and what cutoff frequency would you want the filter to have?

Hi Mark,

thanks for thinking along.
The samplerate is 100Hz. The desired cutoff frequency is 0.3Hz.