diff --git a/files/buzzer.py b/files/buzzer.py new file mode 100644 index 0000000..8f96584 --- /dev/null +++ b/files/buzzer.py @@ -0,0 +1,67 @@ +# buzzer.py +from machine import Pin, PWM +import time + +# === Global note frequencies (A4 = 440 Hz tuning) === +NOTES = { + "C3": 131, "D3": 147, "E3": 165, "F3": 175, "G3": 196, "A3": 220, "B3": 247, + "C4": 262, "D4": 294, "E4": 330, "F4": 349, "G4": 392, "A4": 440, "B4": 494, + "C5": 523, "D#5": 622, "D5": 587, "E5": 659, "F5": 698, "G5": 784, "G#5": 831, "A5": 880, "B5": 988, + "C6": 1047, "D6": 1175, "E6": 1319, "F6": 1397, "G6": 1568, "A6": 1760, "B6": 1976, +} + + +REST = 0 # constant for silence + +class Buzzer: + def __init__(self, pin=29): + self.pwm = PWM(Pin(pin)) + self.pwm.duty_u16(0) + + def _start(self, freq, duty=32768): + self.pwm.freq(freq) + self.pwm.duty_u16(duty) + + def _stop(self): + self.pwm.duty_u16(0) + + def tone(self, freq, duration=200, duty=32768): + """Play a single tone or rest.""" + if freq == REST: + self._stop() + time.sleep_ms(duration) + else: + self._start(freq, duty) + time.sleep_ms(duration) + self._stop() + + def sequence(self, tones): + """ + tones: list of (note, duration) where note can be a string ("E4") or int frequency. + """ + for note, dur in tones: + if note == REST: + self.tone(REST, dur) + elif isinstance(note, str): + self.tone(NOTES[note], dur) + else: + self.tone(note, dur) + time.sleep_ms(30) + + def mario_theme(self): + notes = [ + ("E4",125), ("E4",125), (REST,125), ("E4",125), + (REST,125), ("C4",125), ("E4",125), (REST,125), + ("G4",125), (REST,375), ("G3",125), + (REST,375), ("C4",125), (REST,250), ("G3",125), + (REST,250), ("E4",125), (REST,250), ("A5",125), + (REST,125), ("B5",125), (REST,125), ("A5",125), + ("G5",125), ("E5",125), ("G5",125), ("A5",125), + ] + self.sequence(notes) + + + def wake_up(self): + notes = [("E4", 125), ("C4", 125), ("A5", 125)] + self.sequence(notes) + diff --git a/index.html b/index.html index 318d46d..6ef876c 100644 --- a/index.html +++ b/index.html @@ -22,6 +22,7 @@