Hướng dẫn PWM với ESP32 và Arduino IDE (Analog Output)

Hướng dẫn tạo tín hiệu PWM với ESP32 sử dụng Arduino IDE. Bài viết trình bày hai cách: dùng analogWrite (đơn giản, giống Arduino) và dùng LEDC API (native ESP32). Ví dụ thực hành: điều chỉnh độ sáng LED.
1. Linh kiện cần chuẩn bị
| Linh kiện | Số lượng |
|---|---|
| ESP32 DOIT DEVKIT V1 | 1 |
| LED 5mm | 3 |
| Điện trở 330Ω | 3 |
| Breadboard + dây jumper | 1 bộ |
2. Bộ điều khiển LED PWM của ESP32
ESP32 có bộ điều khiển LED PWM với 6 đến 16 kênh độc lập (tùy model), có thể cấu hình tần số, độ phân giải và duty cycle riêng biệt. Tất cả GPIO có thể làm output đều dùng được làm PWM (trừ GPIO 34–39 là input only). Có hai cách tạo tín hiệu PWM: dùng analogWrite hoặc LEDC API.
3. Cách 1: analogWrite (giống Arduino)
Hàm đơn giản nhất, tương thích với cú pháp Arduino. Nhận 2 tham số: chân GPIO và giá trị duty cycle (0–255).
void analogWrite(uint8_t pin, int value);
Tuỳ chỉnh độ phân giải và tần số:
analogWriteResolution(pin, resolution);
analogWriteFrequency(pin, freq);
4. Cách 2: LEDC API (native ESP32)
bool ledcAttach(uint8_t pin, uint32_t freq, uint8_t resolution);
bool ledcAttachChannel(uint8_t pin, uint32_t freq, uint8_t resolution, uint8_t channel);
void ledcWrite(uint8_t pin, uint32_t duty);
5. Sơ đồ kết nối mạch
Kết nối LED vào GPIO 16 qua điện trở 330Ω
| ESP32 | Kết nối |
|---|---|
| GPIO 16 | Anode LED (qua R 330Ω) |
| GND | Cathode LED |
6. Code ví dụ 1 — analogWrite
LED tăng giảm độ sáng liên tục:
/*
Rui Santos & Sara Santos - Random Nerd Tutorials
https://RandomNerdTutorials.com/esp32-pwm-arduino-ide/
*/
const int ledPin = 16; // GPIO 16
void setup() {
pinMode(ledPin, OUTPUT);
}
void loop(){
// Tăng độ sáng
for(int dutyCycle = 0; dutyCycle <= 255; dutyCycle++){
analogWrite(ledPin, dutyCycle);
delay(15);
}
// Giảm độ sáng
for(int dutyCycle = 255; dutyCycle >= 0; dutyCycle--){
analogWrite(ledPin, dutyCycle);
delay(15);
}
}
7. Code ví dụ 2 — LEDC API
Cùng chức năng nhưng dùng LEDC API với tần số 5000 Hz, độ phân giải 8-bit:
/*
Rui Santos & Sara Santos - Random Nerd Tutorials
https://RandomNerdTutorials.com/esp32-pwm-arduino-ide/
*/
const int ledPin = 16; // GPIO16
const int freq = 5000;
const int resolution = 8;
void setup(){
ledcAttach(ledPin, freq, resolution);
// Hoặc dùng channel cụ thể:
//ledcAttachChannel(ledPin, freq, resolution, 0);
}
void loop(){
// Tăng độ sáng
for(int dutyCycle = 0; dutyCycle <= 255; dutyCycle++){
ledcWrite(ledPin, dutyCycle);
delay(15);
}
// Giảm độ sáng
for(int dutyCycle = 255; dutyCycle >= 0; dutyCycle--){
ledcWrite(ledPin, dutyCycle);
delay(15);
}
}
8. Kết quả thực tế
Upload code lên ESP32 — LED sẽ tăng giảm độ sáng liên tục:
Duty = 0 (tắt)
Duty = 50%
Duty = 75%
Duty = 100%
9. So sánh hai phương pháp
| Tiêu chí | analogWrite | LEDC API |
|---|---|---|
| Độ phức tạp | Đơn giản | Trung bình |
| Tương thích Arduino | ✅ Có | ❌ Không |
| Tuỳ chỉnh tần số | Có (thêm hàm) | Có (trong ledcAttach) |
| Chọn channel thủ công | ❌ Không | ✅ Có |
| Độ phân giải | Cố định 8-bit | Tuỳ chỉnh |