Sharjah, UAE GST
Home/ Projects/ Lesson 7: Smoothing Noisy Readings
Lesson 7 of 9 Sensing Intermediate ◎ 30 min

Lesson 7: Smoothing Noisy Readings

Draw three lines on a live graph - raw, average and median - and see which filter handles a sudden spike best.

Arduino Ultrasonic Distance & Parking Learning Kit
One of 9 projects in the Arduino Ultrasonic Distance & Parking Learning Kit — the parts below are from that kit.

Before you start

Time
30 min
Do these first
On your own
You can do this lesson on your own.

Exact parts

PartHow many
Wiring from Lesson 1 (the other parts can stay)
A book, and your hand (yours)

Not in the box

Nothing extra - just the kit and your computer.

What you build and learn

  • What a filter does to noisy data
  • Average (mean) versus median
  • Arrays: keeping the last 5 readings
  • Drawing live graphs with the Serial Plotter

Every 80 ms the sketch stores the newest good reading in history[], an array of 5. When it is full, the newest reading replaces the oldest, going round in a circle.

The average adds the 5 and divides by 5. It is smooth, but a single wrong reading pulls it off, and it is slow to catch up when the target really moves.

The median sorts the 5 and takes the middle. One spike sits at the end of the sorted list and is ignored. But it too needs 3 new readings before it follows a real move.

Every filter trades smoothness for delay. Lesson 9 uses the median, because ignoring spikes matters most for a parking beeper.

New words

Filter
Code that cleans up readings, for example by combining the last few.
Average (mean)
Add the numbers and divide by how many there are.
Median
Sort the numbers and take the middle one. One wild number cannot move it much.
Array
A row of boxes with one name, such as history[0] to history[4].
Serial Plotter
Tools → Serial Plotter: draws the numbers the UNO sends as moving lines.

What this project uses

Every item is in the kit — nothing extra to buy.

Build this with

Arduino Ultrasonic Distance & Parking Learning Kit

All 9 parts in one box, with this project and 8 more to build from them.

AED 85.00 See the kit
Need only these parts? Order them loose · from AED 78.30
Used in this project tick what you still need
Also needed untick if you already have them
Selected parts AED 78.30

One of each part. Packs (resistor assortment, jumper wires) already hold more than a single build needs. a computer with the Serial Plotter, your hand or a book: included in the kit, ask us for it loose. Delivery is AED 20, free on orders AED 100+.

Connections

Unplug USB before you change any wire. Pin names are the labels printed on the board.

Lesson 7: Smoothing Noisy Readings - connection diagram with labelled pins
Connection diagram, drawn from this lesson's pin plan - not a photo of a tested build. Tap to open it full size. The table below says the same thing in words.
Part / pinConnect toNote
No changesSensor as in Lesson 1TRIG pin 9 · ECHO pin 10

Step by step

One thing at a time. Tick nothing off until it matches the diagram.

  1. Upload the Lesson 7 code. No wiring changes are needed.
  2. Close the Serial Monitor, then open Tools → Serial Plotter at 9600 baud.Watch out: Only one of the two can be open at a time.
  3. Hold a book still 40 cm away: the three lines lie on top of each other.
  4. Wave your hand quickly through the beam: watch which line jumps.
  5. Now move the book smoothly from 40 cm to 20 cm: watch which line lags behind.

Sketch for this project

Written for the board in the kit. Copy it into the Arduino IDE; change the pin numbers if you wire it differently.

lesson7_smoothing.ino arduino
/*
  DIY KIT - Arduino Ultrasonic Distance & Parking Learning Kit
  Lesson 7 of 9: Smoothing Noisy Readings

  WIRING: the sensor from Lesson 1 (TRIG pin 9, ECHO pin 10).

  WHAT SHOULD HAPPEN
    Open Tools > Serial Plotter at 9600 baud. Three lines follow the target:
      raw     - every single reading (jumpy)
      average - the mean of the last 5 readings (smooth, but slow to react)
      median  - the middle of the last 5 readings (ignores single spikes)
    Wave a hand quickly through the beam and watch which line jumps.
*/

const int TRIG_PIN = 9;
const int ECHO_PIN = 10;

const int WINDOW = 5;                          // how many readings each filter remembers - try 3 or 9
const unsigned long ECHO_TIMEOUT_US = 30000;
const int MIN_CM = 2;
const int MAX_CM = 400;

long history[WINDOW];     // the last WINDOW good readings
int filled = 0;           // how many slots hold a reading so far
int nextSlot = 0;         // where the next reading goes

long readOnceCm() {
  digitalWrite(TRIG_PIN, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIG_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG_PIN, LOW);
  unsigned long us = pulseIn(ECHO_PIN, HIGH, ECHO_TIMEOUT_US);
  if (us == 0) return 0;
  long cm = us / 58;
  if (cm < MIN_CM || cm > MAX_CM) return 0;
  return cm;
}

long averageOfHistory() {
  long total = 0;
  for (int i = 0; i < filled; i++) total = total + history[i];
  long average = total / filled;   // whole centimetres
  return average;
}

long medianOfHistory() {
  long sorted[WINDOW];
  for (int i = 0; i < filled; i++) sorted[i] = history[i];
  for (int i = 1; i < filled; i++) {          // sort, smallest first
    long value = sorted[i];
    int j = i - 1;
    while (j >= 0 && sorted[j] > value) {
      sorted[j + 1] = sorted[j];
      j--;
    }
    sorted[j + 1] = value;
  }
  return sorted[filled / 2];                  // the middle one
}

void setup() {
  pinMode(TRIG_PIN, OUTPUT);
  pinMode(ECHO_PIN, INPUT);
  Serial.begin(9600);
}

void loop() {
  long cm = readOnceCm();
  if (cm > 0) {                                // skip "no echo" readings
    history[nextSlot] = cm;
    nextSlot = (nextSlot + 1) % WINDOW;        // go round in a circle
    if (filled < WINDOW) filled++;

    // "name:value,name:value" is the format the Serial Plotter draws.
    Serial.print("raw:");
    Serial.print(cm);
    Serial.print(",average:");
    Serial.print(averageOfHistory());
    Serial.print(",median:");
    Serial.println(medianOfHistory());
  }
  delay(80);
}
ℹCompiler-checked for Arduino UNO (0 warnings) and run in the kit simulator. Pins match the lesson diagram. Not yet bench-tested on the shipped parts.

Upload it

  1. Click Copy (or Download .ino and open the file).
  2. In the Arduino IDE choose File → New Sketch, select everything in it and paste.
  3. Check the bottom of the window says Arduino Uno and your port (Start here, step 5).
  4. Click Upload (the → arrow) and wait for Done uploading.

How the code works

In the codeWhat it does
long history[WINDOW];The array that remembers the last 5 readings.
nextSlot = (nextSlot + 1) % WINDOW;Moves to the next box and wraps from 4 back to 0.
medianOfHistory()Copies the readings, sorts them smallest first, and returns the middle one.
Serial.print("raw:") ...The "name:value,name:value" pattern is what the Serial Plotter draws as labelled lines.

Change it and see

Change: Change WINDOW from 5 to 9.What happens: Both filters get smoother and slower.
Change: Change WINDOW from 5 to 3.What happens: They react faster but let more noise through.

What you should see or hear

  • Three lines - raw, average, median - that sit together while the book is still.
  • A quick hand wave: raw jumps, average bumps, median barely moves.
  • A smooth move: average and median follow a moment after raw.

If it doesn't work

ProblemWhat to check
The Plotter shows nothingClose the Serial Monitor first, then open the Plotter. Check the speed is 9600 baud.
Only one lineUpload the Lesson 7 code again: the line names come from the raw:, average: and median: labels.
The lines jump to 0No echo readings are skipped, so 0 should not appear. If it does, check the sensor wiring.
The upload failsSee Start here, step 6: "If the upload fails".

Small experiment

Numbers 30, 30, 31, 120, 30. Work out the average and the median by hand. Which one is closer to the real 30 cm?

Check what you learned

What is the median of 4, 9, 5, 100, 6?

Sorted: 4, 5, 6, 9, 100 → the middle one is 6.

Why does the average lag when the book moves?

It still includes the older readings from where the book was.

Which filter is better at ignoring a single spike?

The median.

▶In the simulator: In the simulator the readings never spike, so drag the distance slider quickly instead to see the lag.

Next

  • Lesson 8 adds the OLED screen, so the distance shows without a computer screen.

Stuck?

Most problems are one wire in the wrong hole. Check these first:

  1. Unplug, then compare every wire with the lesson's diagram and table. One pin off is the most common problem.
  2. Sensor: are VCC, TRIG, ECHO and GND wired by their labels, with TRIG on 9 and ECHO on 10?
  3. LEDs: is the long leg on the resistor side?
  4. Is the − rail connected to a UNO GND pin, and the + rail to 5V?
  5. Serial Monitor: is it set to 9600 baud (and "New Line" when you type commands)?
  6. Upload problems: is Tools → Board set to Arduino Uno and Tools → Port to your UNO? (Start here, step 5.)
Still stuck? Ask us on WhatsApp. Send this message with a photo of your wiring - it tells us exactly where you are.
Hi DIY KIT, I'm stuck on the Arduino Ultrasonic Distance & Parking Learning Kit.
Lesson: __
Step number: __
What should happen: __
What happens instead: __
Error message (copied exactly): __
I'll attach a photo of my wiring.
Message us on WhatsApp

More from this kit

All projects →

Bot
ECHO
Online — usually replies instantly
Catalog assistant: verify final stock/price on the product page before checkout.