Arduino-esp32: WiFi Auto Reconnect Still Not Working - Is there a best practice to guarantee connection?

Created on 21 Sep 2017  ·  150Comments  ·  Source: espressif/arduino-esp32

Board: ModeMCU ESP32 Dev Module
Core Installation/update date: 15/Sep/2017
IDE name: Arduino IDE

It seems there is no auto reconnect logic allowing the ESP32 to reconnect when the connection drops or if there is its not working properly. I have had completely random results with my ESP32 board, sometimes its up for as little as 30 minutes and at most 18 - 20 hours. WiFi is dropping and doesn't want to reconnect.

The library I am using for WiFi is watching the WiFi event and on a disconnect its trying to reconnect which helps but sometimes it fails the reconnect and then that's it...I have to reboot. There is no sleep/low power mode at all involved and the device is constantly powered by 3.3v in. There was a case opened regarding this, https://github.com/espressif/arduino-esp32/issues/353, but its closed without any real answer (says auto connect is kind of implemented...not sure what that means).

I guess the question comes down to is auto reconnect implemented in the code itself, reliably, and if not what is the best Arduino code way of making sure it is connected?

-Allan

bug

Most helpful comment

UPDATE; i see a lot of WiFiEvent used and for debugging its good but to simply detect wifi down and reconnect the IF/ELSE below works reliably every time.

this works because it takes about 18 seconds from down to reporting WL_CONNECTED change, this gives the DHCP server time to release the IP for a reliable re connect later.

It has been working for over 6 years and counting.

loop()
{
  if ( WiFi.status() ==  WL_CONNECTED ) 
  {
    // WiFi is UP,  do what ever
  } else
  {
    // wifi down, reconnect here
   WiFi.begin(  );
    int WLcount = 0;
    while (WiFi.status() != WL_CONNECTED && WLcount < 200 ) 
    {
      delay( 100 );
         Serial.printf(".");
         if (UpCount >= 60)  // just keep terminal from scrolling sideways
         {
            UpCount = 0;
               Serial.printf("\n");
         }
         ++UpCount;
      ++WLcount;
    }
  }
} // END loop()

take a look at the skeleton code i posted on https://github.com/espressif/arduino-esp32/issues/1100

though it was for setup with SmartConfig it just works.

All 150 comments

can you please enable debug in the board menu and see why it does not want to reconnect when you tell it to do so?

I can try that tonight. The Arduino code is pretty basic, watching the WiFi event and then has this:

case SYSTEM_EVENT_STA_DISCONNECTED:
    Serial.println("WiFi lost connection.  Attempting to reconnect...");
    WiFi.reconnect();
    break;

But shouldn't there be something that can be called to make this happen on it's own?

Just for a quick fix:
Start a timer in the SYSTEM_EVENT_STA_DISCONNECTED that calls the WiFi.reconnect(); function and stop it in the SYSTEM_EVENT_STA_CONNECTED. The main problem is with your idea is if the device cant connect than the SYSTEM_EVENT_STA_DISCONNECTED event is not called so its never try to reconnect again.

Unfortunately I'm adapting someone else library and I'm not very familiar with C++ but I'll see what I can do about adding a timer (I know VB.net...I can at least figure out the logical parts and hopefully adapt).

But I think you are right about it not reconnecting or better yet only trying on a disconnect which then if it fails just once it give up. Enabling debug might show me that so I'll start there.

But back to the original question and the previously closed issue: Is this functionality not built-in? And if not why was the previous issue closed as "kind of" working? Also if not will it be?

I switched the debug level to debug and opened serial monitor and got this over and over:

[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...
[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...
[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...

I checked the last time it sent data to another controller and that was over 24 hours ago so I'm assuming its stuck in this mode. So I powered it down and back up, it connected to WiFi just fine and transmitted data how it should for about 2 hours this time. Then without any other message it disconnected and started with the exact same message over and over. I let it go for a hour, rebooted the controller, and its connected again but I'm sure its just a matter of time before it starts over.

So the first question is how do I fix it. Second this still leads me to my previous questions about auto reconnect

Guys please enable debug so you can see more verbose WiFi state output:
screen shot 2017-09-22 at 13 48 16

I use the following code to check if my device is still connected to the STA (call this from loop()). You get the idea? wifi_is_connected is a global that gets set and reset in the wifi event callback.

static void poll_watchdog_sta(void) {
  static uint32_t ms = millis();
  static uint8_t watchdog = 0;

  // watch out for STA disconnects and reboot if
  // connection cannot be reestablished after
  // X minutes

  // this watchdog MUST NOT reboot the device if
  // wifi is not enabled or never was connected
  // since last reboot

  if (wifi_is_enabled && watchdog_enabled && ((millis() - ms) > 1000 * 6)) {
    ms = millis();

    if (!wifi_is_connected) {
      if (++watchdog < watchdog_timeout * 10) { // timeout in minutes ( * 10 )
        if (watchdog == 1) {
          log_print(F("WIFI: arming network watchdog (reboot in %i min.)"),
            watchdog_timeout
          );
        }
      } else {
        log_print(F("WIFI: still not connected, triggering reboot ..."));
        system_reboot();
      }
    } else {
      if (watchdog) {
        log_print(F("WIFI: network is back, disarming watchdog"));
        watchdog = 0;
      }
    }
  }
}

Yeah, I don't see a Loop() in the library I'm using for WiFi (again, third party) but I understand what you are doing and can run with it.

Going to turn on the verbose logging and see if I get any more info first before changing anything.

Also the WiFi Events that are being checked and acted on are SYSTEM_EVENT_STA_GOT_IP, SYSTEM_EVENT_STA_DISCONNECTED, SYSTEM_EVENT_STA_START, and SYSTEM_EVENT_STA_CONNECTED. There are more however at https://github.com/espressif/esp-idf/blob/master/components/esp32/include/esp_event.h so I added a default: to the switch that should print out the event to see if the library is getting something but just not acting on it.

I saw in the library I'm using a //WiFi.setAutoReconnect(true); so I'm assuming the original author tried to use auto reconnect but it wasn't working so commented it out?

@me-no-dev - Verbose gave a much better explanation. Well...maybe to you:

Everything was fine then got this over and over, maybe 150 times:

[E][WiFiClient.cpp:97] connect(): lwip_connect_r: 113

Followed by this:

[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:187] _eventCallback(): Reason: 7 - NOT_ASSOCED
[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...
[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:187] _eventCallback(): Reason: 202 - ASSOC_FAIL
[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...
[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:187] _eventCallback(): Reason: 2 - AUTH_EXPIRE
[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...
[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:187] _eventCallback(): Reason: 2 - AUTH_EXPIRE
[WiFi-event] event: 5

The the last part (reconnect, event 5, reason 2) just repeats every 4 - 5 seconds.

Based on that first error that repeats over and over I found this: https://github.com/espressif/arduino-esp32/issues/180. In it you said "Try flushing the client or reading all available data. ". How would I go about doing that? I'm looking at the library I'm using and this is what they have to catch the WiFi Event:

//**************************************************************************************
/// Event Handler for ESP32 WiFi Events (needed to implement reconnect logic for now...)
//**************************************************************************************
    void MyESP32WiFi::WiFiEvent(WiFiEvent_t event)
    {
        Serial.printf("[WiFi-event] event: %d\n", event);

        switch (event) {
        case SYSTEM_EVENT_STA_GOT_IP:
            Serial.println("WiFi connected");
            Serial.println("IP address: ");
            Serial.println(WiFi.localIP());
            break;
        case SYSTEM_EVENT_STA_DISCONNECTED:
            Serial.println("WiFi lost connection.  Attempting to reconnect...");
            WiFi.reconnect();
            break;
        case SYSTEM_EVENT_STA_START:
            Serial.println("ESP32 station start");
            break;
        case SYSTEM_EVENT_STA_CONNECTED:
            Serial.println("ESP32 station connected to AP");
            break;
        default:            
            Serial.println("Unhandled WiFi Event raised.");
            break;
        }

    }

Based on the errors in the previous post I'm getting the "5" which is translating to the WiFi connection lost and then the code is trying to execute "WiFi.reconnect();" but its obviously not working. Should I have something else there? Maybe a counter kinda like @everslick example but simpler (just a i = i + 1) and if it end up on the same place after 20 tries it reboots? Or should this not happen/be prevented in the first place?

Try calling WiFi.begin() instead of reconnect and report back :)

@me-no-dev - I changed it to WiFi.begin() instead of WiFi.reconnect() but it didn't help. Worked for about a hour then got the lwip_connect_r:113 line, each one about a minute or so apart followed by the disconnect every 5 or so seconds:

[E][WiFiClient.cpp:97] connect(): lwip_connect_r: 113
[E][WiFiClient.cpp:97] connect(): lwip_connect_r: 113
[E][WiFiClient.cpp:97] connect(): lwip_connect_r: 113
[E][WiFiClient.cpp:97] connect(): lwip_connect_r: 113
[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:187] _eventCallback(): Reason: 7 - NOT_ASSOCED
[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...
[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:187] _eventCallback(): Reason: 2 - AUTH_EXPIRE
[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...
[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:187] _eventCallback(): Reason: 2 - AUTH_EXPIRE

And then the 4 lines just repeat indefinitely until the control is rebooted. What else can I try? The fact @everslick is rebooting the controller when its in the same disconnected state is worrisome....I would think rebooting is the last option and something can be done to keep it online.

As a side note two ESP8266's connected to the same router (Netgear R8000) have no issues and have been stable for over a month without disconnects.

hmmm.... this seems like an issue either in the lower stack or in your router.
you can see the first reason being NOT_ASSOCED and then you get AUTH_EXPIRE.
could you maybe turn off the STA and then turn it back on? The disconnect cause makes me think that something in the re-assoc request is either not changed or your router does not accept, so it refuses you to connect back. I'll see if I can raise an internal issue about this. What is the router firmware version that you are using?

Its a Netgear Nighthawk R8000. Currently on the latest firmware V1.0.3.54_1.1.37 although it did it on the last version also. I have 20 - 25 devices connected at any given time without issues including the previously mentioned two ESP8266's.

I will attempt to replace the Wi-Fi begin/reconnect line with the STA off and on and see what happens.

Edit: Knowing not much about this and using someone elses library....how do I "turn off the STA and then turn it back on"?

Second Edit: It couldn't be related to https://github.com/espressif/esp-idf/issues/499#issuecomment-314262611 could it? One of the only things I've seen with the same NOT_ASSOCED and AUTH_EXPIRE. I wouldn't think so only because I compiled myself without the BLE stuff but never know.

I have also alerted the wifi team :) we will see if anything comes out of this

Thanks. Should I be trying to do the STA off and on? If so can you guide me how or point me in the right direction?

I also saw this: https://github.com/espressif/esp-idf/issues/738#issuecomment-311626685 which indicated that I can't call the WiFi.connect or WiFi.Begin from the event handler? Could that also be my issue? @rojer ?

So I bought a second ESP32, same one, to try and make sure it isn't a hardware issue. I recompiled the firmware yesterday night off a fresh pull from github (https://nodemcu.readthedocs.io/en/dev-esp32/en/build/) and flashed both the new chip and the old one. I also flashed both with the exact same sketch. The original is in my garage, a little ways from my router, and the other test one is in my living room where the WiFi is a lot stronger. Both have serial monitor running on a connected PC with verbose set. I'll report back anything I find.

With the above said is there anything else I can try? How do I do the STA off and on? Can that be done in the STA_Disconnect part where the WiFi.reconnect is?

Well that didn't last long....I'm having the same issue with the new one. First the original one started with the same "[E][WiFiClient.cpp:97] connect(): lwip_connect_r: 113" error and not sending data after barely 30 minutes online. Usually got that error two at a time with about 5 or 6 seconds between then then 45 - 50 seconds between the next set but again kinda random. Did that for around 10 minutes then went into the same disconnect pattern:


[E][WiFiClient.cpp:97] connect(): lwip_connect_r: 113
[E][WiFiClient.cpp:97] connect(): lwip_connect_r: 113
Data: Sending: temperature1 -49.02
[E][WiFiClient.cpp:97] connect(): lwip_connect_r: 113
[E][WiFiClient.cpp:97] connect(): lwip_connect_r: 113
Data: Sending: humidity1 -5.02
[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:187] _eventCallback(): Reason: 7 - NOT_ASSOCED
[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...
[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:187] _eventCallback(): Reason: 202 - ASSOC_FAIL
[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...
[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:187] _eventCallback(): Reason: 2 - AUTH_EXPIRE
[WiFi-event] event: 5

And repeated the last 4 lines over and over. At one point it did do something different...the error message changed slightly:

[E][WiFiClient.cpp:97] connect(): lwip_connect_r: 113
[E][WiFiClient.cpp:97] connect(): lwip_connect_r: 118
Data: Sending: temperature2 -1.00
[E][WiFiClient.cpp:97] connect(): lwip_connect_r: 118
[E][WiFiClient.cpp:97] connect(): lwip_connect_r: 118
Data: Sending: humidity2 -1.00
[E][WiFiClient.cpp:97] connect(): lwip_connect_r: 118
[E][WiFiClient.cpp:97] connect(): lwip_connect_r: 118
[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:187] _eventCallback(): Reason: 2 - AUTH_EXPIRE
[WiFi-event] event: 5

Notice the error switched to ending in 118 as opposed to 113. But from that point on it just repeated the 118 error randomly along with the STA_DISCONNECTED and AUTH_EXPIRED over and over.

Then the new ESP32 started doing the exact same thing. mostly 113 error then the same pattern of NOT_ASSOCED, ASSOC_FAIL, and AUTH_EXPIRE followed by just the disconnect and AUTH_EXPIRE over and over.

They failed at different times, 25 minutes apart, while they were started at the exact same time. WiFi signal doesn't seem to be a factor nor does any certain timing.

Edit: Just to be clear on a reboot it connects instantly on the first try every time:

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
flash read err, 1000
ets_main.c 371 
ets Jun  8 2016 00:22:57

rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0010,len:4
load:0x3fff0014,len:708
load:0x40078000,len:0
load:0x40078000,len:11460
entry 0x400789f4
Everything: init started
Everything: Free RAM = -1
Disabling ESP32 WiFi Access Point
[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 2 - STA_START
[WiFi-event] event: 2
Initializing ESP32 WiFi network.  Please be patient...
ESP32 station start
Attempting to connect to WPA SSID: (SSIDRemoved)
..[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 4 - STA_CONNECTED
[WiFi-event] event: 4
ESP32 station connected to AP
[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 7 - STA_GOT_IP
[WiFi-event] event: 7
WiFi connected
IP address: 
192.168.xx.xx

Still waiting on response from the WiFi team. Will make some more noise as this is annoying to me as well. Issue is somewhere way below Arduino and in the closed source wifi lib.

Thanks. I'm going to attempt to add a counter to the STA_DISCONNECTED event switch statement that I keep getting and after 5 try to re-init the wifi and after 10 reboot the controller and on a connect reset the counter to 0, see if that at least keeps the controller up.

If there is anything else I can provide you to help get this fixed or code to try please let me know. If it matters the ESP32 I'm using is being used for two voltage inputs, one binary input, and a DTH22 (temp + humidity) then that data is being sent to a controller through HTTP.

Hi @vseven, I just can't reproduce this issue myself, could you let me know the firmware version of WiFi? You can get if from the startup log, it looks like "I (588) wifi: wifi firmware version: 2cd69aa", then I can provide a debug version wifi lib to you to debug this issue.

@vseven could you let me know the WiFi reconnect logic? I means when to call esp_wifi_connect()? It will be helpful if you can paste the implementation logic.

@liuzfesp wifi logging is disabled in Arduino.
@vseven comment this line to get it to show

Ok, I commented out that line and recompiled. I'll report back. As a side note I tried to add a counter to reconnect by recalling my init() but it didn't do anything....it was like the init() was never called. I might be doing it wrong though. But when the counter got to 10 the ESP.restart defiantly was called and rebooted correctly which afterward it reconnected:

    void SmartThingsESP32WiFi::WiFiEvent(WiFiEvent_t event)
    {
        Serial.printf("[WiFi-event] event: %d\n", event);
        switch (event) {
        case SYSTEM_EVENT_STA_GOT_IP:
            Serial.println("WiFi connected");
            Serial.println("IP address: ");
            Serial.println(WiFi.localIP());
            break;
        case SYSTEM_EVENT_STA_DISCONNECTED:
            Serial.println("WiFi lost connection.  Attempting to reconnect...");
            WiFi.reconnect();
            disconnectCounter++;
            if (disconnectCounter > 5) {
                Serial.println("We have recieved the STA_DISCONNECTED event 5 times now.  Re-init...");
                void init();
            }
            if (disconnectCounter > 10) {
                Serial.println("We have recieved the STA_DISCONNECTED event 10 times now.  Reboot...");
                ESP.restart();
            }
            break;
        case SYSTEM_EVENT_STA_START:
            Serial.println("ESP32 station start");
            break;
        case SYSTEM_EVENT_STA_CONNECTED:
            Serial.println("ESP32 station connected to AP");
            disconnectCounter = 0;
            break;
        }
    }

@liuzfesp - here is the extra info with that line commented out:

I (243) wifi: wifi firmware version: c1b8a2f
I (243) wifi: config NVS flash: enabled
I (243) wifi: config nano formating: disabled
I (257) wifi: Init dynamic tx buffer num: 32
I (257) wifi: Init data frame dynamic rx buffer num: 64
I (257) wifi: Init management frame dynamic rx buffer num: 64
I (261) wifi: wifi driver task: 3ffd0d8c, prio:23, stack:4096
I (267) wifi: Init static rx buffer num: 10
I (270) wifi: Init dynamic rx buffer num: 0
I (274) wifi: Init rx ampdu len mblock:7
I (278) wifi: Init lldesc rx ampdu entry mblock:4
I (282) wifi: wifi power manager task: 0x3ffd60f0 prio: 21 stack: 2560
I (290) wifi: wifi timer task: 3ffd7148, prio:22, stack:3584
I (314) wifi: mode : null
Disabling ESP32 WiFi Access Point

I (815) wifi: Init Ampdu: 1 tx baw=6 rx baw=6
I (815) wifi: mode : sta (30:ae:a4:25:78:64)
[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 2 - STA_START

Initializing ESP32 WiFi network.  Please be patient...
[WiFi-event] event: 2
ESP32 station start
Attempting to connect to WPA SSID: (SSIDREMOVED)
.I (1946) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
.I (2603) wifi: state: init -> auth (b0)
I (2605) wifi: state: auth -> assoc (0)
I (2612) wifi: state: assoc -> run (10)
I (2670) wifi: connected with (SSIDREMOVED), channel 1
[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 4 - STA_CONNECTED
[WiFi-event] event: 4
ESP32 station connected to AP
[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 7 - STA_GOT_IP
[WiFi-event] event: 7
WiFi connected

And the files I'm using (before I added the disconnect counter):

SmartThingsESP32WiFi.h.txt
SmartThingsESP32WiFi.cpp.txt

@liuzfesp - So it did the same thing with the debug enabled, hopefully something in here will tell you something. It ran fine for a hour or so then started throwing the 113 error randomly. After about 15 minutes of random 113 errors in between the actual data sending routines it did this:

I (5427111) wifi: state: run -> auth (7c0)
I (5427111) wifi: pm stop, total sleep time: 0/1119534452

I (5427111) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:187] _eventCallback(): Reason: 7 - NOT_ASSOCED
[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...
I (5427133) wifi: state: auth -> init (0)
[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:187] _eventCallback(): Reason: 202 - ASSOC_FAIL
[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...
I (5427276) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
I (5427276) wifi: state: init -> auth (b0)
I (5428276) wifi: state: auth -> init (2)
I (5428277) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:187] _eventCallback(): Reason: 2 - AUTH_EXPIRE
[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...
I (5428413) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
I (5428414) wifi: state: init -> auth (b0)
I (5429414) wifi: state: auth -> init (2)
I (5429414) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:187] _eventCallback(): Reason: 2 - AUTH_EXPIRE
[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...
I (5429551) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
I (5429551) wifi: state: init -> auth (b0)
I (5430551) wifi: state: auth -> init (2)
I (5430551) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:187] _eventCallback(): Reason: 2 - AUTH_EXPIRE
[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...
I (5430688) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
I (5430688) wifi: state: init -> auth (b0)
I (5431689) wifi: state: auth -> init (2)
I (5431689) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:187] _eventCallback(): Reason: 2 - AUTH_EXPIRE
[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...
We have recieved the STA_DISCONNECTED event 5 times now.  Re-init...
I (5431826) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
I (5431826) wifi: state: init -> auth (b0)
I (5432826) wifi: state: auth -> init (2)
I (5432826) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:187] _eventCallback(): Reason: 2 - AUTH_EXPIRE
[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...
We have recieved the STA_DISCONNECTED event 5 times now.  Re-init...
I (5432963) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
I (5432963) wifi: state: init -> auth (b0)
I (5433964) wifi: state: auth -> init (2)
I (5433964) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:187] _eventCallback(): Reason: 2 - AUTH_EXPIRE
[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...
We have recieved the STA_DISCONNECTED event 5 times now.  Re-init...
I (5434100) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
I (5434101) wifi: state: init -> auth (b0)
I (5435101) wifi: state: auth -> init (2)
I (5435101) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:187] _eventCallback(): Reason: 2 - AUTH_EXPIRE
[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...
We have recieved the STA_DISCONNECTED event 5 times now.  Re-init...
I (5435238) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
I (5435238) wifi: state: init -> auth (b0)
I (5436238) wifi: state: auth -> init (2)
I (5436239) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:187] _eventCallback(): Reason: 2 - AUTH_EXPIRE
[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...
We have recieved the STA_DISCONNECTED event 5 times now.  Re-init...
I (5436375) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
I (5436376) wifi: state: init -> auth (b0)
I (5437376) wifi: state: auth -> init (2)
I (5437376) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:187] _eventCallback(): Reason: 2 - AUTH_EXPIRE
[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...
We have recieved the STA_DISCONNECTED event 5 times now.  Re-init...
We have recieved the STA_DISCONNECTED event 10 times now.  Reboot...
I (5437405) wifi: flush txq
I (5437407) wifi: stop sw txq
I (5437410) wifi: lmac stop hw txq
ets Jun  8 2016 00:22:57

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)

So for each STA_DISCONNECT it tried calling WiFi.reconnect with no apparent success then it tried running init() after more then 5 disconnects which also didn't help then once it hit 10 disconnects it rebooted which did reboot and reconnect.

I kept serial monitor running on my ESP32 all weekend and it rebooted about 10 times between 6pm Friday night and 9pm Sunday night. Each time it was exactly like the above logs.

@me-no-dev - can you guide me in a way to just turn off and back on the STA to see if that also works for reconnecting and I can try that after 5 failed attempts? The reboot after 10 works but I plan on using this to control RGB lighting and I really don't want to have lights turning off and on.

@liuzfesp - Is there anything else I can provide you with for debugging? Or anything that stands out I can try?

Any updates? Still have constant disconnects with both devices.

@liuzfesp any news here?

I see there are some code changes coming with bluetooth and WiFi. Not sure if any of that will help me or not. I still continue to have the same issues and the reboot is working to keep my data being passed but I haven't been able to use it for RGB light strip control since the lights kept turning off on a reboot.

@liuzfesp - Is there anything in the logs that helps or anything else I can provide or try?

I cleaned up some things, made sure in my code there was nothing doing delays or blocking, and I now have less errors (don't see the 113 and 118 errors) but still having the same disconnect issue and it seems directly related to the WiFi trying to authenticate (renew?) and failing. Here is a fresh capture from this weekend where I had it reboot about 5 times in a 24 hour period. Again, same thing on two different ESP32s, I look for the disconnect (event 5) and try to reconnect with a WiFi.reconnect and a WiFi.begin both with no luck so after 10 tries it reboots and connects fine afterward:

I (1903652) wifi: active cnt: 5
I (1913652) wifi: active cnt: 5
I (1923652) wifi: send null to keep active
I (1933652) wifi: send null to keep active
I (1943653) wifi: active cnt: 1
I (1953653) wifi: active cnt: 2
I (1963653) wifi: send null to keep active
I (1973653) wifi: send null to keep active
I (1983653) wifi: send null to keep active
I (1993653) wifi: active cnt: 1
I (2003654) wifi: send null to keep active
I (2013654) wifi: send null to keep active
I (2023654) wifi: send null to keep active
I (2033654) wifi: send null to keep active
I (2043654) wifi: send null to keep active
I (2053654) wifi: send null to keep active
I (2063654) wifi: send null to keep active
I (2073655) wifi: send null to keep active
I (2083655) wifi: active cnt: 1
I (2093655) wifi: send null to keep active
I (2103655) wifi: send null to keep active
I (2113655) wifi: send null to keep active
I (2123655) wifi: send null to keep active
I (2133655) wifi: send null to keep active
I (2143656) wifi: send null to keep active
I (2153656) wifi: send null to keep active
I (2163656) wifi: send null to keep active
I (2173656) wifi: send null to keep active
I (2183656) wifi: send null to keep active
I (2193656) wifi: send null to keep active
I (2203657) wifi: send null to keep active
I (2213657) wifi: send null to keep active
I (2223657) wifi: send null to keep active
I (2233657) wifi: send null to keep active
I (2243657) wifi: send null to keep active
I (2253657) wifi: send null to keep active
I (2263657) wifi: send null to keep active
I (2273658) wifi: active cnt: 2
I (2283658) wifi: send null to keep active
I (2293658) wifi: send null to keep active
I (2303658) wifi: send null to keep active
I (2313658) wifi: send null to keep active
I (2323658) wifi: send null to keep active
I (2333658) wifi: send null to keep active
I (2343659) wifi: send null to keep active
I (2353659) wifi: send null to keep active
I (2363659) wifi: send null to keep active
I (2373659) wifi: send null to keep active
I (2383659) wifi: send null to keep active
I (2393659) wifi: send null to keep active
I (2403660) wifi: send null to keep active
I (2413660) wifi: send null to keep active
I (2423660) wifi: send null to keep active
I (2433660) wifi: send null to keep active
I (2443660) wifi: send null to keep active
I (2453660) wifi: send null to keep active
I (2463660) wifi: send null to keep active
I (2473661) wifi: send null to keep active
I (2483661) wifi: send null to keep active
I (2483663) wifi: state: run -> auth (7c0)
I (2483663) wifi: pm stop, total sleep time: 0/-1824912959

I (2483663) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...
I (2483674) wifi: state: auth -> init (0)
[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...
I (2483805) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
I (2483805) wifi: state: init -> auth (b0)
I (2484805) wifi: state: auth -> init (2)
I (2484806) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...
I (2484930) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
I (2484931) wifi: state: init -> auth (b0)
I (2485931) wifi: state: auth -> init (2)
I (2485931) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...
I (2486056) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
I (2486056) wifi: state: init -> auth (b0)
I (2487056) wifi: state: auth -> init (2)
I (2487056) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...
I (2487181) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
I (2487181) wifi: state: init -> auth (b0)
I (2488182) wifi: state: auth -> init (2)
I (2488182) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...
I (2488306) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
I (2488307) wifi: state: init -> auth (b0)
I (2489307) wifi: state: auth -> init (2)
I (2489307) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...
I (2489432) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
I (2489432) wifi: state: init -> auth (b0)
I (2490432) wifi: state: auth -> init (2)
I (2490432) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...
I (2490557) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
I (2490557) wifi: state: init -> auth (b0)
I (2491558) wifi: state: auth -> init (2)
I (2491558) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...
I (2491682) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
I (2491683) wifi: state: init -> auth (b0)
I (2492683) wifi: state: auth -> init (2)
I (2492683) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...
I (2492808) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
I (2492808) wifi: state: init -> auth (b0)
I (2493808) wifi: state: auth -> init (2)
I (2493808) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
[WiFi-event] event: 5
WiFi lost connection.  Attempting to reconnect...
We have recieved the STA_DISCONNECTED event over 10 times now.  Reboot...
I (2493819) wifi: flush txq
I (2493822) wifi: stop sw txq
I (2493824) wifi: lmac stop hw txq
ets Jun  8 2016 00:22:57

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0010,len:4
load:0x3fff0014,len:708
load:0x40078000,len:0
load:0x40078000,len:11460
entry 0x400789f4
Everything: init started
Everything: Free RAM = -1
I (749) wifi: wifi firmware version: c1b8a2f
I (749) wifi: config NVS flash: enabled
I (749) wifi: config nano formating: disabled
I (758) wifi: Init dynamic tx buffer num: 32
I (758) wifi: Init data frame dynamic rx buffer num: 64
I (758) wifi: Init management frame dynamic rx buffer num: 64
I (762) wifi: wifi driver task: 3ffca34c, prio:23, stack:4096
I (768) wifi: Init static rx buffer num: 10
I (771) wifi: Init dynamic rx buffer num: 0
I (775) wifi: Init rx ampdu len mblock:7
I (779) wifi: Init lldesc rx ampdu entry mblock:4
I (783) wifi: wifi power manager task: 0x3ffd6004 prio: 21 stack: 2560
I (791) wifi: wifi timer task: 3ffd705c, prio:22, stack:3584
I (815) wifi: mode : null
Disabling ESP32 WiFi Access Point

I (1816) wifi: Init Ampdu: 1 tx baw=6 rx baw=6
I (1816) wifi: mode : sta (30:ae:a4:07:f1:98)
[WiFi-event] event: 2

Initializing ESP32 WiFi network.  Please be patient...
ESP32 station start
Attempting to connect to WPA SSID: (SSIDREMOVED)
.I (2943) wifi: n:1 0, o:1 0, ap:255 255, sta:1 0, prof:1
.I (3600) wifi: state: init -> auth (b0)
I (3602) wifi: state: auth -> assoc (0)
I (3606) wifi: state: assoc -> run (10)
I (3635) wifi: connected with (SSIDREMOVED), channel 1
[WiFi-event] event: 4
ESP32 station connected to AP
[WiFi-event] event: 7
WiFi connected
IP address: 
192.168.1.142

@liuzfesp / @me-no-dev - Is there any other information I can provide? Is this happening to anyone else or only with my two HiLetGo ModeMCU ESP32s? Is there any custom firmware that I can try?

-Allan

I have the exact same behaviour on my WROOM-32 module.
Every 3rd or 4th reboot, it hangs in the STA_DISCONNECTED -> AUTH_EXPIRED loop.
Checked a second module of same type, showing same behaviour.
My Router is a TL-WR841 (TPLINK) but happens as well with a ASUS RT-AC87U.

When will there be a solution, its useless if there is need of a reboot in such situations...

edit: for me, this problem also occurs after boot, i.e. WiFi.begin() will not establish a connection at all but loops in STA_DISCONNECTED -> AUTH_EXPIRED

I haven't gotten a response in a month although, no offense, I'm happy it's happening to someone else so I know I'm not alone.

@liuzfesp / @me-no-dev - Has there been any progress on this or anything we can try to get this to stay connected reliably to WiFi.

poked @liuzfesp again... this is as much as I can really do. I do not have access to the WiFi lib source

@igrr

@copercini why?

Since i was tagged here... @vseven, is there any chance you could perform packet capture using Wireshark and a WiFi adapter in monitor mode? Of particular interest is the time when reconnect process starts failing. Since we don't know what is happening here, and we can't reproduce similar issue in our CI environment, the packet capture might reveal some anomaly, giving a clue about the situation you are facing.

Another thought (just to reduce the number of variables), does this issue also happen if you connect to an open WiFi network?

currently, all reconnects fail with my WROOM32s with following debug output:

[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 2 - STA_START
....[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 4 - STA_CONNECTED
..[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 7 - STA_GOT_IP
WiFi connected
... then I block antenna reception or press RESET at my AP, to force a disconnect ...
[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:270] _eventCallback(): Reason: 200 - NO_AP_FOUND
... when reception should be ok again, it takes about 2 minutes until it says:

[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 8 - STA_WPS_ER_SUCCESS

However it remains disconnected from network forever in that state.
WPS is turned off at my AP. Do not know what the debug message means.
Same behaviour with two different APs and two different WROOM32 modules, using the wificlient example sketch. No matter if WPA2 used or open network.
Can send Wireshark log in monitor mode if needed.

First of all, thanks everyone for your hard work on the SDK. I've had a ton of fun developing with it, and I'm very grateful for all of the effort that's gone into it.

I'm seeing this issue too. I think I may have managed to narrow it down a little bit. I'm using this really small sketch that should work on both ESP8266 and ESP32:

https://github.com/sidoh/esp32_reconnect_demo

I turned off auto reconnect so that I had more control of the variables.

Setup

  1. Testing on both ESP8266 and ESP32
  2. Using a mobile hotspot network. Tried both WPA2 PSK and open networks
  3. Allow MCU to connect to network and run for a few seconds. I added an NTP client to verify connectivity.

Then I tried two different things:

(A) Tear down network, immediately recreate

Under these circumstances, the network is usually recreated by the time the MCU notices it's disconnected.

(B) Tear down network, wait for MCU to notice it's disconnected, recreate network

Observations

  1. Behavior is the same with both WPA2 and open networks.
  2. The ESP8266 successfully reconnects with both (A) and (B).
  3. ESP32 reconnects in experiment (A), but gets stuck in (B).
  4. ESP32 does successfully reconnect in both (A) and (B) if: WiFi.disconnect(true); _and_ WiFi.begin(WIFI_SSID, WIFI_PASSWD); are called. Seems like both are necessary.
    \
    The boolean wifioff parameter to disconnect being set to true also seems necessary. Since WiFi.disconnect(true); appears to clear WiFi settings, it's necessary to re-specify the ssid and password in the call to begin.

Logs

All of these are with an open network. I'm omitting the ESP8266 logs since the behavior was as expected, but can provide if they'd be useful.

ESP32, experiment (A)

I (25) wifi: wifi firmware version: 708a055
I (26) wifi: config NVS flash: enabled
I (26) wifi: config nano formating: disabled
I (31) wifi: Init dynamic tx buffer num: 32
I (32) wifi: Init data frame dynamic rx buffer num: 64
I (32) wifi: Init management frame dynamic rx buffer num: 64
I (35) wifi: wifi driver task: 3ffd46dc, prio:23, stack:4096
I (40) wifi: Init static rx buffer num: 10
I (44) wifi: Init dynamic rx buffer num: 0
I (48) wifi: wifi power manager task: 0x3ffd9418 prio: 21 stack: 2560
I (425) wifi: mode : sta (30:ae:a4:04:42:c8)
[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 2 - STA_START
I (2836) wifi: n:6 0, o:1 0, ap:255 255, sta:6 0, prof:1
I (2836) wifi: state: init -> auth (b0)
I (2853) wifi: state: auth -> assoc (0)
I (2872) wifi: state: assoc -> run (10)
I (2872) wifi: connected with glowyrectangle, channel 6
[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 4 - STA_CONNECTED
[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 7 - STA_GOT_IP
Setup completed
[4] ssid=glowyrectangle
[5] ssid=glowyrectangle
I (5872) wifi: pm start, type:0

[6] ssid=glowyrectangle
[7] ssid=glowyrectangle
[8] ssid=glowyrectangle
[9] ssid=glowyrectangle
[10] ssid=glowyrectangle
I (10388) wifi: state: run -> auth (7c0)
I (10389) wifi: pm stop, total sleep time: 0/4516399

I (10389) wifi: n:6 0, o:6 0, ap:255 255, sta:6 0, prof:1
[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:270] _eventCallback(): Reason: 7 - NOT_ASSOCED
W (11413) wifi: Haven't to connect to a suitable AP now!
[11] ssid=
Attempting to reconnect...
I (13822) wifi: n:6 0, o:6 0, ap:255 255, sta:6 0, prof:1
I (13823) wifi: state: auth -> auth (b0)
I (13826) wifi: state: auth -> assoc (0)
I (13839) wifi: state: assoc -> run (10)
I (13839) wifi: connected with glowyrectangle, channel 6
[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 4 - STA_CONNECTED
[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 7 - STA_GOT_IP
Connection result: 3
[1513219385] ssid=glowyrectangle
[1513219386] ssid=glowyrectangle
[1513219387] ssid=glowyrectangle
[1513219388] ssid=glowyrectangle
I (16839) wifi: pm start, type:0

ESP32, experiment (B)

rst:0x10 (RTCWDT_RTC_RESET),boot:0x17 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0018,len:4
load:0x3fff001c,len:812
load:0x40078000,len:0
load:0x40078000,len:11404
entry 0x40078aa0
I (25) wifi: wifi firmware version: 708a055
I (26) wifi: config NVS flash: enabled
I (26) wifi: config nano formating: disabled
I (35) wifi: Init dynamic tx buffer num: 32
I (36) wifi: Init data frame dynamic rx buffer num: 64
I (36) wifi: Init management frame dynamic rx buffer num: 64
I (39) wifi: wifi driver task: 3ffd46d0, prio:23, stack:4096
I (44) wifi: Init static rx buffer num: 10
I (48) wifi: Init dynamic rx buffer num: 0
I (52) wifi: wifi power manager task: 0x3ffd940c prio: 21 stack: 2560
I (431) wifi: mode : sta (30:ae:a4:04:42:c8)
[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 2 - STA_START
I (2842) wifi: n:6 0, o:1 0, ap:255 255, sta:6 0, prof:1
I (2843) wifi: state: init -> auth (b0)
I (2846) wifi: state: auth -> assoc (0)
I (2863) wifi: state: assoc -> run (10)
I (2863) wifi: connected with glowyrectangle, channel 6
[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 4 - STA_CONNECTED
[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 7 - STA_GOT_IP
Setup completed
[3] ssid=glowyrectangle
[4] ssid=glowyrectangle
I (5863) wifi: pm start, type:0

[5] ssid=glowyrectangle
[1513219573] ssid=glowyrectangle
[1513219574] ssid=glowyrectangle
[1513219575] ssid=glowyrectangle
[1513219576] ssid=glowyrectangle
[1513219577] ssid=glowyrectangle
[1513219578] ssid=glowyrectangle
[1513219579] ssid=glowyrectangle
I (13174) wifi: bcn_timout,ap_probe_send_start
[1513219580] ssid=glowyrectangle
[1513219581] ssid=glowyrectangle
[1513219582] ssid=glowyrectangle
I (15676) wifi: ap_probe_send over, resett wifi status to disassoc
I (15677) wifi: state: run -> init (1)
I (15678) wifi: pm stop, total sleep time: 0/9813809

I (15678) wifi: n:6 0, o:6 0, ap:255 255, sta:6 0, prof:1
[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:270] _eventCallback(): Reason: 200 - NO_AP_FOUND
W (16387) wifi: Haven't to connect to a suitable AP now!
[1513219583] ssid=
Attempting to reconnect...
Connection result: 5
[E][WiFiUdp.cpp:183] endPacket(): could not send data: 118
W (17412) wifi: Haven't to connect to a suitable AP now!
[1513219584] ssid=
Attempting to reconnect...
Connection result: 5
[E][WiFiUdp.cpp:183] endPacket(): could not send data: 118
W (18437) wifi: Haven't to connect to a suitable AP now!
[1513219585] ssid=
Attempting to reconnect...
Connection result: 5
[E][WiFiUdp.cpp:183] endPacket(): could not send data: 118
W (19462) wifi: Haven't to connect to a suitable AP now!
[1513219586] ssid=
Attempting to reconnect...
Connection result: 5

... ( loops like this indefinitely ) ...

ESP32, experiment (B) with disconnect(true) + begin(ssid, passwd)

rst:0x10 (RTCWDT_RTC_RESET),boot:0x17 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0018,len:4
load:0x3fff001c,len:812
load:0x40078000,len:0
load:0x40078000,len:11404
entry 0x40078aa0
I (27) wifi: wifi firmware version: 708a055
I (28) wifi: config NVS flash: enabled
I (28) wifi: config nano formating: disabled
I (36) wifi: Init dynamic tx buffer num: 32
I (36) wifi: Init data frame dynamic rx buffer num: 64
I (36) wifi: Init management frame dynamic rx buffer num: 64
I (39) wifi: wifi driver task: 3ffd46d0, prio:23, stack:4096
I (45) wifi: Init static rx buffer num: 10
I (48) wifi: Init dynamic rx buffer num: 0
I (52) wifi: wifi power manager task: 0x3ffd940c prio: 21 stack: 2560
I (431) wifi: mode : sta (30:ae:a4:04:42:c8)
[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 2 - STA_START
I (2842) wifi: n:6 0, o:1 0, ap:255 255, sta:6 0, prof:1
I (2843) wifi: state: init -> auth (b0)
I (2847) wifi: state: auth -> assoc (0)
I (2863) wifi: state: assoc -> run (10)
I (2863) wifi: connected with glowyrectangle, channel 6
[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 4 - STA_CONNECTED
[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 7 - STA_GOT_IP
Setup completed
[1513219802] ssid=glowyrectangle
[1513219803] ssid=glowyrectangle
[1513219804] ssid=glowyrectangle
I (5863) wifi: pm start, type:0

[1513219805] ssid=glowyrectangle
[1513219806] ssid=glowyrectangle
[1513219807] ssid=glowyrectangle
[1513219808] ssid=glowyrectangle
[1513219809] ssid=glowyrectangle
[1513219810] ssid=glowyrectangle
[1513219811] ssid=glowyrectangle
[1513219812] ssid=glowyrectangle
[1513219813] ssid=glowyrectangle
[1513219814] ssid=glowyrectangle
[1513219815] ssid=glowyrectangle
[1513219816] ssid=glowyrectangle
I (17282) wifi: bcn_timout,ap_probe_send_start
[1513219817] ssid=glowyrectangle
[1513219818] ssid=glowyrectangle
[1513219819] ssid=glowyrectangle
I (19785) wifi: ap_probe_send over, resett wifi status to disassoc
I (19785) wifi: state: run -> init (1)
I (19786) wifi: pm stop, total sleep time: 0/13922305

I (19786) wifi: n:6 0, o:6 0, ap:255 255, sta:6 0, prof:1
[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:270] _eventCallback(): Reason: 200 - NO_AP_FOUND
W (20616) wifi: Haven't to connect to a suitable AP now!
[1513219820] ssid=
Attempting to reconnect...
I (20632) wifi: mode : null
I (20634) wifi: flush txq
I (20634) wifi: stop sw txq
I (20635) wifi: lmac stop hw txq
[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 3 - STA_STOP
I (20644) wifi: mode : sta (30:ae:a4:04:42:c8)
[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 2 - STA_START
[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 2 - STA_START
[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:270] _eventCallback(): Reason: 201 - AUTH_FAIL
Connection result: 1
[E][WiFiUdp.cpp:183] endPacket(): could not send data: 118
W (24182) wifi: Haven't to connect to a suitable AP now!
[1513219823] ssid=
Attempting to reconnect...
I (24254) wifi: mode : null
I (24256) wifi: flush txq
I (24257) wifi: stop sw txq
I (24257) wifi: lmac stop hw txq
I (24266) wifi: mode : sta (30:ae:a4:04:42:c8)
[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 3 - STA_STOP
[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 2 - STA_START
[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 2 - STA_START
[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:270] _eventCallback(): Reason: 201 - AUTH_FAIL
Connection result: 1
[E][WiFiUdp.cpp:183] endPacket(): could not send data: 118
W (27804) wifi: Haven't to connect to a suitable AP now!
[1513219827] ssid=
Attempting to reconnect...
I (27820) wifi: mode : null
I (27822) wifi: flush txq
I (27822) wifi: stop sw txq
I (27822) wifi: lmac stop hw txq
[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 3 - STA_STOP
I (27832) wifi: mode : sta (30:ae:a4:04:42:c8)
[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 2 - STA_START
[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 2 - STA_START
I (30311) wifi: n:6 0, o:1 0, ap:255 255, sta:6 0, prof:1
I (30312) wifi: state: init -> auth (b0)
I (30318) wifi: state: auth -> assoc (0)
I (30339) wifi: state: assoc -> run (10)
I (30340) wifi: connected with glowyrectangle, channel 6
[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 4 - STA_CONNECTED
[D][WiFiGeneric.cpp:265] _eventCallback(): Event: 7 - STA_GOT_IP
Connection result: 3
[1513219831] ssid=glowyrectangle
[1513219832] ssid=glowyrectangle
I (33340) wifi: pm start, type:0

[1513219833] ssid=glowyrectangle
[1513219834] ssid=glowyrectangle
[1513219835] ssid=glowyrectangle
[1513219835] ssid=glowyrectangle
[1513219836] ssid=glowyrectangle

Wrapup

I've done some digging around in the SDK, but don't see anything obvious. I may dig around a bit, but I hope the above information is useful. If there's any other info I can provide please let me know; I'd be more than happy to oblige.

I tried getting some pcaps in monitor mode, but they weren't very interesting. Just seemed that the ESP32 wasn't sending anything after the disconnect.

I'm happy that I've at least found a workaround (disconnect(true) + begin(ssid, passwd)).

@vseven @Markusenz @sidoh
Sorry to reply later, and thanks for your hard work on the SDK.
The attachment is the debug version of wifi lib,you can use it to have a test, then we can analysis your logs to solve the problem.
wifi_lib.tar.gz

@igrr - I have tried both open and secure with the same results. I can try to get you a packet capture but the issue is extremely random, it could do it 4 times in a hour or twice in a day so capturing might be very tedious. Now that multiple people are having the same issue however I will try the debug version that @zhangyanjiaoesp posted and if that still doesn't lead you to the solution I'll try the packet capture.

Will auto reconnect be fixed to work as intended? It sounds like @sidoh is getting around it which I have not had much luck with. Only rebooting seems to get it around these disconnect loops.

I'll get this recompiled and loaded this weekend.

EDIT: The wifi_lib.tar.gz file is empty. Can you please repost?

I think the most interesting thing I noticed was that:

WiFi.disconnect(true);
WiFi.begin(SSID, PASSWORD);

always eventually reconnects for me (the true param to disconnect is important). I think WiFi.disconnect(true) turns off the radio. My guess is that under certain circumstances some state about the network the ESP32 is supposed to be connecting to gets cleared, and the above resets it.

Also interesting is that the issue appears to be 100% reproducible by turning off the wifi network, waiting for the ESP32 to notice it has disconnected, and turning the network back on. If the network reappears before the ESP32 notices, it's sometimes able to reconnect successfully. From the logs, the difference appears to be that a NO_AP_FOUND event is triggered in the former case, but not the latter.

Re-ran the code linked with the debug libs. Logs here:

This was all on an open network.

edit - link to raw logs instead of gist page.

@zhangyanjiaoesp - Any news on this? I haven't tried the debug code because @sidoh already did and provided lots of logs already but then again it's been a couple more weeks and no real answers.

@sidoh
In the slow_ap_recreate.log ,we find there are print like

[1513308152]ssid=
Attempting to reconnect...

it seems like your ssid is empty, so after scanning all channels, return no ap found.
so you should check your code to see whether the ssid is set correctly.
screenshot from 2018-01-04 17-55-20

Hi @zhangyanjiaoesp,

I think this is probably the meat of the issue. In the slow_ap_recreate.log, the reconnection code is just doing (full sketch here):

WiFi.begin();

so it's not supplying an AP. My understanding of the SDK is that it should just reconnect to the last known AP. Perhaps if it can't find the last used SSID, it clears the config? Is that expected?

Using this instead seems to always work:

WiFi.disconnect(true);
WiFi.begin(ssid, passwd);

edit - just to make sure the setup is clear, the case where reconnecting is not working is when the AP disappears for long enough for the SDK to decide that it's gone. Maybe this is expected behavior, though.

@sidoh Yes, you are right. This is expected behavior, you can workaround it by your method:

WiFi.disconnect(true);
WiFi.begin(ssid, passwd);

I see, this makes sense. I'll try to reproduce without the WiFi.begin() in the next couple of days. Think the right thing is to just have the SDK handle reconnection.

Where is reconnection handled in the SDK? Only reference I can find is here, which seems to use WiFi.begin(). Is that expected?

yes, you are right

Doesn't that mean that the SDK code handling reconnections would have the same issue my demo has? If it tries to reconnect after the AP has disappeared, the SSID will get cleared and it won't be able to reconnect unless the AP info is re-supplied?

definitly the SDK should try to reconnect automotically. That is the whole point of having WiFi.setAutoReconnect(true).

@everslick - I agree completely, it doesn't seem to work which is why I posted this originally 3+ months ago. The WiFi.setAutoReconnect(true) doesn't seem to make it reconnect which is ironic to say the least. The only thing that works is to reboot the controller and let it go back through its normal connect (which isn't going to work for me when controlling LEDs as they turn off) or doing the full disconnect and reconnect.

@zhangyanjiaoesp - So you are saying WiFi.setAutoReconnect(true) simply doesn't work? And to work around we have to call the disconnect and reconnect with the SSID and password again? If this is true will it be fixed or at least the documentation updated to say it doesn't work?

I have a similar issue,
After reseting the by software using the following sequence:
WiFi.disconnect(); //Ensure current ssid/password is erased
delay (1000);
ESP.restart();
The ESP reboots but never connects to the AP until an hardware reset.
The function Wifi.disconnect () is also not working correctly.
Robert

The hard way is to connect a GPIO pin to the EN one and force a System reset (GPIO Low) in case reboot/restart or wifi (re)connection is needed.

Don't do the disconnect. Just restart works for me. But again...shouldn't have to restart if WiFi.setAutoReconnect(true) worked properly.

It should be nice to have the Wifi.disconnect or autoreconnect working, but what's the point, if there is a Wifi connection issue, this is a major one in case of ESP32 (all subsequent applications probably relies on Wifi), so the ultimate solution is to try a hardware reset, if this one fails ... bye bye ESP32 usage.

Rebooting is NOT a solution. I'm using this for RGB LED control and rebooting resets the lights to off. If there is a function that tells the ESP that if it loses WiFi it should keep retrying to connect then that function should actually work as documented.

OK, I have tried to reset the ESP through a GPIO, but it looks that ESP doesn't like suicide, so it doesn't work without an external device. So I agreed the only solution that left is that the WiFi disconnect, the ESP restart or the Wifi auto reconnect are actually working.
Another issue for which we have to wait for a functional ESP module (I note that as far I could test it, the I2C protocol is another one for which I am waiting for a solution).
ESP32 is far to be reliable until now ....
Robert

and I didn't mention the SPI interface ...

esp_restart_noos();

For when ESP.restart() doesn't work.

I am using Arduino IDE to configure a WeMos Lolin32.
I use the function:

void unitReset ()
 {
#ifdef DEBUGGING
  Serial.println ("Coordinator will REBOOT NOW ....");
#endif    
  WiFi.disconnect();                          //Ensure current  ssid/password is erased
  delay (1000);
  ESP.restart();
 }

When WeMos connected in WiFi.mode(WIFI_STA), I call this function from MQTT.
It actually restarts the system and the sketch starts, but Wifi (can't synchronise from that point, connection attempts goes in a endless loop). A manual reset solves it.
However the same function called from with WiFi.mode(WIFI_STA) via telnet, works.

@vseven @everslick @rrobinet
You misunderstand the meaning of the function WiFi.setAutoReconnect(true) .
In our code, WiFi.setAutoReconnect(true) is not mean to reconnect wifi utomotically. It means if the ESP32 has connected to wifi before, then when the system restarts next time, it wiil connect the last connected wifi.
So we will add some comments in the code. Sorry to have affected your work.

@zhangyanjiaoesp Sorry for stating it like that: That is just "wrong". That API was introduced for the ESP8266 and it did exactly that: reconnecting wifi automatically. What you describe is what the WiFi.setAutoConnect(); method is for. You cannot change the semantics of a well established API at will.

Besides, even when the API was meant to work like you said, the function naming would be incredible bad and misleading.

Anyway. We are talking IoT devices here. The default should be to stay connected to the network no matter what. If anything, there should be functions to disable automatic reconnects and not to require the API user to jump through hoops to make it behave that way.

@vseven @everslick @rrobinet
Please look at here, it tells user this function works when powered on.

ESP.restart issue, correction.
Well the script above was working with an ESP8266 and not with an ESP32, however after some tests, the issue is the usage of the WiFi.disconnect (true), before the ESP.restart(). This function for ESP32 should be place at the Wifi initialisation (see https://github.com/espressif/arduino-esp32/pull/466)
Something like:

<snip>
  WiFi.disconnect(true);                                      // Clear Wifi Credentials
  WiFi.persistent(false);                                     // Avoid to store Wifi configuration in Flash
  WiFi.mode(WIFI_STA);                                        // Ensure WiFi mode is Station 
  Serial.println("Now Connecting to Access Point ...");  
  // Connect to the Access Point
  WiFi.begin(ssid,key);
<snip>

and the unit reset should be simply:

void unitReset ()
 {
#ifdef DEBUGGING
  Serial.println ("Coordinator will REBOOT NOW ....");
#endif    
  delay (1000);
  ESP.restart();
 }

Can you confirm the following, which I understand so far when reading this thread:

  • ESP32 behaves different than ESP8266, so that with the ESP32 there is no wifi auto reconnect during runtime in case the AP is lost or unreachable for some time. The user has to detect loss of wifi and handle the reconnect in his code (not possible without rebooting device??)
  • ESP32 behaves different than ESP8266 because after boot, it sometimes does not connect to AP. We need certain lines of code to fix it, like here https://github.com/espressif/arduino-esp32/issues/653#issuecomment-356534618
  • the described issues are seen as expected behaviour and it is not intended to change behaviour in the api, so we have to adapt our code accordingly when working with ESP32

@Markusenz, I can confirm that https://github.com/espressif/arduino-esp32/issues/653#issuecomment-355659659 seems to always work for me. It seems like the only reference to getAutoReconnect is the link I pasted in the comment, which wouldn't handle disconnects well, if it all.

@zhangyanjiaoesp, thanks for your help on this. :)

You misunderstand the meaning of the function WiFi.setAutoReconnect(true) .
In our code, WiFi.setAutoReconnect(true) is not mean to reconnect wifi utomotically. It means if the ESP32 has connected to wifi before, then when the system restarts next time, it wiil connect the last connected wifi.

The method you linked to is setAutoConnect, not setAutoReconnect. I think these methods are different. setAutoReconnect is here. It just sets a flag, and I think the only place that flag is used is here.

Given the name of the method, and how that flag is getting used internally, it seems like this method is supposed to do what people are assuming it does -- enable/disable automatic attempts to reconnect to an AP after a disconnect.

My thought is that this feature is just not working as expected, and I think it's possibly because internally the SDK is using WiFi.begin(), which will clear the SSID if the saved AP doesn't exist, as I discovered above.

So this is how it seems to be happening. Can the SDK be updated to NOT clear out the AP if it doesn't see it instantly. Or to do a WiFi.Begin using the last known SSID and password if WiFi.setAutoReconnect(true) or am I missing something?

If my thinking/digging is correct, I really doubt this behavior is intentional or expected. It seems likely that setAutoReconnect is meant to have the functionality that folks in this thread are expecting it to, and it just has some bugs.

My suggestion would be to work around it for now. In my own project I just attach an event handler that does

WiFi.disconnect(true);
WiFi.begin(ssid, passwd);

and it works for me.

It seems like reconnection is currently being handled by the Arduino SDK rather than the underlying stuff. With the ESP8266 Arduino SDK, reconnection is handled by the Non-OS SDK. So a fix to the ESP32 Arduino SDK will probably look a lot like this external workaround would anyway (again -- assuming my thinking is correct. I could certainly be wrong).

edit - here is the relevant section in my code that handles reconnection.

@Markusenz
you are right.
@vseven @sidoh
I agree with @sidoh , you can work around it for now. We will implement the auto connect function, and we have known the importance of this issue, but we need time to provide you a perfect solution.

After some digging I found this to work pretty well:

static bool sta_was_connected = false;

static void poll_connection(void) {                                         
#ifdef ESP32
  // this is a crude workaround due to the inability of
  // the ESP32 to reconnect to an accesspoint automatically.
  //
  // https://github.com/espressif/arduino-esp32/issues/653

  static uint32_t ms = millis();

  if (!WiFi.isConnected() && (millis() - ms) > 1000 * 5) {
    ms = millis();

    if (sta_was_connected) WiFi.reconnect(); else WiFi.begin();
  }
#endif
}

loop() {
  poll_connection();
}

In the WiFi event handler for SYSTEM_EVENT_STA_GOT_IP you have to set sta_was_connected to true.

This will also work when the accesspoint was not available when the ESP32 booted.

The advantage is, that it does not clear the STA config. This is especially useful if you have set a static IP configuration (not using DHCP).

do you get a
[D][WiFiGeneric.cpp:293] _eventCallback(): Event: 8 - STA_LOST_IP
if you wait long enough ( there is a delay )

I am gonna try

    } else if(event->event_id == SYSTEM_EVENT_STA_LOST_IP) {
        if(WiFi.getAutoReconnect()){
            WiFi.begin();
        }

Here is a working solution that bypasses some issues with the WiFi library.
Note the while loops after a WiFi.begin().
I have found the connection delay varies depending on the router and encryption settings, AES, WPA2 seem best, fastest and most reliable.

To that end waiting till you know a connection worked but making sure you don't lock up, pretty much does it.

I noted some are calling WiFi.disconnect(). Be careful to use WiFi.persistent(false); with it or every time you recover you are re-writing the NV FLASH and will brick it when the FLASH dies.

Partial CODE SAMPLE

setup()
{
  WiFi.begin( rssiSSID , password );

  int WLcount = 0;
  while (WiFi.status() != WL_CONNECTED && WLcount < 250 ) 
  {
    delay( 100 );
    #ifdef DEBUG
       Serial.print(".");
    #endif
    ++WLcount;
  }
}

void loop() 
{
  if (WiFi.status() ==  WL_CONNECTED) 
  {
    // PUT_YOUR_UP_TIME_CODE_HERE   

    #ifdef DEBUG
       Serial.print("C");
       if (UpCount >= 20)   // just keep terminal from scrolling sideways
       {
        UpCount = 0;
        Serial.println();
       }
       ++UpCount;
    #endif

      // END WiFi connected loop()
  } else
  {
    // PUT_YOUR_DOWN_TIME_CODE_HERE
    //  WiFi DOWN loop

    #ifdef DEBUG
        WFstatus = getWifiStatus( WFstatus );
    #endif

    WiFi.begin( rssiSSID , password );
    int WLcount = 0;
    // loop - depending on router, connect can be from 4 - 20 seconds
    // usually longer to reconnect than the connect at boot
    // lopping till reconnect seems to let it settle
    // usually around 80 count to breakout
    while (WiFi.status() != WL_CONNECTED && WLcount < 250 ) 
    {
        delay( 100 );
        #ifdef DEBUG  
            Serial.print(".");
            // just keep terminal from scrolling sideways in test
            if (UpCount >= 20)
            {
                UpCount = 0;
                Serial.println();
            }
            ++UpCount;
        #endif
        ++WLcount;
    }
    delay( 1000 );
  }  // END WiFi DOWN 
} // END loop()


int getWifiStatus( int WiFiStatus  )
{
  WiFiStatus = WiFi.status();
  Serial.print("\tStatus "); Serial.print( WiFiStatus );
  switch( WiFiStatus )
     {
        case WL_IDLE_STATUS :           // WL_IDLE_STATUS     = 0, 
                Serial.println(", WiFi IDLE "); 
                break;
        case WL_NO_SSID_AVAIL:          // WL_NO_SSID_AVAIL   = 1,
                Serial.println(", NO SSID AVAIL ");
                break;
        case WL_SCAN_COMPLETED:         // WL_SCAN_COMPLETED  = 2,
                Serial.println(", WiFi SCAN_COMPLETED "); 
                break;
        case WL_CONNECTED:      // WL_CONNECTED       = 3,
                Serial.println(", WiFi CONNECTED "); 
                WiFi.persistent(true);  
                break;
        case WL_CONNECT_FAILED:         // WL_CONNECT_FAILED  = 4,
                Serial.println(", WiFi WL_CONNECT FAILED"); 
                break;
        case WL_CONNECTION_LOST:        // WL_CONNECTION_LOST = 5,
                Serial.println(", WiFi CONNECTION LOST");
                WiFi.persistent(false); // don't keep writing FLASH
                break;   
        case WL_DISCONNECTED:            // WL_DISCONNECTED    = 6
                Serial.println(", WiFi DISCONNECTED ==");
                break;
  }
  return WiFiStatus;
}  // END getWifiStatus()

======
it takes on average 8-15 seconds to detect mode change
note "."'s are connecting
"C"'s are Connected

OUTPUT
CCCCCCCCC     Status 5, WiFi CONNECTION LOST    Unplugged Router here
.........
....................                            Trying
 More lines of dots...
....................
...........       Status 1, NO SSID AVAIL       Gave up, Changed Modes
.........                                       Replugged Router here
....................
................CCCC                            TaDa I'm Back...
CCCCCCCCCCCCCCCCCCCC

I am using this, seems to work for me

void WiFiEvent(WiFiEvent_t event){
    if(event == SYSTEM_EVENT_STA_DISCONNECTED){
      Serial.println("Event: SYSTEM_EVENT_STA_DISCONNECTED, reconnecting");
      WiFi.reconnect();
    }
}

if(WiFi.getAutoReconnect()) WiFi.onEvent(WiFiEvent);

I guess my apartment with the 50 APs nearby is really a great place to test this issue. The solution from tablatronix causes my esp32 to dump and I don't see how mickeypop's solution would do any good, which it didn't help. I've found that restarting the wifi connection works fairly well but even that requires a hard power reset every once in a while. On the side i've got an esp8266 in the same environment that never requires any manual intervention. I've tried a few other suggestions here without luck.

I think it's amazing all the development that's done. Frankly I don't have the skills to come up with a solution. If anyone has something that they want to try in a harsh environment, feel free to send me tests. We really need the esp32 to have a solid connection and handle intermittent wifi gracefully.

Edit: after trying a lot of stuff: @tablatronix If I run this line too fast it crashes/gives backtrace. Calling every few seconds gave me no problems. Now to let it run for a few days to see what happens
if(WiFi.getAutoReconnect()) WiFi.onEvent(WiFiEvent);
Edit2: lasted 30 minutes before dropping off

@thefatmoop I ran into a WiFi reconnect issue that ended up being a NVS corruption issue. #1147 I rewrote a sketch to dump the nvs data. Try it and capture the output. It may show something.
Show NVS Keys

Chuck.

thefatmoop

Both solutions should work.
As i noted; "_Here is a working solution that bypasses some issues with the WiFi library._"

While one bypasses some library issues the other uses the WiFi.onEvent() service, both simply detect when a connection is broken and re-initiate a new connection.

While some have noted after several hours they keep getting bumped, this is almost certainly a function of the lease time of DHCP server in the router.

If the lease time of the router is not the same sometimes devices "forget" to update causing a no IP address even though sometimes the WiFi connect is still there.

  • WiFi.begin() forces the DHCP to get a new IP along with a new connection.
  • WiFi.reconnect() works but often assumes the unit still has an IP and may not do a DHCP request.

The simple way around this is to Ping the DHCP router periodically.
This forces the router to know you are still on the network and keep the lease current.

Rebooting may reconnect, but does not address the WHY of getting disconnected and often applications can get out of sync if you are simply rebooting.

So reconnecting without rebooting is often a necessity.

reconnect does not redo dhcp, I found this out when trying to change hostname and reconnect, was gonna file it as a bug.

Solution from @tablatronix is working for me thanks! @thefatmoop you can check the implementation on OpenMQTTGateway.ino code.

The code is called after MQTT disconnection, if I put the code outside this condition the ESP dump indeed.

If WiFi.reconnect() reconnects, but MQTT client not, you can make another setup_wifi(): with disconnect() delay() and begin(), after a few client reconnect attempts and it works great within the new connection. But what happens when the MQTT server is down?

Thats an application level problem..

Added mickeypop code proposal to the Wiki

Sorry. I'm a beginner in arduino/esp programming. I'm also confronting with the bugs/problems of wifi connect and reconnect. My part of code which manages both the WiFi & MQTT client (PubSubClient), and which actually works on an ESP32 from Adafruit/Huzzah32:

void setupWiFi() {
  WiFi.disconnect(true);
  WiFi.begin(WLAN_SSID, WLAN_PASS);
  WiFi.waitForConnectResult();
}

boolean clientReconnect() {
  if(client.connect("esp32_client")) {
    client.subscribe("/test");
  }
  return client.connected();
}

boolean wifi_connected_once = false;
unsigned long last_client_reconnect_attempt = 0;
int client_reconnect_attempts = 0;

void setup() {  
  client.setServer(MQTT_SERVER, 1883);
  client.setCallback(client_callback);
}

void loop() {
  unsigned long loop_start = millis();

  if(WiFi.isConnected()) {
    // WiFi connected
    if(client.connected()) {
      // client connected
      // publish data every 5 seconds
      if(loop_start - last_client_publish >= 5000) {
        client_publish_data();
        last_client_publish = loop_start;
      }
      client.loop();
    } else {
      // client not connected
      // try reconnect a few times every 5 seconds
      if(client_reconnect_attempts <= 5) {
        if(loop_start - last_client_reconnect_attempt > 5000) {
          client_reconnect_attempts++;
          if(clientReconnect()) {
            // client connected
            client_reconnect_attempts = 0;
          }
          last_client_reconnect_attempt = loop_start;
        }
      } else {
        // maybe MQTT server is down
        // try reconnect in 5 minutes
        if(loop_start - last_client_reconnect_attempt > 300000) {
          last_client_reconnect_attempt = loop_start;
          client_reconnect_attempts = 0;
        }
      }
    }
  } else {
    // WiFi not connected
    // try connect for the first time or 
    // try reconnect every 2 minutes
    if((loop_start - last_client_reconnect_attempt > 120000) || wifi_connected_once == false) {
      last_client_reconnect_attempt = loop_start;
      wifi_connected_once = true;
      client_reconnect_attempts = 0;
      setupWiFi();
    }
  }
}

Tested with some router reboots and the code seems working without the need of ESP reboot.
Do you have any much better suggestion?

This issue is killing me. It's happening randomly sometimes in the first hour sometimes after six hours while running without issues. I've tried all sorts of configurations and none of them is reliable. Restarting the ESP by software or hardware is the last resort that actually works but that's not a viable solution for my product.

Last time I left it running and tried more than FOUR THOUSANDS attempts, none of them with success.

I have tried so far:

1) Enabling autoReconnect and calling reconnect
2) Disabling autoReconnect and manually disconnecting and reconnecting. In this configuration I've tried both methods of completely switching off the antenna or not. Does not work in any mode.

Here you have some logs (this is actually running right now with more than 600 attempts to reconnect on a perfectly working router (TP-LINK):

WARNING: WiFi lost connection. Trying reconnection attempt 632 on next iteration
Triggering WiFi Reconnection attempt 632
I (14944038) wifi: mode : softAP (30:ae:a4:1a:ca:1d)
Creating WiFi with SSID 'Nano BAB - Development' and password '#######'
Connecting to WiFi 'TP-LINK_A8FB38'
[D][WiFiGeneric.cpp:293] _eventCallback(): Event: 3 - STA_STOP
[D][WiFiGeneric.cpp:293] _eventCallback(): Event: 2 - STA_START
[WiFi-event] event: 2
[D][WiFiGeneric.cpp:293] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:298] _eventCallback(): Reason: 201 - AUTH_FAIL

As you can see is failing on authentication however the password is correct. On some previous attempt (number 578!!) from the same example is raising error 2:

WARNING: WiFi lost connection. Trying reconnection attempt 578 on next iteration
Triggering WiFi Reconnection attempt 578
I (14134199) wifi: mode : softAP (30:ae:a4:1a:ca:1d)
Creating WiFi with SSID 'Nano BAB - Development' and password '#########'
[D][WiFiGeneric.cpp:293] _eventCallback(): Event: 3 - STA_STOP
[WiFi-event] event: 3
Connecting to WiFi 'TP-LINK_A8FB38'
[D][WiFiGeneric.cpp:293] _eventCallback(): Event: 13 - AP_START
[WiFi-event] event: 13I (14134890) wifi: mode : sta (30:ae:a4:1a:ca:1c) + softAP (30:ae:a4:1a:ca:1d)
[D][WiFiGeneric.cpp:293] _eventCallback(): Event: 2 - STA_START*

[WiFi-event] event: 2[D][WiFiGeneric.cpp:293] _eventCallback(): Event: 2 - STA_START
[WiFi-event] event: 2I (14137748) wifi: ap channel adjust o:1,1 n:6,1
I (14137749) wifi: n:6 1, o:1 0, ap:6 1, sta:6 1, prof:1
I (14138422) wifi: state: init -> auth (b0)
I (14139423) wifi: state: auth -> init (2)
I (14139424) wifi: n:6 0, o:6 1, ap:6 1, sta:6 1, prof:6
[D][WiFiGeneric.cpp:293] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:298] _eventCallback(): Reason: 2 - AUTH_EXPIRE

It's always one of the two errors. In the end is simply that it does not reconnect.

Funny thing is I can disconnect manually the router by pulling the power cord for a few minutes, my code detects the disconnectiong and starts retrying and then my system reconnects OK when back in, however if the router is working normally this issue eventually happens and the ESP simply does not reconnect.

Btw, I am running with:

Running on SDK: 'v3.1-dev-239-g1c3dd23f-dirty'
CPU Frequency: 240MHz
WiFi both creating its own private WiFi and connecting to another one with access to the internet

When was the last time you pulled in from repo ?

1132

you only posted logs, no sketch or reconnect solution.

Last time was about a week or so. My SDK version is 3.1-dev-239.
Sorry I did not add the code because I basically tested all the solutions within the post. At startup I call something similar to:

WiFi.disconnect(true);
WiFi.softAP(wifiName, wifiPassword);
WiFi.begin(connectoToWifiSSID, connectToWifiPassword);

Then I handle WiFi events and especially the event SYSTEM_EVENT_STA_DISCONNECTED. When this event happens, I have tried 3 different ways of reconnection:

1) When Wifi autoreconnect was enabled I left the system to handle itself the reconnection
2) I tried by disabling autoreconnect and on that event calling WiFi.reconnect()
3) Latest one I am trying is to disconnect by turning off the radio and connecting again if no other disconnection as triggered it. I've got something like:

reconnections++;
needsReconnection = true;
reconnectionDetection = millis();
Serial.printf("\r\nWARNING: WiFi lost connection. Trying reconnection attempt %d on next iteration\r\n", reconnections);

needsReconnection is a flag that is checked in the main loop and triggers again the connection by basically running the first 3 lines of code.

Hope it makes sense now ;-)

Not sure if there is another way of doing it.

I forgot to mention, I am running too a mongoose server to implement a Rest API, allowing a max of 3 concurrent connections. Not sure if that could be the cause of it.

  1. There is no autoreconnect, that is what this issue is for.
  2. WiFi.reconnect might not be the same as disconnect, begin() ( dhcp etc )
  3. This might be mode specific , without code nobody knows what you are doing, no idea how you are handling events, or "turning radio off"

I'd suggest pulling in changes and making a simple test case.

josmunpav

your issue may be WiFi mode's

your code

WiFi.softAP(wifiName, wifiPassword);
WiFi.begin(connectoToWifiSSID, connectToWifiPassword);

You are running mixed Modes.
WiFi.softAP(); default is WIFI_MODE_AP mode

WiFi.begin(); default is WIFI_AP_STA mode

if you proceed with the WIFI_MODE_APSTA mode (mixed mode) they should not change and WiFi EVENT will not get mixed up with different modes.

WiFi.mode( WIFI_MODE_APSTA );
WiFi.softAP(wifiName, wifiPassword);
WiFi.begin(connectoToWifiSSID, connectToWifiPassword);

REF INFO
in esp_wifi_types.h

typedef enum {
    WIFI_MODE_NULL = 0,  /**< null mode */
    WIFI_MODE_STA,       /**< WiFi station mode */
    WIFI_MODE_AP,        /**< WiFi soft-AP mode */
    WIFI_MODE_APSTA,     /**< WiFi station + soft-AP mode */
    WIFI_MODE_MAX
} wifi_mode_t;

in wifitypes.h

typedef enum {
    WL_NO_SHIELD        = 255,   // for compatibility with WiFi Shield library
    WL_IDLE_STATUS      = 0,
    WL_NO_SSID_AVAIL    = 1,
    WL_SCAN_COMPLETED   = 2,
    WL_CONNECTED        = 3,
    WL_CONNECT_FAILED   = 4,
    WL_CONNECTION_LOST  = 5,
    WL_DISCONNECTED     = 6
} wl_status_t;

Hi mickeypop ,

I am testing your solution of:


WiFi.mode( WIFI_MODE_APSTA );
WiFi.softAP(wifiName, wifiPassword);
WiFi.begin(connectoToWifiSSID, connectToWifiPassword);

I am calling WiFi.reconnect() when event SYSTEM_EVENT_STA_DISCONNECTED happens, which I tried by manually disconnecting the router and seems to be working (that bit worked before too).

So far it has been working overnight for 7 hours non stop on 2 different ESP32. I've been pinging them every 5 seconds and no issues so far. Could not imagine that mixed mode declaration could be the reason, I thought it was automatically enabled when calling WiFi.begin and WiFi.softAP() . Fingers crossed. I will start now with more heavy testing to confirm it is the solution to the problems I am facing.

By the way, THANK YOU so much!!

@mickeypop @josmunpav thanks for sharing your findings.
I added it to the Wiki

This makes no sense this indicates that there is a bug in enablesta or enablesoftap if setting mode beforehand changes the outcome. That is why I suggested this is mode specific, workarounds should not be needed. So reproduction code would be nice

A lot of this doesn't make sense as @everslick clearly pointed out above: https://github.com/espressif/arduino-esp32/issues/653#issuecomment-356515973. In fact I cant believe I posted this 6 months ago and were still talking about it when it should have never been a issue in the first place.

Why something is called "autoReconnect" that doesn't auto reconnect is beyond puzzling. Everyone seems to be making up there own code to get through this shortcoming/bug. I'm going to pull a fresh copy of the code and reflash per @tablatronix suggestion but the whole point of this is we shouldn't have to do any of this....it should work like the ESP8266 and reconnect on it's own!

I'm personally still having issue with the chip completely locking up on occasion when it gets into this disconnect loop. I have it counting to 10 and restarting but randomly (1 out of 15 or so reboots) it doesn't reboot and just hard locks which requires a cold reboot. I'd switch to the ESP8266 in a heartbeat if it had better/more analog inputs but it unfortunately doesn't. Not that the ESP32 is very good at that either (https://www.esp32.com/viewtopic.php?f=19&t=2881).

In esp8266 autoreconnect is implemented in SDK, in esp32 there is no implementation, so it was added to the library to bring some form of compatibility, although it is only implemented for WIFI_REASON_AUTH_EXPIRE.

It can be implemented but it needs to be worked out, and this library is still alpha so there really should be no expectation, the sdk is subject to change, the entire event system is subject to change. So implementing core features like this takes time.

Not to mention, if espressif implements this in SDK , then we just wasted all our time.

When I say it needs to be worked out, I mean there are several outstanding issues that need to be resolved. That is why I ask for test sketches for people the above event solution is failing for.

  • reconnect, may fail lose dhcp assignment, as opposed to disconnect(),begin()**
  • autoconnect causes wrong wl_status emit, and infinite loop
  • sdk emits auth_expire for auth_fail on some routers, triggers above
  • esp_wifi_set_mode is asynchronous, race conditions
  • autoconnect, doesn't even work, https://github.com/espressif/arduino-esp32/issues/173

** reconnect does not enablesta, it just returns false, you should always be checking for return values!

If using my workaround above, I suggest disabling autoreconnect to avoid 2 of those bugs.

Hi guys I am back with a sample that reproduce the issues I am facing. The sample is full of comments but basically consists into:

  1. Two tasks: main one and web/wifi (implemented by mongoose 6.11 library)
  2. Some shared objects to do dummy tasks like setting PWM on a pin, reading average ADC value and a shared int counter
  3. A test page at http://your_esp32_ip/ that you can leave it running and will let you know when it disconnects. It also shows the values of the dummy tasks being performed
  4. A semaphore to avoid data corruption between tasks. Main task does changes on pwm pin, reads from ADC and increase the counter. Web task presents that data at the home page.
  5. Typical WiFi methods for connecting, disconnecting and handling WiFi events.
  6. It runs on APSTA mode so you need to configure your own WiFi (your WiFi needs internet connection as the home web page uses jQuery from a CDN to make API calls implemented by the ESP32 in the sample)

What I have found so far is that if you disable the dummy tasks (there is a flag for it) then both tasks run fine endlessly. If you enable them, then eventually (sometimes can take hours but normally happens within the first hour) the ESP32 disconnects from the WiFi and cannot reconnect, running the connection attempt every 10 seconds without success all the time.

I think there is some interference between ADC or PWM library (implemented by esp32-hal-ledc.h), because I could not reproduce the issue when the main task does nothing but doing a dummy waiting.

Something else I noticed is when the disconnection happens the WiFi signal for the AP decreases a lot. I checked this on my smartphone.

This is the typical WiFi log messages you can find when it fails:

[WiFi-event] event: 5
Disconnected from WiFi. Trying connection again in 10000ms
Web/Main Task is up and running. Shared counter is 11309, Average ADC Value = 1305.000000, PWM Value = 0
Connecting to WiFi 'TP-LINK_A8FB38' with password: 'C1A8FB38' on connection attempt = 108
Oops, there was a problem when connecting. It returned error: 1[D][WiFiGeneric.cpp:293] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:298] _eventCallback(): Reason: 2 - AUTH_EXPIRE

Please find the attached source code and sample pages:

working
not_working

ESP32_APSTA_Mode_Disconnection_Test.zip

PS: My real app is doing kind of the same. Starting APSTA mode with two tasks one for updating sensors, devices and GPIOS and the second for handling WiFi and the webserver implemented by mongoose and facing the very same issue.

I built this sketch to test the connection, get time every 10 seconds 10 times, disconnect wifi, reconnect wifi. Seems to work pretty good so I'm implementing in my other code to run for a few days because I was having re-connection issues.

#include <WiFi.h>
#include "time.h"

const char* ssid       = "ssid1";
const char* password   = "password1";

const char* ntpServer = "pool.ntp.org";
const long  gmtOffset_sec = 3600;
const int   daylightOffset_sec = 3600;

byte wfConnectTry = 0;
byte loopCnt = 0;

void printLocalTime()
{
  struct tm timeinfo;
  if (!getLocalTime(&timeinfo)) {
    Serial.println("Failed to obtain time");
    return;
  }
  Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
}

void setup()
{
  Serial.begin(115200);

  //connect to WiFi
  Serial.printf("Connecting to %s ", ssid);
  //WiFi.begin(ssid, password);
  wifiStart();
  //init and get the time
  configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
  if (WiFi.status() == WL_CONNECTED) {
    printLocalTime();
  }

}

void loop()
{
  delay(10000);
  printLocalTime();
  while (WiFi.status() != WL_CONNECTED || wfConnectTry >=5) {
    wfConnectTry++;
    wifiReconnect();

  }
  if (loopCnt >= 10){
    wifiReconnect();
  }
  loopCnt++;
}

void wifiReconnect()
{
  Serial.println(F("Disconnecting"));
  WiFi.disconnect(true);
  delay(500);
  Serial.println(F("Starting WiFi!"));
  wifiStart();
  loopCnt = 0;
}

void wifiStart()
{
  unsigned long timer1 = millis();
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED && millis() - timer1 < 5000UL) {
    delay(500);
    Serial.print(".");
  }
  if (WiFi.status() == WL_CONNECTED) {
    Serial.println(F(" CONNECTED"));
    wfConnectTry = 0;
  }
  else {
    Serial.println(F("Could not connect!"));
  }
}

....thanks for the code tip @tablatronix

Use code fences three ticks newline before amd after

Here is an interesting piece of information. I tried every trick mentioned in this thread and nothing worked. However, every time I install and run SimpleWiFiServer things get reset and then I can reinstall my app and things work again.

My app connects just fine to WiFi and at some point (days or weeks) it loses the connection and nothing can make it connect. I tried all the tricks on this thread and nada. As I said above, the only way I can make my ESP32 connect again to Wifi is by installing this other app to reset things. I wonder what it does that it makes my ESP32 work again with WiFi.

@gdombiak, do you have any debug information to show what the ESP32 is doing when it locks up? I had a recent issue where one of my sketches worked like a champ except when new day rolled over and there were two lines that put it into a continuous loop and the ESP finally just shit itself down till I reset or reloaded. Another issue I had was that I had another ESP that was up as a AP_STA and it kept trying to connect to it rather than the normal WiFI. Had to reload the other ESP and stipulate WiFi.mode(WIFI_STA) to fix that.

@AIWIndustries

Check out a post I put up at: https://github.com/espressif/arduino-esp32/issues/1100
Search for "SmartConfig / WiFi skeleton"

I wrote a complete skeleton that; saves, set with SmartConfig, deals with WiFi UP and DOWN, auto reconnects if Down.

It's a full structure and has always re-connected when WiFi went down or just disconnected for unknown reasons.

Take note in loop() for "// WiFi DOWN". I use a simple if()/else to track the WiFi status.
Because of the espressif libraries, it takes about 30-40 seconds to report when the WiFi is down then starts looking to reconnect.

If the AP is power cycled it takes about 30 seconds for the AP to boot and another 15 seconds to reconnect but always reconnects.

@AIWIndustries

There is a way to look up a lockup if the Traceback is printed to the terminal.

Install "ESP Exception Decoder" from; https://github.com/me-no-dev/EspExceptionDecoder
Instructions are there.

Once installed just copy and paste the traceback line and it will tell you what is happening at lock up.

Hi All,

The following code is working for me.

void wifiReconnect() {
while (WiFi.status() != WL_CONNECTED) {
WiFi.begin(ssid, password);
for(int i=0; i<=50; i++) {
digitalWrite(LED_BUILTIN, HIGH);
delay(100);
Serial.print(".");
digitalWrite(LED_BUILTIN, LOW);
delay(100);
}
}
}

Use this in the loop() as

if (WiFi.status() != WL_CONNECTED) {
wifiReconnect();
}

Hi All
I was using ESP32 core updated around 2 months ago.
In my program i use Wifi.begin(ssid, pass) in setup() and calling WiFi.reconnect() method on "SYSTEM_EVENT_STA_DISCONNECTED" event. The system was connecting automatically if there are any disconnection. But yesterday i updated to latest core and that started giving error with reason code 8.
After some hit and trials, i have commented WiFi.reconnect() then it started working perfectly. Also wifi reconnects automatically if AP is switched off and on.

In my case only in setup method i am using
WiFi.mode(WIFI_STA);
Wifi.begin()

this is working properly.
Can we say that in new core there is no need to call reconnect() and autoreconnect is now working in latest core?

correct. there is no need to call reconnect anymore ;) I have that fixed :P

There is a serious flaw in wifi.Reconnect().

In a deep look thru the libraries I found in several conditions it will connect without doing a DHCP update so you are connected without an IP address. -- I reported it but have not seen a fix yet.

I proved this once buy adding a UDP call in some test code. - I could talk to the AP by UDP but had no IP address. At the same time the MAC showed up on the AP connection list.

You want to use wifi.begin() it is always reliable. - You simply must be sure that you are down when calling it to connect or you could end up with stack overflow issues.

_The template I wrote below has never failed to reconnect._ It is uses SmartConfig and preferences instead of hard coding the AP/Pass though that could easily be changed.

Some of my code is proprietary to the LED flasher so i left comments in place instead. You can put any indicator code you want there.

Take a look at the wifi down part of loop(). I call WiFi.begin( PrefSSID.c_str() , PrefPassword.c_str() ); while always testing for a return status of WL_CONNECTED.

Hope this helps some.

// ESP32 only,  8266 will not work here
#include "FS.h"
#include "esp_system.h"
#include <esp_wifi.h>
#include <string.h>
#include <WiFi.h>
#include <Preferences.h> // WiFi storage

const char* rssiSSID;        // NO MORE hard coded set AP, all SmartConfig
const char* password;
String PrefSSID, PrefPassword;   // used by preferences storage

int WFstatus;
int UpCount; = 0;
int32_t rssi;         // store WiFi signal strength here
String getSsid;
String getPass;
String MAC;

// SSID storage
  Preferences preferences;       // declare class object
// END SSID storage

void setup() {
  Serial.begin(115200);

  Serial.printf("\tWiFi Setup -- \n" ); 
  wifiInit();      // get WiFi connected
  IP_info();
  MAC = getMacAddress();

  delay(2000);  // let thing settle
} // END setup()

void loop()
{
  if ( WiFi.status() == WL_CONNECTED )
  {   // Main connected loop

         // ANY MAIN LOOP CODE HERE

  }   // END Main connected loop()
  else
  {      // WiFi DOWN

    //  wifi down start LED flasher here

    WFstatus = getWifiStatus( WFstatus );
    WiFi.begin(  PrefSSID.c_str() , PrefPassword.c_str() );
    int WLcount = 0;
    while (  WiFi.status() != WL_CONNECTED && WLcount < 200 )
    {
      delay( 100 );
      Serial.printf(".");

        if (UpCount >= 60)  // keep from scrolling sideways forever
        {
           UpCount = 0;
           Serial.printf("\n");
        }
        ++UpCount;
        ++WLcount;
    }

    if( getWifiStatus( WFstatus ) == 3 )   //wifi returns
    { 
      // stop LED flasher, wifi going up
    }
   delay( 1000 );
  } // END WiFi down
} // END loop()


void wifiInit() //
{
  WiFi.mode(WIFI_AP_STA); // required to read NVR before WiFi.begin()

  // load credentials from NVR, a little RTOS code here
  wifi_config_t conf;
  esp_wifi_get_config(WIFI_IF_STA, &conf);     // load wifi settings to struct comf
  rssiSSID = reinterpret_cast<const char*>(conf.sta.ssid);
  password = reinterpret_cast<const char*>(conf.sta.password);

  //  Serial.printf( "SSID = %s\n", rssiSSID );  // un-comment for debuging
  //  Serial.printf( "Pass = %s\n", password );  // un-comment for debuging
  // Open Preferences with wifi namespace. Namespace is limited to 15 chars
  preferences.begin("wifi", false);
    PrefSSID     = preferences.getString("ssid", "none"); //NVS key ssid
    PrefPassword = preferences.getString("password", "none"); //NVS key password
  preferences.end();

  // keep from rewriting flash if not needed
  if( !checkPrefsStore() )   // see is NV and Prefs are the same
  {                          // not the same, setup with SmartConfig
    if( PrefSSID == "none" ) // New...setup wifi
    {
      initSmartConfig();
      delay( 3000);
      ESP.restart(); // reboot with wifi configured
    }
  }

  // I flash LEDs while connecting here

  WiFi.begin( PrefSSID.c_str() , PrefPassword.c_str() );

  int WLcount = 0;
  while (WiFi.status() != WL_CONNECTED && WLcount < 200 ) // can take > 100 loops depending on router settings
  {
    delay( 100 );
    Serial.printf(".");
    ++WLcount;
  }
  delay( 3000 );

  // stop the led flasher here

} // END wifiInit()

// match WiFi IDs in NVS to Pref store, assumes WiFi.mode(WIFI_AP_STA); was executed
bool checkPrefsStore()
{
  bool val = false;
  String NVssid, NVpass, prefssid, prefpass;

  NVssid = getSsidPass( "ssid" );
  NVpass = getSsidPass( "pass" );

  // Open Preferences with my-app namespace. Namespace name is limited to 15 chars
  preferences.begin("wifi", false);
    prefssid  =  preferences.getString("ssid",     "none"); //NVS key ssid
    prefpass  =  preferences.getString("password", "none"); //NVS key password
  preferences.end();

  if( NVssid.equals(prefssid) && NVpass.equals(prefpass) )
  { 
    val = true; 
  }
  return val;
} // END checkPrefsStore()

void initSmartConfig()
{
  // start LED flasher here
  int loopCounter = 0;

  WiFi.mode( WIFI_AP_STA );     //Init WiFi, start SmartConfig
  Serial.printf( "Entering SmartConfig\n" );

  WiFi.beginSmartConfig();

  while (!WiFi.smartConfigDone())
  { // flash led to indicate not configured
    Serial.printf( "." );
    if( loopCounter >= 40 )
    {
      loopCounter = 0;
      Serial.printf( "\n" );
    }
    delay(600);
    ++loopCounter;
  }
  loopCounter = 0;

  // stopped flasher here

  Serial.printf("\nSmartConfig received.\n Waiting for WiFi\n\n");
  delay(2000 );

  while( WiFi.status() != WL_CONNECTED )
  { // check till connected
     delay(500);
  }
  IP_info();

  preferences.begin("wifi", false); // put it in storage
    preferences.putString( "ssid" ,    getSsid);
    preferences.putString( "password", getPass);
  preferences.end();

  delay(300);
} // END SmartConfig()

void IP_info()
{
  getSsid = WiFi.SSID();
  getPass = WiFi.psk();
  rssi = getRSSI( rssiSSID );
  WFstatus = getWifiStatus( WFstatus );
  MAC = getMacAddress();

  Serial.printf( "\n\n\tSSID\t%s, ", getSsid.c_str() );
  Serial.print( rssi);  Serial.printf(" dBm\n" );  // printf??
  Serial.printf( "\tPass:\t %s\n", getPass.c_str() ); 
  Serial.print( "\n\n\tIP address:\t" );  Serial.print(WiFi.localIP() );
  Serial.print( " / " );              Serial.println( WiFi.subnetMask() );
  Serial.print( "\tGateway IP:\t" );  Serial.println( WiFi.gatewayIP() );
  Serial.print( "\t1st DNS:\t" );     Serial.println( WiFi.dnsIP() );
  Serial.printf( "\tMAC:\t\t%s\n", MAC.c_str() );
}  // END IP_info()

int getWifiStatus( int WiFiStatus )
{
  WiFiStatus = WiFi.status();
  Serial.printf("\tStatus %d", WiFiStatus );
  switch( WiFiStatus )
  {
    case WL_IDLE_STATUS : // WL_IDLE_STATUS = 0,
        Serial.printf(", WiFi IDLE \n");
        break;
    case WL_NO_SSID_AVAIL: // WL_NO_SSID_AVAIL = 1,
        Serial.printf(", NO SSID AVAIL \n");
        break;
    case WL_SCAN_COMPLETED: // WL_SCAN_COMPLETED = 2,
        Serial.printf(", WiFi SCAN_COMPLETED \n");
        break;
    case WL_CONNECTED: // WL_CONNECTED = 3,
        Serial.printf(", WiFi CONNECTED \n");
        break;
    case WL_CONNECT_FAILED: // WL_CONNECT_FAILED = 4,
        Serial.printf(", WiFi WL_CONNECT FAILED\n");
        break;
    case WL_CONNECTION_LOST: // WL_CONNECTION_LOST = 5,
        Serial.printf(", WiFi CONNECTION LOST\n");
        WiFi.persistent(false); // don't write FLASH
        break;
    case WL_DISCONNECTED: // WL_DISCONNECTED = 6
        Serial.printf(", WiFi DISCONNECTED ==\n");
        WiFi.persistent(false); // don't write FLASH when reconnecting
        break;
  }
  return WiFiStatus;
}  // END getWifiStatus()

// Get the station interface MAC address.
// @return String MAC
String getMacAddress(void)
{
  WiFi.mode(WIFI_AP_STA); // required to read NVR before WiFi.begin()
  uint8_t baseMac[6];
  esp_read_mac( baseMac, ESP_MAC_WIFI_STA ); // Get MAC address for WiFi station
  char macStr[18] = { 0 };
  sprintf(macStr, "%02X:%02X:%02X:%02X:%02X:%02X", baseMac[0], baseMac[1], baseMac[2], baseMac[3], baseMac[4], baseMac[5]);
  return String(macStr);
}  // END getMacAddress()

// Return RSSI or 0 if target SSID not found
// const char* SSID = "YOUR_SSID"; // declare in GLOBAL space
// call: int32_t rssi = getRSSI(SSID);
int32_t getRSSI( const char* target_ssid )
{
  byte available_networks = WiFi.scanNetworks();

  for (int network = 0; network < available_networks; network++)
  {
    if ( strcmp( WiFi.SSID( network).c_str(), target_ssid ) == 0)
    {
      return WiFi.RSSI( network );
    }
  }
  return 0;
} // END getRSSI()

// Requires; #include <esp_wifi.h>
// Returns String NONE, ssid or pass arcording to request
// ie String var = getSsidPass( "pass" );
String getSsidPass( String s )
{
  String val = "NONE"; // return "NONE" if wrong key sent
  s.toUpperCase();
  if( s.compareTo("SSID") == 0 )
  {
    wifi_config_t conf;
    esp_wifi_get_config( WIFI_IF_STA, &conf );
    val = String( reinterpret_cast<const char*>(conf.sta.ssid) );
  }
  if( s.compareTo("PASS") == 0 )
  {
    wifi_config_t conf;
    esp_wifi_get_config( WIFI_IF_STA, &conf );
    val = String( reinterpret_cast<const char*>(conf.sta.password) );
  }
  return val;
}  // END getSsidPass()

I noticed this as well, but never narrowed it down, But I noticed that reconnect() and begin(ssid..) does not always reset dhcp, edge case I think

Begin(args)
only redoes dhcp if config is not equal or not already connected, else it returns, which might be a problem.

    wifi_config_t current_conf;
    esp_wifi_get_config(WIFI_IF_STA, &current_conf);
    if(!sta_config_equal(current_conf, conf)) {
        if(esp_wifi_disconnect()){
            log_e("disconnect failed!");
            return WL_CONNECT_FAILED;
        }

        esp_wifi_set_config(WIFI_IF_STA, &conf);
    } else if(status() == WL_CONNECTED){
        return WL_CONNECTED;
    }
 // We do not always get here
    if(!_useStaticIp) {
        if(tcpip_adapter_dhcpc_start(TCPIP_ADAPTER_IF_STA) == ESP_ERR_TCPIP_ADAPTER_DHCPC_START_FAILED){
            log_e("dhcp client start failed!");
            return WL_CONNECT_FAILED;
        }
    } else {
        tcpip_adapter_dhcpc_stop(TCPIP_ADAPTER_IF_STA);
    }

@mickeypop thanks for sharing code. But i have one doubt.
As you said:
I proved this once buy adding a UDP call in some test code. - I could talk to the AP by UDP but had no IP address. At the same time the MAC showed up on the AP connection list.

but as far i know, we can not make UDP connection without having an IP. UDP is built on IP layer.

@jjassar

UDP does not require any IP at all, just it's own MAC.

UDP is where the magic in the SmartConfig is. The app on your cell sends a specially formatted UDP packet just for the ESP32 with the AP credentials.

Because UDP is Connectionless, all WiFi devices on or off the AP can see it.

When the ESP32 sees this, it sends a different UDP to the AP to get a connection and the IP address from the AP. Remember before the connect there is no IP.

UDP is the under layer used in DHCP to get the IP in the first place but is also used in many other ways.

@mickeypop is it possible, that you are mixing TCP/UDP with broadcast/multicast?
TCP and UDP both reside on transport layer, which is build on top of internet layer, where IP is.

@mickeypop @bedenko you both may be right, i think, it could be UDP broadcast on address 255.255.255.255.
Anyway, i have found a new issue with latest repo.
I was having an esp32 which was connected to AP, I switched off AP and Switched it back after some time.
On disconnection if the reason code is 201(REASON_NO_AP_FOUND) then it connects automatically
But sometimes the disconnection reason code 7(REASON_NOT_ASSOCED) then it never connects back, Only reconnect after hardware restart.
Why reason code 7 is coming if I have switched off AP?

Probably, because code 201 is resoved here, but code 7 is ignored.

@jjassar @bedenko

Think about it for a moment.
There has to be a protocol to connect BEFORE the device has an IP otherwise DHCP would not have any means to contact the DHCP server to "Get" an IP.

I was a Network Engineer for over 30 years and if UDP was not an integral part of TCP/IP you would have to re-setup IPs every time you moved to another network.

here's a little primer.

DHCP PROTOCOL

_DHCP protocol is a connectionless protocol using UDP_ Port 68 and 67. It operates on client & server model. The DHCP client is our device ( traveller ) and the DHCP server is the one who shall provide us the IP ( The innkeeper ).

DHCP operates on UDP because DHCP client works on broadcasts, which can only be supported by UDP. This is needed because the client machine has still not received an IP address (this is the DHCP negotiation protocol purpose) and there would not be any way to establish a TCP stream without the IP address itself.

DHCP client starts by broadcasting the DHCP DISCOVER packet. The broadcast is received by the DHCP Server(s), which in turn replies with the DHCP OFFER message. The DHCP OFFER message contains the IP address offered by the server and the time period for which the IP address is allocated (The IP may be random, or based on an admin policy).

The DHCP client may receive multiple DHCP OFFER messages, however it chooses only one DHCP OFFER message based on the policy configured in the DHCP Client. Usually its on the first come first serve basis. However we can configure the DHCP Client to choose the DHCP OFFER having the longest lease time or some preferred subnet. The DHCP client now replies with the DHCP REQUEST message.

The DHCP REQUEST message is a broadcast message. When other DHCP servers receive this message, they withdraw any offers that they might have made to the client and return the offered address to the pool of available addresses. The intended DHCP server on receiving the message sends a DHCP ACK message, thus confirming the transaction and allocating the IP to the host for the specified amount of time.

@mickeypop: i agree with your explanation, except with the fact, that UDP can operate without IP address. All DHCP negotiation is done on broadcast IP 255.255.255.255 (info).

@bedenko
You pretty much have to agree. I cut and pasted it directly from the official docs.

You are both right and wrong and here's why.

All network protocols use the same packet structure. AppleTalk, TCP/IP, Arpnet, AIX, etc... This let them coexist on the same ethernet without conflict.

The structure includes bits for protocol, type, checksum, destination etc... All look for the 24(255.255.255.255) bits in the destination identifier as a Special Identifier.

that said;

IP traffic is processed thru a Network Mask so all devices can determine if a packet is meant for them or not as well as routing.

UDP has no Network Mask. The 255.255.255.255 is not meant for the UDP sender or even used by them, it is so all other devices see the Special Identifier. It is not treated like an IP in this case at all.

NOTE: UDP sends by MAC not by IP.

Take DHCP for example, you don't have either IP or netmask yet, so the device goes into promiscuous mode looking for any packet with its own MAC address.

A DHCP DISCOVER packet is sent by UDP with the senders MAC address since the DHCP server must know who is requesting an IP.

The sender clearly cannot process it as IP traffic yet and to that end the DHCP server cannot use IP to send a response. Hence UDP.

The DHCP OFFER message returned by UDP must include the MAC for the client to know it is for them. Mind you all traffic is structured the same but it is not IP at all yet.

It is not until all negotiations are finished that any IP traffic is even possible.

=====
Seperatly, i should note;
I was on the team in 1968 - 70 developing the UNIX OS. There is where TCP/IP came to be.
We used an early draft of UDP before TCP/IP even existed.

@mickeypop Thanks for your work! We can all touch the Sky because we stand on the Shoulders of Giants!

Chuck.

Hi.
I use this code for this

  if (WiFi.status() != WL_CONNECTED)
{
  digitalWrite(26,0);
  WIFI_Connect();
} else {
  digitalWrite(26,1);
}

and, this is te function "WIFI_Connect"

void WIFI_Connect()
{
digitalWrite(26,HIGH);
WiFi.disconnect();
Serial.println("Reconectando WiFi...");
WiFi.mode(WIFI_AP_STA);
WiFi.begin(ssid, password);
// Wait for connection
for (int i = 0; i < 50; i++)
{
if ( WiFi.status() != WL_CONNECTED ) {
delay ( 500 );
digitalWrite(26,0);
Serial.print ( "." );
delay ( 500 );
digitalWrite(26,1);
}
}
digitalWrite(26,0);
}

For me this code work.
Obs: The version 2.3

include

include

define WIFI_SSID "===="

define WIFI_PASSWORD "==="

//this firebase project was deleted
//you'll need to enter your own firebase info

define FIREBASE_HOST "home-automation-1122.firebaseio.com"

define FIREBASE_AUTH "============"

define LED1 5

define LED2 4

define LED3 0

define LED4 2

define LED5 14

define LED6 12

define LED7 13

define LED8 15

void setup() {

pinMode(LED1,OUTPUT);

digitalWrite(LED1,0);

pinMode(LED2,OUTPUT);

digitalWrite(LED2,0);

pinMode(LED3,OUTPUT);

digitalWrite(LED3,0);

pinMode(LED4,OUTPUT);

digitalWrite(LED4,0);

pinMode(LED5,OUTPUT);

digitalWrite(LED5,0);

pinMode(LED6,OUTPUT);

digitalWrite(LED6,0);

pinMode(LED7,OUTPUT);

digitalWrite(LED7,0);

pinMode(LED8,OUTPUT);

digitalWrite(LED8,0);

Serial.begin(9600);

WiFi.begin(WIFI_SSID, WIFI_PASSWORD);

Serial.print("connecting");

while (WiFi.status() != WL_CONNECTED) {

Serial.print(".");

delay(500);

}

Serial.println();

Serial.print("connected: ");

Serial.println(WiFi.localIP());

Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH);

Firebase.setInt("LEDStatus",0);

}

void loop() {

if(Firebase.getInt("field1"))

{

digitalWrite(LED1,LOW);

}

else

{
digitalWrite(LED1,HIGH);

}
if(Firebase.getInt("field2"))

{

digitalWrite(LED2,LOW);

}

else

{

digitalWrite(LED2,HIGH);

}

if(Firebase.getInt("field3"))

{

digitalWrite(LED3,LOW);

}

else

{
digitalWrite(LED3,HIGH);

}

if(Firebase.getInt("field4"))

{

digitalWrite(LED4,LOW);

}

else

{

digitalWrite(LED4,HIGH);

}
if(Firebase.getInt("field5"))

{

digitalWrite(LED5,LOW);

}

else

{

digitalWrite(LED5,HIGH);

}
if(Firebase.getInt("field6"))

{

digitalWrite(LED6,LOW);

}

else

{

digitalWrite(LED6,HIGH);

}
if(Firebase.getInt("field7"))

{

digitalWrite(LED7,LOW);

}

else

{

digitalWrite(LED7,HIGH);

}
if(Firebase.getInt("field8"))

{

digitalWrite(LED8,LOW);

}

else

{

digitalWrite(LED8,HIGH);

}

//Serial.println(Firebase.getInt("led1"));
//Serial.println(Firebase.getInt("led2"));
//Serial.println(Firebase.getInt("led3"));
//Serial.println(Firebase.getInt("led4"));
//Serial.println(Firebase.getInt("led5"));
//Serial.println(Firebase.getInt("led6"));
//Serial.println(Firebase.getInt("led7"));
//Serial.println(Firebase.getInt("led8"));

Serial.println("...............");
if (Firebase.failed()) // Check for errors {

Serial.print("setting /number failed:");

Serial.println(Firebase.error());

return;

}

my nodemcu esp8226 not reconnect after connection lost til i re power it

This thread is for esp32. Are u using esp8266, or was it a typo?

esp82255 nodemcu

On Tue, 11 Sep 2018 1:45 PM Bedenko, notifications@github.com wrote:

This thread is for esp32. Are u using esp8266, or was it a typo?


You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/espressif/arduino-esp32/issues/653#issuecomment-420196435,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ApKpJ7SS4fk4KrHA1sVKmwV7brGVeh93ks5uZ3gxgaJpZM4PfOia
.

Sorry this is esp8266

On Tue, 11 Sep 2018 1:48 PM Ijaz Ahmad, conceptualboy2@gmail.com wrote:

esp82255 nodemcu

On Tue, 11 Sep 2018 1:45 PM Bedenko, notifications@github.com wrote:

This thread is for esp32. Are u using esp8266, or was it a typo?


You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/espressif/arduino-esp32/issues/653#issuecomment-420196435,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ApKpJ7SS4fk4KrHA1sVKmwV7brGVeh93ks5uZ3gxgaJpZM4PfOia
.

anyone here help me?

This thread is for a ESP32, not a 8266. Try a different repo.

can u help me please with 8226

@vseven how can i solve this problem?

@ijaz1122 look here if there is any issue that suits your problem. otherwise open a new one over there.
you currently asking for a solution on a different device. this is the wrong repo for your problem.

Hey all finally I get this code working to connect and reconnect my wifi/portable hotspot multiple times

Thanks to @ThiagoCas for his codes

`/************
Include Libraries
************/

include

/************
Define Constants
************/

define WIFISSID "==Your Wifi SSID==" // Put your WifiSSID here

define PASSWORD "==Your Password==" // Put your wifi password here

// constants won't change. Used here to set a pin number:
const int ledPin = 2;// the number of the LED pin

/************
Define Variables
************/
// Variables will change:
int ledState = LOW; // ledState used to set the LED

int interval = 100; // interval at which to blink (milliseconds)

// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMillis = 0; // will store last time LED was updated

/************
Auxiliar Functions
************/
void WIFI_Connect()
{
WiFi.disconnect();
Serial.println("Connecting to WiFi...");
WiFi.mode(WIFI_AP_STA);
WiFi.begin(WIFISSID, PASSWORD);

for (int i = 0; i < 60; i++)
{
if ( WiFi.status() != WL_CONNECTED )
{
delay ( 250 );
digitalWrite(ledPin, LOW);
Serial.print ( "." );
delay ( 250 );
digitalWrite(ledPin, HIGH);
}
}
if ( WiFi.status() == WL_CONNECTED )
{
Serial.println("");
Serial.println("WiFi Connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
digitalWrite(ledPin, 0);
}

/************
Main Functions
************/

void setup()
{
Serial.begin(115200);

// set the digital pin as output:
pinMode(ledPin, OUTPUT);
WIFI_Connect();
}

void loop()
{
unsigned long currentMillis = millis();

if (currentMillis - previousMillis >= interval)
{
if (WiFi.status() != WL_CONNECTED)
{
Serial.println("wifi disconnected ");
WIFI_Connect();
}
// save the last time you blinked the LED
previousMillis = currentMillis;
// if the LED is off turn it on and vice-versa:
if (ledState == LOW)
{
ledState = HIGH;
interval = 100;
}
else
{
ledState = LOW;
interval = 2500;
}
// set the LED with the ledState of the variable:
digitalWrite(ledPin, ledState);
}
}`

Newer firmware seems to help, gonna close this.

@vseven by newer firmware ... do you mean latest version from master of this library? I do not see new commits to master since Sep 26th so wonder if you are referring to something else.

Thanks for your clarification
Gaston

I opened this over a year ago now so yes, newer as in the last couple months.

Great. Thanks for the clarification. I'm not sure when I updated last (2 months ago?) but I never saw this error after the last update (and it used to happen once every couple of months). I thought I was being lucky but I now see that it was more than luck. ;)

Great job.
Gaston

Also this seems to help:

    esp_wifi_set_ps(WIFI_PS_NONE);

@vseven

Newer firmware seems to help, gonna close this.

Hello there,
I always thought platformio by updating the arduino-esp32 library was also able to update what you called the firmware. Am i wrong? I'm still suffering from this problem!

@vseven
Newer firmware seems to help, gonna close this.

Hello there,
I always thought platformio by updating the arduino-esp32 library was also able to update what you called the firmware. Am i wrong? I'm still suffering from this problem!

Same here. Would like to have a pointer to how to update firmware by platformio to get around the disconnect issue myself...

@vseven
Platform IO setup instructions and update are addressed here
https://github.com/espressif/arduino-esp32/blob/master/docs/platformio.md

a tid bit however: on both Arduino and Platform IO when i use git to update the SDK i have on some occasions found the update was not complete and had issues.

Rename the esp32 folder and re-install from a fresh git and i have always gotten a clean update.
Just follow their instructions.

@mickeypop: well, my platformio is on the latest stable version, but I still have the disconnect issue. Do you suggest using the stage or upstream versions instead? The stable was only updated a few days ago, by the way.

@Miq1 does this issue exist if only use IDF example?

I must confess that I am using the Arduino in Platformio environment only - I never dealt with the IDF. I will look into it today to see if I can set up a basic version of my application there.

Just for the records: I found that the workaround with disconnect() and subsequent begin() works for me if I do a mode(WIFI_OFF) and mode(WIFI_STA) in between. I am currently trying the reconnect 5 times in a row and would do an esp.restart() if all attempts failed, but so far no restart was necessary.

I observed a few restarts in the meantime, so the workaround seems not to be as effective.

Is there any update about this bug?

FWIW I see this often on ESP8266 units too - exact same symptoms. I've found I can change the connect quite drastically simply by orienting the unit differently - so it seems to be related to how the units (both ESP8266 and ESP32) respond to bad signal.

Given I am using NonOS and an ESP8266, the common denominator seems to be the low level networking below lwIP

(Using 1.0.4 version of Arduino-esp32)

I had the same problem here (using ESP32). Found that rebooting the router solves the problem... once. That is, after the reboot, the ESP32 is able to connect to the AP, get an IP address and stay connected, but if something causes the connection to fail (like rebooting the ESP32), the ESP32 then _is never able to connect to the AP again_.

The router is a TP-Link TL-MR2030 that I keep around for wired ethernet tests and has firmware that is hopelessly outdated by years and no newer official firmware exists.

However, if I try to use other APs, like some quite new Ubiquiti units at the office, the problem simply does not happen at all. I even raised some suspicion on the IT staff by forcing the board to purposely reboot and reconnect repeatedly as fast as possible for hours on end... and no trouble at all.

_So, in the end, while it is possible that something is wrong or incomplete in the ESP32's libraries, I am ready to put all the blame on the old router's firmware._ Time to get a new router for tests, not from TP-LINK, however.

I usually suspect dns for things like this. Or sometimes the router still thinks you are connected and never allows you to reconnect

No, the router is not to blame. At least in my case. Sure, it's not the newest (wnr2200) but with an up-to-date DD-WRT installed and several android, linux and windows devices working without issues.

To finally solve this issue for myself, I started over with a completely new implementation, based on WiFiClientEvents.ino - so it's event-based. I also read the newest commit messages of arduino-esp32 which revealed very recent but relevant commits. I had to do some debugging in WiFiGeneric.cpp and found that mode doesn't always do what's expected (https://github.com/espressif/arduino-esp32/issues/1306).

Final result: with a little patch on WiFiGeneric.cpp (see end of file), I was able to connect and disconnect several times to/from my AP - hurray :)

Let me know if you see something to improve.

/*
 * This is a very stable example of repeated connecting and disconnecting to/from a wifi access point on STA32
 * Unfortunately, it needs patching of the WiFiGeneric.cpp library file
 * Author: Daniel Alder, based on the example WiFiClientEvents.ino
 * Tested with Arduino 1.8.5 and 1.8.10 with ESP library from Nov 11 2019 (cec3fca4) + patch
*/

#include <WiFi.h>   

#include "HomeWifiConfig.h" // use an extra include or uncomment the following 2 lines
//const char* ssid     = "myssid"; // your network SSID (name of wifi network)
//const char* password = "****";   // your network password

typedef enum {
  MYSTATE_OFFLINE = 0,
  MYSTATE_CONNECTING,
  MYSTATE_ONLINE,
  MYSTATE_DISCONNECTING
} mystate_t;
mystate_t mystate = MYSTATE_OFFLINE;
long state_since = 0;

#define TIMEOUT_ONLINE     20  // reconnect after this [s] offline time
#define TIMEOUT_OFFLINE    20  // disconnect after this [s] online time
#define TIMEOUT_CONNECTING 20  // cancel connecting after this [s] without success

////////////////////////////////////////////////////////////////////////////////

long getUptime() {
  return esp_timer_get_time() / 1000000L;
}

void changeState(mystate_t state) {
  mystate = state;
  state_since = getUptime();
}

void WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info)
{
    Serial.printf("[WiFi-event] event: %d\n", event);

    switch (event) {
        case SYSTEM_EVENT_WIFI_READY: 
            Serial.println("WiFi interface ready");
            break;
        case SYSTEM_EVENT_SCAN_DONE:
            Serial.println("Completed scan for access points");
            break;
        case SYSTEM_EVENT_STA_START:
            Serial.println("WiFi client started");
            break;
        case SYSTEM_EVENT_STA_STOP:
            Serial.println("WiFi client stopped");
            changeState(MYSTATE_OFFLINE);
            break;
        case SYSTEM_EVENT_STA_CONNECTED:
            Serial.println("Connected to access point");
            break;
        case SYSTEM_EVENT_STA_DISCONNECTED:
            Serial.println("Disconnected from WiFi access point");
            break;
        case SYSTEM_EVENT_STA_AUTHMODE_CHANGE:
            Serial.println("Authentication mode of access point has changed");
            break;
        case SYSTEM_EVENT_STA_GOT_IP:
            Serial.print("Obtained IP address: ");
            //Serial.println(WiFi.localIP());
            //Serial.println("WiFi connected");
            //Serial.print("IP address: ");
            Serial.println(IPAddress(info.got_ip.ip_info.ip.addr));

            changeState(MYSTATE_ONLINE);

            break;
        case SYSTEM_EVENT_STA_LOST_IP:
            Serial.println("Lost IP address and IP address is reset to 0");
            //changeState(MYSTATE_OFFLINE);
            break;
        case SYSTEM_EVENT_STA_WPS_ER_SUCCESS:
            Serial.println("WiFi Protected Setup (WPS): succeeded in enrollee mode");
            break;
        case SYSTEM_EVENT_STA_WPS_ER_FAILED:
            Serial.println("WiFi Protected Setup (WPS): failed in enrollee mode");
            break;
        case SYSTEM_EVENT_STA_WPS_ER_TIMEOUT:
            Serial.println("WiFi Protected Setup (WPS): timeout in enrollee mode");
            break;
        case SYSTEM_EVENT_STA_WPS_ER_PIN:
            Serial.println("WiFi Protected Setup (WPS): pin code in enrollee mode");
            break;
        case SYSTEM_EVENT_AP_START:
            Serial.println("WiFi access point started");
            break;
        case SYSTEM_EVENT_AP_STOP:
            Serial.println("WiFi access point  stopped");
            break;
        case SYSTEM_EVENT_AP_STACONNECTED:
            Serial.println("Client connected");
            break;
        case SYSTEM_EVENT_AP_STADISCONNECTED:
            Serial.println("Client disconnected");
            break;
        case SYSTEM_EVENT_AP_STAIPASSIGNED:
            Serial.println("Assigned IP address to client");
            break;
        case SYSTEM_EVENT_AP_PROBEREQRECVED:
            Serial.println("Received probe request");
            break;
        case SYSTEM_EVENT_GOT_IP6:
            Serial.println("IPv6 is preferred");
            break;
        case SYSTEM_EVENT_ETH_START:
            Serial.println("Ethernet started");
            break;
        case SYSTEM_EVENT_ETH_STOP:
            Serial.println("Ethernet stopped");
            break;
        case SYSTEM_EVENT_ETH_CONNECTED:
            Serial.println("Ethernet connected");
            break;
        case SYSTEM_EVENT_ETH_DISCONNECTED:
            Serial.println("Ethernet disconnected");
            break;
        case SYSTEM_EVENT_ETH_GOT_IP:
            Serial.println("Obtained IP address");
            break;
        default: break;
    }
}

#include "esp_wifi.h" // only for fixWifiPersistencyFlag()
/**
 * Disable persistent mode, see https://github.com/espressif/arduino-esp32/issues/1393
 */
void fixWifiPersistencyFlag() {
  wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
  Serial.printf("cfg.nvs_enable before: %d\n", cfg.nvs_enable);
  cfg.nvs_enable = 0;
}

////////////////////////////////////////////////////////////////////////////////

void setup()
{
  Serial.begin(115200);
  Serial.println("-----------------------------------------");
  Serial.println("THIS IS: newWifiImplementationUsingEvents");
  Serial.println("-----------------------------------------");

  WiFi.persistent(false);
  fixWifiPersistencyFlag();

  //Serial.setDebugOutput(true); 
  //WiFi.printDiag(Serial); 

  // delete old config
  WiFi.disconnect(true);

  state_since = getUptime();

  delay(1000);

  // warning: only the last defined event handler gets events!
  WiFi.onEvent(WiFiEvent);

  Serial.println("End of setup");
}

bool firstTime = true;

void loop()
{
  long uptime = getUptime();
  if (mystate == MYSTATE_ONLINE && state_since + TIMEOUT_ONLINE < uptime) {
    Serial.println("Disconnecting NOW");
    changeState(MYSTATE_DISCONNECTING);
    WiFi.disconnect(true);
    WiFi.mode(WIFI_OFF);
  } else if (mystate == MYSTATE_OFFLINE && state_since+TIMEOUT_OFFLINE < uptime) {
    Serial.println("Connecting NOW");
    changeState(MYSTATE_CONNECTING);
    if (firstTime) {
      Serial.println("(firstTime)");
      WiFi.begin(ssid, password);
      firstTime = false;
    } else {
      // doesn't work without WiFiGeneric.cpp patch below
      WiFi.mode(WIFI_STA);
      WiFi.reconnect();
    }
  } else if (mystate == MYSTATE_CONNECTING && state_since+TIMEOUT_CONNECTING < uptime) {
    Serial.println("Cancelling NOW after no connect success");
    changeState(MYSTATE_DISCONNECTING);
    WiFi.disconnect(true);
    WiFi.mode(WIFI_OFF);
  }

  delay(1000);
  if (uptime % 10 == 0) {
    Serial.printf("uptime %d\n", uptime);
  }
}

/* PATH FOR LIBRARY
diff --git a/libraries/WiFi/src/WiFiGeneric.cpp b/libraries/WiFi/src/WiFiGeneric.cpp
index e562921..aab5805 100644
--- a/libraries/WiFi/src/WiFiGeneric.cpp
+++ b/libraries/WiFi/src/WiFiGeneric.cpp
@@ -483,8 +483,10 @@ void WiFiGenericClass::enableLongRange(bool enable)
 bool WiFiGenericClass::mode(wifi_mode_t m)
 {
     wifi_mode_t cm = getMode();
+    log_d("mode() cm=%d, m=%d", cm, m);
     if(cm == m) {
-        return true;
+        log_d("HACK: skip return true");
+        //return true;
     }
     if(!cm && m){
         if(!wifiLowLevelInit(_persistent)){
*/


/* ISSUES:
 *  
 * 1) The example WiFiClientEvents.ino says:
 * 
 *   WiFi.onEvent(WiFiEvent);
 *   WiFi.onEvent(WiFiGotIP, WiFiEvent_t::SYSTEM_EVENT_STA_GOT_IP);
 *   
 *   but the WiFiEvent function never receives a SYSTEM_EVENT_STA_GOT_IP!
 *   
 * 2) I used code from https://github.com/espressif/arduino-esp32/issues/1393 to fix the persistent config issue
 * 
 * 3) The list of events in WiFiClientEvents.ino (comment block) is missing an event. Same bug as fixed in 188560e7f33
 * 
 * 4) Without pathing of WiFiGeneric.cpp, the mode() function doesn't do anything anymore once WiFi it was initialized (not even connected)
 * 
 *   see also: https://github.com/espressif/arduino-esp32/issues/1306 (but the this patch is not yet mentioned there)
 * 
 * 5) just a note: there is a STA_LOST_IP event, 2 minutes after disconnecting. 
 *   So if you want to make your code stable, you should also test with TIMEOUT_OFFLINE > 130
 */

Has anyone wiresharked this?

Had a similar issue with an arduino wifi rev 2 (different hardware, but issues negotiating between ap's and the device was eerily similar.)

https://github.com/arduino/nina-fw/issues/14

@mrarmyant What do you expect to see using wireshark? I think we are talking about issues on OSI layers 1 and 2. Differently said: no SSID, no frequency, no packets

My code (above your post) runs stable since I posted it. But I don't think the problem is portable to something different than ESP* chips because it addresses issues of the ESP SDK, not Arduino

I blame issues like this on power supply

i wouldn't blame the PS, it's very unlikely unless you have a really weak supply this will not happen.

Wireshark is really useless here.

To understand you have to dig deep into the RTOS libraries where the real work is done, not the Arduino libs as they are a wrapper.

If you are using WiFi.reconnect() instead of WiFi.begin() you need to know a few things.

WiFi.begin() starts by setting all needed registers on the wifi chip and RTOS states before connecting, reconnect() does not.
This was reported over 2 years ago.

WiFi.reconnect() often makes only half of the connection, establishing a chip level MAC connection with UDP but never making the TCP/IP connection as these are separate protocols. This is due to needed states not being preset by reconnect() it simply assumes they are there.
This is why some of you are not getting the SYSTEM_EVENT_STA_GOT_IP on reconnect.

Remember; reconnecting is needed because the states have already changed.

I ALWAYS reconnect with WiFi.begin() and have never failed.

======
as to a reset not connecting and saying there is already a connection you need to know DHCP.
DHCP IP address is commonly re-established every 15 seconds.
Now let's say 2 second after reestablishing you press the reset.
The DHCP server isn't going to release the IP for another 13 seconds and on trying to connect it will report it in use.

A simple delay on boot before connecting has fixed this for me every time.
If you are setting up multiple other libraries, set them all first before WiFi.begin().

A good start timer will help here.
take a long var = millis(); in the first line of setup() and Serial.print( millis()-var); just before WiFi.begin() and find out just how fast you are actually booting. Then adjust accordingly.

I have been using the ESP32 for over 6 years and this has always worked.

UPDATE; i see a lot of WiFiEvent used and for debugging its good but to simply detect wifi down and reconnect the IF/ELSE below works reliably every time.

this works because it takes about 18 seconds from down to reporting WL_CONNECTED change, this gives the DHCP server time to release the IP for a reliable re connect later.

It has been working for over 6 years and counting.

loop()
{
  if ( WiFi.status() ==  WL_CONNECTED ) 
  {
    // WiFi is UP,  do what ever
  } else
  {
    // wifi down, reconnect here
   WiFi.begin(  );
    int WLcount = 0;
    while (WiFi.status() != WL_CONNECTED && WLcount < 200 ) 
    {
      delay( 100 );
         Serial.printf(".");
         if (UpCount >= 60)  // just keep terminal from scrolling sideways
         {
            UpCount = 0;
               Serial.printf("\n");
         }
         ++UpCount;
      ++WLcount;
    }
  }
} // END loop()

take a look at the skeleton code i posted on https://github.com/espressif/arduino-esp32/issues/1100

though it was for setup with SmartConfig it just works.

@mrarmyant What do you expect to see using wireshark? I think we are talking about issues on OSI layers 1 and 2. Differently said: no SSID, no frequency, no packets

My code (above your post) runs stable since I posted it. But I don't think the problem is portable to something different than ESP* chips because it addresses issues of the ESP SDK, not Arduino

I wasn't referring really to arduino, but the wifi soc that is onboard that particular unit. It had issues with reconnect based on being hinky with dhcp. Someone reported that restarting their router fixed it, which is the problem we had (well restarting a windows dhcp server). There was an issue with the way it was acknowledging wether or not it had been disconnected. Just thought it might help with those issues up there, because neither unit would ever show as connected on the reconnects, and wireshark showed us why. Static IP's had no problem. It ended up being the wifi soc firmware that had to be fixed to handle the delay mentioned for DHCP issues. All of which were discovered via wireshark.

Was this page helpful?
5 / 5 - 1 ratings

Related issues

0x1abin picture 0x1abin  ·  3Comments

OAXP picture OAXP  ·  4Comments

huming2207 picture huming2207  ·  4Comments

mistergreen picture mistergreen  ·  4Comments

ComputerLag picture ComputerLag  ·  3Comments