🛠 Jouer une mélodie avec un buzzer passif et le PWM
Objectifs
Fabriquer un petit synthé : un buzzer passif n'est rien d'autre qu'une membrane qu'on fait vibrer avec un signal carré. Le RP2040 fournit l'horloge idéale : 16 canaux PWM (8 tranches × 2 canaux) alimentés par le clock de 125 MHz (datasheet RP2040). Tu calculeras période et rapport cyclique pour jouer des notes justes, puis une mélodie complète.
Matériel
- 1 × carte RP2040 générique
- 1 × buzzer passif (5–12 V ; les buzzers « actifs » sonnent sur simple tension et ne font pas de mélodie)
- 1 × câble : broche du buzzer sur GP8, l'autre sur GND (certains buzzers ont une polarité : fil + au GPIO)
- Firmware MicroPython rp2
Code complet
# melodie.py — GP8, PWM 50 % de rapport cyclique, gamme ~31 Hz..62 kHz
from machine import Pin, PWM
import time
buz = PWM(Pin(8))
buz.duty_u16(32768) # 50 % = son le plus fort (16 bits)
NOTE = { # fréquences tempérées (LA4 = 440 Hz)
'C4': 262, 'D4': 294, 'E4': 330, 'F4': 349, 'G4': 392,
'A4': 440, 'B4': 494, 'C5': 523, ' ': 0,
}
def note(nom, duree_ms):
f = NOTE.get(nom, 0)
if f:
buz.freq(f)
buz.duty_u16(32768)
else: # silence
buz.duty_u16(0)
time.sleep_ms(duree_ms)
buz.duty_u16(0)
time.sleep_ms(20) # petite articulation entre notes
# « Au clair de la lune » (début)
partition = [('C4',400),('C4',400),('C4',400),('D4',400),
('E4',800),('D4',800),('C4',1200),(' ',400)]
while True:
for n, d in partition:
note(n, d)
time.sleep_ms(800)
Vérification attendue
La mélodie sonne juste (compare le LA4 au diapason de ton téléphone). En changeant buz.freq(440) en direct dans le REPL, le son monte/descend en continu : tu contrôles la hauteur. Un duty_u16 plus bas (ex. 8000) baisse le volume sans changer la note — le PWM sert aussi d'amplitude.
Erreurs fréquentes
- Buzzer actif : il contient son propre oscillateur, seule une tension suffit et le PWM ne change rien à la hauteur — achète un passif.
- Oublier
duty_u16(32768): par défaut le rapport cyclique peut être à 0, aucun son ne sort même avec une fréquence correcte. - Fréquence hors gamme utile : un buzzer passif sonne correctement ~100 Hz–10 kHz ; en dessous ça grésille, au-dessus on n'entend plus rien.
- Une seule tranche PWM par fréquence : si un autre périphérique (servo, LED) utilise la même tranche, changer la fréquence le dérègle — les 8 tranches sont là pour ça, une par usage.
- Buzzer qui siffle en continu au boot : la broche garde l'état du programme précédent ; ajoute
buz.duty_u16(0)au démarrage.
Autres tutoriels pour cette carte
- Piloter la LED RGB embarquée WS2812 d'une carte RP2040 générique
- Avoir une console série sur une carte sans pont USB (UART0)
- Afficher sur un OLED I2C SSD1306 et déboguer le bus
- Logger sur carte microSD en SPI (mode carte)
- Interruptions GPIO et alarmes matérielles avec le Pico SDK
- Transformer la carte en clavier USB HID avec TinyUSB
Exemples de code pour cette carte
clignotante.pyPythonbouton-interruption.pyPythonpwm-servo.pyPythonlecture-adc.pyPythonneopixel.pyPythonoled-i2c.pyPython