from machine import Pin, PWM
from utime import sleep
# --- CONFIGURATION ---
# Buzzer connected to GP5 (Physical Pin 7)
buzzer = PWM(Pin(5))
# MUSICAL SETTINGS
bpm = 120 # Beats Per Minute (Change this to adjust speed)
beat_duration = 60 / bpm # Duration of one whole beat in seconds
# Frequency Dictionary (Natural notes and Sharps 's')
tones = {
'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,
'rest': 0
}
# Melody: (Note, Beat Value)
# 1.0 = Quarter note (negra), 0.5 = Eighth note (corchea), 2.0 = Half note (blanca)
melody = [
('c4', 1.0), ('e4', 1.0), ('g4', 1.0), ('c5', 2.0),
('as4', 0.5), ('a4', 0.5), ('g4', 1.0), ('rest', 0.5)
]
def play_tone(frequency, duration):
"""Plays a note for a duration calculated by BPM."""
if frequency > 0:
buzzer.freq(frequency)
buzzer.duty_u16(32768) # 50% Volume
else:
buzzer.duty_u16(0) # Silence for 'rest'
# Calculate real time based on BPM
sleep(duration * beat_duration)
# Short pause to separate notes (staccato feel)
buzzer.duty_u16(0)
sleep(0.02)
# --- MAIN EXECUTION ---
print(f"Playing melody at {bpm} BPM on GPIO 5...")
try:
for note, duration in melody:
if note in tones:
play_tone(tones[note], duration)
else:
print(f"Error: Note {note} not found!")
except KeyboardInterrupt:
print("\nStopped by user.")
finally:
buzzer.deinit()
print("Buzzer off.")