IoTLabs

Nghiên cứu, Sáng tạo và Thử nghiệm

Nắm vững ESP32 logic level 3.3V vs 5V: Cách kết nối an toàn tránh làm cháy board và chân GPIO

1. Vấn Đề: Tại Sao 3.3V Và 5V Không Thể Kết Nối Trực Tiếp?

ESP32 hoạt động ở 3.3V — tất cả các GPIO đều dùng mức logic 3.3V. Nhưng nhiều module và cảm biến phổ biến hoạt động ở 5V (HC-SR04, LCD 16×2, servo, relay module).

Kết nối trực tiếp giữa 2 mức logic có thể dẫn đến:

Kịch bảnHậu quả
5V → GPIO ESP32 (module 5V gửi tín hiệu 5V vào GPIO 3.3V)🔥 Cháy GPIO ESP32!
GPIO ESP32 → module 5V (ESP32 3.3V gửi tín hiệu vào module 5V)⚠️ Module không nhận được tín hiệu HIGH (ngưỡng 5V là ~3.5V)
ESP32 3.3V → Arduino 5VArduino đọc HIGH ở >3.0V — thường OK nhưng không đảm bảo

2. Mức Logic Là Gì?

Mỗi chip vi điều khiển có một điện áp hoạt động (VDD). Mức logic HIGH và LOW được định nghĩa dựa trên VDD:

Thông sốESP32 (3.3V)Arduino Uno (5V)
VDD (điện áp hoạt động)3.3V5V
VIH (Input HIGH tối thiểu)2.475V (0.75 × VDD)3.5V (0.7 × VDD)
VIL (Input LOW tối đa)0.825V (0.25 × VDD)1.5V (0.3 × VDD)
VOH (Output HIGH tối thiểu)2.64V (0.8 × VDD)4.2V (0.84 × VDD)
VOL (Output LOW tối đa)0.66V (0.2 × VDD)0.9V (0.18 × VDD)
Dòng tối đa mỗi GPIO40mA (khuyến nghị <12mA)40mA (khuyến nghị <20mA)

Giải thích:

  • VIH: Nếu bạn đưa điện áp >= VIH vào chân INPUT, chip đọc là HIGH
  • VIL: Nếu bạn đưa điện áp <= VIL vào chân INPUT, chip đọc là LOW
  • VOH: Khi chip output HIGH, điện áp tối thiểu nó tạo ra
  • VOL: Khi chip output LOW, điện áp tối đa nó tạo ra

Vấn đề với ESP32:

  • VIH của ESP32 = 2.475V → ESP32 đọc 3.3V là HIGH, 0V là LOW. Nhưng không được đưa >3.3V vào GPIO!
  • GPIO ESP32 KHÔNG 5V-tolerant (không chịu được 5V) — nếu đưa 5V vào, GPIO sẽ cháy
  • Các module 5V output ra tín hiệu ~5V → CẦN hạ xuống 3.3V trước khi vào ESP32

3. Các Module 5V Phổ Biến Và Cách Kết Nối

3.1. Module ADC với board 5V

Module/BoardLogic LevelKết nối với ESP32
Arduino Uno5V⚠️ Cần level shifter khi giao tiếp
HC-SR04 (siêu âm)5V⚠️ Echo pin output 5V → cần voltage divider
LCD 16×2 I2C5V✅ I2C bus có pull-up, ESP32 SDA/SCL 3.3V → module 5V đọc được
Servo SG905V✅ Signal từ ESP32 3.3V đủ cho servo, nhưng cấp nguồn 5V riêng
DHT223.3-5V✅ Dùng được với ESP32 trực tiếp (cả 3.3V và 5V)
HC-05 Bluetooth3.3V✅ Dùng trực tiếp (nhưng cần kiểm tra voltage regulator)
RFID RC5223.3V✅ Dùng trực tiếp
MAX7219 LED Matrix5V⚠️ MOSI/SCLK 5V → cần level shifter hoặc voltage divider

4. 5 Phương Pháp Kết Nối An Toàn

4.1. KHÔNG ĐƯỢC: Kết nối trực tiếp ❌

// ❌ SAI — HC-SR04 Echo (5V) vào GPIO ESP32 (3.3V)
const int echoPin = 5; // 5V signal → GPIO5 ESP32 → CHÁY GPIO!

4.2. Voltage Divider (2 điện trở) — Đơn giản nhất ✅

Đây là cách rẻ nhất và đơn giản nhất để hạ 5V xuống 3.3V.

Mạch:

Module 5V OUT ────[R1: 10kΩ]────┐
                                   ├──── ESP32 GPIO
                                [R2: 4.7kΩ]
                                   │
                                  GND

Tính toán:

V_out = V_in × R2 / (R1 + R2)
V_out = 5V × 4.7k / (10k + 4.7k) = 5 × 4.7 / 14.7 = 1.6V

Chờ — 1.6V < 2.475V (VIH của ESP32) → KHÔNG được! ESP32 sẽ đọc là LOW.

Công thức đúng:

Cần V_out > VIH (ESP32) = 2.475V, và càng gần 3.3V càng tốt.

Với R1 = 1kΩ, R2 = 2kΩ:

V_out = 5V × 2k / (1k + 2k) = 5 × 2/3 = 3.33V ✅ Gần 3.3V

Giá trị dễ mua:

R1R2V_out (ngõ vào 5V)Kết luận
2.2kΩ3.3kΩ3.0V✅ Tốt
1kΩ2kΩ3.33V✅ Tốt (gần 3.3V)
10kΩ4.7kΩ1.6V❌ Quá thấp
1kΩ1kΩ2.5V⚠️ Sát ngưỡng, không khuyến nghị

Code hoàn chỉnh với voltage divider (HC-SR04):

// HC-SR04 với voltage divider cho Echo pin

#define TRIG_PIN GPIO_NUM_12
#define ECHO_PIN GPIO_NUM_14 // Echo qua voltage divider (R1=2.2k, R2=3.3k)

void setup() {
  Serial.begin(115200);
  pinMode(TRIG_PIN, OUTPUT);
  pinMode(ECHO_PIN, INPUT);
}

void loop() {
  // Gửi xung trigger
  digitalWrite(TRIG_PIN, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIG_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG_PIN, LOW);

  // Đọc Echo (đã hạ xuống ~3.0V qua voltage divider)
  long duration = pulseIn(ECHO_PIN, HIGH, 30000);
  float distance = duration * 0.034 / 2;

  Serial.print("Distance: ");
  Serial.print(distance);
  Serial.println(" cm");
  delay(500);
}

4.3. Level Shifter Module (Nâng/Hạ Mức) — Khuyên dùng

Mua module 4-channel bi-directional level shifter (~10,000đ). Module này dùng MOSFET để chuyển đổi 2 chiều giữa 3.3V và 5V.

Sơ đồ chân:

LV (Low Voltage)  ──── 3.3V (từ ESP32)
HV (High Voltage) ──── 5V (từ nguồn ngoài)
GND               ──── GND chung
LV1, LV2...       ──── 3.3V signal (ESP32 GPIO)
HV1, HV2...       ──── 5V signal (module 5V)

Cách dùng với HC-SR04:

HC-SR04 VCC ──── 5V
HC-SR04 GND ──── GND

HC-SR04 Trig ──── HV1 (Level Shifter) ──── LV1 ──── ESP32 GPIO12 (OUTPUT)
HC-SR04 Echo ──── HV2 (Level Shifter) ──── LV2 ──── ESP32 GPIO14 (INPUT)

4.4. Serial Logic: Dùng 3.3V Arduino Board

Một số board tương thích Arduino hoạt động ở 3.3V:

  • Arduino Due (3.3V)
  • Teensy 3.x/4.x (3.3V)
  • ESP8266 (3.3V)
  • Raspberry Pi Pico (3.3V)

Nếu bạn kết nối ESP32 với các board này, không cần level shifter.

4.5. Dùng I2C: Tự Động Tương Thích

Nhiều module 5V giao tiếp qua I2C (LCD 1602 I2C, BMP280, MPU6050). Trên bus I2C, điện trở pull-up kéo lên 3.3V (hoặc 5V):

  • ESP32 SDA/SCL = 3.3V
  • Module 5V có pull-up 5V trên board → module tự đọc được tín hiệu 3.3V
  • Module 5V gửi tín hiệu về → tín hiệu có thể lên 5V → cần kiểm tra — một số module I2C có điện trở pull-up yếu, tín hiệu chỉ lên ~3.3V

Cách an toàn: dùng module I2C 3.3V hoặc level shifter.

4.6. So sánh các phương pháp

Phương phápChi phíĐộ tin cậyChiềuDễ làm
Voltage divider~200đ (2 điện trở)⚠️ Trung bình (sai số điện trở)5V→3.3V (1 chiều)✅ Rất dễ
Level shifter module~10,000đ✅ Cao2 chiều✅ Dễ
Dùng I2C0đ (nếu module có I2C)✅ Cao2 chiều✅ Dễ
Dùng board 3.3V✅ Rất cao
Kết nối trực tiếp❌ Rủi ro cháy GPIO❌ Không an toàn

5. Trường Hợp Đặc Biệt: Open-Drain Output

Một số module (như cảm biến DHT22, DS18B20) dùng open-drain output — chúng chỉ kéo xuống GND (LOW) hoặc thả nổi (để điện trở pull-up kéo lên).

Ưu điểm: bạn có thể dùng pull-up 3.3V hoặc 5V tùy ý → tương thích với cả 2 mức logic.

// DHT22: dùng được với ESP32 trực tiếp (3.3V) hoặc 5V
// Data pin cần pull-up 10kΩ lên 3.3V (nếu dùng ESP32)

6. Bảng Tra Nhanh Kết Nối Các Module Với ESP32

ModuleLogicKết nối ESP32Phương pháp
DHT223.3-5V✅ Trực tiếpPull-up 10kΩ lên 3.3V
DS18B203.3-5V✅ Trực tiếpPull-up 4.7kΩ lên 3.3V
HC-SR045V⚠️ Echo→cần dividerVoltage divider (R1=2.2k, R2=3.3k)
LCD 16×2 I2C5V⚠️ Thường OKKiểm tra: module có pull-up 5V → thường vẫn đọc được 3.3V
OLED SSD1306 I2C3.3-5V✅ Trực tiếpNhiều module đã có 3.3V regulator
Servo SG905V✅ Signal OKSignal 3.3V đủ cho servo, cấp nguồn 5V riêng
Relay module5V⚠️ Cần transistorDùng NPN transistor (2N2222) hoặc relay module opto
NeoPixel WS2812B5V⚠️ Signal 3.3VThường OK (một số LED cần level shifter nếu dây dài)
MAX72195V⚠️ Cần level shifterMOSI/SCLK/CS 5V → cần divider hoặc level shifter
RFID RC5223.3V✅ Trực tiếpTuyệt đối không cấp 5V vào VCC!
BMP280 (GY-BMP280)3.3V✅ Trực tiếpModule 3.3V, dùng I2C
MPU60503.3V✅ Trực tiếpModule 3.3V, dùng I2C
Ethernet ENC28J603.3V✅ Trực tiếpModule 3.3V, dùng SPI
SD Card module5V⚠️ SPI 5V → level shifterCần level shifter cho SPI (hoặc dùng module 3.3V)
Arduino Uno5V⚠️ Level shifterI2C: OK nếu pull-up 3.3V. UART/SPI: cần level shifter

7. Mạch Level Shifter Tự Chế (MOSFET)

Bạn có thể tự làm level shifter 2 chiều với 1 con BSS138 (N-Channel MOSFET):

            3.3V (ESP32)             5V (Module)
                │                       │
              [10kΩ]                  [10kΩ]
                │                       │
ESP32 TX ───────┤                      ├──── Module RX
                │                   ┌───┤
                └─── Drain BSS138 ──┤ Gate
                              Source ─┬───
                                       │
                                      GND

Cách hoạt động:

  • Khi ESP32 output LOW (0V): MOSFET OFF → Module RX kéo lên 5V qua R2
  • Khi ESP32 output HIGH (3.3V): MOSFET ON → Module RX kéo xuống GND → LOW
  • Chiều ngược lại: Module output LOW → MOSFET OFF → ESP32 đọc 3.3V qua R1

Mạch này có sẵn trên module level shifter 4 channel chỉ 10,000đ — khuyên dùng module thay vì tự hàn.

8. Lỗi Thường Gặp Và Debug

Dấu hiệu GPIO đã bị cháy

  1. GPIO luôn ở mức 0V hoặc 3.3V bất kể code nói gì — dấu hiệu chắc chắn đã cháy
  2. ESP32 không boot được — nếu nhiều GPIO bị cháy có thể ảnh hưởng boot
  3. GPIO bị nóng khi chạm — dòng rò quá lớn do cháy bên trong chip
  4. Cảm nhận mùi khét — dấu hiệu cuối cùng, chip đã hỏng hoàn toàn

Debug Checklist

  • [ ] Kiểm tra datasheet: module này dùng 3.3V hay 5V?
  • [ ] Đo VCC module: có đúng 5V hoặc 3.3V không?
  • [ ] Đo điện áp tín hiệu từ module: có >3.3V không?
  • [ ] Đã nối GND chung giữa ESP32 và module?
  • [ ] Nếu dùng voltage divider, đã tính V_out đúng?
  • [ ] Nếu dùng level shifter, đã cấp nguồn cho cả LV (3.3V) và HV (5V)?
  • [ ] Dùng trực tiếp: module có thực sự 3.3V không?

9. Kết Luận

Kết nối thiết bị 3.3V và 5V là một trong những lỗi phổ biến nhất gây cháy GPIO trên ESP32. Hãy nhớ quy tắc vàng:

  1. KIỂM TRA DATASHEET trước khi kết nối — module chạy 3.3V hay 5V?
  2. KHÔNG đưa 5V vào GPIO ESP32 — dùng voltage divider hoặc level shifter
  3. GND chung là bắt buộc — cả 2 board phải cùng tham chiếu GND
  4. Dùng level shifter module — 10,000đ rẻ hơn mua ESP32 mới
  5. Nếu nghi ngờ, đo trước — dùng multimeter đo điện áp tín hiệu trước khi kết nối
  6. I2C thường tương thích — nhưng kiểm tra pull-up voltage trước

Bài tiếp theo: UART là gì? Debug và giao tiếp Serial với ESP32.

Tài liệu tham khảo

  • Espressif ESP32 Datasheet — Section “GPIO Specifications”