Build a simple musical keyboard using Raspberry Pi GPIO pins, push buttons, and Python. Press buttons to play sounds - a great introduction to physical computing and programming!
Kit List
- Raspberry Pi (any model with GPIO pins)
- Breadboard (large enough for the number of buttons)
- 5 x Momentary Push Buttons
- 5 x LEDs (optional - for visual feedback)
- 5 x 330 ohm resistors (for LEDs)
- GPIO breakout board (optional but recommended)
- Jumper Cables (male-to-female)
- Speakers or headphones
STEP 1: Setting up the Breadboard
TIPS: The momentary push buttons used to create the keys of the piano can be tricky to push into the breadboard. Carefully check the pins are straight and that they are in the correct position. With a little force, push the buttons with two fingers either side of the push button.
Button Wiring (Simple Method)
For each button, you only need two connections:
- Connect one leg of the button to a GPIO pin (e.g., GPIO 17, 18, 27, 22, 23)
- Connect the opposite leg to GND (ground)
The internal pull-up resistor in the Raspberry Pi keeps the GPIO pin HIGH. When you press the button, it connects to GND and goes LOW - our code detects this change.
STEP 2: Prepare Your Sound Files
You'll need sound files for each key. You can:
- Download piano note samples from free sound libraries
- Record your own sounds using Audacity
- Use any .wav files - sound effects, drum samples, etc.
Place your sound files in a folder, for example: /home/pi/sounds/
STEP 3: Writing the Python Code
Create a new file called piano.py:
from gpiozero import Button
import pygame
# Initialize pygame mixer for sound
pygame.mixer.init()
# Load sound files
sounds = {
17: pygame.mixer.Sound('/home/pi/sounds/note_c.wav'),
18: pygame.mixer.Sound('/home/pi/sounds/note_d.wav'),
27: pygame.mixer.Sound('/home/pi/sounds/note_e.wav'),
22: pygame.mixer.Sound('/home/pi/sounds/note_f.wav'),
23: pygame.mixer.Sound('/home/pi/sounds/note_g.wav'),
}
# Create buttons with internal pull-up resistors
buttons = {
17: Button(17),
18: Button(18),
27: Button(27),
22: Button(22),
23: Button(23),
}
# Function to play sound when button pressed
def play_sound(pin):
sounds[pin].play()
# Connect button press events to sound playback
for pin, button in buttons.items():
button.when_pressed = lambda p=pin: play_sound(p)
print("RPi-ano ready! Press buttons to play.")
print("Press Ctrl+C to exit.")
# Keep the program running
try:
while True:
pass
except KeyboardInterrupt:
print("\nGoodbye!")
pygame.mixer.quit() Running Your Piano
Open a terminal and run:
python3 piano.py STEP 4: Adding LEDs (Optional)
Add visual feedback by lighting up an LED when each key is pressed:
from gpiozero import Button, LED
import pygame
pygame.mixer.init()
# Define GPIO pins for buttons and LEDs
keys = [
{'button': 17, 'led': 5, 'sound': '/home/pi/sounds/note_c.wav'},
{'button': 18, 'led': 6, 'sound': '/home/pi/sounds/note_d.wav'},
{'button': 27, 'led': 13, 'sound': '/home/pi/sounds/note_e.wav'},
{'button': 22, 'led': 19, 'sound': '/home/pi/sounds/note_f.wav'},
{'button': 23, 'led': 26, 'sound': '/home/pi/sounds/note_g.wav'},
]
# Set up buttons, LEDs, and sounds
for key in keys:
key['button_obj'] = Button(key['button'])
key['led_obj'] = LED(key['led'])
key['sound_obj'] = pygame.mixer.Sound(key['sound'])
# Play sound and light LED
def play_key(key):
key['sound_obj'].play()
key['led_obj'].on()
def release_key(key):
key['led_obj'].off()
# Connect events
for key in keys:
key['button_obj'].when_pressed = lambda k=key: play_key(k)
key['button_obj'].when_released = lambda k=key: release_key(k)
print("RPi-ano with LEDs ready!")
try:
while True:
pass
except KeyboardInterrupt:
pygame.mixer.quit() STEP 5: Testing and Playing
- Check all wiring connections
- Run the Python script
- Press each button to test the sounds
- If a button doesn't work, check its GPIO connection
Extension Activities
- Add more buttons for a full octave
- Create a drum machine with percussion sounds
- Build a memory game - the Pi plays a sequence, you repeat it
- Add recording functionality to capture your compositions
- Use different sound effects for a gaming controller
Troubleshooting
- No sound? Check audio output settings with
raspi-config, ensure speakers/headphones are connected - Button not responding? Double-check GPIO pin numbers and ground connections
- Sound delayed? Pre-load sounds at startup (as shown in code), use smaller audio files
- Multiple sounds at once? pygame.mixer supports multiple channels by default