Project Overview
Arduino Nano + KY-006 passive piezo buzzer: Use one digital pin and the Arduino tone() function to play real songs by converting melodies into note and duration arrays.
This project turns simple beeps into recognizable music while teaching timing and arrays you can reuse in other builds.
- Time: ~30 minutes
- Skill level: Beginner
- What you will build: A one-pin music player with a note table you can extend to any song.
Parts List
From ShillehTek
- KY-006 Passive Piezo Buzzer Module - Passive is the key: it plays whatever frequency you send (active buzzers only beep one note).
- Arduino Nano V3.0 (or any Uno) - Runs the sketch that converts arrays into notes.
- 400-Point Breadboard - Quick prototyping for the buzzer hookup.
- Dupont Jumper Wires - Simple 3-wire connection to the buzzer module.
External
- None - three wires total
Note: tone() generates a square wave at a chosen frequency on a digital pin. Musical notes are just frequencies (A4 = 440 Hz, middle C = 262 Hz), so a lookup table turns sheet music into integers.
Step-by-Step Guide
Step 1 - Wire the buzzer
Goal: Connect the passive buzzer to the Arduino using a single signal pin.
What to do: Buzzer signal to D9, VCC to 5V, and GND to GND. If you are using a bare piezo element instead of a module, connect signal and ground.
Expected result: The hardware is ready to play tones.
Step 2 - Convert a melody into two arrays
Goal: Understand the data format used to store songs.
What to do: Represent each song as a list of (note, duration) pairs: one array of note frequencies, and one array of note lengths where 4 = quarter note, 8 = eighth note, and negative numbers mark dotted notes. Compute each note duration in milliseconds by dividing a whole-note time by the note type.
Expected result: You can read a melody array the same way you read simple sheet music timing.
Step 3 - Upload the player sketch
Goal: Play a short melody (Ode to Joy) and confirm timing and spacing are correct.
What to do: Paste the sketch below into the Arduino IDE, verify the buzzer pin matches your wiring (D9 here), then upload.
Code:
#define NOTE_C4 262
#define NOTE_D4 294
#define NOTE_E4 330
#define NOTE_F4 349
#define NOTE_G4 392
const int BUZZER = 9;
const int TEMPO = 120; // beats per minute
// Ode to Joy, first phrase: {note, type} (4 = quarter, 8 = eighth)
int melody[] = { NOTE_E4, NOTE_E4, NOTE_F4, NOTE_G4,
NOTE_G4, NOTE_F4, NOTE_E4, NOTE_D4,
NOTE_C4, NOTE_C4, NOTE_D4, NOTE_E4,
NOTE_E4, NOTE_D4, NOTE_D4 };
int durations[] = { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 2 };
void setup() {
int wholenote = (60000 * 4) / TEMPO;
for (unsigned i = 0; i < sizeof(melody) / sizeof(int); i++) {
int noteMs = wholenote / durations[i];
tone(BUZZER, melody[i], noteMs * 0.9); // play 90% of the slot
delay(noteMs); // 10% silence separates notes
noTone(BUZZER);
}
}
void loop() {} // plays once on boot / reset
Expected result: Press reset and the buzzer plays the phrase clearly. The 90% play and 10% gap makes notes distinct instead of running together.
Step 4 - Swap in a song library melody
Goal: Go beyond a single phrase by pasting in a pre-made song.
What to do: Replace the melody[] and durations[] arrays with any pre-transcribed song that uses the same two-array format (movies, games, holiday songs). Keep the player loop the same. You can also wire a button later to trigger playback for things like a doorbell, alarm tone, or a game-over jingle.
Expected result: Your Arduino becomes a simple one-pin jukebox you can reuse across projects.
Conclusion
You built an Arduino Nano passive buzzer music player using tone(), plus note and duration arrays to turn melodies into real songs. Once this format clicks, you can add audio cues to alarms, games, and notifications using a single pin and a low-cost buzzer.
Want the exact parts used in this build? Grab them from ShillehTek.com. If you want help customizing this project or building something for your product, check out our IoT consulting services.
Photo credit and original reference: HiBit on Hackster.io.







