Skip to content

Eight-Key Piano

Welcome to the Piano Lab

Monty waving welcome In this lab, you will wire up eight buttons and turn your Pico into a real playable piano! Press a button and hear a note.

Parts You Will Need

  1. A Raspberry Pi Pico
  2. A standard-size breadboard (or two half-size breadboards)
  3. 8 momentary push buttons
  4. A speaker or a piezo buzzer
  5. (Optional) A small sound amplifier such as the LM386 DC 5V-12V Mini Micro Audio Amplifier for under $2. In a quiet room you may not need it.

Eight Key Piano

How the Buttons Are Wired

Each button connects one GPIO pin to the 3.3 V rail on the breadboard. When you press the button, the pin reads HIGH (1). When you release it, the pin reads LOW (0).

You do not need external resistors. You set each pin to use an internal pull-down resistor in code:

1
button_pin_1 = machine.Pin(10, machine.Pin.IN, machine.Pin.PULL_DOWN)

This means the pin is always pulled to 0 V (LOW) until a button press connects it to 3.3 V (HIGH).

The Play-Tone Functions

Two functions handle all the sound:

1
2
3
4
5
6
7
8
def play_tone(frequency):
    speaker.duty_u16(1000)     # turn the PWM signal on
    speaker.freq(frequency)    # set the pitch to the given frequency
    builtin_led.high()         # turn the built-in LED on to show a note is playing

def be_quiet():
    speaker.duty_u16(0)        # turn the PWM signal off (silence)
    builtin_led.low()          # turn the built-in LED off

To check if a button is pressed, you read the pin's value:

1
2
if button_pin_1.value() == 1:  # if the pin is HIGH, the button is pressed
    play_tone(220)             # play note A3 (220 Hz)

Key Idea

Monty thinking The eight notes go from A3 (220 Hz) up to A4 (440 Hz). A4 is exactly twice the frequency of A3 — that is one octave higher. Each step in between is a note in the musical scale.

Full Program

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# Play a tone while a button is held down
from machine import Pin, PWM
from utime import sleep, ticks_ms
import machine

SPEAKER_PIN = 22               # GPIO pin connected to the speaker
speaker = PWM(Pin(SPEAKER_PIN))

builtin_led = machine.Pin(25, Pin.OUT)  # the built-in LED on the Pico

# Connect each GPIO pin through a button to the 3.3 V rail
button_pin_1 = machine.Pin(10, machine.Pin.IN, machine.Pin.PULL_DOWN)
button_pin_2 = machine.Pin(11, machine.Pin.IN, machine.Pin.PULL_DOWN)
button_pin_3 = machine.Pin(12, machine.Pin.IN, machine.Pin.PULL_DOWN)
button_pin_4 = machine.Pin(13, machine.Pin.IN, machine.Pin.PULL_DOWN)
button_pin_5 = machine.Pin(14, machine.Pin.IN, machine.Pin.PULL_DOWN)
button_pin_6 = machine.Pin(15, machine.Pin.IN, machine.Pin.PULL_DOWN)
button_pin_7 = machine.Pin(16, machine.Pin.IN, machine.Pin.PULL_DOWN)
button_pin_8 = machine.Pin(17, machine.Pin.IN, machine.Pin.PULL_DOWN)

def play_tone(frequency):
    """Turn the speaker on at the given frequency and light the LED."""
    speaker.duty_u16(1000)     # turn the PWM signal on
    speaker.freq(frequency)    # set the pitch
    builtin_led.high()         # show that a note is playing

def be_quiet():
    """Turn the speaker off and turn off the LED."""
    speaker.duty_u16(0)        # silence the speaker
    builtin_led.low()          # show that no note is playing

while True:                    # keep checking buttons forever
    if   button_pin_1.value() == 1:
        play_tone(220)         # A3 — the lowest note
    elif button_pin_2.value() == 1:
        play_tone(247)         # B3
    elif button_pin_3.value() == 1:
        play_tone(262)         # C4 (Middle C)
    elif button_pin_4.value() == 1:
        play_tone(294)         # D4
    elif button_pin_5.value() == 1:
        play_tone(330)         # E4
    elif button_pin_6.value() == 1:
        play_tone(349)         # F4
    elif button_pin_7.value() == 1:
        play_tone(392)         # G4
    elif button_pin_8.value() == 1:
        play_tone(440)         # A4 — one octave above A3
    else:
        be_quiet()             # no button pressed — stay silent

What Each Section Does

  1. SPEAKER_PIN = 22 — the GPIO pin number where the speaker is connected.
  2. machine.Pin.PULL_DOWN — sets each button pin to use an internal pull-down resistor.
  3. while True: — loops forever, checking all eight buttons every cycle.
  4. elif — checks each button in order. Only the first pressed button gets to play.
  5. else: be_quiet() — if no button is pressed, turn the sound off.

Monty's Tip

Monty giving a tip The built-in LED on pin 25 lights up while any note is playing. This gives you a visual sign that the circuit is working even if you cannot hear anything.

Exercises

  1. Rewrite the code using two lists — one for pin numbers and one for note frequencies. Use a loop to check each button.
  2. Try different note frequencies to play other musical scales (minor scale, pentatonic scale).
  3. Add a ninth button that shifts all the notes up one octave by doubling their frequencies.
  4. Connect an OLED display and show the name of the note being played on screen.
  5. Print the time each note is pressed and the length of the pauses between notes.
  6. Save the sequence of notes to a file so you can play it back later.
  7. Add a simple menu: start a new recording, save it, or play it back.
  8. Eight keys are not enough for many songs. Use two full-size breadboards to add more keys.
  9. Look into a small MIDI keyboard such as the 32-key $40 MIDIPLUS AKM320 USB MIDI Keyboard Controller.
  10. Read about running Musical Instrument Digital Interface (MIDI) on the Pico: MIDI, MicroPython and the Raspberry Pi Pico.

Great Work!

Monty celebrating You built a real playable instrument! Next, you will learn how to play full audio files stored on the Pico's memory.