Trying to average analog input values over several seconds

I have been trying to use the smoothing sketch to give an average input value, but I am finding that the sketch does not seem to be suitable for this. My input will can range from 0.4V to somewhere in the 1.2V range and it can take around ten seconds or so to sweep that range That range is not linear and is also unstable. It seems that the smoothing sketch is not able to cope with such a range over that much time. Is there a better sketch that is available for something like this?

the smoothing sketch

Which sketch would that be ? Please post it here so that we can see what you are talking about.


Reads repeatedly from an analog input, calculating a running average and
printing it to the computer. Keeps ten readings in an array and continually
averages them.

The circuit:

  • analog sensor (potentiometer will do) attached to analog input 0

created 22 Apr 2007
by David A. Mellis
modified 9 Apr 2012
by Tom Igoe

This example code is in the public domain.


// Define the number of samples to keep track of. The higher the number, the
// more the readings will be smoothed, but the slower the output will respond to
// the input. Using a constant rather than a normal variable lets us use this
// value to determine the size of the readings array.
const int numReadings = 10;

int readings[numReadings]; // the readings from the analog input
int readIndex = 0; // the index of the current reading
int total = 0; // the running total
int average = 0; // the average

int inputPin = A0;

void setup() {
// initialize serial communication with computer:
// initialize all the readings to 0:
for (int thisReading = 0; thisReading < numReadings; thisReading++) {
readings[thisReading] = 0;

void loop() {
// subtract the last reading:
total = total - readings[readIndex];
// read from the sensor:
readings[readIndex] = analogRead(inputPin);
// add the reading to the total:
total = total + readings[readIndex];
// advance to the next position in the array:
readIndex = readIndex + 1;

// if we’re at the end of the array…
if (readIndex >= numReadings) {
// …wrap around to the beginning:
readIndex = 0;

// calculate the average:
average = total / numReadings;
// send it to the computer as ASCII digits
delay(1); // delay in between reads for stability

That sketch will average the readings over about 10 milliseconds. That's a far cry from "several seconds".

You need to either record more readings or record them less often (or both).

Correct, recording more inputs and extending the time would produce a better result I am sure. I did try to put in a delay, but doing that seemed to only slow down the print time and not actually spread out the sampling rate over more time.

It seems like the delay only slows the sketch down, but does not actually slow down the rate in which the sample points are taken.

The last line in your "loop()" introduces one millisecond of delay. Changing the value to 1000 will delay for 1 second and this will cause your average to be based on ~10 seconds of readings.

With a delay of 1000, my serial monitor simply gives the output every second. That seems strange to me because the "if" statement says that "average" is sent to the serial once the index is greater than or equal to the number of initial readings. So, I would have expected the serial monitor to print every ten seconds, but that does not happen.

Everything in "loop()" will be executed once every second if you set the delay to 1000. This means that one measurement and one Serial.println will be performed each second.

"if" statement says that "average" is sent to the serial once the index is greater than or equal to the number of initial readings.

No it doesn't. Look carefully where the {} braces are locate. The print statement is not inside the "if" statement block. It is in its own code block.