Mức logic 3,3 V và 5 V: khi nào cần chuyển mức và cách nối an toàn với ESP32
Giải thích mức logic 3,3 V và 5 V: ngưỡng mức thấp, mức cao của ESP32, Arduino và các họ IC; khi nào nối thẳng được, khi nào cần mạch chia áp hoặc mạch chuyển mức MOSFET. Kèm chương trình đo kiểm tra.
ESP32 làm việc ở 3,3 V, trong khi rất nhiều module, cảm biến và mạch Arduino cũ làm việc ở 5 V. Nối hai loại này với nhau mà không để ý mức điện áp là nguyên nhân phổ biến làm hỏng chân GPIO hoặc làm tín hiệu lúc được lúc mất. Bài viết giải thích mức logic là gì, ngưỡng của các họ linh kiện thường gặp, khi nào nối thẳng được, khi nào phải chia áp hoặc dùng mạch chuyển mức, và dùng chính ESP32 để đo kiểm tra mạch chia áp trước khi nối.
1. Mức logic là gì?
- Mạch số chỉ phân biệt hai trạng thái: mức thấp (0) và mức cao (1). Mỗi chân vào có hai ngưỡng điện áp để quyết định.
- Dưới ngưỡng thấp (ký hiệu VIL): chắc chắn được hiểu là 0.
- Trên ngưỡng cao (ký hiệu VIH): chắc chắn được hiểu là 1.
- Ở giữa hai ngưỡng: không xác định. Chân có thể đọc ra 0 hoặc 1 tùy lúc, và tín hiệu trở nên chập chờn.
- Ngoài ra mỗi chân có một điện áp tối đa chịu được. Vượt quá mức này, chân có thể hỏng vĩnh viễn.
2. Ngưỡng của các họ linh kiện thường gặp
| Chân vào của | Nguồn | Mức thấp khi dưới | Mức cao khi trên | Nhận mức cao 3,3 V? |
|---|---|---|---|---|
| ESP32 | 3,3 V | 0,825 V | 2,475 V | Được |
| Arduino Uno, Nano (ATmega328P) | 5 V | 1,5 V | 3,0 V | Được, dư ít |
| IC họ TTL, 74HCT, 74AHCT | 5 V | 0,8 V | 2,0 V | Được |
| IC họ 74HC, LED WS2812 | 5 V | 1,5 V | 3,5 V | Không bảo đảm |
Chân của ESP32 chỉ chịu được tối đa khoảng 3,6 V. Mức cao 5 V của thiết bị khác đưa thẳng vào sẽ vượt giới hạn này.
3. Xét từng chiều tín hiệu
ESP32 phát, thiết bị 5 V nhận
- ESP32 phát mức cao khoảng 3,3 V. Phần lớn chân vào 5 V coi đó là mức cao, nên thường nối thẳng được: chân RX của module UART, chân điều khiển module relay, chân vào của Arduino.
- Ngoại lệ là các chân vào cần trên 3,5 V như IC họ 74HC hoặc LED WS2812 cấp nguồn 5 V. Khi đó thêm một IC đệm họ 74HCT hoặc 74AHCT cấp nguồn 5 V: IC này nhận 3,3 V là mức cao và phát ra 5 V.
Thiết bị 5 V phát, ESP32 nhận
- Không nối thẳng. Dùng mạch chia áp gồm hai điện trở: R1 nối từ tín hiệu 5 V tới chân ESP32, R2 nối từ chân ESP32 xuống GND.
- Với R1 = 2,2 kΩ và R2 = 3,3 kΩ, điện áp ra là 5 × 3,3 / (2,2 + 3,3) = 3,0 V: trên ngưỡng mức cao 2,475 V và dưới giới hạn 3,6 V.
- Cặp 1 kΩ và 2 kΩ cho 3,33 V cũng dùng được. Điện trở lớn hơn (10 kΩ và 20 kΩ) tốn ít dòng hơn nhưng làm chậm sườn xung, chỉ hợp với tín hiệu chậm.
- Mạch chia áp chỉ dùng cho một chiều và cho tín hiệu không quá nhanh như UART hoặc mức tĩnh.
Tín hiệu hai chiều trên cùng một dây
- I2C và 1-Wire truyền hai chiều trên một dây nên không chia áp được. Mạch chuyển mức thông dụng dùng một MOSFET kênh N (thường là BSS138) và hai điện trở kéo lên, một lên 3,3 V, một lên 5 V.
- Khi một bên kéo dây xuống thấp, MOSFET dẫn và bên kia cũng xuống thấp. Khi cả hai bên nhả, mỗi bên được kéo lên mức riêng của mình.
- Module chuyển mức 4 kênh bán sẵn chính là bốn mạch như vậy. Mạch này hợp với I2C và tín hiệu chậm, không hợp với SPI tốc độ cao.
4. Các tình huống hay gặp
| Tình huống | Cách nối |
|---|---|
| Module UART 5 V (GPS, Bluetooth đời cũ) với ESP32 | TX của ESP32 nối thẳng RX của module; TX của module qua mạch chia áp rồi mới vào RX của ESP32 |
| Module I2C có điện trở kéo lên, cấp nguồn 5 V | Điện trở kéo SDA, SCL lên 5 V: không nối thẳng. Cấp nguồn 3,3 V cho module nếu module cho phép, hoặc dùng mạch chuyển mức MOSFET |
| Module relay 5 V | Chân IN thường nối thẳng được; xem bài ESP32 điều khiển module relay |
| Module thẻ nhớ có IC ổn áp và IC đệm | Nối thẳng: tín hiệu trên module đã ở mức 3,3 V dù cấp nguồn 5 V |
| Cảm biến có ngõ ra số 5 V (ví dụ module thu hồng ngoại, cảm biến siêu âm đo khoảng cách) | Ngõ ra qua mạch chia áp rồi mới vào ESP32 |
| Nối ESP32 với Arduino Uno qua UART | TX của ESP32 nối thẳng RX của Uno; TX của Uno qua mạch chia áp |
Cách ít rủi ro nhất là tránh phải chuyển mức: chọn module chạy được ở 3,3 V và cấp nguồn 3,3 V cho module. Khi không chắc mức ngõ ra của một module, đo bằng đồng hồ hoặc bằng chương trình dưới đây trước khi nối.
5. Chuẩn bị
- Một mạch ESP32 DevKit V1 30 chân (hoặc bản dùng chip CH340).
- Hai điện trở 2,2 kΩ và 3,3 kΩ.
- Breadboard và dây cắm.
- Arduino IDE 2.x với gói esp32 by Espressif Systems (bài dùng phiên bản 3.3.10). Không cần cài thêm thư viện.
6. Mạch thử
Lắp đủ hai điện trở trước, kiểm tra lại, rồi mới nối điểm giữa vào D34. Không nối thẳng VIN vào bất kỳ chân GPIO nào.
7. Chương trình đo mức logic
Chương trình đo điện áp tại D34 bằng ADC và so với hai ngưỡng của ESP32, giống một đồng hồ đo đơn giản cho biết điện áp đó sẽ được hiểu là mức gì.
/*
PYWORLD.VN - Mức logic 3,3 V và 5 V: dùng ESP32 đo điện áp sau mạch chia áp trước khi nối vào chân số
Nối điểm giữa của mạch chia áp vào D34; mỗi giây chương trình in điện áp và cho biết ESP32 sẽ hiểu là mức gì
Ngưỡng của ESP32 ở nguồn 3,3 V: dưới 0,825 V là mức thấp, trên 2,475 V là mức cao
*/
#define CHAN_DO 34
const int NGUON_MV = 3300;
const int NGUONG_THAP_MV = NGUON_MV / 4; // 0,25 x nguồn: từ đây trở xuống chắc chắn là mức thấp
const int NGUONG_CAO_MV = NGUON_MV * 3 / 4; // 0,75 x nguồn: từ đây trở lên chắc chắn là mức cao
const int GIOI_HAN_DO_MV = 3100; // ADC của ESP32 đo không còn chính xác ở sát mức nguồn
const int SO_MAU = 32;
int doDienApMv() {
uint32_t tong = 0;
for (int i = 0; i < SO_MAU; i++) {
tong += analogReadMilliVolts(CHAN_DO);
delayMicroseconds(200);
}
return tong / SO_MAU;
}
void setup() {
Serial.begin(115200);
analogSetPinAttenuation(CHAN_DO, ADC_11db);
Serial.printf("\nNguong muc thap %d mV, nguong muc cao %d mV\n", NGUONG_THAP_MV, NGUONG_CAO_MV);
}
void loop() {
int dienAp = doDienApMv();
if (dienAp >= GIOI_HAN_DO_MV) {
Serial.printf("Dien ap tu %d mV tro len: sat hoac vuot muc nguon 3,3 V, kiem tra lai mach chia ap\n", GIOI_HAN_DO_MV);
} else if (dienAp >= NGUONG_CAO_MV) {
Serial.printf("Dien ap %d mV: muc CAO, cao hon nguong %d mV\n", dienAp, dienAp - NGUONG_CAO_MV);
} else if (dienAp <= NGUONG_THAP_MV) {
Serial.printf("Dien ap %d mV: muc THAP\n", dienAp);
} else {
Serial.printf("Dien ap %d mV: vung khong xac dinh, khong dung lam tin hieu so\n", dienAp);
}
delay(1000);
}
ADC của ESP32 đo kém chính xác ở sát mức nguồn, vì vậy chương trình chỉ báo "sát hoặc vượt mức nguồn" khi kết quả từ 3100 mV trở lên. Nền tảng về ADC có trong bài đọc ADC trên ESP32.
8. Kết quả mong đợi
- Mở Tools > Serial Monitor ở 115200 baud. Với R1 = 2,2 kΩ và R2 = 3,3 kΩ, điện áp ở quanh 3000 mV và được báo là mức cao.
- Thử hai điện trở bằng nhau nối từ 3V3 xuống GND: điện áp khoảng 1650 mV, rơi vào vùng không xác định.
- Nối D34 xuống GND: báo mức thấp.
9. Xử lý lỗi thường gặp
| Hiện tượng | Nguyên nhân thường gặp | Cách xử lý |
|---|---|---|
| Chương trình báo sát hoặc vượt mức nguồn | Thiếu điện trở R2, hoặc lắp nhầm vị trí hai điện trở | Rút dây khỏi D34 ngay; kiểm tra R2 đã nối xuống GND chưa |
| Điện áp thấp hơn tính toán nhiều | Dùng điện trở quá lớn, hoặc "5 V" thực tế thấp hơn 5 V | Đo chân VIN (khoảng 4,6 đến 5 V khi cấp qua USB); dùng điện trở cỡ kΩ |
| Thiết bị 5 V không nhận lệnh từ ESP32 | Chân vào của thiết bị cần mức cao trên 3,5 V | Thêm IC đệm họ 74HCT hoặc 74AHCT cấp nguồn 5 V |
| UART qua mạch chia áp bị lỗi ở tốc độ cao | Điện trở chia áp quá lớn làm sườn xung chậm | Giảm xuống cỡ 1 đến 3,3 kΩ, hoặc giảm tốc độ baud |
| Chân GPIO của ESP32 không còn hoạt động | Đã nhận 5 V trực tiếp | Chân đó có thể đã hỏng; chuyển sang chân khác và thêm mạch bảo vệ |
Xem thêm