A passive buzzer has no oscillator inside, so the Pico W has to make the sound — which means you choose the pitch. MicroPython’s PWM sets the frequency in hertz, and a 50 % duty cycle drives the buzzer hardest.
The script plays a C-major scale (Sa Re Ga Ma… if you think in sargam) and a short tune on GP18. Edit the TUNE list to play your own.
Wiring
| Raspberry Pi Pico W | Passive buzzer module | Wire | Notes |
|---|---|---|---|
| GP18 | I/O | orange | GP18 is physical pin 24. |
| 3V3 | VCC | red | 3V3 is pin 36. VBUS (pin 40) is louder on the 3-pin module. |
| GND | GND | black |
3.3–5 V part, 3.3 V board. On the 3-pin module the I/O pin only drives a transistor, so a 3.3 V GPIO is enough even with the buzzer on 5 V. The 2-pin bare buzzer or KY-006 can run straight from a GPIO through a 100 Ω resistor at low volume.
Board quirks
- Arduino’s
tone()does not exist in MicroPython:PWM.freq()sets the pitch andduty_u16(32768)(50 %) gives the loudest square wave.duty_u16(0)is silence. - Every Pico GPIO can do PWM, but GPIOs sharing a PWM slice share a frequency (GP18 and GP19 are one slice). Don’t put a buzzer and a servo on the same slice.
- A bare 2-pin buzzer can hang off GP18 through a 100 Ω resistor (quieter). The 3-pin module has a transistor, so it is safe at any volume.
Code
# Passive buzzer on a Raspberry Pi Pico W (MicroPython): play notes with hardware PWM.
# Wiring (3-pin module): I/O -> GP18 (pin 24), VCC -> 3V3 (pin 36), GND -> GND.
# A passive buzzer needs a square wave - a steady HIGH makes no sound.
from machine import Pin, PWM
import time
buzzer = PWM(Pin(18))
buzzer.duty_u16(0) # silent
NOTES = {"C4": 262, "D4": 294, "E4": 330, "F4": 349, "G4": 392, "A4": 440, "B4": 494, "C5": 523}
# "Sa Re Ga Ma Pa Dha Ni Sa" mapped onto C major, then a short tune
SCALE = ["C4", "D4", "E4", "F4", "G4", "A4", "B4", "C5"]
TUNE = [("E4", 200), ("E4", 200), ("F4", 200), ("G4", 400), ("G4", 200), ("F4", 200), ("E4", 200), ("D4", 400)]
def tone(freq, ms, volume=0.5):
buzzer.freq(freq)
buzzer.duty_u16(int(32768 * volume)) # 50 % duty = loudest square wave
time.sleep_ms(ms)
buzzer.duty_u16(0)
time.sleep_ms(30) # short gap so repeated notes are heard separately
print("Passive buzzer on GP18")
while True:
print("Scale")
for n in SCALE:
tone(NOTES[n], 250)
time.sleep(1)
print("Tune")
for n, ms in TUNE:
tone(NOTES[n], ms)
time.sleep(2)# Passive buzzer on a Raspberry Pi Pico W (MicroPython): play notes with hardware PWM.
# Wiring (3-pin module): I/O -> GP18 (pin 24), VCC -> 3V3 (pin 36), GND -> GND.
# A passive buzzer needs a square wave - a steady HIGH makes no sound.
from machine import Pin, PWM
import time
buzzer = PWM(Pin(18))
buzzer.duty_u16(0) # silent
NOTES = {"C4": 262, "D4": 294, "E4": 330, "F4": 349, "G4": 392, "A4": 440, "B4": 494, "C5": 523}
# "Sa Re Ga Ma Pa Dha Ni Sa" mapped onto C major, then a short tune
SCALE = ["C4", "D4", "E4", "F4", "G4", "A4", "B4", "C5"]
TUNE = [("E4", 200), ("E4", 200), ("F4", 200), ("G4", 400), ("G4", 200), ("F4", 200), ("E4", 200), ("D4", 400)]
def tone(freq, ms, volume=0.5):
buzzer.freq(freq)
buzzer.duty_u16(int(32768 * volume)) # 50 % duty = loudest square wave
time.sleep_ms(ms)
buzzer.duty_u16(0)
time.sleep_ms(30) # short gap so repeated notes are heard separately
print("Passive buzzer on GP18")
while True:
print("Scale")
for n in SCALE:
tone(NOTES[n], 250)
time.sleep(1)
print("Tune")
for n, ms in TUNE:
tone(NOTES[n], ms)
time.sleep(2)Expected serial output
Passive buzzer on GP18
Scale
TunePassive buzzer on GP18 Scale Tune
Common errors
Silence, but an active buzzer works on the same pin
Check duty_u16 is not 0 and that you are on the I/O pin, not VCC.
Notes sound rough or crackly
Very low frequencies on a tiny buzzer always sound buzzy. Stay above about 200 Hz.