Source: https://mokxi.com/learn/arduino-moving-average
Updated: 2026-11-02

Learn

# Arduino moving average: smoothing a noisy analog reading

Beginner

Written by the Mokxi team, updated November 2, 2026

Start building free Open the editor

Or see every lesson.

- 505 parts on the bench
- 45 boards running now
- 1.00x real time, on every board

Click to open it in the editor

Paste the smoothing sketch below in place of this one, turn the knob quickly, and watch avg and ema follow raw more slowly.

A moving average replaces each reading with the average of the last few, so the random wobble of a sensor or a potentiometer cancels out and the slow changes you care about remain. It costs a little lag and a little RAM. An exponential moving average does the same with one variable and no array, and a median gets rid of single spikes that an average only spreads out.

The circuit above is a potentiometer on A0 of an Uno, read five times a second. Set to the middle, it prints "A0 = 512 (2502 mV)" every time: the simulator’s converter reads a still knob as a still number. A real one wanders by a few counts, more with long wires or a noisy supply, so for the numbers on this page we wobbled the knob by up to 25 counts every 10 ms around 512, then moved it to 800 two seconds in.

Below is a moving average and an exponential one side by side, what each costs in lag, the zeros at the start, an integer version that never arrives, the overflow that turns 64 readings negative, and the median.

Want the step-by-step version? The lesson "Reading a voltage" walks through this with checkpoints.
Open the lesson

## A moving average of ten readings

Keep the last ten readings in an array, and a running total of them. Each pass, take the oldest reading out of the total, put the new one in its place, add it to the total, and divide by ten. That is one subtraction and one addition however many readings you keep, rather than adding up the whole array every time.

The same sketch keeps an exponential moving average as well: ema = ema + 0.1 * (raw - ema) moves a tenth of the way toward each new reading. Between 0.5 and 2 seconds the raw readings ranged from 487 to 536, the moving average from 505 to 518, and the exponential one from 505.6 to 516.9. Both cut the wobble to about a quarter.

A moving average and an exponential one

Open this sketch in the editor The code alone: the editor places the board and the parts it can read from the sketch.

## The price is lag

Smoothing means a real change shows up slowly too. When the knob moved from 512 to 800 at two seconds, the line "2112 raw 816 avg 798 ema 709.9" came 100 ms later: the moving average had arrived, because all ten readings in its array were new by then, and the exponential one was only two thirds of the way. It reached 794.9 at 2318 ms.

So the moving average of N readings lags by exactly N readings and then stops lagging, while an exponential average never quite finishes and keeps a little of every old reading. More readings, or a smaller factor than 0.1, means a smoother line that follows more slowly. Pick the size from how fast the real signal can change: a thermometer can average a second of readings, a knob a player turns wants a tenth of that.

## The zeros at the start

Both filters start from nothing. With the knob still at 512, the first line printed was "50 raw 512 avg 307 ema 239.9": the array still held zeros and the exponential average had started at 0. The moving average was right after ten readings; the exponential one was still at 510.6 after half a second.

The fix is to start them from a real reading. In setup(), read A0 once, fill the array with it and set the total to ten times it, and set ema to the same reading. Then the first value out is already right.

## An exponential average in whole numbers

Floats are slow on an Uno, so a common shortcut is ema = ema + (raw - ema) / 8; with ema an int. It never gets there. With the knob held at 800, it printed "800 793" for ever, because once the difference is under 8, dividing it by 8 gives 0 and nothing changes.

Keep the average eight times larger instead, so the fraction is not thrown away: long ema8;, then ema8 = ema8 + raw - ema8 / 8;, and ema8 / 8 is the smoothed value.

## The total needs a long

An int on an Uno holds up to 32767, and 64 readings of 1023 add up to 65472. With int total and the knob all the way up, the sketch printed "total -64 average -1". The same sketch with long total printed "total 65472 average 1023". Make the total a long whenever readings times count can pass 32767, which for a 10-bit reading is any average of more than 32.

## Spikes: use a median

An average spreads a single wild reading out rather than removing it. With the RunningAverage and RunningMedian libraries, both built into Mokxi, five readings each, one reading of 1023 among steady 512s printed "1023 average 614.2 median 512.00", and the average stayed at 614.2 until that reading left its window. The median of five ignores any one or two readings that are far from the rest.

A median costs more time, because it sorts its readings, so the common recipe is a short median to remove spikes, followed by an average to remove the wobble.

A running average and a running median

Open this sketch in the editor The code alone: the editor places the board and the parts it can read from the sketch.

Open this circuit in the editor. Arduino Uno: a potentiometer on A0, wired as it runs at the top of this page. Change a part or a value and run it again.
Open the circuit

## Questions

How do I smooth analogRead values on an Arduino?

Average the last few readings: keep them in an array with a running total and divide by how many there are. Ten readings at 10 ms apart cut random wobble to about a quarter and add 100 ms of lag.

What is the difference between a moving average and an exponential moving average?

A moving average weighs the last N readings equally and needs an array. An exponential one needs a single variable, weighs new readings most, and keeps a little of every old one, so it never quite finishes following a change.

Why does my average start at zero?

The array of readings starts full of zeros, and the first average includes them. Fill the array with the first real reading in setup(), and start an exponential average from it too.

Why is my average negative?

The total overflowed an int. On an Uno an int stops at 32767, so more than 32 readings of up to 1023 need a long for the total.

Is there a smoothing library for Arduino?

Yes: RunningAverage and RunningMedian by Rob Tillaart are common, and both work in Mokxi. They do what the sketches on this page do, and the median one also removes single spikes.

Related

## Keep going

Analog vs Digital Pins, and ADC Resolution Arduino Potentiometer Wiring and Code: Dim an LED Arduino Array: Lists of Pins, Patterns and Notes Arduino Data Types: int, long, float and byte Arduino map() Function: Scale Any Reading ESP32 analogRead: 12 Bits, Attenuation and ADC2 The project page, with the full sketch Beginner

Sources

## Where the facts on this page come from

- Arduino: Smoothing
- RunningAverage on GitHub
- RunningMedian on GitHub

## Build this for real

Open the editor, change a value and watch the number move with it. Nothing to install, and no account needed.

Start building free Open the editor
