An active buzzer is the simplest way to make an ESP32 project audible: one GPIO, HIGH to beep, LOW to stop. It is what most gas, water-tank and door alarms use.
On the DevKit V1 the I/O pin only drives the module’s transistor, so 3.3 V logic is fine even with the buzzer running from VIN for extra volume. The one catch is the module type: low-level-trigger boards need to run from 3V3, or a 3.3 V HIGH won’t silence them. The sketch plays three patterns you can reuse — OK, warning and alarm.
Wiring
| ESP32 DevKit V1 | Active buzzer module (high-level trigger) | Wire | Notes |
|---|---|---|---|
| D25 | I/O | yellow | Drives the module’s transistor only — 3.3 V is enough. |
| VIN | VCC | red | VIN (5 V on USB) is louder. For a “low-level trigger” module use 3V3 instead — see the quirks. |
| GND | GND | black |
3.3–5 V part, 3.3 V board. The I/O pin only drives the module's transistor, so a 3.3 V GPIO is enough even when the buzzer runs from 5 V. Check the label: "high-level trigger" beeps when I/O is HIGH; "low-level trigger" modules (with a PNP transistor) beep when I/O is LOW.
Board quirks
- Active vs passive: an active buzzer beeps on a plain HIGH (it has its own oscillator, usually a sealed back and a sticker on top). If yours only clicks, it is passive — use the passive buzzer guide and
tone(). - Low-level-trigger modules use a PNP transistor and beep when I/O is LOW. Powered from VIN (5 V), a 3.3 V HIGH can’t switch the PNP fully off and the buzzer hums constantly. Power those from 3V3 and set
ACTIVE_HIGH = false. - GPIO25 has no boot role, so the buzzer stays silent while the ESP32 starts. On D2, D5, D14 or D15 it may chirp at every reset because those pins toggle during boot.
- The sketch uses
delay()for clarity. In a real alarm, time the beeps withmillis()so the ESP32 keeps reading sensors and Wi-Fi between beeps.
Code
// Active buzzer module (high-level trigger) on an ESP32 DevKit V1.
// I/O → D25 (GPIO25), VCC → VIN (5 V, louder) or 3V3, GND → GND.
// An active buzzer has its own oscillator: HIGH = beep, LOW = silent. No tone() needed.
constexpr uint8_t BUZZER_PIN = 25;
constexpr bool ACTIVE_HIGH = true; // set false for a "low-level trigger" module
void buzz(bool on) { digitalWrite(BUZZER_PIN, (on == ACTIVE_HIGH) ? HIGH : LOW); }
void beep(uint16_t onMs, uint16_t offMs, uint8_t times) {
for (uint8_t i = 0; i < times; i++) {
buzz(true);
delay(onMs);
buzz(false);
delay(offMs);
}
}
void setup() {
buzz(false); // silent before the pin becomes an output
pinMode(BUZZER_PIN, OUTPUT);
Serial.begin(115200);
Serial.println("Active buzzer on GPIO25");
}
void loop() {
Serial.println("Pattern: 2 short pips (OK)");
beep(80, 120, 2);
delay(2000);
Serial.println("Pattern: 1 long beep (warning)");
beep(600, 200, 1);
delay(2000);
Serial.println("Pattern: 5 fast beeps (alarm)");
beep(150, 100, 5);
delay(4000);
}// Active buzzer module (high-level trigger) on an ESP32 DevKit V1.
// I/O → D25 (GPIO25), VCC → VIN (5 V, louder) or 3V3, GND → GND.
// An active buzzer has its own oscillator: HIGH = beep, LOW = silent. No tone() needed.
constexpr uint8_t BUZZER_PIN = 25;
constexpr bool ACTIVE_HIGH = true; // set false for a "low-level trigger" module
void buzz(bool on) { digitalWrite(BUZZER_PIN, (on == ACTIVE_HIGH) ? HIGH : LOW); }
void beep(uint16_t onMs, uint16_t offMs, uint8_t times) {
for (uint8_t i = 0; i < times; i++) {
buzz(true);
delay(onMs);
buzz(false);
delay(offMs);
}
}
void setup() {
buzz(false); // silent before the pin becomes an output
pinMode(BUZZER_PIN, OUTPUT);
Serial.begin(115200);
Serial.println("Active buzzer on GPIO25");
}
void loop() {
Serial.println("Pattern: 2 short pips (OK)");
beep(80, 120, 2);
delay(2000);
Serial.println("Pattern: 1 long beep (warning)");
beep(600, 200, 1);
delay(2000);
Serial.println("Pattern: 5 fast beeps (alarm)");
beep(150, 100, 5);
delay(4000);
}Expected serial output
Active buzzer on GPIO25
Pattern: 2 short pips (OK)
Pattern: 1 long beep (warning)
Pattern: 5 fast beeps (alarm)Active buzzer on GPIO25 Pattern: 2 short pips (OK) Pattern: 1 long beep (warning) Pattern: 5 fast beeps (alarm)
Common errors
Buzzer sounds all the time, even when the pin is LOW
A low-level-trigger module, or a 5 V-powered PNP module that a 3.3 V HIGH can’t turn off. Move VCC to 3V3 and flip ACTIVE_HIGH.
Only a faint click each time
It is a passive buzzer. It needs a square wave from tone(), not a steady HIGH.
Very quiet on 3V3
Normal — most active buzzers are rated 5 V. Use VIN (high-level-trigger modules only), or a louder 12 V piezo switched by a transistor.