From dd72ad3d41a29bb67436256ed263983a1cb3f1d7 Mon Sep 17 00:00:00 2001 From: "torlando-agent[bot]" <281092095+torlando-agent[bot]@users.noreply.github.com> Date: Sat, 20 Jun 2026 20:34:47 -0400 Subject: [PATCH] fix(wifi): don't disturb the boot connect or wear NVS (greptile) - Backstop ARMS its timer on the first disconnected tick instead of firing immediately, so it can't issue a redundant begin() ~1s into boot and reset the in-progress association (or setAutoReconnect's own retry). Re-armed on each (re)connect so every drop gets a fresh ~15s grace. - WiFi.persistent(false): begin() no longer writes creds to NVS on every call, so the periodic backstop during a long outage doesn't wear flash. Creds are already persisted by the app's Preferences store; setAutoReconnect is in-RAM. Co-Authored-By: Claude Opus 4.8 (1M context) Claude-Session: https://claude.ai/code/session_01UWZuYkHBRqNb6BZHV8sTG5 --- src/main.cpp | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 9a5111ea..59772982 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -542,7 +542,11 @@ void setup_wifi() { // Reconnect automatically if the AP drops the association — without this the // device stays offline until a reboot or a manual Settings -> Reconnect. WiFi.setAutoReconnect(true); - WiFi.persistent(true); + // Don't persist creds to NVS on every begin(): the backstop re-issues begin() + // periodically while down, and the app already persists creds in Preferences, + // so NVS writes here would be redundant flash wear. setAutoReconnect is in-RAM + // and unaffected. + WiFi.persistent(false); WiFi.begin(app_settings.wifi_ssid.c_str(), app_settings.wifi_password.c_str()); // Don't block boot waiting for WiFi association — the main loop @@ -2452,12 +2456,20 @@ void loop() { // Backstop auto-reconnect: WiFi.setAutoReconnect() handles most drops in // the background, but not every disconnect reason — without an explicit // retry the device can sit offline until a reboot (which is exactly what - // happened). Re-issue begin() every ~15s while down. Non-blocking; the + // happened). While down, re-issue begin() every ~15s. Non-blocking; the // connected-edge above picks up once association lands. - if (!wifi_connected && app_settings.wifi_ssid.length() > 0) { - static uint32_t last_wifi_retry = 0; + static uint32_t last_wifi_retry = 0; + if (wifi_connected) { + last_wifi_retry = 0; // re-arm the grace period for the next drop + } else if (app_settings.wifi_ssid.length() > 0) { + // Arm the timer on the first disconnected tick rather than firing + // immediately, so we don't interrupt the in-progress boot association + // (or setAutoReconnect's own retry) with a redundant begin() that + // would reset the WiFi state machine. First real retry is ~15s later. uint32_t nowms = millis(); - if (last_wifi_retry == 0 || (nowms - last_wifi_retry) >= 15000) { + if (last_wifi_retry == 0) { + last_wifi_retry = nowms; + } else if ((nowms - last_wifi_retry) >= 15000) { last_wifi_retry = nowms; INFO("WiFi down — attempting reconnect"); WiFi.begin(app_settings.wifi_ssid.c_str(), app_settings.wifi_password.c_str());