Active buzzer là linh kiện phát âm thanh không cần MCU tạo dao động — chỉ cần cấp nguồn là kêu. Bài này giải thích tại sao, phân biệt active và passive buzzer (lỗi thường gặp nhất), và xây dựng các pattern cảnh báo thực tế.
Nguyên Lý Hoạt Động
1. Bên Trong Active Buzzer — Oscillator Tích Hợp
Active buzzer có tên “active” vì chứa mạch dao động chủ động (active oscillator) bên trong:
Active Buzzer — Cắt ngang:
VCC (+)
│
┌──────┴──────────────┐
│ RC Oscillator │ ← Mạch tạo dao động tần số cố định
│ (hoặc IC đơn giản)│
│ │
│ [Transducer] │ ← Biến đổi điện → âm thanh
└──────┬──────────────┘
│
GND (-)
Mạch dao động RC (relaxation oscillator):
- Tụ C nạp qua điện trở R đến ngưỡng → transistor dẫn → C xả → lặp lại
- Tần số: f ≈ 1/(1.1 × R × C) — cố định, không điều chỉnh được
- Thường 2000-4000 Hz (tần số nghe rõ nhất với tai người)
Phần tử biến đổi — 2 loại:
| Loại | Cơ chế | Dòng tiêu thụ | Âm thanh |
|---|---|---|---|
| Piezoelectric | PZT ceramic uốn cong do điện áp xoay chiều | 5-30 mA | Cao, sắc, 2-5 kHz |
| Electromagnetic | Cuộn dây tạo từ trường rung màng sắt | 30-100 mA | Trầm hơn, 0.5-2 kHz |
2. Piezoelectric Transducer — Hiệu Ứng Áp Điện Ngược
Ceramic PZT (Lead Zirconate Titanate — Chì Zirconate Titanate):
- Vật liệu áp điện: áp lực ↔ điện áp
- Chiều thuận (sensor): lực cơ học → điện áp (dùng trong Knock sensor)
- Chiều ngược (actuator): điện áp → biến dạng cơ học
Khi oscillator tạo xung AC ~3kHz → ceramic bends rapidly → air compression waves → âm thanh.
3. Active vs Passive Buzzer — Phân Biệt Quan Trọng
Đây là điểm nhầm lẫn phổ biến nhất:
| Active Buzzer | Passive Buzzer | |
|---|---|---|
| Oscillator | Tích hợp bên trong | KHÔNG có — cần tín hiệu từ MCU |
| Điều khiển | HIGH/LOW (bật/tắt) | PWM signal (tần số = điều chỉnh tông) |
| Hàm Arduino | digitalWrite() | tone(pin, frequency) |
| Âm thanh | Một tần số cố định | Điều chỉnh được tần số → nhạc |
| Phân biệt | Thường có nhãn dán | Thường không có nhãn |
| Nhìn đáy | Có PCB nhỏ bên trong | Thấy thẳng vào ceramic |
Dấu hiệu nhận biết:
- Lấy nguồn 3V thẳng từ nguồn → active buzzer kêu ngay, passive không kêu
- Active buzzer thường có sticker che bên trên
- Trọng lượng: active nặng hơn (có IC bên trong)
Lỗi phổ biến: Dùng tone() với active buzzer → âm thanh sai hoặc không ổn định. Ngược lại, dùng digitalWrite() với passive buzzer → không kêu.
Thông Số Kỹ Thuật
| Thông số | Giá trị |
|---|---|
| Điện áp hoạt động | 3.3V – 5V |
| Dòng tiêu thụ | ~30mA (5V) |
| Tần số phát | ~2.3 kHz (cố định) |
| Mức âm thanh | ~85 dB @ 10cm |
| Nhiệt độ hoạt động | -20°C đến 70°C |
Sơ Đồ Chân (Pinout)
Module KY-012 (3-pin)
KY-012 — Nhìn từ trước (có buzzer):
┌──────────────────────────────┐
│ [BUZZER] │
│ [Transistor NPN] │
│ [Điện trở base 1kΩ] │
└──────────────────────────────┘
GND VCC S
(-) (3.3-5V) (Signal IN)
| Chân | Ký hiệu | Mô tả |
|---|---|---|
| S | Signal | Tín hiệu điều khiển — HIGH = kêu |
| VCC | + | Nguồn 3.3V-5V |
| GND | – | Mass |
Lưu ý module: Một số module KY-012 dùng NPN transistor để khuếch đại dòng → GPIO chỉ cần cấp 1-2mA điều khiển base → transistor cấp 30mA cho buzzer. An toàn cho cả ESP32 (GPIO max 12mA) và Arduino (GPIO max 40mA).
Kiểm tra module của bạn:
- Nhìn mặt sau: có transistor → S = HIGH → kêu (NPN)
- Không có transistor: buzzer nối thẳng → GPIO phải chịu toàn bộ dòng
Kết Nối Phần Cứng
KY-012 với ESP32 DevKit V1
ESP32 DevKit V1 KY-012 Module
───────────────────── ─────────────────
GPIO5 (Output) ────────→ S (Signal)
3V3 ─────────────────→ VCC
GND ─────────────────→ GND
GPIO5 an toàn: output-capable, không phải strapping pin, hoạt động ở 3.3V.
KY-012 với Arduino Uno
Arduino Uno KY-012 Module
───────────────────── ─────────────────
Pin 9 (OUTPUT) ────────→ S (Signal)
5V ─────────────────→ VCC
GND ─────────────────→ GND
Code Arduino IDE
Code Beep Đơn Giản — Arduino Uno
/*
* Active Buzzer KY-012 — Beep đơn giản
* Board: Arduino Uno
* Kết nối: S→Pin9, VCC→5V, GND→GND
*
* QUAN TRỌNG: Active buzzer dùng digitalWrite(), KHÔNG dùng tone()
* tone() tạo PWM → âm thanh sai với active buzzer
*/
const int BUZZER_PIN = 9;
void setup() {
Serial.begin(9600);
pinMode(BUZZER_PIN, OUTPUT);
digitalWrite(BUZZER_PIN, LOW); // Tắt buzzer ban đầu
Serial.println("=== Active Buzzer KY-012 ===");
}
// Phát tiếng beep: durationMs = thời gian kêu (milliseconds)
void beep(int durationMs) {
digitalWrite(BUZZER_PIN, HIGH); // Bật buzzer
delay(durationMs);
digitalWrite(BUZZER_PIN, LOW); // Tắt buzzer
}
void loop() {
Serial.println("Beep 1 lần dài (1 giây)");
beep(1000);
delay(1000); // Nghỉ 1 giây
Serial.println("Beep 3 lần ngắn");
beep(100); delay(100);
beep(100); delay(100);
beep(100);
delay(1000);
}
Code Pattern Cảnh Báo — Arduino Uno
/*
* Active Buzzer — Pattern cảnh báo: SOS Morse + alarm
* Board: Arduino Uno
* Kết nối: S→Pin9, VCC→5V, GND→GND
*/
const int BUZZER_PIN = 9;
// Hằng số Morse: thời gian cơ bản (đơn vị: 1 "dit")
const int DIT = 150; // Ngắn (.)
const int DAH = 450; // Dài (-)
const int PAUSE = 150; // Nghỉ giữa ký tự
const int GAP = 450; // Nghỉ giữa chữ cái
const int SPACE = 1050; // Nghỉ giữa từ
void setup() {
Serial.begin(9600);
pinMode(BUZZER_PIN, OUTPUT);
digitalWrite(BUZZER_PIN, LOW);
}
// Phát 1 âm với thời gian xác định
void beep(int durationMs) {
digitalWrite(BUZZER_PIN, HIGH);
delay(durationMs);
digitalWrite(BUZZER_PIN, LOW);
delay(PAUSE);
}
// SOS Morse: ... --- ...
void sos() {
// S = . . .
beep(DIT); beep(DIT); beep(DIT);
delay(GAP);
// O = - - -
beep(DAH); beep(DAH); beep(DAH);
delay(GAP);
// S = . . .
beep(DIT); beep(DIT); beep(DIT);
delay(SPACE);
}
// Alarm: 5 beep nhanh
void alarm() {
for (int i = 0; i < 5; i++) {
digitalWrite(BUZZER_PIN, HIGH);
delay(50);
digitalWrite(BUZZER_PIN, LOW);
delay(50);
}
delay(500);
}
void loop() {
Serial.println("SOS Morse...");
sos();
delay(500);
Serial.println("Alarm pattern...");
alarm();
delay(2000);
}
Code ESP32 — Non-Blocking Beep
/*
* Active Buzzer KY-012 — ESP32, non-blocking beep
* Board: ESP32 DevKit V1
* Kết nối: S→GPIO5, VCC→3V3, GND→GND
*
* Không dùng delay() → MCU vẫn xử lý được các task khác
* Ứng dụng: beep khi có sự kiện (sensor trigger, MQTT, button)
*/
const int BUZZER_PIN = 5;
// State cho non-blocking beep
unsigned long buzzerOnTime = 0; // Thời điểm bật buzzer (millis)
unsigned long buzzerOffTime = 0; // Thời điểm tắt buzzer
bool buzzerActive = false; // Đang kêu?
// Lên lịch 1 tiếng beep — không block
void scheduleBeep(unsigned long durationMs) {
if (!buzzerActive) {
buzzerOnTime = millis();
buzzerOffTime = buzzerOnTime + durationMs;
buzzerActive = true;
digitalWrite(BUZZER_PIN, HIGH); // Bật ngay
Serial.println("Buzzer BẬT");
}
}
// Gọi mỗi loop() — quản lý tắt buzzer đúng thời điểm
void updateBuzzer() {
if (buzzerActive && millis() >= buzzerOffTime) {
digitalWrite(BUZZER_PIN, LOW);
buzzerActive = false;
Serial.println("Buzzer TẮT");
}
}
void setup() {
Serial.begin(115200);
pinMode(BUZZER_PIN, OUTPUT);
digitalWrite(BUZZER_PIN, LOW);
Serial.println("=== Active Buzzer ESP32 Non-Blocking ===");
}
unsigned long lastBeepTime = 0;
const unsigned long BEEP_INTERVAL = 3000; // Beep mỗi 3 giây
void loop() {
// Lên lịch beep định kỳ
if (millis() - lastBeepTime >= BEEP_INTERVAL) {
lastBeepTime = millis();
scheduleBeep(200); // Beep 200ms
}
// Cập nhật trạng thái buzzer (tắt đúng thời điểm)
updateBuzzer();
// Các task khác vẫn chạy ở đây: WiFi, MQTT, đọc sensor...
}
Code ESP32 — Buzzer Cảnh Báo Theo Mức Nguy Hiểm
/*
* Active Buzzer — Cảnh báo 3 mức: OK / Cảnh báo / Nguy hiểm
* Board: ESP32 DevKit V1
* Kết nối: S→GPIO5, VCC→3V3, GND→GND
*
* Ứng dụng: kết hợp với gas sensor, PIR, smoke detector
*/
const int BUZZER_PIN = 5;
// Phát pattern theo mức nguy hiểm
void alertLevel(int level) {
switch (level) {
case 0: // OK — im lặng
digitalWrite(BUZZER_PIN, LOW);
break;
case 1: // Cảnh báo nhẹ — 1 beep dài mỗi 3 giây
digitalWrite(BUZZER_PIN, HIGH);
delay(300);
digitalWrite(BUZZER_PIN, LOW);
break;
case 2: // Nguy hiểm — 3 beep nhanh liên tục
for (int i = 0; i < 3; i++) {
digitalWrite(BUZZER_PIN, HIGH);
delay(100);
digitalWrite(BUZZER_PIN, LOW);
delay(100);
}
break;
case 3: // Khẩn cấp — liên tục không ngừng
digitalWrite(BUZZER_PIN, HIGH);
delay(50);
digitalWrite(BUZZER_PIN, LOW);
delay(50);
break;
}
}
void setup() {
Serial.begin(115200);
pinMode(BUZZER_PIN, OUTPUT);
digitalWrite(BUZZER_PIN, LOW);
Serial.println("=== Buzzer Cảnh Báo 3 Mức ===");
}
void loop() {
// Giả lập mức nguy hiểm — thay bằng đọc sensor thực tế
Serial.println("Mức 1: Cảnh báo nhẹ");
for (int i = 0; i < 3; i++) {
alertLevel(1);
delay(3000);
}
Serial.println("Mức 2: Nguy hiểm");
for (int i = 0; i < 5; i++) {
alertLevel(2);
delay(500);
}
Serial.println("Mức 3: Khẩn cấp 3 giây");
unsigned long start = millis();
while (millis() - start < 3000) {
alertLevel(3);
}
digitalWrite(BUZZER_PIN, LOW);
Serial.println("OK — im lặng 5 giây");
delay(5000);
}
Kết Quả Mong Đợi
=== Active Buzzer ESP32 Non-Blocking ===
Buzzer BẬT
Buzzer TẮT
Buzzer BẬT
Buzzer TẮT
Ứng Dụng Thực Tế
| Ứng dụng | Kết hợp với | Pattern |
|---|---|---|
| Cảnh báo gas rò rỉ | MQ-2 sensor (Bài 07) | 3 beep nhanh |
| Báo động phát hiện chuyển động | PIR HC-SR501 (Bài 09) | Liên tục |
| Cảnh báo khoảng cách quá gần | HC-SR04 (Bài 08) | Beep nhanh dần |
| Xác nhận button bấm | Button | 1 beep ngắn |
| Báo thức khi cảm biến đạt ngưỡng | Mọi sensor analog | Pattern theo level |
Lưu Ý Khi Sử Dụng
1. KHÔNG dùng tone() với active buzzer
tone() tạo xung PWM tần số tùy chỉnh — chỉ dành cho passive buzzer. Với active buzzer:
tone()có thể gây âm thanh không đúng hoặc bị tắt do interference với internal oscillator- Chỉ dùng
digitalWrite(HIGH)/digitalWrite(LOW)
2. Dòng tiêu thụ — kiểm tra module có transistor không
Nếu module KY-012 của bạn KHÔNG có transistor:
- Arduino Uno: GPIO chịu được 40mA — thường OK, nhưng kéo dài dễ hỏng GPIO
- ESP32: GPIO max 12mA — KHÔNG đủ cho buzzer 30mA → thêm transistor NPN
Transistor NPN (2N2222 hoặc BC547) cho ESP32 không có module:
GPIO5 ──[1kΩ]──→ Base (B) của NPN
Collector (C) → GND của buzzer
Emitter (E) → GND
VCC → (+) buzzer
3. Âm thanh không thể thay đổi tần số
Tần số do oscillator nội quyết định — không điều chỉnh. Nếu cần nhạc hoặc nhiều tông → dùng passive buzzer (Bài 19).
4. Buzzer gây nhiễu điện từ
Active buzzer khi đóng/mở tạo spike điện áp. Với mạch nhạy cảm: thêm tụ 100nF song song với buzzer, và diode fly-back nếu dùng electromagnetic buzzer.


