diff --git a/wled00/const.h b/wled00/const.h index c771dfa74..b8b71cafa 100644 --- a/wled00/const.h +++ b/wled00/const.h @@ -157,6 +157,10 @@ #define AP_BEHAVIOR_NO_CONN 1 //Open when no connection (either after boot or if connection is lost) #define AP_BEHAVIOR_ALWAYS 2 //Always open #define AP_BEHAVIOR_BUTTON_ONLY 3 //Only when button pressed for 6 sec +#define AP_BEHAVIOR_TEMPORARY 4 //Open AP when no connection after boot but only temporary +#ifndef WLED_AP_TIMEOUT + #define WLED_AP_TIMEOUT 300000 //Temporary AP timeout +#endif //Notifier callMode #define CALL_MODE_INIT 0 //no updates on init, can be used to disable updates diff --git a/wled00/data/settings_wifi.htm b/wled00/data/settings_wifi.htm index acd0c513c..45a119bc9 100644 --- a/wled00/data/settings_wifi.htm +++ b/wled00/data/settings_wifi.htm @@ -186,10 +186,12 @@ Access Point WiFi channel:
AP opens:
+ + + + + +
AP IP: Not active

Experimental

Force 802.11g mode (ESP8266 only):
diff --git a/wled00/json.cpp b/wled00/json.cpp index 90770f834..2213dd5b1 100644 --- a/wled00/json.cpp +++ b/wled00/json.cpp @@ -470,6 +470,19 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId) } } + JsonObject wifi = root[F("wifi")]; + if (!wifi.isNull()) { + bool apMode = getBoolVal(wifi[F("ap")], apActive); + if (!apActive && apMode) WLED::instance().initAP(); // start AP mode immediately + else if (apActive && !apMode) { // stop AP mode immediately + dnsServer.stop(); + WiFi.softAPdisconnect(true); + apActive = false; + } + //bool restart = wifi[F("restart")] | false; + //if (restart) forceReconnect = true; + } + stateUpdated(callMode); if (presetToRestore) currentPreset = presetToRestore; diff --git a/wled00/wled.cpp b/wled00/wled.cpp index 32b33931a..f5fe63ad3 100644 --- a/wled00/wled.cpp +++ b/wled00/wled.cpp @@ -34,6 +34,8 @@ void WLED::reset() void WLED::loop() { + static uint32_t lastHeap = UINT32_MAX; + static unsigned long heapTime = 0; #ifdef WLED_DEBUG static unsigned long lastRun = 0; unsigned long loopMillis = millis(); @@ -151,6 +153,21 @@ void WLED::loop() createEditHandler(false); } + // reconnect WiFi to clear stale allocations if heap gets too low + if (millis() - heapTime > 15000) { + uint32_t heap = ESP.getFreeHeap(); + if (heap < MIN_HEAP_SIZE && lastHeap < MIN_HEAP_SIZE) { + DEBUG_PRINT(F("Heap too low! ")); DEBUG_PRINTLN(heap); + forceReconnect = true; + strip.resetSegments(); // remove all but one segments from memory + } else if (heap < MIN_HEAP_SIZE) { + DEBUG_PRINTLN(F("Heap low, purging segments.")); + strip.purgeSegments(); + } + lastHeap = heap; + heapTime = millis(); + } + //LED settings have been saved, re-init busses //This code block causes severe FPS drop on ESP32 with the original "if (busConfigs[0] != nullptr)" conditional. Investigate! if (doInitBusses) { @@ -844,34 +861,20 @@ void WLED::initInterfaces() void WLED::handleConnection() { static byte stacO = 0; - static uint32_t lastHeap = UINT32_MAX; - static unsigned long heapTime = 0; unsigned long now = millis(); if (now < 2000 && (!WLED_WIFI_CONFIGURED || apBehavior == AP_BEHAVIOR_ALWAYS)) return; - if (lastReconnectAttempt == 0) { - DEBUG_PRINTLN(F("lastReconnectAttempt == 0")); + if (lastReconnectAttempt == 0 || forceReconnect) { + DEBUG_PRINTLN(F("Initial connect or forced reconnect.")); initConnection(); + interfacesInited = false; + forceReconnect = false; + wasConnected = false; return; } - // reconnect WiFi to clear stale allocations if heap gets too low - if (now - heapTime > 5000) { - uint32_t heap = ESP.getFreeHeap(); - if (heap < MIN_HEAP_SIZE && lastHeap < MIN_HEAP_SIZE) { - DEBUG_PRINT(F("Heap too low! ")); - DEBUG_PRINTLN(heap); - forceReconnect = true; - strip.resetSegments(); - } else if (heap < MIN_HEAP_SIZE) { - strip.purgeSegments(); - } - lastHeap = heap; - heapTime = now; - } - byte stac = 0; if (apActive) { #ifdef ESP8266 @@ -893,14 +896,6 @@ void WLED::handleConnection() } } } - if (forceReconnect) { - DEBUG_PRINTLN(F("Forcing reconnect.")); - initConnection(); - interfacesInited = false; - forceReconnect = false; - wasConnected = false; - return; - } if (!Network.isConnected()) { if (interfacesInited) { DEBUG_PRINTLN(F("Disconnected!")); @@ -918,8 +913,19 @@ void WLED::handleConnection() initConnection(); } if (!apActive && now - lastReconnectAttempt > 12000 && (!wasConnected || apBehavior == AP_BEHAVIOR_NO_CONN)) { - DEBUG_PRINTLN(F("Not connected AP.")); - initAP(); + if (!(apBehavior == AP_BEHAVIOR_TEMPORARY && now > WLED_AP_TIMEOUT)) { + DEBUG_PRINTLN(F("Not connected AP.")); + initAP(); // start AP only within first 5min + } + } + if (apActive && apBehavior == AP_BEHAVIOR_TEMPORARY && now > WLED_AP_TIMEOUT && stac == 0) { // disconnect AP after 5min if no clients connected + // if AP was enabled more than 10min after boot or if client was connected more than 10min after boot do not disconnect AP mode + if (now < 2*WLED_AP_TIMEOUT) { + dnsServer.stop(); + WiFi.softAPdisconnect(true); + apActive = false; + DEBUG_PRINTLN(F("Temporary AP disabled.")); + } } } else if (!interfacesInited) { //newly connected DEBUG_PRINTLN(""); @@ -940,7 +946,7 @@ void WLED::handleConnection() dnsServer.stop(); WiFi.softAPdisconnect(true); apActive = false; - DEBUG_PRINTLN(F("Access point disabled (handle).")); + DEBUG_PRINTLN(F("Access point disabled (connected).")); } } }