Passive buzzer khác active buzzer ở điểm then chốt: không có oscillator bên trong — chỉ là piezoelectric transducer thuần túy. MCU phải tự tạo xung vuông tần số mong muốn. Đổi lại, điều này cho phép phát bất kỳ tần số nào, từ đó chơi nhạc thực sự.
Nguyên Lý Hoạt Động
1. Piezoelectric Transducer Thuần Túy
Bên trong passive buzzer chỉ có một phần tử ceramic PZT mỏng gắn trên màng đồng:
Passive Buzzer — Cấu trúc:
(+) (-)
│ │
┌──────┴───────┴──────┐
│ Màng đồng (brass) │
│ ┌────────────────┐ │
│ │ PZT Ceramic │ │ ← Biến điện áp → biến dạng cơ học
│ └────────────────┘ │
└─────────────────────┘
Không có IC, không có oscillator
Hiệu ứng áp điện ngược (converse piezoelectric effect):
- Điện áp DC → ceramic bị kéo dãn hoặc nén theo một chiều cố định
- Điện áp xoay chiều (AC) → ceramic liên tục co giãn → rung → âm thanh
- Tần số âm thanh = tần số xoay chiều đầu vào
Vì vậy: Passive buzzer cần MCU tạo xung vuông với tần số = tần số âm thanh mong muốn. Active buzzer tự tạo xung → passive không tự làm được.
2. So Sánh Active vs Passive
| Active Buzzer | Passive Buzzer | |
|---|---|---|
| Oscillator | Tích hợp | Không có |
| Điều khiển | digitalWrite() HIGH/LOW | tone(pin, frequency) |
| Tần số | Cố định (~2-4kHz) | Tùy chỉnh (20Hz-20kHz) |
| Phát nhạc | Không | Có |
| Dùng MCU | Nhẹ (chỉ ON/OFF) | Cần timer/PWM |
| Nhận biết | Có nhãn/sticker | Thường không có nhãn, thấy ceramic trong vỏ |
3. Hàm tone() — Cách Arduino Tạo Tần Số
tone() dùng hardware timer của MCU để tạo xung vuông 50% duty cycle:
Xung vuông tone(pin, 440) — A4 = 440 Hz:
HIGH ┌──┐ ┌──┐ ┌──┐ ┌──┐
│ │ │ │ │ │ │ │
LOW ┘ └──┘ └──┘ └──┘ └──
←──────────────────────→
1/440s = 2.27ms
Duty cycle = 50% → cả hai nửa chu kỳ bằng nhau
Arduino Uno: Timer2 (8-bit) → tone() thay thế PWM trên Pin 3 và Pin 11 khi đang dùng.
ESP32:
- Arduino-ESP32 2.x: dùng LEDC peripheral →
ledcWriteTone(channel, frequency) - Arduino-ESP32 3.x:
tone(pin, frequency)hoạt động trực tiếp
4. Tần Số và Nốt Nhạc
Mỗi nốt nhạc tương ứng một tần số Hz cố định (hệ thống bình quân 12 âm):
| Nốt | Octave 4 (Hz) | Octave 5 (Hz) |
|---|---|---|
| C (Đô) | 262 | 523 |
| D (Ré) | 294 | 587 |
| E (Mi) | 330 | 659 |
| F (Fa) | 349 | 698 |
| G (Sol) | 392 | 784 |
| A (La) | 440 | 880 |
| B (Si) | 494 | 988 |
Tần số tăng gấp đôi khi lên 1 octave: C4=262Hz, C5=523Hz, C6=1047Hz.
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ụ | 5-30 mA |
| Dải tần số | 20 Hz – 20 kHz |
| Trở kháng | ~8Ω (như loa nhỏ) |
| Đường kính | 12mm / 23mm (2 loại phổ biến) |
Sơ Đồ Chân (Pinout)
Module KY-006 (3-pin)
┌──────────────────────────────┐
│ [PASSIVE BUZZER] │
│ [Điện trở 100Ω nối tiếp] │
└──────────────────────────────┘
GND VCC S
(-) (3.3-5V) (Signal PWM)
| Chân | Ký hiệu | Mô tả |
|---|---|---|
| S | Signal | Tín hiệu PWM từ MCU |
| VCC | + | Nguồn 3.3V-5V |
| GND | – | Mass |
Lưu ý: Module KY-006 thường chỉ có buzzer + điện trở nối tiếp (không có transistor). Tín hiệu S nối thẳng vào buzzer qua điện trở. Dòng qua buzzer ~5-10mA tại 3.3V → an toàn cho ESP32 GPIO (max 12mA).
Kết Nối Phần Cứng
KY-006 với ESP32 DevKit V1
ESP32 DevKit V1 KY-006 Module
───────────────────── ─────────────────
GPIO5 (PWM Output)─────→ S (Signal)
3V3 ─────────────────→ VCC (hoặc để trống — buzzer lấy điện qua S)
GND ─────────────────→ GND
GPIO5: PWM-capable, không phải strapping pin, an toàn.
Lưu ý: Thực tế nhiều module KY-006 chỉ cần cắm S và GND — buzzer lấy điện từ tín hiệu PWM. Nếu âm thanh yếu → cắm thêm VCC.
KY-006 với Arduino Uno
Arduino Uno KY-006 Module
───────────────────── ─────────────────
Pin 8 (Digital Output)─→ S (Signal)
5V ─────────────────→ VCC
GND ─────────────────→ GND
Pin 8 trên Arduino Uno không phải hardware PWM pin — nhưng tone() dùng software timer nên hoạt động trên bất kỳ digital pin nào.
Code Arduino IDE
Code Tone Đơn Giản — Arduino Uno
/*
* Passive Buzzer KY-006 — Phát tông đơn giản
* Board: Arduino Uno
* Kết nối: S→Pin8, VCC→5V, GND→GND
*
* tone(pin, frequency) : bắt đầu phát tần số (không tự dừng)
* tone(pin, frequency, dur) : phát trong dur milliseconds rồi tự dừng
* noTone(pin) : dừng phát
*/
const int BUZZER_PIN = 8;
void setup() {
Serial.begin(9600);
// Không cần pinMode() cho tone() — nhưng nên set để rõ ràng
pinMode(BUZZER_PIN, OUTPUT);
Serial.println("=== Passive Buzzer KY-006 ===");
}
void loop() {
// Phát Do (C4 = 262 Hz) trong 500ms
Serial.println("Phát Đô (C4 - 262 Hz)");
tone(BUZZER_PIN, 262, 500);
delay(600); // Chờ hơn duration để có khoảng lặng
// Phát Sol (G4 = 392 Hz) trong 500ms
Serial.println("Phát Sol (G4 - 392 Hz)");
tone(BUZZER_PIN, 392, 500);
delay(600);
// Phát La (A4 = 440 Hz) trong 1 giây
Serial.println("Phát La chuẩn (A4 - 440 Hz)");
tone(BUZZER_PIN, 440, 1000);
delay(1100);
// Sweep tần số từ thấp đến cao
Serial.println("Sweep 200 Hz → 2000 Hz");
for (int freq = 200; freq <= 2000; freq += 50) {
tone(BUZZER_PIN, freq, 50);
delay(60);
}
noTone(BUZZER_PIN);
delay(1000);
}
Code Phát Nhạc Twinkle Twinkle — Arduino Uno
/*
* Passive Buzzer — Phát nhạc Twinkle Twinkle Little Star
* Board: Arduino Uno
* Kết nối: S→Pin8, VCC→5V, GND→GND
*/
const int BUZZER_PIN = 8;
// Tần số nốt nhạc (Hz) — octave 4 và 5
#define C4 262
#define D4 294
#define E4 330
#define F4 349
#define G4 392
#define A4 440
#define B4 494
#define C5 523
#define REST 0 // Nghỉ (không phát âm)
// Thời gian nốt nhạc (ms)
#define QUARTER 400 // Nốt đen
#define HALF 800 // Nốt trắng
// Bài Twinkle Twinkle Little Star
// Format: {nốt, thời_gian}
int melody[][2] = {
{C4, QUARTER}, {C4, QUARTER}, {G4, QUARTER}, {G4, QUARTER},
{A4, QUARTER}, {A4, QUARTER}, {G4, HALF},
{F4, QUARTER}, {F4, QUARTER}, {E4, QUARTER}, {E4, QUARTER},
{D4, QUARTER}, {D4, QUARTER}, {C4, HALF},
{G4, QUARTER}, {G4, QUARTER}, {F4, QUARTER}, {F4, QUARTER},
{E4, QUARTER}, {E4, QUARTER}, {D4, HALF},
{G4, QUARTER}, {G4, QUARTER}, {F4, QUARTER}, {F4, QUARTER},
{E4, QUARTER}, {E4, QUARTER}, {D4, HALF},
{C4, QUARTER}, {C4, QUARTER}, {G4, QUARTER}, {G4, QUARTER},
{A4, QUARTER}, {A4, QUARTER}, {G4, HALF},
{F4, QUARTER}, {F4, QUARTER}, {E4, QUARTER}, {E4, QUARTER},
{D4, QUARTER}, {D4, QUARTER}, {C4, HALF},
};
int noteCount = sizeof(melody) / sizeof(melody[0]);
void setup() {
Serial.begin(9600);
pinMode(BUZZER_PIN, OUTPUT);
Serial.println("Phát Twinkle Twinkle Little Star...");
}
void playMelody() {
for (int i = 0; i < noteCount; i++) {
int note = melody[i][0];
int duration = melody[i][1];
if (note == REST) {
noTone(BUZZER_PIN);
} else {
tone(BUZZER_PIN, note, duration);
}
// Khoảng lặng 10% giữa các nốt (để nốt không dính vào nhau)
delay(duration * 1.1);
noTone(BUZZER_PIN);
}
}
void loop() {
playMelody();
delay(2000); // Nghỉ 2 giây rồi phát lại
}
Code ESP32 — tone() và Sweep Tần Số
/*
* Passive Buzzer KY-006 — ESP32 (Arduino-ESP32 2.x+)
* Board: ESP32 DevKit V1
* Kết nối: S→GPIO5, VCC→3V3, GND→GND
*
* Arduino-ESP32 2.x+: tone() dùng LEDC nội bộ
* Không cần ledcSetup() thủ công — tone() tự cấu hình
*/
const int BUZZER_PIN = 5;
// Nốt nhạc
#define C4 262
#define D4 294
#define E4 330
#define F4 349
#define G4 392
#define A4 440
#define B4 494
#define C5 523
void setup() {
Serial.begin(115200);
Serial.println("=== Passive Buzzer ESP32 ===");
}
// Phát 1 nốt nhạc với duration ms
void playNote(int frequency, int durationMs) {
if (frequency == 0) {
noTone(BUZZER_PIN);
} else {
tone(BUZZER_PIN, frequency, durationMs);
}
delay(durationMs * 1.05); // Chờ hơn 5% để nốt không dính
noTone(BUZZER_PIN);
}
// Scale Đô Ré Mi từ C4 đến C5
void playScale() {
int notes[] = {C4, D4, E4, F4, G4, A4, B4, C5};
Serial.println("Phát scale Đô Ré Mi...");
for (int i = 0; i < 8; i++) {
playNote(notes[i], 300);
}
}
// Chuông báo động: 3 tiếng tăng dần
void alertBeep() {
Serial.println("Chuông cảnh báo...");
playNote(880, 100); // A5
delay(50);
playNote(988, 100); // B5
delay(50);
playNote(1047, 300); // C6
}
void loop() {
playScale();
delay(500);
alertBeep();
delay(2000);
}
Kết Quả Mong Đợi
=== Passive Buzzer ESP32 ===
Phát scale Đô Ré Mi... ← Nghe: Đô Ré Mi Fa Sol La Si Đô
Chuông cảnh báo... ← Nghe: 3 tiếng tăng dần cao
Phát scale Đô Ré Mi...
...
Ứng Dụng Thực Tế
| Ứng dụng | Mô tả |
|---|---|
| Chuông cửa | Phát melody ngắn khi nhấn button |
| Nhạc chuông báo thức | Kết hợp với DS3231 RTC (Bài 37) |
| Âm thanh phản hồi UI | Beep xác nhận khi bấm nút |
| Cảnh báo mức nguy hiểm | Tone khác nhau theo severity |
| Dạy nhạc đơn giản | Hiển thị nốt trên LCD + phát âm |
Lưu Ý Khi Sử Dụng
1. Phân biệt active/passive trước khi code
Nếu code tone() nhưng dùng active buzzer → âm thanh không ổn định, tần số sai. Kiểm tra: cấp nguồn thẳng → active kêu ngay, passive im lặng.
2. tone() trên Arduino Uno chiếm Timer2
Khi dùng tone(), Timer2 bận → PWM của Pin 3 và Pin 11 bị disable. Tránh dùng analogWrite() trên 2 pin này khi đang phát âm thanh.
3. Khoảng lặng giữa các nốt (articulation)
Nếu delay = đúng bằng duration → các nốt dính vào nhau, khó phân biệt. Cách fix:
tone(BUZZER_PIN, note, duration);
delay(duration * 1.1); // 10% extra pause
noTone(BUZZER_PIN);
4. Âm lượng nhỏ — tăng bằng điện trở thấp hơn hoặc transistor
Module KY-006 có điện trở nối tiếp giới hạn dòng → âm lượng vừa phải. Để to hơn: thêm transistor NPN khuếch đại dòng hoặc dùng buzzer 8Ω 0.5W kết hợp với op-amp/transistor.
5. ESP32 — kiểm tra phiên bản Arduino-ESP32
- Arduino-ESP32 1.x:
tone()có thể không hoạt động → dùngledcSetup()+ledcWriteTone() - Arduino-ESP32 2.x+:
tone()hoạt động bình thường - Kiểm tra trong Arduino IDE: Tools → Board → Board Manager → esp32 → version


