QC

Play music in the air! | Arduino Air Piano Project

The Air Piano is a hands-free musical instrument that allows you to play songs in the air by moving your hand.

Devices and components

Arduino Uno Rev3

Breadboard - 830 contacts

10 connecting wires 150 mm male

resistance 220

Passive ringing

LED lights

Jumper Male to Female 20 cm

Ultrasonic sensor HC-SR04

Software and tools

Arduino IDE

Project description

Air Piano demonstration.

Air Piano Making Tutorial

Mode 1: Follow the song

Mode 2: Free Play (Air Piano)

Advanced ideas you can try:

Air Piano

Simply copy this code into the Arduino IDE.

1#define ECHO_PIN 3
2#define TRIGGER_PIN 4
3
4#define LED_Do 13
5#define LED_Re 12
6#define LED_Mi 11
7#define LED_Fa 10
8#define LED_Sol 9
9#define LED_La 8
10#define LED_Si 7
11#define LED_Do_High 6
12
13#define BUZZER_PIN 2
14
15unsigned long last_time_ultrasonic_trigger = millis();
16unsigned long ultrasonic_trigger_delay = 100;
17
18volatile unsigned long pulse_in_begin;
19volatile unsigned long pulse_in_end;
20volatile bool new_distance_available = false;
21
22const int time_delay = 500;
23
24// 🎵 Notes (8 notes: Do Re Mi Fa Sol La Si Do)
25int notes[] = {
26 523, // Do (C5)
27 587, // Re (D5)
28 659, // Mi (E5)
29 698, // Fa (F5)
30 784, // Sol (G5)
31 880, // La (A5)
32 988, // Si (B5)
33 1046 // Do (C6)
34};
35
36// 🎵 SONGS
37int melody_mary[] = {
38 LED_Mi, LED_Re, LED_Do, LED_Re, LED_Mi, LED_Mi, LED_Mi,
39 LED_Re, LED_Re, LED_Re, LED_Mi, LED_Sol, LED_Sol, LED_Mi, LED_Re,
40 LED_Do, LED_Re, LED_Mi, LED_Mi, LED_Mi, LED_Re, LED_Re,
41 LED_Mi, LED_Re, LED_Do
42};
43int length_mary = sizeof(melody_mary) / sizeof(melody_mary[0]);
44
45int melody_twinkle[] = {
46 LED_Do, LED_Do, LED_Sol, LED_Sol, LED_La, LED_La, LED_Sol,
47 LED_Fa, LED_Fa, LED_Mi, LED_Mi, LED_Re, LED_Re, LED_Do,
48 LED_Sol, LED_Sol, LED_Fa, LED_Fa, LED_Mi, LED_Mi, LED_Re,
49 LED_Sol, LED_Sol, LED_Fa, LED_Fa, LED_Mi, LED_Mi, LED_Re,
50 LED_Do, LED_Do, LED_Sol, LED_Sol, LED_La, LED_La, LED_Sol,
51 LED_Fa, LED_Fa, LED_Mi, LED_Mi, LED_Re, LED_Re, LED_Do
52};
53int length_twinkle = sizeof(melody_twinkle) / sizeof(melody_twinkle[0]);
54
55int melody_bus[] = {
56 LED_Do, LED_Do, LED_Do, LED_Mi, LED_Sol,
57 LED_Mi, LED_Do, LED_Re, LED_Do, LED_Re,
58 LED_Sol, LED_Mi, LED_Do, LED_Do, LED_Do,
59 LED_Do, LED_Mi, LED_Sol, LED_Mi, LED_Do,
60 LED_Re, LED_Sol, LED_Do, LED_Do
61};
62int length_bus = sizeof(melody_bus) / sizeof(melody_bus[0]);
63
64int melody_yankee_doodle[] = {
65 LED_Fa, LED_Fa, LED_Sol, LED_La, LED_Fa, LED_La, LED_Sol,
66 LED_Fa, LED_Fa, LED_Sol, LED_La, LED_Fa, LED_Mi,
67 LED_Fa, LED_Fa, LED_Sol, LED_La, LED_Si, LED_La, LED_Sol,
68 LED_Fa, LED_Mi, LED_Do, LED_Re, LED_Mi, LED_Fa, LED_Fa
69};
70int length_yankee_doodle = sizeof(melody_yankee_doodle) / sizeof(melody_yankee_doodle[0]);
71
72int* current_melody = melody_mary;
73int current_melody_length = length_mary;
74
75int melody_tracker = 0;
76bool free_play_mode = false;
77
78void trigger_ultrasonic_sensor() {
79 digitalWrite(TRIGGER_PIN, LOW);
80 delayMicroseconds(2);
81 digitalWrite(TRIGGER_PIN, HIGH);
82 delayMicroseconds(10);
83 digitalWrite(TRIGGER_PIN, LOW);
84}
85
86void echo_pin_interrupt() {
87 if (digitalRead(ECHO_PIN) == HIGH) {
88 pulse_in_begin = micros();
89 } else {
90 pulse_in_end = micros();
91 new_distance_available = true;
92 }
93}
94
95double get_distance() {
96 double duration_micros = pulse_in_end - pulse_in_begin;
97 return duration_micros / 58.0;
98}
99
100void turn_off_all_leds() {
101 digitalWrite(LED_Do, LOW);
102 digitalWrite(LED_Re, LOW);
103 digitalWrite(LED_Mi, LOW);
104 digitalWrite(LED_Fa, LOW);
105 digitalWrite(LED_Sol, LOW);
106 digitalWrite(LED_La, LOW);
107 digitalWrite(LED_Si, LOW);
108 digitalWrite(LED_Do_High, LOW); // Turn off high Do
109}
110
111void setup() {
112 Serial.begin(115200);
113 pinMode(ECHO_PIN, INPUT);
114 pinMode(TRIGGER_PIN, OUTPUT);
115 pinMode(LED_Do, OUTPUT);
116 pinMode(LED_Re, OUTPUT);
117 pinMode(LED_Mi, OUTPUT);
118 pinMode(LED_Fa, OUTPUT);
119 pinMode(LED_Sol, OUTPUT);
120 pinMode(LED_La, OUTPUT);
121 pinMode(LED_Si, OUTPUT);
122 pinMode(LED_Do_High, OUTPUT);
123 pinMode(BUZZER_PIN, OUTPUT);
124
125 attachInterrupt(digitalPinToInterrupt(ECHO_PIN), echo_pin_interrupt, CHANGE);
126
127 Serial.println("🎶 Select a song to play:");
128 Serial.println("1 - Mary Had a Little Lamb");
129 Serial.println("2 - Twinkle Twinkle Little Star");
130 Serial.println("3 - The Wheels on the Bus");
131 Serial.println("4 - Yankee Doodle");
132 Serial.println("0 - Free play mode (Air Piano)");
133}
134
135void loop() {
136 unsigned long time_now = millis();
137
138 if (Serial.available() > 0) {
139 char input = Serial.read();
140 melody_tracker = 0;
141
142 if (input == '1') {
143 current_melody = melody_mary;
144 current_melody_length = length_mary;
145 free_play_mode = false;
146 Serial.println("Now playing: Mary Had a Little Lamb");
147 } else if (input == '2') {
148 current_melody = melody_twinkle;
149 current_melody_length = length_twinkle;
150 free_play_mode = false;
151 Serial.println("Now playing: Twinkle Twinkle Little Star");
152 } else if (input == '3') {
153 current_melody = melody_bus;
154 current_melody_length = length_bus;
155 free_play_mode = false;
156 Serial.println("Now playing: The Wheels on the Bus");
157 } else if (input == '4') {
158 current_melody = melody_yankee_doodle;
159 current_melody_length = length_yankee_doodle;
160 free_play_mode = false;
161 Serial.println("Now playing: Yankee Doodle");
162 } else if (input == '0') {
163 free_play_mode = true;
164 Serial.println("🎹 Free play mode activated!");
165 } else {
166 Serial.println("Invalid choice. Please enter 0, 1, 2, 3, or 4.");
167 }
168 }
169
170 if (time_now - last_time_ultrasonic_trigger > ultrasonic_trigger_delay) {
171 last_time_ultrasonic_trigger = time_now;
172 trigger_ultrasonic_sensor();
173 }
174
175 if (!free_play_mode && melody_tracker < current_melody_length) {
176 int next_led = current_melody[melody_tracker];
177 turn_off_all_leds();
178 digitalWrite(next_led, HIGH);
179 }
180
181 if (new_distance_available) {
182 new_distance_available = false;
183 double distance = get_distance();
184 int note_index = -1;
185
186 if (distance > 2 && distance <= 10) note_index = 0;
187 else if (distance > 10 && distance <= 20) note_index = 1;
188 else if (distance > 20 && distance <= 30) note_index = 2;
189 else if (distance > 30 && distance <= 40) note_index = 3;
190 else if (distance > 40 && distance <= 50) note_index = 4;
191 else if (distance > 50 && distance <= 60) note_index = 5;
192 else if (distance > 60 && distance <= 70) note_index = 6;
193 else if (distance > 70 && distance <= 80) note_index = 7; // NEW: High Do
194
195 if (note_index != -1) {
196 int led;
197 if (note_index == 7) {
198 led = LED_Do_High; // NEW High Do
199 } else {
200 led = LED_Do - note_index;
201 }
202
203 if (free_play_mode) {
204 turn_off_all_leds();
205 digitalWrite(led, HIGH);
206 tone(BUZZER_PIN, notes[note_index]);
207 delay(time_delay);
208 noTone(BUZZER_PIN);
209 } else if (melody_tracker < current_melody_length && current_melody[melody_tracker] == led) {
210 tone(BUZZER_PIN, notes[note_index]);
211 delay(time_delay);
212 noTone(BUZZER_PIN);
213 melody_tracker++;
214
215 if (melody_tracker >= current_melody_length) {
216 melody_tracker = 0;
217 turn_off_all_leds();
218 Serial.println("🎵 Song finished. Pick a new one (0, 1, 2, 3, or 4).\n");
219 }
220 }
221 }
222 }
223}

Downloadable files

Air piano diagram

Complete diagram of the air piano

https://wokwi.com/projects/429461599850304513




Note: Content and images are from: https://projecthub.arduino.cc/, with some modifications.
If you want it removed due to copyright reasons, please leave a comment. Thank you.
I want to share this article more widely so that everyone knows about Arduino and your project.

Easy remote control

Remotely control an LED with ease. Devices and components Arduino Nano 33 BLE with headers Box 525 Resistors precision 1% - 17 values Breadb...