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!

Programming Options: This lesson uses Python with gpiozero, the recommended approach for modern Raspberry Pi projects. gpiozero is pre-installed on Raspberry Pi OS and provides a simple, beginner-friendly API for GPIO 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
Note on resistors: With gpiozero, we use the internal pull-up resistors on the GPIO pins, so external resistors for buttons are not required. This simplifies the wiring!

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:

  1. Connect one leg of the button to a GPIO pin (e.g., GPIO 17, 18, 27, 22, 23)
  2. 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

  1. Check all wiring connections
  2. Run the Python script
  3. Press each button to test the sounds
  4. 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