Have you ever wondered how a keyboard turns a key press into a musical note? Under the hood it’s simple: a switch closes, a chip notices, and a speaker vibrates at a fixed frequency. Once you see that, you can build your own Arduino piano on a breadboard in an evening.
In this project we build a working 8-key piano using Arduino, 8 push buttons, and a passive buzzer. Each button plays one note of the C major scale (C4 to C5), so you can play real songs like “Twinkle Twinkle Little Star” as soon as you power it up. There is no shield, no library, and no soldering. It is a great first project if you want to learn digital inputs, INPUT_PULLUP, and the tone() function.
Let’s see what you need to build it.
Table of Contents
Requirements
Hardware requirements:
- Arduino Uno R3 (Nano or Mega also work)
- 8 × tactile push buttons (6×6 mm)
- 1 × passive piezo buzzer (or a small 8Ω speaker with a 100Ω series resistor)
- Breadboard
- Jumper wires
- USB cable
Software requirements:
No external library is needed. Everything runs on the built-in tone() function.
Component details
Passive buzzer
A buzzer has a small piezo disc inside that bends when voltage is applied. If you switch the voltage on and off fast enough, the disc vibrates and you hear a tone.
Active vs passive: this is where most people go wrong. An active buzzer has its own oscillator inside, so it makes only one fixed beep when powered. A passive buzzer has no oscillator, so the Arduino decides the frequency, and that is what lets it play different notes. For a piano you need the passive one.
A quick test: connect the buzzer straight to 5V. If it beeps by itself, it’s active. If you only hear a faint click, it’s passive.
Typical specifications of a passive buzzer:
- Working voltage: 3.3V to 5V
- Current: under 30 mA
- Loudest around 2 to 4 kHz, but it plays lower notes fine
- Two pins (some have a + marking)
Tactile push button
Each key of our piano is a 4-pin tactile switch. The legs are joined in pairs internally, and pressing the button connects one pair to the other. So you connect one leg on each side of the button and you are done. Using two legs from the same side does nothing, because they are always connected.
How the Arduino piano works
The logic is only three steps:
- Each button is wired between an Arduino pin and GND.
- We turn on the Arduino’s internal pull-up resistor with
INPUT_PULLUP. The pin reads HIGH normally and LOW when the button is pressed. - When a pin goes LOW, we call
tone()with that key’s frequency. When no key is pressed, we callnoTone().
Because we use the internal pull-ups, you don’t need eight external resistors, and the breadboard stays clean.
Here are the notes we assign to each key:
| Key | Note | Frequency (Hz) | Arduino pin |
|---|---|---|---|
| 1 | C4 (Do) | 262 | D2 |
| 2 | D4 (Re) | 294 | D3 |
| 3 | E4 (Mi) | 330 | D4 |
| 4 | F4 (Fa) | 349 | D5 |
| 5 | G4 (Sol) | 392 | D6 |
| 6 | A4 (La) | 440 | D7 |
| 7 | B4 (Ti) | 494 | D8 |
| 8 | C5 (Do) | 523 | D9 |
Build a Professional Digital Piano with PCBWay—Custom PCBs & 3D-Printed Enclosures for Your Arduino Project
Create a compact, responsive 8-key piano that delivers clean tones and reliable performance. PCBWay’s integrated manufacturing services help you transform your Arduino and button matrix prototype into a polished, playable instrument—perfect for beginners learning electronics or musicians experimenting with DIY synthesizers.
Custom PCB Manufacturing for Responsive Key Detection:
PCBWay manufactures high-quality custom PCBs that consolidate your Arduino, tactile push buttons, buzzer or speaker output, and power regulation onto a single compact board. Their PCBs feature clean signal routing with proper debouncing circuitry to eliminate false triggers, dedicated traces for each key to ensure accurate note detection, and stable power delivery for consistent audio output. Choose a professional SMT assembly to receive a fully populated, tested board ready for your musical firmware.
Professional 3D-Printed Piano Enclosure:
Design and order a custom piano housing through PCBWay’s advanced 3D printing service. Create an elegant, compact enclosure using smooth-finish PLA+ or premium ABS, featuring precisely sized key openings for comfortable finger placement, a speaker grille for clear sound projection, and a stable base with rubber feet for desktop stability. Add internal PCB mounting bosses and battery compartment options—all printed with precision for a professional, instrument-grade appearance.
Why PCBWay Delivers Professional Results:
- Responsive Playability: Clean PCB design ensures accurate, lag-free key detection
- Quality Acoustics: Custom enclosures with proper speaker placement enhance sound clarity
- Seamless Integration: Perfect PCB-to-enclosure fit from one trusted source
- Complete Solution: From prototype to a finished, playable digital piano
Build Your Arduino Piano Today:
Upload your PCB design and enclosure model for instant quotes, DFM feedback, and professional manufacturing only at PCBWAY.COM
Circuit diagram and pin connections
Place the 8 buttons in a row on the breadboard, straddling the center gap. Then wire them as below.

Buttons:
- One leg of each button goes to its Arduino pin (D2 to D9, as in the table above).
- The other leg of every button goes to the GND rail of the breadboard.
- Connect the GND rail to the GND pin of the Arduino.
Buzzer:
- Buzzer + (positive) goes to D10.
- Buzzer – (negative) goes to GND.
That’s the whole circuit. Since each button shares the same ground rail, you only need one wire from the rail to the Arduino.
Tip: Keep the buttons in the same order as the notes, left to right. Low to high is how a real piano is laid out, and it makes playing songs much easier.
Arduino piano code
Copy the code below into the Arduino IDE, select Arduino Uno and the correct COM port, and upload.
// Arduino Piano with 8 Keys - CircuitSchools
// 8 push buttons + passive buzzer
const int buzzerPin = 10;
const int keyPins[8] = {2, 3, 4, 5, 6, 7, 8, 9};
const int notes[8] = {262, 294, 330, 349, 392, 440, 494, 523};
const char* noteNames[8] = {"C4", "D4", "E4", "F4", "G4", "A4", "B4", "C5"};
int lastKey = -1; // -1 means no key is pressed
void setup() {
Serial.begin(9600);
pinMode(buzzerPin, OUTPUT);
for (int i = 0; i < 8; i++) {
pinMode(keyPins[i], INPUT_PULLUP); // pressed = LOW
}
Serial.println("Arduino Piano Ready!");
}
void loop() {
int pressedKey = -1;
// Find the first key that is currently pressed
for (int i = 0; i < 8; i++) {
if (digitalRead(keyPins[i]) == LOW) {
pressedKey = i;
break;
}
}
// Only act when the key state changes
if (pressedKey != lastKey) {
if (pressedKey == -1) {
noTone(buzzerPin); // key released
} else {
tone(buzzerPin, notes[pressedKey]); // play the note
Serial.print("Playing: ");
Serial.print(noteNames[pressedKey]);
Serial.print(" (");
Serial.print(notes[pressedKey]);
Serial.println(" Hz)");
}
lastKey = pressedKey;
}
}
How the code works
keyPins[]andnotes[]are two arrays that line up one to one, so key 1 is always note 1. If you want a different scale, you only change the numbers innotes[].- Inside
loop()we scan all 8 pins and remember the first pressed one. - The
if (pressedKey != lastKey)check makes suretone()is called once per key press instead of thousands of times a second. This keeps the sound clean and stops the buzzer from crackling. noTone()silences the buzzer the moment you lift your finger.
Working of the Arduino piano
Power the Arduino from USB and press the first button. You should hear a clear C4 note that lasts as long as you hold the key. Release it and the sound stops immediately. Press each key from left to right and you will hear the full scale climbing up to C5.
Open the Serial Monitor at 9600 baud and you will see the note name and frequency printed every time you press a key, which is handy for debugging.
One thing to know: the tone() function can only generate one frequency at a time, so this piano is monophonic. If you press two keys together, the key with the lower number wins. Real chords need a different approach, which I cover in the upgrade ideas below.
Play your first song
Here is “Twinkle Twinkle Little Star” using our 8 keys. Numbers refer to the key numbers in the table above:
1 1 5 5 6 6 5 (Twinkle twinkle little star)
4 4 3 3 2 2 1 (How I wonder what you are)
Take your time, and pause a little between repeated notes. Since the code reacts to key changes, pressing the same key twice without lifting your finger won’t retrigger the note.
Troubleshooting
No sound at all
- Check that your buzzer is passive, not active. An active buzzer gives a constant tone regardless of the frequency you send.
- Check the buzzer polarity and that the buzzer + is on D10.
- Confirm the Arduino is powered and the code uploaded without errors.
One note plays constantly
- The button is probably wired using two legs from the same side, which are always connected. Rotate the button 90° on the breadboard.
A key does nothing
- Check the jumper wire from that button to the right pin, and that the other leg reaches the GND rail.
- Make sure you used
INPUT_PULLUPand not plainINPUT. A floating pin gives random results.
Sound is very quiet
- Passive piezo buzzers are naturally quiet at low notes. Try a small speaker with a 100Ω resistor, or add a transistor (2N2222 or BC547) to drive it.
Notes sound slightly off
- The Uno’s timer resolution means frequencies are approximate, and small differences are normal. For a toy piano they are not noticeable.
Upgrade ideas
Once your basic piano works, try these:
- Add 8 LEDs, one beside each key, so the pressed key lights up.
- Add an octave switch using a 9th button that shifts all notes up or down.
- Add an OLED display to show the note name as you play.
- Record and playback: store pressed notes in an array and play them back with a “play” button.
- Move to ESP32 and build a Wi-Fi piano controlled from a web page.
- Use a small amplifier module (like the PAM8403) with a speaker for a much louder sound.
Frequently asked questions
Can I use more than 8 keys?
Yes. The Uno has 13 digital pins and 6 analog pins that can also act as digital inputs. For more keys, use a button matrix or a shift register like the 74HC165.
Why do you use pin 10 for the buzzer?
On the Uno, tone() uses Timer2, which interferes with PWM on pins 3 and 11. Pin 10 is safe, but pin 3 is in use for a key here, so avoid using analogWrite() on pins 3 and 11 in this project.
Can I play two notes at once?
Not with tone(). It generates one frequency at a time. You would need a second buzzer with its own timer, or a dedicated sound chip or DAC.
Does this work with Arduino Nano or Mega?
Yes, the code is identical as long as you use the same pins.
Do I need resistors for the buttons?
No. The internal pull-up resistors of the Arduino handle it.
Conclusion
You now have a working Arduino piano with 8 keys built from nothing more than a few buttons and a buzzer. Along the way you learned how INPUT_PULLUP works, how arrays make code cleaner, and how tone() turns frequencies into music. Try changing the values in the notes[] array to make your own scales, or add LEDs to turn it into a light-up keyboard.
If you get stuck, drop your question in the comments and we will help you out.
