Cấp nguồn cho ESP32 đúng cách: cổng USB, chân VIN, 3V3, pin 18650 và lỗi brownout khi bật Wi-Fi
Cấp nguồn cho ESP32 qua cổng USB, chân VIN, 3V3, từ adapter hay pin 18650; vì sao ESP32 tự khởi động lại khi bật Wi-Fi (brownout) và chương trình đo sụt áp nguồn.
ESP32 chạy được hay không, chạy có ổn định hay không, phần lớn phụ thuộc vào nguồn cấp. Lỗi hay gặp nhất là mạch tự khởi động lại mỗi khi bật Wi-Fi, Serial Monitor hiện dòng Brownout detector was triggered. Bài này tổng hợp các cách cấp nguồn cho mạch ESP32 DevKit: qua cổng USB, chân VIN (bản 38 chân là chân 5V), chân 3V3, từ adapter, từ pin 18650; giải thích lỗi sụt áp (brownout) và kèm một chương trình để tự đo xem nguồn đang dùng có đủ khỏe hay không.
1. Đường nguồn trên mạch ESP32 DevKit

Chip ESP32 chạy ở 3,3 V. Trên mạch DevKit, 5 V từ cổng USB đi qua một diode tới đường 5 V (nối ra chân VIN), rồi qua IC ổn áp tuyến tính (thường là loại AMS1117-3.3) hạ xuống 3,3 V nối ra chân 3V3. Như vậy có ba chỗ đưa nguồn vào:
- Cổng USB: cách tiện nhất. Dùng củ sạc 5 V từ 1 A trở lên và cáp ngắn, dây to. Cổng USB 2.0 của máy tính chỉ đảm bảo 500 mA, đủ để nạp code và chạy thử, có thể thiếu khi bật Wi-Fi kèm cảm biến, màn hình.
- Chân VIN (bản 38 chân là chân 5V): cấp 5 V ổn định. IC ổn áp tuyến tính cần điện áp vào cao hơn 3,3 V khoảng 1–1,3 V, nên dưới khoảng 4,5 V là bắt đầu thiếu áp. Cao hơn 5 V thì phần dư biến thành nhiệt trên IC: công suất tỏa nhiệt bằng (điện áp vào − 3,3 V) × dòng. Ví dụ 12 V, 250 mA tỏa khoảng 2,2 W, quá nhiều cho IC dán nhỏ trên mạch.
- Chân 3V3: chỉ dùng khi đã có nguồn 3,3 V ổn định (3,0–3,6 V) từ một IC ổn áp bên ngoài. Cách này bỏ qua IC ổn áp trên mạch. Khi cấp vào 3V3, không nối gì vào VIN; cắm cáp USB để nạp code thì tháo nguồn 3,3 V ngoài ra.
Hai cách sai hay gặp: đưa 12 V thẳng vào VIN, và nối pin 18650 thẳng vào 3V3 (pin đầy 4,2 V, vượt mức chip chịu được) hoặc vào VIN (pin 3,0–4,2 V, không đủ cho IC ổn áp tạo ra 3,3 V).
2. Chọn nguồn theo từng trường hợp

- Adapter 9 V, 12 V, 24 V: qua mạch hạ áp DC-DC chỉnh 5 V rồi vào VIN. Mạch hạ áp gần như không nóng như IC ổn áp tuyến tính. Cách chọn và chỉnh mạch hạ áp xem bài chọn mạch hạ áp, tăng áp DC-DC và LM2596: cách chỉnh 5 V.
- Pin 18650 một cell: tăng áp lên 5 V rồi vào VIN, hoặc dùng IC ổn áp 3,3 V loại sụt áp thấp rồi vào 3V3. Hai cách được so sánh chi tiết trong bài cấp nguồn ESP32 bằng pin 18650 sạc qua jack Type-C. Hoặc dùng luôn mạch ESP32 tích hợp đế pin 18650 và mạch quản lý pin.
- Khối pin 2S, 3S: điện áp thay đổi từ khoảng 6 V tới 12,6 V theo mức pin, nên dùng mạch hạ áp DC-DC xuống 5 V.
- Đế ra chân ESP32 30 chân: cắm adapter 6,5–16 V vào jack DC trên đế, IC ổn áp trên đế hạ xuống 5 V cho ESP32. Xem bài đế ra chân ESP32 30 chân.
Tải lớn lấy nguồn riêng. Relay, động cơ, servo, dải LED không lấy nguồn từ chân 3V3 hay VIN của ESP32; cấp từ nguồn riêng, chỉ nối chung GND với ESP32.
3. Lỗi brownout: ESP32 tự khởi động lại khi bật Wi-Fi
ESP32 có bộ phát hiện sụt áp (brownout detector). Khi điện áp nguồn của chip tụt xuống dưới một ngưỡng (với cấu hình mặc định của gói esp32 cho Arduino, khoảng 2,43 V theo tài liệu của Espressif), chip tự reset để tránh chạy sai hoặc ghi hỏng bộ nhớ flash. Serial Monitor hiện:
Brownout detector was triggered

Nguyên nhân là mỗi lần phát sóng Wi-Fi, ESP32 kéo dòng vài trăm mA trong thời gian rất ngắn. Nguồn yếu, cáp dài và mảnh, mối nối lỏng làm điện áp tụt theo từng xung dòng. Ví dụ cáp USB dây mảnh có điện trở tổng khoảng 0,5 Ω, xung 0,4 A làm sụt 0,2 V ngay trên dây cáp.
Cách khắc phục, làm lần lượt:
- Đổi nguồn và cáp: củ sạc 5 V từ 1 A trở lên, cáp ngắn và dày. Đây là nguyên nhân của phần lớn trường hợp.
- Thêm tụ: tụ hóa 470–1000 µF song song với tụ gốm 100 nF, đặt sát giữa chân VIN và GND.
- Tách nguồn tải: relay, servo, động cơ lấy nguồn riêng, không dùng chung với ESP32.
- Dùng mạch hạ áp đủ dòng khi cấp từ adapter hay pin, không dùng IC ổn áp tuyến tính nhỏ cho điện áp vào cao.
- Giảm công suất phát nếu thiết bị đặt gần bộ phát Wi-Fi: gọi
WiFi.setTxPower(WIFI_POWER_15dBm)sau khi bật Wi-Fi. Đây là cách chữa cháy, không thay được việc sửa nguồn.
Không nên tắt bộ phát hiện sụt áp như một số hướng dẫn trên mạng: lỗi vẫn còn, chỉ là chip chạy tiếp khi điện áp không đủ, dễ treo, chạy sai hoặc hỏng dữ liệu trong flash.
4. Chương trình kiểm tra nguồn
Chương trình dưới đây giúp biết nguồn đang dùng có đủ khỏe hay không:
- in lý do lần khởi động gần nhất, và đếm số lần reset do sụt áp kể từ lúc cấp nguồn;
- đo điện áp chân VIN qua cầu phân áp hai điện trở 100 kΩ nối vào chân D34 (GPIO34);
- cứ 5 giây quét Wi-Fi một lần (lúc ESP32 phát sóng nhiều nhất) và ghi lại mức VIN thấp nhất trong lúc quét.
Nối dây

| Linh kiện | Nối |
|---|---|
| Điện trở R1 100 kΩ | từ chân VIN tới điểm giữa |
| Điện trở R2 100 kΩ | từ điểm giữa tới GND |
| Điểm giữa | chân D34 (GPIO34) |
| Tụ hóa 470–1000 µF (tùy chọn, để so sánh) | cực + vào VIN, cực − vào GND, đặt sát mạch |
GPIO34 thuộc bộ ADC1 nên vẫn đo được khi Wi-Fi đang bật (các chân ADC2 thì không). Điểm đo không gắn tụ, để bắt được những lần sụt áp ngắn.
Chương trình
Bài dùng gói esp32 phiên bản 3.3.10 trên Arduino IDE 2, không cần thư viện ngoài. Chọn bo mạch ESP32 Dev Module.
// PYWORLD.VN - Kiểm tra nguồn cấp cho ESP32: lý do khởi động lại và số lần reset do sụt áp (brownout)
// PYWORLD.VN - Đo điện áp chân VIN qua cầu phân áp 100 kΩ / 100 kΩ nối vào GPIO34
// PYWORLD.VN - Ghi mức VIN thấp nhất trong lúc ESP32 quét Wi-Fi, lúc phát sóng tốn dòng nhất
#include <WiFi.h>
#include "esp_system.h"
#include "esp_attr.h"
// Cầu phân áp hai điện trở 100 kΩ: VIN — 100 kΩ — GPIO34 — 100 kΩ — GND.
// Điện áp tại GPIO34 bằng một nửa VIN. GPIO34 thuộc ADC1 nên vẫn đo được khi bật Wi-Fi.
// Không gắn tụ ở điểm đo: tụ sẽ làm phẳng các lần sụt áp ngắn mà bài muốn bắt.
const int CHAN_DO_VIN = 34;
const uint32_t HE_SO_CAU = 2; // VIN = điện áp tại chân đo × (100k + 100k) / 100k
const uint32_t NGUONG_CANH_BAO_MV = 4500; // VIN dưới mức này là nguồn đã yếu
// Biến đặt trong vùng nhớ RTC không khởi tạo: giữ giá trị qua reset mềm và reset do sụt áp,
// mất khi rút nguồn. Dùng một số đánh dấu để biết giá trị đang giữ có hợp lệ hay không.
RTC_NOINIT_ATTR uint32_t danhDau;
RTC_NOINIT_ATTR uint32_t soLanBrownout;
const uint32_t DANH_DAU_HOP_LE = 0x50595744;
const char *tenLyDo(esp_reset_reason_t lyDo) {
switch (lyDo) {
case ESP_RST_POWERON: return "cap nguon lan dau";
case ESP_RST_SW: return "khoi dong lai bang phan mem";
case ESP_RST_PANIC: return "loi chuong trinh (panic)";
case ESP_RST_INT_WDT:
case ESP_RST_TASK_WDT:
case ESP_RST_WDT: return "watchdog";
case ESP_RST_DEEPSLEEP: return "thuc day tu ngu sau";
case ESP_RST_BROWNOUT: return "SUT AP (brownout)";
default: return "khac";
}
}
// Đo VIN (mV): lấy trung bình 16 lần đo cho số ổn định
uint32_t doVinTrungBinh() {
uint32_t tong = 0;
for (int i = 0; i < 16; i++) {
tong += analogReadMilliVolts(CHAN_DO_VIN);
}
return tong / 16 * HE_SO_CAU;
}
void setup() {
Serial.begin(115200);
delay(300);
esp_reset_reason_t lyDo = esp_reset_reason();
if (danhDau != DANH_DAU_HOP_LE || lyDo == ESP_RST_POWERON) {
danhDau = DANH_DAU_HOP_LE;
soLanBrownout = 0;
}
if (lyDo == ESP_RST_BROWNOUT) {
soLanBrownout++;
}
Serial.println();
Serial.printf("Ly do khoi dong: %s\n", tenLyDo(lyDo));
Serial.printf("So lan sut ap tu luc cap nguon: %u\n", (unsigned)soLanBrownout);
Serial.printf("VIN luc chua bat Wi-Fi: %u mV\n", (unsigned)doVinTrungBinh());
}
void loop() {
WiFi.mode(WIFI_STA);
uint32_t vinTruoc = doVinTrungBinh();
uint32_t thapNhat = vinTruoc;
// Quét Wi-Fi ở chế độ không chặn; trong lúc quét, đo VIN liên tục để bắt mức thấp nhất
WiFi.scanNetworks(true);
uint32_t dem = 0;
while (WiFi.scanComplete() == WIFI_SCAN_RUNNING) {
uint32_t v = analogReadMilliVolts(CHAN_DO_VIN) * HE_SO_CAU;
if (v < thapNhat) {
thapNhat = v;
}
if (++dem % 50 == 0) {
delay(1); // nhường CPU cho các tác vụ khác
}
}
int soMang = WiFi.scanComplete();
WiFi.scanDelete();
WiFi.mode(WIFI_OFF);
Serial.printf("Quet Wi-Fi: %d mang | VIN truoc %u mV, thap nhat %u mV, sut %u mV (%u lan do)\n",
soMang, (unsigned)vinTruoc, (unsigned)thapNhat, (unsigned)(vinTruoc - thapNhat), (unsigned)dem);
if (thapNhat < NGUONG_CANH_BAO_MV) {
Serial.println("Canh bao: VIN xuong duoi 4,5 V khi phat Wi-Fi: nguon yeu, day dai hoac nho");
}
delay(5000);
}
Kết quả

Cách đọc kết quả:
- Dòng "Ly do khoi dong" hiện "SUT AP (brownout)" nghĩa là lần khởi động vừa rồi do sụt áp. Số lần sụt áp tăng dần sau mỗi lần quét là nguồn đang không đủ.
- Khi cấp qua cổng USB, VIN thường thấp hơn 5 V khoảng 0,2–0,4 V vì sụt áp trên diode và cáp.
- Mức "sut" là độ sụt khi phát Wi-Fi. Nguồn tốt, cáp ngắn thường chỉ sụt vài chục tới khoảng 100 mV. Sụt vài trăm mV, hoặc VIN xuống dưới 4,5 V, là nguồn hay cáp đang yếu.
- Thử lần lượt: đổi cáp, đổi củ sạc, thêm tụ 1000 µF, rồi so sánh mức sụt giữa các lần.
Giải thích các phần chính
esp_reset_reason()trả về lý do lần khởi động gần nhất;ESP_RST_BROWNOUTlà reset do sụt áp.RTC_NOINIT_ATTRđặt biến đếm vào vùng nhớ RTC không bị xóa khi reset mềm hay reset do sụt áp, chỉ mất khi rút nguồn. Số đánh dấuDANH_DAU_HOP_LEgiúp nhận ra giá trị rác lúc mới cấp nguồn.analogReadMilliVolts()đọc điện áp chân ADC đã hiệu chuẩn, đơn vị mV; nhân 2 để ra VIN vì cầu phân áp chia đôi.WiFi.scanNetworks(true)quét Wi-Fi ở chế độ không chặn, nên vòng lặp vẫn đo được VIN liên tục trong lúc quét;delay(1)sau mỗi 50 lần đo để nhường CPU cho các tác vụ khác.
5. Lỗi thường gặp
| Hiện tượng | Nguyên nhân hay gặp | Cách xử lý |
|---|---|---|
| Khởi động lại khi bật Wi-Fi, báo Brownout | Nguồn yếu, cáp dài mảnh | Củ sạc 1 A trở lên, cáp ngắn, thêm tụ 1000 µF |
| Khởi động lại khi relay hoặc động cơ chạy | Tải dùng chung nguồn với ESP32 | Cấp nguồn riêng cho tải, chỉ nối chung GND |
| IC ổn áp trên mạch rất nóng | Cấp 9–12 V vào VIN | Dùng mạch hạ áp DC-DC xuống 5 V |
| Chạy pin 18650 được một lúc thì tắt | Nối pin vào VIN không qua tăng áp, pin xuống dưới khoảng 4,5 V là thiếu | Thêm mạch tăng áp 5 V hoặc ổn áp 3,3 V sụt áp thấp |
| Mạch nóng ran, chip hỏng | Nối 5 V hoặc pin 4,2 V vào chân 3V3 | Chân 3V3 chỉ nhận 3,0–3,6 V |
| Chạy bằng máy tính được, bằng củ sạc thì không | Củ sạc kém, điện áp dao động | Đo bằng chương trình ở mục 4, thay củ sạc |
6. Xem thêm
- Sản phẩm: mạch hạ áp LM2596, mạch nguồn MP1584, ESP32 tích hợp pin 18650 và mạch quản lý pin, jack nguồn DC gắn hộp, jack Type-C tích hợp mạch sạc pin 1S.
- Mạch hạ áp LM2596 và MP1584: cách chọn, chỉnh điện áp và cấp nguồn ESP32.
- Sơ đồ chân ESP32 DevKit V1 30 chân và 38 chân.
- Kết nối Wi-Fi trên ESP32: quét mạng, tự kết nối lại và Deep Sleep tiết kiệm pin.
- IC ổn áp tuyến tính 7805, AMS1117: cách tính nhiệt.
Cần tư vấn chọn nguồn cho thiết bị ESP32, liên hệ PYWORLD qua số 0915703319.
Xem thêm