Skip to content

Commit 0d3a121

Browse files
committed
[WiF] Improve disconnect/reconnect stability
The ESP node appears to reboot at the reconnect sequence when the wifi connection was lost. See also esp8266/Arduino#5527 (comment)
1 parent 88c34c5 commit 0d3a121

File tree

5 files changed

+84
-33
lines changed

5 files changed

+84
-33
lines changed

src/ESPEasy-Globals.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1755,6 +1755,8 @@ byte cmd_within_mainloop = 0;
17551755
unsigned long connectionFailures = 0;
17561756
unsigned long wdcounter = 0;
17571757
unsigned long timerAPoff = 0;
1758+
unsigned long timerAPstart = 0;
1759+
unsigned long timerWiFiReconnect = 0;
17581760
unsigned long timerAwakeFromDeepSleep = 0;
17591761
unsigned long last_system_event_run = 0;
17601762

src/ESPEasyStorage.ino

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ String LoadSettings()
312312
else{
313313
addLog(LOG_LEVEL_ERROR, F("CRC : SecuritySettings CRC ...FAIL"));
314314
}
315-
setUseStaticIP(useStaticIP());
315+
setupStaticIPconfig();
316316
afterloadSettings();
317317
SecuritySettings.validate();
318318
return(err);

src/ESPEasyWiFiEvent.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ void setUseStaticIP(bool enabled) {
2727

2828
void markGotIP() {
2929
lastGetIPmoment = millis();
30-
wifiStatus = ESPEASY_WIFI_GOT_IP;
30+
wifiStatus = wifiStatus | ESPEASY_WIFI_GOT_IP;
3131
processedGetIP = false;
3232
}
3333

@@ -41,7 +41,7 @@ void WiFiEvent(system_event_id_t event, system_event_info_t info) {
4141
case SYSTEM_EVENT_STA_CONNECTED:
4242
lastConnectMoment = millis();
4343
processedConnect = false;
44-
wifiStatus = ESPEASY_WIFI_CONNECTED;
44+
wifiStatus = wifiStatus | ESPEASY_WIFI_CONNECTED;
4545
break;
4646
case SYSTEM_EVENT_STA_DISCONNECTED:
4747
lastDisconnectMoment = millis();
@@ -66,7 +66,7 @@ void WiFiEvent(system_event_id_t event, system_event_info_t info) {
6666
break;
6767
case SYSTEM_EVENT_AP_STADISCONNECTED:
6868
for (byte i = 0; i < 6; ++i) {
69-
lastMacConnectedAPmode[i] = info.sta_disconnected.mac[i];
69+
lastMacDisconnectedAPmode[i] = info.sta_disconnected.mac[i];
7070
}
7171
processedDisconnectAPmode = false;
7272
break;
@@ -86,7 +86,7 @@ void WiFiEvent(system_event_id_t event, system_event_info_t info) {
8686
void onConnected(const WiFiEventStationModeConnected& event){
8787
lastConnectMoment = millis();
8888
processedConnect = false;
89-
wifiStatus = ESPEASY_WIFI_CONNECTED;
89+
wifiStatus = wifiStatus | ESPEASY_WIFI_CONNECTED;
9090
last_channel = event.channel;
9191
last_ssid = event.ssid;
9292
bssid_changed = false;

src/ESPEasyWifi.ino

Lines changed: 72 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
1+
#define WIFI_RECONNECT_WAIT 20000 // in milliSeconds
22
#define WIFI_AP_OFF_TIMER_DURATION 60000 // in milliSeconds
33

44
bool unprocessedWifiEvents() {
@@ -12,10 +12,9 @@ bool unprocessedWifiEvents() {
1212
//********************************************************************************
1313
void processConnect() {
1414
if (processedConnect) return;
15-
processedConnect = true;
1615
delay(100); // FIXME TD-er: See https://github.com/letscontrolit/ESPEasy/issues/1987#issuecomment-451644424
1716
++wifi_reconnects;
18-
if (wifiStatus < ESPEASY_WIFI_CONNECTED) return;
17+
if ((wifiStatus & ESPEASY_WIFI_CONNECTED) == 0) return;
1918
const long connect_duration = timeDiff(last_wifi_connect_attempt_moment, lastConnectMoment);
2019
if (loglevelActiveFor(LOG_LEVEL_INFO)) {
2120
String log = F("WIFI : Connected! AP: ");
@@ -44,11 +43,11 @@ void processConnect() {
4443
WiFi.setAutoConnect(true);
4544
}
4645
logConnectionStatus();
46+
processedConnect = true;
4747
}
4848

4949
void processDisconnect() {
5050
if (processedDisconnect) return;
51-
processedDisconnect = true;
5251
delay(100); // FIXME TD-er: See https://github.com/letscontrolit/ESPEasy/issues/1987#issuecomment-451644424
5352
if (Settings.UseRules) {
5453
String event = F("WiFi#Disconnected");
@@ -64,11 +63,15 @@ void processDisconnect() {
6463
}
6564
addLog(LOG_LEVEL_INFO, log);
6665
}
66+
WiFiUDP::stopAll();
67+
WiFiClient::stopAll();
68+
mqtt_reconnect_count = 0;
6769
if (Settings.WiFiRestart_connection_lost()) {
68-
setWifiMode(WIFI_OFF);
69-
delay(100);
70+
WifiDisconnect();
71+
//setWifiMode(WIFI_OFF);
7072
}
7173
logConnectionStatus();
74+
processedDisconnect = true;
7275
}
7376

7477

@@ -316,9 +319,9 @@ void WifiScanAsync() {
316319
bool WifiIsAP(WiFiMode_t wifimode)
317320
{
318321
#if defined(ESP32)
319-
return (wifimode == WIFI_MODE_AP) || (wifimode == WIFI_MODE_APSTA);
322+
return ((wifimode & WIFI_MODE_AP) != 0);
320323
#else
321-
return (wifimode == WIFI_AP) || (wifimode == WIFI_AP_STA);
324+
return ((wifimode & WIFI_AP) != 0);
322325
#endif
323326
}
324327

@@ -356,6 +359,9 @@ void setSTA(bool enable) {
356359

357360
void setAP(bool enable) {
358361
WiFiMode_t wifimode = WiFi.getMode();
362+
if (WifiIsAP(wifimode) == enable) {
363+
return;
364+
}
359365
switch(wifimode) {
360366
case WIFI_OFF:
361367
if (enable) setWifiMode(WIFI_AP);
@@ -370,23 +376,15 @@ void setAP(bool enable) {
370376
if (!enable) setWifiMode(WIFI_STA);
371377
break;
372378
default:
379+
addLog(LOG_LEVEL_INFO, F("WIFI : Unknown mode (setAP)"));
373380
break;
374381
}
375-
if (WifiIsAP(wifimode) && !enable) {
376-
String event = F("WiFi#APmodeDisabled");
377-
rulesProcessing(event);
378-
}
379-
if (WifiIsAP(wifimode) != enable) {
380-
// Mode has changed
381-
setAPinternal(enable);
382-
}
383382
}
384383

385384
//Only internal scope
386385
void setAPinternal(bool enable)
387386
{
388387
if (enable) {
389-
timerAPoff = millis() + WIFI_AP_OFF_TIMER_DURATION;
390388
// create and store unique AP SSID/PW to prevent ESP from starting AP mode with default SSID and No password!
391389
// setup ssid for AP Mode when needed
392390
String softAPSSID=WifiGetAPssid();
@@ -434,9 +432,14 @@ void setAPinternal(bool enable)
434432

435433

436434
void setWifiMode(WiFiMode_t wifimode) {
437-
if (WiFi.getMode() == wifimode) {
435+
const WiFiMode_t cur_mode = WiFi.getMode();
436+
if (cur_mode == wifimode) {
438437
return;
439438
}
439+
String log = F("WIFI : Current mode ");
440+
log += String(cur_mode);
441+
addLog(LOG_LEVEL_INFO, log);
442+
440443
switch (wifimode) {
441444
case WIFI_OFF:
442445
addLog(LOG_LEVEL_INFO, F("WIFI : Switch off WiFi"));
@@ -451,11 +454,23 @@ void setWifiMode(WiFiMode_t wifimode) {
451454
addLog(LOG_LEVEL_INFO, F("WIFI : Set WiFi to AP+STA"));
452455
break;
453456
default:
457+
addLog(LOG_LEVEL_INFO, F("WIFI : Unknown mode"));
454458
break;
455459
}
456-
setUseStaticIP(useStaticIP());
457-
WiFi.mode(wifimode);
460+
if (!WiFi.mode(wifimode)) {
461+
addLog(LOG_LEVEL_INFO, F("WIFI : Cannot set mode!!!!!"));
462+
}
463+
setupStaticIPconfig();
458464
delay(30); // Must allow for some time to init.
465+
bool new_mode_AP_enabled = WifiIsAP(wifimode);
466+
if (WifiIsAP(cur_mode) && !new_mode_AP_enabled) {
467+
String event = F("WiFi#APmodeDisabled");
468+
rulesProcessing(event);
469+
}
470+
if (WifiIsAP(cur_mode) != new_mode_AP_enabled) {
471+
// Mode has changed
472+
setAPinternal(new_mode_AP_enabled);
473+
}
459474
}
460475

461476

@@ -493,21 +508,30 @@ bool WiFiConnected() {
493508
// For ESP82xx, do not rely on WiFi.status() with event based wifi.
494509
if (wifiStatus == ESPEASY_WIFI_SERVICES_INITIALIZED) {
495510
if (WiFi.RSSI() < 0 && WiFi.isConnected()) {
511+
timerAPstart = 0;
512+
processDisableAPmode();
496513
STOP_TIMER(WIFI_ISCONNECTED_STATS);
497514
return true;
498515
}
499516
// else wifiStatus is no longer in sync.
500517
addLog(LOG_LEVEL_INFO, F("WIFI : WiFiConnected() out of sync"));
501518
resetWiFi();
502519
}
520+
if (timerAPstart == 0) {
521+
timerAPstart = millis() + WIFI_RECONNECT_WAIT;
522+
}
523+
if (timeOutReached(timerAPstart)) {
524+
setAP(true);
525+
}
503526
delay(1);
504527
STOP_TIMER(WIFI_NOTCONNECTED_STATS);
505528
return false;
506529
}
507530

508531
void WiFiConnectRelaxed() {
509-
if (WiFiConnected())
532+
if (WiFiConnected()) {
510533
return; //already connected, need to disconnect first
534+
}
511535
if (prepareWiFi()) {
512536
if (selectValidWiFiSettings()) {
513537
tryConnectWiFi();
@@ -633,7 +657,12 @@ void setConnectionSpeed() {
633657

634658
void setupStaticIPconfig() {
635659
setUseStaticIP(useStaticIP());
636-
if (!useStaticIP()) return;
660+
if (!useStaticIP()) {
661+
// For newer core versions, simply setting to 0's will disable DHCPc
662+
uint32_t zero_ip = 0u;
663+
WiFi.config(zero_ip, zero_ip, zero_ip, zero_ip);
664+
return;
665+
}
637666
const IPAddress ip = Settings.IP;
638667
const IPAddress gw = Settings.Gateway;
639668
const IPAddress subnet = Settings.Subnet;
@@ -702,6 +731,7 @@ bool tryConnectWiFi() {
702731
default:
703732
WiFi.begin(ssid, passphrase);
704733
}
734+
delay(100); // FIXME TD-er: Not sure why, but a delay is really needed here or else you will run into timeouts.
705735
++wifi_connect_attempt;
706736
logConnectionStatus();
707737
switch (WiFi.status()) {
@@ -903,8 +933,8 @@ void WifiCheck()
903933
{
904934
if(wifiSetup)
905935
return;
906-
907-
processDisableAPmode();
936+
delay(0);
937+
// processDisableAPmode();
908938
IPAddress ip = WiFi.localIP();
909939
if (WiFiConnected()) { // let's just check for wifi, no matter if we have an IP or not...
910940
if (!useStaticIP()) {
@@ -921,11 +951,25 @@ void WifiCheck()
921951
}
922952
}
923953

924-
if (wifiStatus != ESPEASY_WIFI_SERVICES_INITIALIZED) {
925-
if (timeOutReached(last_wifi_connect_attempt_moment + (1000 + wifi_connect_attempt * 200))) {
926-
WiFiConnectRelaxed();
927-
}
954+
if (WiFi.status() == WL_DISCONNECTED && timePassedSince(last_wifi_connect_attempt_moment) > 5000) {
955+
WifiDisconnect();
928956
}
957+
958+
switch (wifiStatus) {
959+
case ESPEASY_WIFI_SERVICES_INITIALIZED:
960+
break;
961+
case ESPEASY_WIFI_DISCONNECTED:
962+
if (lastDisconnectMoment == 0 || timeOutReached(lastDisconnectMoment + 500)) {
963+
WiFiConnectRelaxed();
964+
}
965+
break;
966+
default:
967+
if (timeOutReached(last_wifi_connect_attempt_moment + (10000 + wifi_connect_attempt * 200))) {
968+
WifiDisconnect();
969+
}
970+
break;
971+
}
972+
929973
if (mqtt_reconnect_count > 10) {
930974
connectionCheckHandler();
931975
}

src/Networking.ino

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -721,6 +721,7 @@ bool connectClient(WiFiClient& client, IPAddress ip, uint16_t port)
721721
return false;
722722
}
723723
bool connected = (client.connect(ip, port) == 1);
724+
yield();
724725
if (!connected) {
725726
sendGratuitousARP_now();
726727
}
@@ -743,6 +744,7 @@ bool resolveHostByName(const char* aHostname, IPAddress& aResult) {
743744
#else
744745
bool resolvedIP = WiFi.hostByName(aHostname, aResult, CONTROLLER_CLIENTTIMEOUT_DFLT) == 1;
745746
#endif
747+
yield();
746748
if (!resolvedIP) {
747749
sendGratuitousARP_now();
748750
}
@@ -778,6 +780,9 @@ bool beginWiFiUDP_randomPort(WiFiUDP& udp) {
778780
}
779781

780782
void sendGratuitousARP() {
783+
if (!WiFiConnected()) {
784+
return;
785+
}
781786
#ifndef ESP32
782787
// See https://github.com/letscontrolit/ESPEasy/issues/2374
783788
START_TIMER;

0 commit comments

Comments
 (0)