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)."));
}
}
}