Skip to content

Sensors & Signal Processing

How a moving average filter smooths a noisy sensor

A moving average smooths a noisy sensor by replacing each reading with the average of the last N readings. Random noise pushes each reading a different way, so in a sum the ups and downs partly cancel while the real value adds up in full. Averaging N readings shrinks the noise by about √N: 16 readings leave a quarter of it. The cost is time.

Why averaging works

Say a sensor reads 511 with noise of up to ±30. One reading might say 538, the next 494. Add 16 readings together and the true 511 adds up 16 times, but the noise, pointing every which way, grows only about √16 = 4 times as much. Divide by 16 and the noise has shrunk to a quarter:

noise after averaging ≈ noise of one reading over √N

So ±30 becomes about ±7.5 with 16 readings, and about ±3.75 with 64. Each halving of the noise needs four times the readings.

Live experiment

Average away the flicker

A knob at half reads 511 with ±30 of noise, and the lamp lights above 530. Average 1, 4, 16 or 64 readings per decision and run it for 2 s: one reading flashes the lamp about 26 times; sixteen cut the wobble to a quarter and keep it dark.

Try it yourself: free lesson

“A noisy reading” is lesson 1 of 6 in Signal Sands, Sensors & Signal Processing World 1. Free with an account. It’s open as soon as you sign up.

A running average in code

A moving average keeps the last N readings in a ring buffer and a running total. Each new reading replaces the oldest, so there's an average on every sample, not just every N:

const int N = 16;
int buf[N];
int idx = 0;
long total = 0;

int smoothed(int reading) {
  total = total - buf[idx] + reading;   // drop the oldest, add the newest
  buf[idx] = reading;
  idx = (idx + 1) % N;
  return total / N;
}

The total is a long because 64 readings near 1023 add up to more than an Uno's int can hold. The buffer starts full of zeros, so the first N outputs climb up from 0; fill it with real readings in setup() if that matters.

What it costs

Averaging only removes random noise. A steady offset, a wrong calibration, survives any amount of averaging. And a single wild spike, from a loose wire, gets smeared into several outputs instead of removed; a median filter handles those better.

Where you'll meet it

Thermometers, scales, battery gauges and light meters all average their readings, because people would rather see a steady number than a flickering one. When memory is tight, an exponential moving average gives a similar result with one variable instead of a buffer.

Free lesson

Now build it yourself

Each lesson comes in three short parts: see the idea, try it on a live board, then build it yourself, with quick checks as you go.

Try it yourself: free lesson

“A noisy reading” is lesson 1 of 6 in Signal Sands, Sensors & Signal Processing World 1. Free with an account. It’s open as soon as you sign up.

Or start from the very first lesson, no account needed

Practice questions

Three quick questions from the lessons. Pick an answer to check it.

  1. Question 1 of 3A sensor's noise is ±30 on a single reading. Averaging 16 readings leaves about…
    Show the answer

    Answer: ±7. Noise shrinks by the square root of the number of readings: √16 is 4, and 30 ÷ 4 is about 7.

    • Why not “±2”? ±2 would need far more readings. Noise falls with the square root of N, so 16 readings cut it by 4, not 15.
    • Why not “±30”? Averaging does shrink random noise; ±30 would mean it had no effect at all.
    • Why not “±16”? ±16 confuses the number of readings with the noise. 30 ÷ √16 is 30 ÷ 4, about 7.
  2. Question 2 of 3Averaging more readings always costs…
    Show the answer

    Answer: Time: the answer comes slower. Each reading takes time to make. Sixty-four of them make the answer sixty-four times slower to arrive.

    • Why not “Nothing”? It does cost something: each answer needs many readings, so it comes more slowly.
    • Why not “Memory only”? A running total needs little memory. The real cost is time: the answer arrives later.
    • Why not “Accuracy”? Averaging makes a reading more accurate, not less, as long as the thing measured is steady.
  3. Question 3 of 3Averaging 64 readings per pass instead of 16 makes the lamp…
    Show the answer

    Answer: Steadier, but it reacts four times more slowly. Four times the readings is a quarter of the noise and four times the time per decision. Averaging always trades speed for steadiness.

    • Why not “Steadier and faster”? More readings can't make the answer faster: each decision waits for four times as many.
    • Why not “Flicker more”? More averaging always reduces random noise, so it flickers less, not more.
    • Why not “The same”? Four times the readings halves the noise again, so the lamp does change: steadier and slower.
Keep practising: free lesson

“A noisy reading” is lesson 1 of 6 in Signal Sands, Sensors & Signal Processing World 1. Free with an account. It’s open as soon as you sign up.

Questions people ask

How does a moving average filter reduce noise?

Random noise pushes each reading up or down by a different amount, so when you add several together the ups and downs partly cancel, while the true value adds up in full. Averaging N readings shrinks random noise by about the square root of N.

How many samples should a moving average use?

Enough to bring the noise under what you can tolerate, and no more, because each extra sample adds delay. Noise falls with √N, so 4 samples halve it, 16 quarter it and 64 cut it to an eighth.

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

A moving average weights the last N readings equally and needs to store them. An exponential moving average keeps one running value and nudges it toward each new reading, so older readings fade gradually. It needs no buffer and is the more common choice on microcontrollers.

Every topic