from machine import Pin, PWM # Import Pin for GPIO control and PWM for buzzer functionality
import utime # Import utime for delays and timing functions
# Define LEDs and button
redled = Pin(15, Pin.OUT)
yellowled = Pin(13, Pin.OUT)
greenled = Pin(12, Pin.OUT)
push_button = Pin(14, Pin.IN, Pin.PULL_DOWN)
buzzer = PWM(Pin(20)) # Define the buzzer on GP20
# Define tones for the buzzer to play songs (Create a dictionary called notes with the following values.)
tones = {
"B0": 31, "C1": 33, "CS1": 35, "D1": 37, "DS1": 39, "E1": 41, "F1": 44, "FS1": 46, "G1": 49, "GS1": 52,
"A1": 55, "AS1": 58, "B1": 62, "C2": 65, "CS2": 69, "D2": 73, "DS2": 78, "E2": 82, "F2": 87, "FS2": 93,
"G2": 98, "GS2": 104, "A2": 110, "AS2": 117, "B2": 123, "C3": 131, "CS3": 139, "D3": 147, "DS3": 156,
"E3": 165, "F3": 175, "FS3": 185, "G3": 196, "GS3": 208, "A3": 220, "AS3": 233, "B3": 247, "C4": 262,
"CS4": 277, "D4": 294, "DS4": 311, "E4": 330, "F4": 349, "FS4": 370, "G4": 392, "GS4": 415, "A4": 440,
"AS4": 466, "B4": 494, "C5": 523, "CS5": 554, "D5": 587, "DS5": 622, "E5": 659, "F5": 698, "FS5": 740,
"G5": 784, "GS5": 831, "A5": 880, "AS5": 932, "B5": 988, "C6": 1047, "CS6": 1109, "D6": 1175, "DS6": 1245,
"E6": 1319, "F6": 1397, "FS6": 1480, "G6": 1568, "GS6": 1661, "A6": 1760, "AS6": 1865, "B6": 1976, "C7": 2093,
"CS7": 2217, "D7": 2349, "DS7": 2489, "E7": 2637, "F7": 2794, "FS7": 2960, "G7": 3136, "GS7": 3322, "A7": 3520,
"AS7": 3729, "B7": 3951, "C8": 4186, "CS8": 4435, "D8": 4699, "DS8": 4978
}
# Create a list (aka array) of notes for your song. Use the letter P to represent pauses in the music. Each note should be in quotation marks
song = ["E5","G5","A5","P","E5","G5","B5","A5","P","E5","G5","A5","P","G5","E5"]
# create a function called playtone that will take any frequency and play it at full volume
def playtone(frequency):
buzzer.duty_u16(1000) # Set duty cycle to play the tone
buzzer.freq(frequency) # Set frequency to the desired tone
#create a function called bequiet that will silence the buzzer by change duty_u16 to 0.
def bequiet():
buzzer.duty_u16(0)
# Create a function called playsong that you will use to iterate through the array of notes and play each or pause when it sees P.
def playsong(mysong):
for i in range(len(mysong)): # Check for pause
if (mysong[i] == "P"):
bequiet()
else:
playtone(tones[mysong[i]]) # Play the corresponding note
utime.sleep(0.2) # Wait for 0.2 seconds per note
bequiet() # Silence the buzzer at the end
# Global variable used by the ISR (Interrupt Service Routine)
# Indicates whether the crossing sequence should interrupt the default LED sequence
PEDESTRIAN_CROSSING = False
# Interrupt Service Routine for button press
def handle_button(pin):
global PEDESTRIAN_CROSSING
PEDESTRIAN_CROSSING = True # Set the flag to initiate the crossing sequence
# Attach the interrupt to the push button (trigger on rising edge)
push_button.irq(trigger=Pin.IRQ_RISING, handler=handle_button)
CROSSING_TIME = 30 # Define crossing time in seconds
while True:
if PEDESTRIAN_CROSSING:
# Pedestrian logic triggered by button press
greenled.value(0) # Ensure all LEDs are off before starting the sequence
# Implements the LED sequence: Yellow ON → Red ON
yellowled.value(1) # Yellow LED ON
utime.sleep(5) # LED ON for 5 seconds
yellowled.value(0) # Yellow LED OFF
redled.value(1) # Turn Red LED ON
start_time = utime.ticks_ms() # Record the start time
while utime.ticks_diff(utime.ticks_ms(), start_time) < CROSSING_TIME * 1000: # Keep Red LED ON for crossing time
playsong(song) # Play the song; repeats within crossing time
redled.value(0) # Turn Red LED OFF
PEDESTRIAN_CROSSING = False # Reset the flag to allow the default LED sequence to resume
else:
# Default LED sequence (Green → Yellow → Red)
greenled.value(1) # Turn Green LED ON
utime.sleep(5) # Keep Green LED ON for 5 seconds
greenled.value(0)
if PEDESTRIAN_CROSSING:
continue # Skip remaining steps if the crossing flag is set
yellowled.value(1) # Turn Yellow LED ON
utime.sleep(5) # Keep Yellow LED ON for 5 seconds
yellowled.value(0)
if PEDESTRIAN_CROSSING:
continue # Skip remaining steps if the crossing flag is set
redled.value(1) # Turn Red LED ON
utime.sleep(30) # Keep Red LED on for 30 seconds
redled.value(0)