Have you ever wanted to control music just by waving your hand? In this project, we are building an "Air Radio" (or Air Piano) using an Arduino Nano and a custom sensor shield. By moving your hand closer to or further away from the device, you can trigger different classic tunes—all while a display keeps you updated on what's currently playing.
Let's break down how this magic works, the hardware you need, and the clever software tricks used to keep the experience smooth and responsive. Code for this project is available here.
The Hardware Setup
Because we are using an Arduino Nano with a shield, wiring up the components is incredibly straightforward. Here is what is driving the project:
-
Ultrasonic Sensor (HC-SR04): This acts as our "eye," measuring exactly how far away your hand is. The
TRIG_PINis connected to pin 9, and theECHO_PINis connected to pin 10. - Passive Buzzer: This is our speaker. It's connected to pin 11, waiting for specific frequencies to generate our musical notes.
- I2C LCD Display: To show the current status and song, we are using an LCD panel operating on I2C address 0x27.
Component Pinout Guide
Wire your components to the Arduino Nano using the following connections (standard I2C and power pins are assumed based on the standard Nano architecture):
| Component | Component Pin | Arduino Nano Pin | Function |
|---|---|---|---|
| Ultrasonic Sensor | VCC | 5V | Power supply |
| Ultrasonic Sensor | GND | GND | Ground |
| Ultrasonic Sensor | TRIG_PIN | D9 | Trigger pulse |
| Ultrasonic Sensor | ECHO_PIN | D10 | Receive echo |
| Passive Buzzer | Positive / Signal | D11 | Plays musical notes |
| Passive Buzzer | GND | GND | Ground |
| I2C LCD | VCC | 5V | Power supply |
| I2C LCD | GND | GND | Ground |
| I2C LCD | SDA | A4 | I2C Data line |
| I2C LCD | SCL | A5 | I2C Clock line |
How It Works: The Distance Zones
The core logic of the Air Radio revolves around dividing the space in front of the sensor into specific "zones." As the sensor constantly calculates the distance, the Arduino maps that distance to a specific action:
To prevent erratic readings, any distance reading over 200 cm is safely ignored and capped out.
Technical Highlights in the Code
This code isn't just a basic loop; it solves a few notorious issues that plague beginner Arduino projects: screen flickering and unresponsive delay loops.
1. Custom I2C Drivers for the LCD
Instead of relying on standard third-party libraries (like LiquidCrystal_I2C), this code gets right down to the bare metal. It uses standard Wire.h to send low-level 4-bit instructions directly to the LCD. This keeps the compiled memory footprint light and gives complete control over the display's initialization.
2. Flicker-Free Screen Updates
A common mistake in display projects is clearing and redrawing the screen on every single loop. This causes a terrible flickering effect. To solve this, the code implements a state-tracking variable called currentZone. The LCD only receives a clear and redraw command when your hand actually moves from one zone to a completely different one.
3. "Snappy" Dynamic Playback
Playing music on an Arduino usually involves the delay() function, which freezes the entire board until the note is done playing. If you move your hand away, you would normally have to wait for the whole song to finish before the Arduino noticed!
To fix this, the playSong function breaks down the pause between notes into tiny, 20-millisecond chunks. During every single one of those tiny chunks, it rapidly checks the ultrasonic sensor again. If it detects that your hand has left the active zone, it immediately kills the buzzer tone and breaks out of the playback loop. This makes the instrument feel incredibly fast and responsive.
Powering It Up
When you first power on the Nano, the screen boots up with a friendly initialization message: "AIR PIANO / READY TO PLAY".
From there, it's all in the hands of the user. Just hover your hand over the sensor, find the sweet spots, and enjoy the music!