Error in Smoothing tutorial code

I was working on a project that is reading an analog input on my Uno. The input seams a bit noisy as the value jumps around a little without a change to the actual input ( I was using a linear POT connected to 5v and gnd with the center wiper going to the input).

So I was looking for examples of smoothing code and ran onto the tutorial here on the site. I implemented the code in my design and it works well although the averaged response to the change can take a while to influence the result (I already knew that though). I spent some time looking at the code and trying to come up with ways to improve it without changing the size of the array.

I doing that I realized that there was an error int eh code as it was originally posted. The error is in the main loop in the following section:

readings[index] = analogRead(inputPin);
// add the reading to the total:
total= total + readings[index];
// advance to the next position in the array:
index = index + 1;

// if we're at the end of the array...
if (index >= numReadings) The check is for greater than or equal to but the current index has not been used yet. Thus readings[numReadings] is never actually changed from the initialization value.
// ...wrap around to the beginning:
index = 0;

// calculate the average:
average = total / numReadings;

As noted above (in red) there is a test to see if the index for the Array is greater than or equal to the value set for the last index in the array. However, the index was incremented one line above that and the current index location in the array has not been used. Then the index is set to 0. The issue with this is that the rest of the logic assumes that there are numReadings values in the sum that is averaged in the calculation. Thus total will contain the sum of n values and it is divided by n+1.

So even on the best of days chances are your averaged value will never reach the true average even if the input could be held at one value for numReadings times through the loop. It's a small issue and can easily be fixed by changing the line to read:

if (index > numReadings)

instead of the original code. The result is probably close enough for most times that this is used but for what I was doing it was causing me problems. Hope this helps someone else out that was having the similar issue that I was. Krazie

Thus readings[numReadings] is never actually changed from the initialization value.

There is no readings[numReadings] - it would be off the end of the array.

Is that true is the array was defined using readings[numReadings]? Why would the array be define-1? That doesn't make much sense. If I ask for an array of n elements then I should expect n elements not n-1. Is that not true?

You can't see how 'total' is initialized in this code snippit, but if you start total at 0, you don't get the desired rounding effect. Consider if 9 of 10 readings are 1 and one is 0.

average = total / numReadings;
average = 9 / 10
average = 0

But the expected value would be 1.

Starting off with

total = numReadings / 2;

... then adding up the values would give you

average = (5 + 9) / 10
average = 1

Krazie4Acans:
I should expect n elements not n-1. Is that not true?

100% true. The trick is that they are numbered with 0 being the first one. For an array of 10, the elements are numbered 0, 1, 2,... 9.

In the tutorial everything is initialized to 0. total, average, all elements of the array, etc. Not numReadings obviously.

So that is probably why I am seeing the rounding issue. Looks like the code is correct and my issue is just coming from rounding due to simple math. I'll look at fixing that instead of writing to an array index that might put me in the weeds. :slight_smile: Thanks guys. Krazie