Skip to content

Commit 8ba6e9f

Browse files
committed
Add buzzer examples and modernize Buzzer init
Add XRPExamples/buzzer_examples.py demonstrating basic note playback, custom songs, background playback with movement, and driving+beeping examples. Refactor XRPLib/buzzer.py: remove unused urandom import and the fixed BUZZER_PIN constant; change constructor to accept buzzer_pin (int|str) and prefer a BOARD_BUZZER entry on machine.Pin.board when no pin is provided, otherwise raise a clear exception. Initialize PWM duty to 0 on creation. Update XRPLib/defaults.py to detect a board buzzer using hasattr(Pin.board, "BOARD_BUZZER") before creating the buzzer instance. These changes make buzzer configuration more flexible and explicit for boards with a predefined buzzer pin.
1 parent bcd1e46 commit 8ba6e9f

3 files changed

Lines changed: 97 additions & 10 deletions

File tree

XRPExamples/buzzer_examples.py

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
from lib.XRPLib.buzzer import Buzzer
2+
from XRPLib.defaults import *
3+
import time
4+
5+
"""
6+
By the end of this file students will learn how to use the Buzzer class
7+
to play individual notes, custom songs, and how to make the robot
8+
play music while it is moving.
9+
"""
10+
11+
# Get the singleton instance of the buzzer
12+
buzzer = Buzzer.get_default_buzzer()
13+
14+
def simple_scale():
15+
"""Plays a basic C major scale."""
16+
print("Playing a simple scale...")
17+
notes = ["C4", "D4", "E4", "F4", "G4", "A4", "B4", "C5"]
18+
for note in notes:
19+
buzzer.play_note(note, "quarter")
20+
21+
def custom_song_example():
22+
"""Demonstrates how to create and play a custom list of notes."""
23+
print("Playing a custom melody...")
24+
# A song is a list of (note, duration) tuples
25+
# Durations can be "whole", "half", "quarter", "eighth", "sixteenth"
26+
my_song = [
27+
("E4", "eighth"), ("G4", "eighth"), ("E5", "quarter"),
28+
("rest", "eighth"),
29+
("C4", "quarter"), ("G3", "half")
30+
]
31+
32+
# Set tempo to 140 Beats Per Minute
33+
buzzer.set_tempo(140)
34+
buzzer.play_song(my_song)
35+
36+
def siren():
37+
"""Simple two-tone siren effect using individual notes."""
38+
print("Siren started!")
39+
for _ in range(3):
40+
buzzer.play_note("A4", "quarter")
41+
buzzer.play_note("E4", "quarter")
42+
43+
def musical_robot():
44+
"""
45+
Playing music while driving.
46+
We use blocking=False so the code continues to the next line
47+
while the music plays in the background.
48+
"""
49+
print("Dancing with music!")
50+
51+
# Start 'Move It' in the background
52+
buzzer.play_move_it(blocking=False)
53+
54+
# While the song is playing, the robot can perform actions
55+
for i in range(4):
56+
drivetrain.set_effort(0.6, -0.6) # Spin right
57+
time.sleep(0.5)
58+
drivetrain.set_effort(-0.6, 0.6) # Spin left
59+
time.sleep(0.5)
60+
61+
drivetrain.stop()
62+
print("Dance finished.")
63+
64+
def drive_and_beep():
65+
"""Driving forward and playing a note at the same time."""
66+
# Start driving forward (this is non-blocking)
67+
drivetrain.set_effort(0.5, 0.5)
68+
69+
# Play a long note (blocking=True) so the robot drives for the duration of the note
70+
print("Driving for a whole note...")
71+
buzzer.play_note("C5", "whole", blocking=True)
72+
73+
drivetrain.stop()
74+
75+
def main():
76+
# Run the examples
77+
simple_scale()
78+
time.sleep(1)
79+
80+
siren()
81+
time.sleep(1)
82+
83+
musical_robot()
84+
85+
main()

XRPLib/buzzer.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
import machine
66
import time
7-
import urandom
87
from machine import Timer
98

109
class Buzzer:
@@ -16,9 +15,6 @@ class Buzzer:
1615
Supports natural notes, sharps, and flats.
1716
"""
1817

19-
# Pin configuration for the buzzer
20-
BUZZER_PIN = 13
21-
2218
# Duration constants (based on a default 120 BPM tempo)
2319
WHOLE = 4
2420
HALF = 2
@@ -50,15 +46,21 @@ def get_default_buzzer(cls):
5046
cls._DEFAULT_BUZZER_INSTANCE = cls()
5147
return cls._DEFAULT_BUZZER_INSTANCE
5248

53-
def __init__(self, pin: int = None):
49+
def __init__(self, buzzer_pin: int|str = None):
5450
"""
5551
Initialize the buzzer.
5652
57-
:param pin: The pin number for the buzzer
58-
:type pin: int
53+
:param buzzer_pin: The pin number for the buzzer
54+
:type buzzer_pin: int|str
5955
"""
60-
if pin is None:
61-
pin = self.BUZZER_PIN
56+
if buzzer_pin is not None:
57+
pin = buzzer_pin
58+
else:
59+
if hasattr(machine.Pin.board, "BOARD_BUZZER"):
60+
pin = "BOARD_BUZZER"
61+
else:
62+
raise Exception("No buzzer pin defined, are you sure this board has a buzzer?")
63+
6264
self._pin = machine.Pin(pin)
6365
self._pwm = machine.PWM(self._pin)
6466
self._pwm.duty_u16(0) # Start silent

XRPLib/defaults.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,5 +42,5 @@
4242
if hasattr(Pin.board, "SERVO_4"):
4343
servo_four = Servo.get_default_servo(index=4)
4444

45-
if "NanoXRP" in implementation._machine:
45+
if hasattr(Pin.board, "BOARD_BUZZER"):
4646
buzzer = Buzzer.get_default_buzzer()

0 commit comments

Comments
 (0)