added buzzer tab
parent
0ded6c003b
commit
5612339adb
|
|
@ -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)
|
||||
|
||||
80
index.html
80
index.html
|
|
@ -22,6 +22,7 @@
|
|||
<div class="max-w-8xl mx-auto px-4 py-4 flex space-x-6 select-none">
|
||||
<button class="tab-btn active text-blue-600" data-target="lesson1">Environment Setup</button>
|
||||
<button class="tab-btn text-gray-600 hover:text-blue-600" data-target="lesson2">Uploading Code</button>
|
||||
<button class="tab-btn text-gray-600 hover:text-blue-600" data-target="lesson2b">Buzzer</button>
|
||||
<button class="tab-btn text-gray-600 hover:text-blue-600" data-target="lesson3">Motors</button>
|
||||
<button class="tab-btn text-gray-600 hover:text-blue-600" data-target="lesson4">Color Sensors</button>
|
||||
<button class="tab-btn text-gray-600 hover:text-blue-600 hidden" data-target="lesson5">I2C Multiplexing</button>
|
||||
|
|
@ -147,6 +148,85 @@
|
|||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Lesson 2b (hidden initially) -->
|
||||
<section id="lesson2b" class="lesson-content hidden">
|
||||
<h1 class="text-3xl font-bold mb-6">Using the Buzzer</h1>
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
|
||||
<!-- Step 1 -->
|
||||
<div class="prose">
|
||||
<h2>Step 1: Wiring</h2>
|
||||
<p>The buzzer is a simple piezo speaker. We drive it with PWM from a single GPIO pin, so we only
|
||||
need signal and ground.</p>
|
||||
</br>
|
||||
<p><code>RP2040 GP29 ------ BUZZER +</code></p>
|
||||
<p><code>RP2040 GND ------- BUZZER -</code></p>
|
||||
</br>
|
||||
<p>By changing the PWM frequency we change the pitch of the sound. Higher frequency means a higher
|
||||
note.</p>
|
||||
</div>
|
||||
<div>
|
||||
</div>
|
||||
|
||||
<!-- Step 2 -->
|
||||
<div class="prose">
|
||||
<h2>Step 2: Coding</h2>
|
||||
<p>The code for the buzzer includes note frequencies and helpers for playing tones and sequences, so
|
||||
we'll upload this file to our device, or copy->paste the contents into a new file called
|
||||
buzzer.py.</p>
|
||||
</br>
|
||||
<p><a href="files/buzzer.py">buzzer.py</a></p>
|
||||
</br>
|
||||
<p>We initialize the buzzer with <code>buzz = buzzer.Buzzer()</code>. By default it uses pin 29.
|
||||
</p>
|
||||
</br>
|
||||
<p>We play a list of notes with
|
||||
<code>buzz.sequence([(freq, duration), ...])</code>. Each pair is a frequency in Hz and a
|
||||
duration in milliseconds.
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<pre class="bg-gray-100 p-4 rounded shadow text-sm"><code class="language-python">
|
||||
# main.py
|
||||
import time
|
||||
import buzzer
|
||||
|
||||
buzz = buzzer.Buzzer()
|
||||
buzz.sequence([(440, 200),
|
||||
(880, 200)])
|
||||
</code></pre>
|
||||
</div>
|
||||
|
||||
<!-- Step 3 -->
|
||||
<div class="prose">
|
||||
<h2>Step 3: Adding more notes</h2>
|
||||
<p>The data we pass to buzz.sequence([]) in the square brackets is called an array.</p>
|
||||
<p>You can add as many (note, duration) pairs as you want..</p>
|
||||
</div>
|
||||
<div>
|
||||
<pre class="bg-gray-100 p-4 rounded shadow text-sm"><code class="language-python">
|
||||
# main.py
|
||||
import buzzer
|
||||
import time
|
||||
|
||||
buzz = buzzer.Buzzer()
|
||||
|
||||
# Play named notes
|
||||
buzz.sequence([(440, 200),
|
||||
(880, 200),
|
||||
(600, 100),
|
||||
(1200, 100)])
|
||||
time.sleep(2)
|
||||
|
||||
# Or use a built-in tune
|
||||
buzz.mario_theme()
|
||||
</code></pre>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Lesson 3 (hidden initially) -->
|
||||
<section id="lesson3" class="lesson-content hidden">
|
||||
<h1 class="text-3xl font-bold mb-6">Driving a Motor</h1>
|
||||
|
|
|
|||
Loading…
Reference in New Issue