Thư viện ArduinoOTA: update firmware ESP32 không cần dây
ArduinoOTA là thư viện tích hợp sẵn trong Arduino-ESP32 cho phép nạp firmware qua WiFi từ Arduino IDE — không cần rút USB. Một khi config xong, board ESP32 hiện trong Tools → Port giống cổng COM ảo. Bài này hướng dẫn từ setup đến best practice cho production.
1. ArduinoOTA hoạt động thế nào?
ESP32 chạy code ArduinoOTA.begin() + ArduinoOTA.handle() trong loop. Khi Arduino IDE chọn cổng "network" và nhấn Upload:
- IDE phát mDNS broadcast tìm ESP32.
- ESP32 trả lời với IP + hostname.
- IDE upload firmware mới qua TCP port 3232.
- ESP32 ghi firmware vào phân vùng OTA dự phòng.
- Reboot vào firmware mới.
Nếu firmware mới crash → ESP32 tự rollback về phân vùng cũ (nếu enable).
2. Code setup tối thiểu
#include
#include
void setup() {
Serial.begin(115200);
WiFi.begin("SSID", "PASS");
while (WiFi.status() != WL_CONNECTED) delay(500);
Serial.println(WiFi.localIP());
ArduinoOTA.begin();
Serial.println("OTA ready");
}
void loop() {
ArduinoOTA.handle();
// ... code chính của bạn
}
Restart IDE sau khi nạp lần đầu qua USB. Vào Tools → Port — bạn sẽ thấy esp32-XXXXXX at 192.168.x.x trong network ports.
3. Setup nâng cao
void setup() {
// ... wifi ...
ArduinoOTA.setHostname("esp32-phong-khach");
ArduinoOTA.setPassword("otaSecret123");
// Hoặc dùng MD5 hash để password không lộ trong code:
// ArduinoOTA.setPasswordHash("21232f297a57a5a743894a0e4a801fc3");
ArduinoOTA.setPort(3232); // mặc định 3232
ArduinoOTA.onStart([]() {
String type = (ArduinoOTA.getCommand() == U_FLASH) ? "firmware" : "SPIFFS";
Serial.println("Start update " + type);
});
ArduinoOTA.onEnd([]() {
Serial.println("\nOTA done");
});
ArduinoOTA.onProgress([](unsigned p, unsigned t) {
Serial.printf("%u%%\r", (p * 100) / t);
});
ArduinoOTA.onError([](ota_error_t error) {
Serial.printf("Error[%u]: ", error);
if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
else if (error == OTA_END_ERROR) Serial.println("End Failed");
});
ArduinoOTA.begin();
}
4. API tóm tắt
| Hàm | Mục đích |
|---|---|
begin() | Khởi động OTA service |
handle() | Gọi mỗi loop để xử lý update |
setHostname(name) | Đặt tên hiện trong IDE (mDNS) |
setPassword(p) | Mật khẩu plaintext |
setPasswordHash(h) | Mật khẩu MD5 hash |
setPort(port) | Đổi port (mặc định 3232) |
onStart(cb) | Callback khi bắt đầu update |
onEnd(cb) | Callback khi xong |
onProgress(cb) | Callback mỗi packet (in %) |
onError(cb) | Callback khi lỗi |
getCommand() | U_FLASH hoặc U_SPIFFS |
5. Partition scheme — bắt buộc cho OTA
Arduino IDE → Tools → Partition Scheme. ESP32 cần phân vùng kép app0/app1:
- Default 4MB with spiffs: app0 1.2MB, app1 1.2MB, SPIFFS 1.5MB. OTA ✓.
- Minimal SPIFFS: app0/1 1.9MB mỗi, SPIFFS 190KB. OTA ✓, app lớn.
- No OTA (Large APP): app 2MB, SPIFFS 1.5MB. OTA ✗.
- No OTA (Huge APP): app 3MB. OTA ✗.
Nếu firmware > 1.2MB và OTA fail, đổi sang Minimal SPIFFS.
6. Auto-reconnect WiFi trong khi OTA
Nếu WiFi rớt giữa OTA → update fail. Khuyến nghị:
void loop() {
if (WiFi.status() != WL_CONNECTED) {
Serial.println("WiFi lost, reconnecting...");
WiFi.reconnect();
delay(1000);
return;
}
ArduinoOTA.handle();
// ... code khác
}
7. Network port không hiện trong Arduino IDE
Vấn đề phổ biến — Windows firewall chặn mDNS:
- Mở Firewall: Allow "Arduino IDE" và "Java(TM) Platform" qua Private network.
- Hoặc tạm tắt firewall, test xem có hiện không.
- Linux/Mac: cài avahi-daemon (Linux) hoặc Bonjour (Mac có sẵn).
- Cùng subnet — máy tính và ESP32 cùng wifi.
Workaround: tạm dùng WebOTA (ElegantOTA) — upload qua trình duyệt, không cần mDNS.
8. Rollback an toàn
ESP-IDF có feature "rollback verify" — nếu firmware mới boot lỗi (panic, watchdog) trong vài giây đầu, ESP32 tự về firmware cũ. Arduino-ESP32 mặc định không enable — phải config:
// Trong setup, sau khi mọi thứ OK:
esp_ota_mark_app_valid_cancel_rollback();
Nếu code chính chưa được "mark valid" trong N giây từ boot, ESP32 rollback.
9. So sánh với WebOTA và HTTP OTA
| Phương pháp | Setup | Phù hợp |
|---|---|---|
| ArduinoOTA | Dễ nhất, qua IDE | Dev personal |
| WebOTA (ElegantOTA) | Upload .bin qua trình duyệt | Người dùng cuối cập nhật |
| HTTP OTA | ESP32 tự GET từ server | Deploy hàng loạt |
| HTTPS OTA | Như trên + TLS | Production thương mại |
10. Lỗi thường gặp
- "Auth failed": sai password.
- "No response": ESP32 không chạy
ArduinoOTA.handle()đủ thường xuyên (block trong code). - Update fail giữa chừng: WiFi yếu, sụt nguồn, hoặc firmware quá lớn.
- Sau OTA boot fail: firmware mới crash → rollback (nếu enable) hoặc nạp lại USB.
Liên quan
Bài hướng dẫn full: ESP32 OTA update qua WiFi (ArduinoOTA). Xem thêm ESPAsyncWebServer để dùng kèm ElegantOTA cho web upload.