Play an air piano with the ultrasonic sensor

Play music without touching anything. The ultrasonic sensor measures how high your hand is, and a piano on your computer screen plays a different note for every 5 cm. Hold still to hold a note.
  • Level:Intermediate
  • Duration: 45 min
  • Ages 10+
  • Platform: Arduino

Tools for this lesson

Helpful for this build. Open a tool to see tips and more projects that use it.

Play an air piano with the ultrasonic sensor – EEMENTOR STEM™ lesson

A theremin is a strange old instrument that you play without touching it: you wave your hands near its antennas. In this lesson you build a modern relative. The ultrasonic sensor points up and measures how far away your hand is. The UNO sends that distance to the air piano in the Arduino Playground, where every 5 cm between 5 and 45 cm is one note of the scale. Move your hand up and down and you play a tune in the air; keep it still and the note keeps sounding. The built-in LED shows when your hand is in the playing zone.

What you'll learn

  • How the ultrasonic sensor measures distance with an echo
  • How a median of three readings removes jumps
  • How a range of distances is turned into musical notes
  • How a computer makes sound from a frequency

What you need

  • UNO R3 board and USB cable (UNO R3 Starter Kit)
  • Ultrasonic sensor HC-SR04 (UNO R3 Starter Kit)
  • A computer with Chrome or Edge and speakers or headphones
  • Breadboard and jumper wires (UNO R3 Starter Kit)

Wiring

Breadboard wiring diagram: Play an air piano with the ultrasonic sensor
Breadboard view. Check each connection against the wiring table below.
From To
HC-SR04 VCC 5V
HC-SR04 Trig UNO pin 9
HC-SR04 Echo UNO pin 10
HC-SR04 GND GND

Stand the sensor up so its two "eyes" look at the ceiling, for example by bending it on the breadboard or taping it to a box. Your hand plays above it.

Example screen for: Play an air piano with the ultrasonic sensor
Example screen with sample values. Yours may look different.

The sketch

const int TRIG_PIN = 9, ECHO_PIN = 10, LED_PIN = 13;

long measureCm() {
  digitalWrite(TRIG_PIN, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIG_PIN, HIGH);           // a 10 µs pulse starts one measurement
  delayMicroseconds(10);
  digitalWrite(TRIG_PIN, LOW);
  long echo = pulseIn(ECHO_PIN, HIGH, 25000);   // give up after 25 ms (about 4 m)
  return echo / 58;                       // 0 when there was no echo
}

long middleOfThree(long a, long b, long c) {
  if ((a <= b && b <= c) || (c <= b && b <= a)) return b;
  if ((b <= a && a <= c) || (c <= a && a <= b)) return a;
  return c;
}

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

void loop() {
  long a = measureCm();
  delay(5);
  long b = measureCm();
  delay(5);
  long c = measureCm();
  long cm = middleOfThree(a, b, c);       // one odd reading can't spoil it
  if (cm > 60) cm = 0;                    // far away = no hand

  digitalWrite(LED_PIN, cm >= 5 && cm < 45);   // LED on in the playing zone
  Serial.print("cm:");
  Serial.println(cm);
  delay(20);
}

Play it

  1. Upload the sketch. Open the Serial Monitor at 115200 baud for a moment to check that the numbers change when you move your hand above the sensor, then close the Serial Monitor: only one program can use the USB port at a time.
  2. Open the Arduino Playground in Chrome or Edge on a computer. These browsers can talk to a USB board through a feature called Web Serial.
  3. Click Connect your board, choose the port of your UNO (often called "USB Serial" or "CH340") and click Connect.
  4. Play! The status line says "Connected", and "Connection help" under the game shows the last line your UNO sent.

No board at hand? Click Play with the keyboard on the Playground page to try the game first.

Try Twinkle Twinkle Little Star: C C G G A A G. C is 5–10 cm, G is 25–30 cm and A is 30–35 cm.

How it works

The sensor sends a burst of ultrasound and times the echo. Sound travels about 343 metres per second, so 58 microseconds of echo time is 1 cm to the hand and 1 cm back. A flat hand reflects sound well, but sometimes the burst bounces off a finger or the side of your arm and one reading jumps. That's why the sketch measures three times and keeps the middle value, the median: a single wrong reading always ends up at the top or the bottom, never in the middle.

The game divides the space from 5 to 45 cm into eight steps of 5 cm, one for each note of the C major scale: C, D, E, F, G, A, B and the next C. Every note is a frequency: the A in the middle of a piano vibrates 440 times per second, and the next C up vibrates exactly twice as fast as the lower C. The browser has a small built-in synthesiser (Web Audio) that makes a tone at any frequency, and fades it in and out so the notes don't click.

Try this next

  • Make the zones smaller (3 cm) for a 13-note keyboard. You will need to change the numbers in your head, or keep a list next to the sensor!
  • Add a second instrument: the passive buzzer on pin 8 plays the same note with tone(), using the frequency list from the lesson about melodies.
  • Play with two hands: one hand selects the note, the other hand mutes it by covering a second sensor.

Troubleshooting

  • The notes jump around: keep your hand flat and level over the sensor, and keep other things (your arm, a table edge) out of its view cone.
  • The distance stays at 0: check Trig on 9 and Echo on 10. Swapped wires are the most common mistake.
  • No sound in the browser: click once on the game first; browsers only allow sound after you have clicked on the page. Check the volume.
  • "Could not connect" or "Failed to open serial port": another program is using the port. Close the Serial Monitor and the Serial Plotter in the Arduino IDE, then click Connect again.

Build it yourself

Everything used in this lesson comes in one kit, with parts tested by our engineers.

UNO R3 Starter Kit | Arduino IDE Compatible | Free Tutorials $56.00

Shop the kit