Raspberry Pi Pico
Buttons, LEDs & A Buzzer

The code on this page was written whilst I was thinking about how to approach the Simon game. I had orginally wanted to use interrupts. I ran out of patience with that but, on the way, came up with this method of combining the buttons, LEDs and buzzer into some code that might make more sense in another project.

The idea is to have the LEDs light up when their associated buttons are pressed and have them switch off when the button is released. The buzzer will play a different note whilst each button is held down and stop playing the note when it is released.

The circuit used is the same as for the Simon game.

Pico Circuit

The Fritzing diagram shows the same concept using separate buttons and LEDs.

Pico Circuit

from machine import PWM, Pin
from time import sleep

# buzzer, frequency, duration - play tone subroutine
def tone(frequency,duration):
    buzzer.duty_u16(volume)
    buzzer.freq(frequency)
    sleep(duration)
    buzzer.duty_u16(0)

# frequency - plays until stopped
def note_on(frequency):
    buzzer.duty_u16(volume)
    buzzer.freq(frequency)

# stop the noise
def note_off():
    buzzer.duty_u16(0)

# button press-release handler
def btn_press(pin):
    if pin.value()==1:
        # release
        note_off()
        for led in leds:
            led.value(0)
    else:
        # press
        for i in range(4):
            if pin==btns[i]:
                note_on(notes[i])
                leds[i].value(1)
               
# define the pin to use for buzzing
buzzer = PWM(Pin(16))
# the duty cycle to use when the note is on
volume = 2512
# button pins
btn_pins = [21,20,19,18]
# led pins
led_pins = [28,27,26,22]
# notes for our Simon game
notes = [659, 880, 330, 554]

# configure button and led pins in new lists
btns = []
leds = []
for i in range(4):
    btns.append(Pin(btn_pins[i], Pin.IN, Pin.PULL_UP))    
    btns[i].irq(trigger=Pin.IRQ_RISING|Pin.IRQ_FALLING, handler=btn_press)
    leds.append(Pin(led_pins[i], Pin.OUT))

Obviously, you could add code to make something else happen for each of the buttons. I was just getting the press and release part of the project working.

This program uses only one subroutine to handle both the press and release of the buttons. When defining the interrupts, you can use the pipe (|) for a logical OR to have the interrupt fire on both the rising and falling edge of the signal change. Examining the value of the button in the handler allows you to find out which button triggered the event and whether it was a press or release.