Buzzers are the simplest way to add audio feedback to your project -- think alarm beeps, button click sounds, notification tones, or even simple melodies. There are two types of buzzers, and they work quite differently. In this guide, you will learn the difference between active and passive buzzers, how to wire each one, and how to play everything from a simple beep to a recognizable melody.
This guide uses the ESP32-WROOM-32 DevKit. Pin labels and GPIO numbers may differ on your board -- always check your board's pinout diagram.
🔗Active vs. Passive Buzzers
| Feature | Active Buzzer | Passive Buzzer |
|---|---|---|
| Internal oscillator | Yes -- built in | No -- needs external signal |
| To make sound | Just apply DC voltage (HIGH/LOW) | Send a PWM signal at desired frequency |
| Frequency control | Fixed tone (one pitch only) | Variable -- you choose the frequency |
| Melodies | No (only on/off beeping) | Yes -- play different notes |
| How to identify | Has a sealed top, often with a + mark | Open PCB on the back, or exposed elements |
Tip: If you are unsure which type you have, connect it briefly to 3.3V and GND. An active buzzer will immediately produce a continuous tone. A passive buzzer will either make no sound or produce a faint click.
🔗Key Specs
| Parameter | Value |
|---|---|
| Operating voltage | $3.3$ to $5\,\text{V}$ (varies by model) |
| Current draw | $\approx 25$ to $30\,\text{mA}$ |
| Frequency (active) | Fixed, typically $\approx 2\,\text{kHz}$ |
| Frequency (passive) | Depends on your PWM signal ($200$ to $5000\,\text{Hz}$ typical) |
🔗What You'll Need
| Component | Qty | Notes | Buy |
|---|---|---|---|
| ESP32 dev board | 1 | AliExpress | Amazon.de .co.uk .com | |
| Active buzzer | 1 | Or passive buzzer for melodies | AliExpress | Amazon.de .co.uk .com |
| Breadboard | 1 | AliExpress | Amazon.de .co.uk .com | |
| Jumper wires | 2 | AliExpress | Amazon.de .co.uk .com |
Links marked Amazon/AliExpress are affiliate links. We may earn a small commission at no extra cost to you.
🔗Wiring
The wiring is the same for both active and passive buzzers.
| Buzzer Pin | ESP32 Pin | Notes |
|---|---|---|
| + (longer leg) | GPIO 26 | Signal pin |
| - (shorter leg) | GND |
Note: Some buzzer modules have three pins (S, VCC, GND) on a small PCB. In that case, connect S to GPIO 26, VCC to 3.3V, and GND to GND.
Most small buzzers draw around $25\,\text{mA}$, which is within the ESP32 GPIO's capability. For louder buzzers that draw more current, consider driving them through a transistor (NPN such as 2N2222 with a $1\,\text{k}\Omega$ base resistor).
🔗Code Example: Active Buzzer -- Beep Pattern
An active buzzer only needs a HIGH signal to sound. This sketch creates an alarm-like beeping pattern.
#define BUZZER_PIN 26
void setup() {
pinMode(BUZZER_PIN, OUTPUT);
}
void beep(int onTime, int offTime) {
digitalWrite(BUZZER_PIN, HIGH);
delay(onTime);
digitalWrite(BUZZER_PIN, LOW);
delay(offTime);
}
void loop() {
// Three short beeps
for (int i = 0; i < 3; i++) {
beep(100, 100);
}
delay(500);
// One long beep
beep(500, 500);
delay(1000);
}🔗Code Example: Passive Buzzer -- Play a Scale
A passive buzzer needs a PWM signal to produce sound. The frequency of the signal determines the pitch. The ESP32 provides the ledcWriteTone() function, which is perfect for this.
#define BUZZER_PIN 26
// Note frequencies in Hz
#define NOTE_C4 262
#define NOTE_D4 294
#define NOTE_E4 330
#define NOTE_F4 349
#define NOTE_G4 392
#define NOTE_A4 440
#define NOTE_B4 494
#define NOTE_C5 523
int scale[] = {NOTE_C4, NOTE_D4, NOTE_E4, NOTE_F4,
NOTE_G4, NOTE_A4, NOTE_B4, NOTE_C5};
void setup() {
ledcAttach(BUZZER_PIN, 2000, 8); // Initial frequency does not matter
}
void playTone(int frequency, int duration) {
ledcWriteTone(BUZZER_PIN, frequency);
delay(duration);
ledcWriteTone(BUZZER_PIN, 0); // Silence
delay(50); // Short gap between notes
}
void loop() {
// Play ascending scale
for (int i = 0; i < 8; i++) {
playTone(scale[i], 300);
}
delay(1000);
// Play descending scale
for (int i = 7; i >= 0; i--) {
playTone(scale[i], 300);
}
delay(2000);
}🔗Code Example: Passive Buzzer -- Simple Melody
This sketch plays a recognizable melody by defining arrays of notes and durations.
#define BUZZER_PIN 26
// Note definitions (frequency in Hz)
#define NOTE_C4 262
#define NOTE_D4 294
#define NOTE_E4 330
#define NOTE_F4 349
#define NOTE_G4 392
#define NOTE_A4 440
#define NOTE_B4 494
#define NOTE_C5 523
#define REST 0
// "Ode to Joy" (simplified)
int melody[] = {
NOTE_E4, NOTE_E4, NOTE_F4, NOTE_G4,
NOTE_G4, NOTE_F4, NOTE_E4, NOTE_D4,
NOTE_C4, NOTE_C4, NOTE_D4, NOTE_E4,
NOTE_E4, NOTE_D4, NOTE_D4, REST
};
// Note durations (in milliseconds)
int durations[] = {
400, 400, 400, 400,
400, 400, 400, 400,
400, 400, 400, 400,
600, 200, 800, 400
};
int noteCount = sizeof(melody) / sizeof(melody[0]);
void setup() {
ledcAttach(BUZZER_PIN, 2000, 8);
}
void playTone(int frequency, int duration) {
if (frequency == REST) {
ledcWriteTone(BUZZER_PIN, 0);
} else {
ledcWriteTone(BUZZER_PIN, frequency);
}
delay(duration);
ledcWriteTone(BUZZER_PIN, 0);
delay(30); // Brief pause between notes
}
void loop() {
for (int i = 0; i < noteCount; i++) {
playTone(melody[i], durations[i]);
}
delay(3000); // Wait before repeating
}🔗How It Works
🔗Active Buzzers
An active buzzer contains an internal oscillator circuit. When you apply a DC voltage (set the GPIO HIGH), the oscillator drives a piezoelectric element at a fixed frequency, producing a tone. The pitch is determined by the internal circuit and cannot be changed -- you can only control whether the buzzer is on or off.
🔗Passive Buzzers
A passive buzzer is essentially a bare piezoelectric element with no internal oscillator. It needs an external AC signal (a square wave) to produce sound. The frequency of your signal determines the pitch:
$$f = \text{frequency in Hz} \Rightarrow \text{perceived pitch}$$
Human hearing ranges from approximately $20\,\text{Hz}$ to $20{,}000\,\text{Hz}$. The most audible and pleasant tones for buzzers are in the $200$ to $5000\,\text{Hz}$ range.
The ESP32's ledcWriteTone(pin, frequency) function generates a square wave at the specified frequency on the given pin, making it straightforward to play notes.
🔗Troubleshooting
| Problem | Possible Cause | Solution |
|---|---|---|
| No sound at all | Wrong buzzer pin or wiring reversed | Check GPIO number in code; verify polarity |
Active buzzer makes no sound with ledcWriteTone() | Active buzzers need DC, not PWM at arbitrary frequency | Use digitalWrite() for active buzzers |
| Passive buzzer clicks but no tone | Using digitalWrite() instead of PWM | Use ledcWriteTone() for passive buzzers |
| Sound is very quiet | GPIO current too low for the buzzer | Drive through a transistor (2N2222 + $1\,\text{k}\Omega$ base resistor) |
| Tone sounds off-pitch | Wrong frequency values | Double-check note frequency definitions |
| Buzzing or distortion | PWM resolution or frequency mismatch | Try different resolution values in ledcAttach() |
🔗Next Steps
- Use a buzzer as an alarm triggered by a sensor (for example, a motion detector or gas sensor)
- Build a simple electronic piano with buttons mapped to different notes
- Create a notification system that plays different tones for different events
- Combine with a relay module for both audible and visual/electrical alerts