# averaging filter program

I have a arduino "averaging filter" that looks like this:

``````const int numReadings = 35;

int index = 0;                  // the index of the current reading
int total = 0;                  // the running total
int average = 0;                // the average

int index_ = 0;                  // the index of the current reading
int total_ = 0;                  // the running total
int average_ = 0;

int indexA = 0;                  // the index of the current reading
int totalA = 0;                  // the running total
int averageA = 0;                // the average

int index_A = 0;                  // the index of the current reading
int total_A = 0;                  // the running total
int average_A = 0;

//============================================================================================

int filter_x(int num) {
// advance to the next position in the array:
index = index + 1;

// if we're at the end of the array...
// ...wrap around to the beginning:
index = 0;

// calculate the average:

return average;
}

int filter_y(int num) {
// advance to the next position in the array:
index_ = index_ + 1;

// if we're at the end of the array...
// ...wrap around to the beginning:
index_ = 0;

// calculate the average:

return average_;
}

int filter_xA(int num) {
// advance to the next position in the array:
index = index + 1;

// if we're at the end of the array...
// ...wrap around to the beginning:
index = 0;

// calculate the average:

return average;
}

int filter_yA(int num) {
// advance to the next position in the array:
index_ = index_ + 1;

// if we're at the end of the array...
// ...wrap around to the beginning:
index_ = 0;

// calculate the average:

return average_;
}
``````

I really don't understand after studying it for 1 entire day, can anybody kindly explain how this works?

Thanks

It works like any average (arithmetic mean); 1) add up all the samples, and 2) divide by the number of samples. However, because new samples are coming in each cycle, it keeps a circular buffer of samples, puts in the most recent and removes the oldest. You only need to add in the new value and subtract the oldest value from a running total, but obviously you have to store all samples to know which is the oldest.

The example isn't (IMHO) very well written - virtually identical code is repeated four times - the addition of a simple structure would reduce the amount of code to about a third of what's there, and make it easier to maintain and debug.

Another thing about this filter - before it has collected its first 'n' samples, it will return a false mean, because the running total won't have 'n' samples-worth of data in it.

This is an example of a digital filter or DSP (Digital Signal Processing) , this can be quite complex and mathematical, a good introduction to the topic is here:- https://ccrma.stanford.edu/~jos/filters/

Try this:-

Yn=Yn-1+(1/kana*(Xn-Yn-1)) // Averaging formula

Very easy to implement. See here:-

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1264723470

Ian.

Just remember the fewer the terms the lower order is the filter. The best filters have a lot of terms in them. Like so many things in life there is a trade off. This time between performance and complexity. Also the more complex a filter the longer it takes to compute and so the lower the frequency you can use it at given a fixed amount of processing power.

Ian,
I don’t quite understand your formula, specifically the two “-1” terms.
Yn=Yn-1+(1/kana*(Xn-Yn-1))

By rearranging the terms it becomes:
Y = (1-k)Y + kX - (1+k); // where k = 1/kana

The first part is a formula that I’m familiar with and use quite often. But I don’t understand the highlighted portion. It would seem to give you a permanent offset from the true value. I.e. if X were perfectly constant then Y would eventually become equal to X - (1+k).

Yn=Yn-1+(1/kana*(Xn-Yn-1))

I think this is missing some subscripts?

Yn=Yn-1+(1/kana*(Xn-Yn-1))

Just to explain to those who don’t know:-

Yn is the nth result you get

Yn-1 is the result you got before the nth result.

Xn is the nth sample you take.

That would make a lot more sense, and would match the formula that I've used a number of times before. It's just that the code shown in the linked post was actually subtracting the "1", which is why that didn't make sense to me.

Quote:

``````AnaIY0 = AnaIY0 - 1 + (1 / kana * ((float)AI_Raw0 - AnaIY0 - 1));
``````

Correct implementation would be:

``````Y = Y + (1/kana * (X-Y));

// OR

Y = k * X + (1- k) * Y;  // where k = 1/kana
``````

i got it, thks 4 all the replies :)

Y = k * X + (1- k) * Y; // where k = 1/kana

For a reasonably fast approximation, using powers of 2:

``````Y = (X - (X >> Pow2)) + (Y >> Pow2);
``````

Extra marks awarded for fixed-point representations.