Cách nạp code cho ESP-01 và ESP-01S bằng USB-TTL, đế nạp: sơ đồ chân và lỗi thường gặp
Cách nạp code cho ESP-01, ESP-01S: sơ đồ 8 chân, khác nhau giữa hai bản, nối USB-TTL đúng cách, cấp nguồn 3,3 V đủ dòng, chế độ nạp GPIO0, cài Arduino IDE, chương trình đầu tiên và lỗi hay gặp.
ESP-01 và ESP-01S là module Wi-Fi nhỏ nhất dùng chip ESP8266: chỉ bằng con tem, 8 chân, giá rẻ. Chúng hay dùng làm module Wi-Fi cho Arduino, công tắc thông minh nhỏ, cảm biến gửi dữ liệu. Nhưng module không có cổng USB, nên nạp code là chỗ người mới hay vướng: nối USB-TTL sao cho đúng, kéo GPIO0 xuống lúc nào, vì sao nạp mãi báo "Failed to connect". Bài này hướng dẫn cách nạp code cho ESP-01 bằng mạch USB-TTL hoặc đế nạp, sơ đồ chân, khác biệt giữa ESP-01 và ESP-01S, chương trình đầu tiên và các lỗi hay gặp.
1. Sơ đồ chân ESP-01

Module có hai hàng chân 2,54 mm. Chú ý ba chân quyết định module có chạy hay không:
- VCC: chỉ nhận 3,3 V. Cấp 5 V là hỏng chip. Khi phát Wi-Fi, module kéo dòng đỉnh khoảng 300 mA.
- CH_PD (còn ghi EN, CH_EN): phải ở mức cao. ESP-01 đời cũ không có điện trở kéo lên, để hở là chip không chạy.
- GPIO0: ở mức thấp lúc khởi động thì chip vào chế độ nạp; ở mức cao (hoặc để hở với ESP-01S) thì chạy chương trình.
Chỉ có GPIO0, GPIO2, RXD (GPIO3), TXD (GPIO1) dùng được làm chân vào ra. GPIO0 và GPIO2 là chân khởi động nên không được nối thiết bị kéo chúng xuống thấp lúc cấp điện.
2. ESP-01 và ESP-01S khác nhau thế nào

ESP-01S là bản cải tiến: có sẵn điện trở kéo lên cho CH_PD, RST, GPIO0, bỏ LED đỏ báo nguồn (tiết kiệm dòng), LED xanh nối GPIO2 nên điều khiển được trong chương trình. Mua mới thì nên chọn ESP-01S.
3. Nối ESP-01 với mạch USB-TTL

Cần một mạch USB-TTL (CP2102, CH340, FT232) có chế độ 3,3 V:
- TX của USB-TTL nối RXD của ESP-01, RX nối TXD (nối chéo).
- GND nối GND.
- 3,3 V nối VCC; với ESP-01 đời cũ, nối thêm CH_PD lên 3,3 V.
- GPIO0 nối GND (qua dây cắm hoặc nút nhấn) khi muốn nạp.
Chân 3,3 V của nhiều mạch USB-TTL chỉ cấp được vài chục mA, không đủ cho ESP-01 khi phát Wi-Fi: module reset liên tục hoặc nạp lỗi giữa chừng. Cách chắc chắn là lấy 5 V từ USB-TTL qua một ổn áp AMS1117-3.3 hoặc mạch hạ áp như MP1584 chỉnh 3,3 V, thêm tụ 100 µF cạnh VCC, nối chung GND.
Đế nạp ESP-01 (mạch USB cắm thẳng module, có chip CH340 và ổn áp) tiện hơn nhiều. Loại có công tắc "PROG/UART" thì gạt sang PROG để nạp, gạt về UART để chạy. Loại không có công tắc thì phải hàn thêm nút nối GPIO0 xuống GND.
4. Chế độ nạp và chế độ chạy

ESP8266 chỉ đọc GPIO0 lúc vừa cấp điện hoặc vừa reset. Vì vậy quy trình nạp tay là: nối GPIO0 xuống GND → reset (chạm RST xuống GND hoặc rút cắm điện) → bấm Upload → nạp xong, bỏ nối GPIO0 → reset để chạy chương trình mới.
5. Cài đặt Arduino IDE và nạp chương trình
- Cài gói ESP8266 (thêm
https://arduino.esp8266.com/stable/package_esp8266com_index.jsonvào File → Preferences → Additional boards manager URLs, rồi cài esp8266 trong Boards Manager). Bài dùng gói 3.1.2. - Tools → Board → esp8266 → Generic ESP8266 Module.
- Flash Size: 1MB (FS: 64KB, OTA: ~470KB). Builtin Led: 2. Reset Method: "no dtr (aka ck)" khi nạp tay; "dtr (aka nodemcu)" khi đế nạp có mạch tự reset.
- Chọn cổng COM, đưa module vào chế độ nạp, bấm Upload.
Chương trình mẫu nháy LED xanh của ESP-01S và quét các mạng Wi-Fi xung quanh, không cần linh kiện nào khác:
// PYWORLD.VN - Chương trình đầu tiên cho ESP-01 / ESP-01S: nháy LED và quét mạng Wi-Fi xung quanh
// PYWORLD.VN - Chọn bo "Generic ESP8266 Module", Flash Size 1MB; ESP-01S có LED xanh ở GPIO2 (sáng mức thấp)
// PYWORLD.VN - ESP-01 đời cũ: LED xanh nối chân TX nên chỉ nháy khi có dữ liệu Serial, không điều khiển riêng được
#include <ESP8266WiFi.h>
const uint8_t CHAN_LED = 2; // GPIO2 trên ESP-01S
const uint32_t CHU_KY_QUET_MS = 15000;
uint32_t lanQuet = 0;
uint32_t lanNhay = 0;
bool ledSang = false;
void quetWifi() {
Serial.println("Dang quet Wi-Fi...");
int n = WiFi.scanNetworks();
if (n <= 0) {
Serial.println("Khong thay mang nao");
return;
}
for (int i = 0; i < n; i++) {
Serial.printf("%2d. %-24s %4d dBm kenh %2d %s\n", i + 1, WiFi.SSID(i).c_str(), WiFi.RSSI(i), WiFi.channel(i),
WiFi.encryptionType(i) == ENC_TYPE_NONE ? "mo" : "co mat khau");
}
WiFi.scanDelete();
}
void setup() {
Serial.begin(115200);
delay(100);
Serial.println();
Serial.printf("ESP-01: chip ID %06X, flash %u KB\n", (unsigned)ESP.getChipId(), (unsigned)(ESP.getFlashChipRealSize() / 1024));
pinMode(CHAN_LED, OUTPUT);
WiFi.mode(WIFI_STA);
WiFi.disconnect();
quetWifi();
lanQuet = millis();
}
void loop() {
if (millis() - lanNhay >= 500) {
lanNhay = millis();
ledSang = !ledSang;
digitalWrite(CHAN_LED, ledSang ? LOW : HIGH);
}
if (millis() - lanQuet >= CHU_KY_QUET_MS) {
lanQuet = millis();
quetWifi();
}
}

Mức sóng càng gần 0 càng mạnh: từ −50 dBm trở lên là rất tốt, khoảng −70 dBm vẫn dùng được, dưới −80 dBm dễ mất kết nối. ESP-01 có anten mạch in nhỏ nên đặt module xa vỏ kim loại, xa nguồn nhiễu.
6. Lỗi hay gặp
| Hiện tượng | Nguyên nhân | Cách xử lý |
|---|---|---|
Failed to connect to ESP8266: Timed out waiting for packet header | Chưa vào chế độ nạp; nối TX/RX không chéo | Nối GPIO0 xuống GND rồi reset; đảo TX, RX |
| Nạp được một phần rồi lỗi | Nguồn 3,3 V yếu | Dùng ổn áp riêng, tụ 100 µF |
| Nạp xong không chạy, LED không nháy | GPIO0 vẫn nối GND; CH_PD để hở (ESP-01) | Bỏ nối GPIO0, kéo CH_PD lên 3,3 V, reset |
| Chữ lạ trên Serial Monitor | Log khởi động 74880 baud | Bình thường; chương trình in ở 115200 |
| Module nóng, không nhận | Đã cấp 5 V vào VCC hoặc mức 5 V ở RX | Kiểm tra jumper 3,3 V của USB-TTL; module có thể đã hỏng |
Cần nhiều chân hơn, có sẵn cổng USB và tự nạp thì dùng mạch ESP8266 lớn hơn như Wemos D1 R2 hoặc mạch ESP8266 có màn hình OLED.
Xem thêm