Arduino-esp32: Change of WiFi behavior after recent commit: disconnect(true) seems to *permanently* close WiFi

Created on 27 Nov 2019  路  16Comments  路  Source: espressif/arduino-esp32

Hardware:

Board: LOLIN32
Core Installation version: Latest commit (4846d9c1862f38b8a7c50e5590dbcf70d21f77f8)
IDE name: Arduino IDE / VSCode
Flash Frequency: 80Mhz
PSRAM enabled: no
Upload Speed: 921600
Computer OS: Win10-x64

Description:

An old piece of code that worked for some time stopped working after updating core to latest commit (4846d9c1862f38b8a7c50e5590dbcf70d21f77f8). More specifically calls to WiFi.scanNetworks() failed with messages like this in the serial:
```
E (8376) wifi: esp_wifi_scan_start 1245 wifi not start
-2
E (9563) wifi: esp_wifi_scan_start 1245 wifi not start
-2

By git bisecting, I found the last core version that my code works to be commit e50613622e3d9dc3f7204b2c24f53ab026cc756f. Code stops working in commit 0cdfb0b193d9bf04adc50bf0d6020e95a28f7d21.

By slimming down my code, this is a simple sketch to reproduce the issue:
```cpp
#include <WiFi.h>
#include <HTTPClient.h>

void setup() {
  Serial.begin(115200);
  WiFi.persistent(false);
  WiFi.setAutoConnect(false);
  WiFiCheck();
}

void loop() {
  boolean trigger = false;
  while (Serial.available() > 0) {
    String temp = String(Serial.read());
    trigger = true;
  }
  if (trigger) {
    Serial.println(WiFi.scanNetworks());
  }
}


void WiFiCheck() {
  WiFi.mode(WIFI_STA);
  if (!connectToAP()) return;
  getPayloadFromServer();
  WiFi.disconnect(true);
}


boolean connectToAP() {
  Serial.printf("Attempting AP connection (10 sec timeout).\n");
  WiFi.begin("YourSSID", "YourPass");
  for (uint8_t i = 0; i < 10; i++) {
    if (WiFi.status() == WL_CONNECTED) break;
    delay(1000);
  }
  return (WiFi.status() == WL_CONNECTED);
}


void getPayloadFromServer() {
  HTTPClient http;
  Serial.printf("Sending HTTP GET request to remote server.\n");
  http.begin("http://ip-api.com/json/");
  if (http.GET() == HTTP_CODE_OK) {
    Serial.printf("Server responded with requested payload: %s\n", http.getString().c_str());
  } else {
    Serial.printf("Server could not be reached or server did not reply to GET request with a valid payload.\n");
  }
  http.end();
}

It initially attempts to send a HTTP GET request to a server and get the payload (successfully). After that it calls WiFi.disconnect(true) to disconnect and set WiFi mode to WIFI_OFF. It then waits for anything in the Serial to call WiFi.scanNetworks() and output the number of found networks.

That call fails in recent core commits (after 0cdfb0b193d9bf04adc50bf0d6020e95a28f7d21) and succeeds in older ones, hence the change in behavior.

Now, one could argue that this is a fix and not an issue, because WiFi is off after disconnect(true), so it's normal for scanNetworks() to fail. But it seems that scanNetworks() fails even if you try to change the WiFi mode to WIFI_STA again, which should not happen.

Just replace the loop() above with this one:

void loop() {
  boolean trigger = false;
  while (Serial.available() > 0) {
    String temp = String(Serial.read());
    trigger = true;
  }
  if (trigger) {
    WiFi.mode(WIFI_STA);
    Serial.println(WiFi.scanNetworks());
    WiFi.mode(WIFI_OFF);
  }
}

This still fails.

I also tried WiFi.mode(WIFI_MODE_STA) and WiFi.enableSTA(true) instead of WiFi.mode(WIFI_STA) but WiFi.scanNetworks() always fails with the above message in the Serial.

Now, until that time, I thought this issue was specific to WiFi.scanNetworks(). Then I replaced it in the loop() with a call to WiFiCheck() - the same function that is called successfully in setup().

void loop() {
  boolean trigger = false;
  while (Serial.available() > 0) {
    String temp = String(Serial.read());
    trigger = true;
  }
  if (trigger) {
    WiFiCheck();
  }
}

These calls to WiFiCheck() fail.

It seems that after the initial disconnect(true), there is no way to change the WiFi mode again.

stale

Most helpful comment

I had a similar issue on my ESP32 with "WiFi.mode(WIFI_STA);" not turning the WIFI back on after a "WiFi.mode(WIFI_OFF);" (and causing a "esp_wifi_disconnect 1153 wifi not start" error message.)

As identified above by @mouridis (#3522) , this error was introduced by commit https://github.com/espressif/arduino-esp32/commit/0cdfb0b193d9bf04adc50bf0d6020e95a28f7d21 ("Add support for WiFi long range mode (#3190)" dated 6Oct19).

The solution I found was to change a single line in the "WiFiGeneric.cpp" file back to the original line as follows:

From the new:

wifi_mode_t WiFiGenericClass::getMode()
{
    if(!lowLevelInitDone){
        return WIFI_MODE_NULL;
    }

Back to the original:

wifi_mode_t WiFiGenericClass::getMode()
{
  if(!_esp_wifi_started){
        return WIFI_MODE_NULL;
    }

@me-no-dev: I am unsure if this will effect the "WiFi long range mode" code, but it certainly fixes my ""esp_wifi_disconnect 1153 wifi not start" error.

PS. A simple sketch to demonstrate this issue is as follows:

#include <WiFi.h>
const char* ssid     = "xxx"; // your network SSID (name of wifi network)
const char* password = "yyy"; // your network password

void setup() {
  Serial.begin(115200); delay(100);
  Serial.println("\nWait 3s"); delay(3000);
  Serial.print("\nAttempting to connect to SSID.");
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {Serial.print("."); delay(1000);}
  Serial.println("Connected ok");
  delay(5000);
  Serial.println("Wifi.disconnect..."); WiFi.disconnect(); delay(5);
  Serial.println("WiFi.mode(WIFI_OFF)..."); WiFi.mode(WIFI_OFF);
  delay(5000);
  Serial.println("WiFi.mode(WIFI_STA)..."); WiFi.mode(WIFI_STA); delay(1000);
  Serial.print("\nAttempting to connect to SSID for a 2nd time (this is where it might fail).");
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {Serial.print("."); delay(1000);}
  // with ESP32-arduino-github as at 23Nov19, this sketch hangs on the
  // above line with the error "esp_wifi_disconnect 1153 wifi not start"
  // (unless the "WiFiGeneric.cpp" file is edited as described in above post)
  Serial.println("Connected ok");
  delay(5000);
  WiFi.disconnect(); delay(5); Serial.println("Wifi.disconnect (you can press the 'reset' button now)"); 
  // NB. you must "WiFi.disconnect()" before 'reset'ing, as otherwise you
  // will get the "E (16544) wifi: Set status to INIT" wifi-error.
}

void loop() {}

All 16 comments

Well, there may be some relation but it's not the same issue because the code above worked fine up until 0cdfb0b193d9bf04adc50bf0d6020e95a28f7d21 which was released like 1.5 month ago, while #1306 dates back to 2018.

I set my build back to 1.11.0, which is dated right before the commit you linked and I do still see similar issues.
After connect/reconnect it does take quite a few disconnect/reconnect attempts to be able to have a proper TCP/IP setup so it seems.
The webserver remains unresponsive and the MQTT client on the node cannot connect to the browser.
I do see a lot of WiFi disconnect events when it tries to connect. Some as soon as 2 - 4 msec after the initial connection to the AP is made.

1.11.0? There's no 1.11.0 release. Do you mean 1.0.1? If so, that's kind of old.

And no matter what build you used, it seems you are talking for some other unrelated issue. I'm not talking about delays to connect sometimes or periodic instabilities. The OP describes an easily reproducible situation 100% of the times, where WiFi is totally dead. No delays - no, "sometimes it kinda works". Any WiFi call returns immediately with an error mentioning "wifi not start". It never gets to a point that makes sense discussing about TCP/IP and MQTT. It seems you experience issues unrelated to mine.

1.11.0? There's no 1.11.0 release. Do you mean 1.0.1? If so, that's kind of old.

I think I mixed the PlatformIO numbers then.

I would really appreciate it if someone could acknowledge that this is indeed a general issue and doesn't occur only on me. The original post contains code you can copy/paste , edit one line for your access point credentials and immediately confirm if you experience the issue or not.

I had a similar issue on my ESP32 with "WiFi.mode(WIFI_STA);" not turning the WIFI back on after a "WiFi.mode(WIFI_OFF);" (and causing a "esp_wifi_disconnect 1153 wifi not start" error message.)

As identified above by @mouridis (#3522) , this error was introduced by commit https://github.com/espressif/arduino-esp32/commit/0cdfb0b193d9bf04adc50bf0d6020e95a28f7d21 ("Add support for WiFi long range mode (#3190)" dated 6Oct19).

The solution I found was to change a single line in the "WiFiGeneric.cpp" file back to the original line as follows:

From the new:

wifi_mode_t WiFiGenericClass::getMode()
{
    if(!lowLevelInitDone){
        return WIFI_MODE_NULL;
    }

Back to the original:

wifi_mode_t WiFiGenericClass::getMode()
{
  if(!_esp_wifi_started){
        return WIFI_MODE_NULL;
    }

@me-no-dev: I am unsure if this will effect the "WiFi long range mode" code, but it certainly fixes my ""esp_wifi_disconnect 1153 wifi not start" error.

PS. A simple sketch to demonstrate this issue is as follows:

#include <WiFi.h>
const char* ssid     = "xxx"; // your network SSID (name of wifi network)
const char* password = "yyy"; // your network password

void setup() {
  Serial.begin(115200); delay(100);
  Serial.println("\nWait 3s"); delay(3000);
  Serial.print("\nAttempting to connect to SSID.");
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {Serial.print("."); delay(1000);}
  Serial.println("Connected ok");
  delay(5000);
  Serial.println("Wifi.disconnect..."); WiFi.disconnect(); delay(5);
  Serial.println("WiFi.mode(WIFI_OFF)..."); WiFi.mode(WIFI_OFF);
  delay(5000);
  Serial.println("WiFi.mode(WIFI_STA)..."); WiFi.mode(WIFI_STA); delay(1000);
  Serial.print("\nAttempting to connect to SSID for a 2nd time (this is where it might fail).");
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {Serial.print("."); delay(1000);}
  // with ESP32-arduino-github as at 23Nov19, this sketch hangs on the
  // above line with the error "esp_wifi_disconnect 1153 wifi not start"
  // (unless the "WiFiGeneric.cpp" file is edited as described in above post)
  Serial.println("Connected ok");
  delay(5000);
  WiFi.disconnect(); delay(5); Serial.println("Wifi.disconnect (you can press the 'reset' button now)"); 
  // NB. you must "WiFi.disconnect()" before 'reset'ing, as otherwise you
  // will get the "E (16544) wifi: Set status to INIT" wifi-error.
}

void loop() {}

I am using Ethernet LAN8720. After disconnecting WiFi and trying to reconnect, I got an error every time. I tried some tips, but nothing helped. I accidentally discovered that if you turn on the access point mode, turn off Wifi again, then after that the connection will be successful

I can confirm that using the following code to disable wifi after using it:
WiFi.disconnect(true);
WiFi.mode(WIFI_OFF);

and then trying to connect to WiFi again with:
WiFi.mode(WIFI_STA);
WiFi.begin(.....)

fails with errors:
E (2690) wifi: esp_wifi_disconnect 1153 wifi not start
[E][WiFiSTA.cpp:158] begin(): disconnect failed!

With @Rob58329 's fix, it works:

wifi_mode_t WiFiGenericClass::getMode()
{
if(!_esp_wifi_started){
return WIFI_MODE_NULL;
}

I have the same problem:

void p(int n) {
  Serial.println(n);
}

void test() {
  Serial.println(WiFi.getMode());
  WiFi.persistent(false);    p(1);
  WiFi.disconnect(true);     p(2);
  WiFi.enableSTA(true);      p(3);
  WiFi.begin(... ...);       p(4);
}
Result:
1  <--- mode WIFI_MODE_STA
1

That's all. Stops at WiFi.disconnect(true);

@me-no-dev The workaround that @Rob58329 mentioned in the comment above seems to work for us having this issue. The question is, is this a general solution or is it just a workaround that works for us but breaks other use cases? I guess bottom line is, if a PR is submitted with this, will it be accepted?

I think he was trying to avoid a crash that can occur if you ask for the state before the device has been initialized. Submit it with if(!lowLevelInitDone || !_esp_wifi_started){

The @lbernstone alterative
" if(!lowLevelInitDone || !_esp_wifi_started){ "
works fine for me!

Have found this behaviour also last week!
Thank's: Does work for me too.

[STALE_SET] This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 14 days if no further activity occurs. Thank you for your contributions.

[STALE_DEL] This stale issue has been automatically closed. Thank you for your contributions.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

huming2207 picture huming2207  路  4Comments

AsafFisher picture AsafFisher  路  4Comments

Darkhub picture Darkhub  路  3Comments

ComputerLag picture ComputerLag  路  3Comments

Curclamas picture Curclamas  路  4Comments