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.

SendData

Điều khiển trạng thái qua Firebase Trạng thái hiện tại: Đang tải... ĐỔI TRẠNG THÁI