Symptom
The device works for hours or days, then goes silent after a router reboot, a DHCP hiccup or a short outage, and only comes back after a power cycle.
Why
In ESP-IDF, the Wi-Fi driver does not reconnect on its own. The documentation states it is the application's responsibility; the recommended strategy is to call esp_wifi_connect() when WIFI_EVENT_STA_DISCONNECTED arrives. If the disconnect came from your own esp_wifi_disconnect(), you may choose not to reconnect.
ESP-IDF pattern
static void on_wifi_event(void *arg, esp_event_base_t base, int32_t id, void *data) {
if (base == WIFI_EVENT && id == WIFI_EVENT_STA_START) {
esp_wifi_connect();
} else if (base == WIFI_EVENT && id == WIFI_EVENT_STA_DISCONNECTED) {
// Optionally inspect ((wifi_event_sta_disconnected_t *)data)->reason
esp_wifi_connect(); // recommended by ESP-IDF; add backoff if you also scan
}
}
If your application also calls esp_wifi_scan_start() at arbitrary times, a naive reconnect-on-every-disconnect loop can block scanning; use a state machine or a timer-based retry instead.
Arduino pattern
#include <WiFi.h>
void onWiFiEvent(WiFiEvent_t event) {
// Runs on a separate thread: keep it short, set flags, don't block.
if (event == ARDUINO_EVENT_WIFI_STA_DISCONNECTED) {
Serial.println("Wi-Fi lost");
} else if (event == ARDUINO_EVENT_WIFI_STA_GOT_IP) {
Serial.println("Wi-Fi back, IP: " + WiFi.localIP().toString());
}
}
void setup() {
Serial.begin(115200);
WiFi.onEvent(onWiFiEvent);
WiFi.setAutoReconnect(true);
WiFi.begin("your-ssid", "your-password");
}
void loop() {
// Application-level health check: MQTT/HTTP clients need their own reconnect logic,
// even when Wi-Fi itself has reconnected.
}
Checklist
- Treat "Wi-Fi connected" and "got IP" as different events; only start network clients after an IP is assigned.
- Reconnect your protocol clients (MQTT, WebSocket, HTTP keep-alive) after Wi-Fi returns; they don't recover automatically in most libraries.
- Add backoff between attempts so a dead access point doesn't keep the radio busy (and the battery drained).
- Consider a last-resort restart (
esp_restart()) after a long period offline, and log why. - Don't hard-code credentials in published code; store them in NVS/Preferences.