Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change of WiFi behavior after recent commit: disconnect(true) seems to *permanently* close WiFi #3522

Closed
mouridis opened this issue Nov 27, 2019 · 16 comments
Labels
Status: Stale Issue is stale stage (outdated/stuck)

Comments

@mouridis
Copy link
Contributor

Hardware:

Board: LOLIN32
Core Installation version: Latest commit (4846d9c)
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 (4846d9c). 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 e506136. Code stops working in commit 0cdfb0b.

By slimming down my code, this is a simple sketch to reproduce the issue:

#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 0cdfb0b) 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.

@TD-er
Copy link
Contributor

TD-er commented Dec 2, 2019

Maybe related to this issue: #1306 (comment) ?

@mouridis
Copy link
Contributor Author

mouridis commented Dec 2, 2019

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

@TD-er
Copy link
Contributor

TD-er commented Dec 2, 2019

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.

@mouridis
Copy link
Contributor Author

mouridis commented Dec 3, 2019

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.

@TD-er
Copy link
Contributor

TD-er commented Dec 3, 2019

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.

@mouridis
Copy link
Contributor Author

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.

@Rob58329
Copy link
Contributor

Rob58329 commented Dec 15, 2019

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 0cdfb0b ("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() {}

@Voha888
Copy link

Voha888 commented Jan 17, 2020

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

Rob58329 referenced this issue Feb 23, 2020
* Add support for WiFi long range mode

* Update WiFiGeneric.cpp
@maribeiro
Copy link

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;
}

@olonsoft
Copy link

olonsoft commented May 3, 2020

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);

@mouridis
Copy link
Contributor Author

mouridis commented Jun 9, 2020

@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?

@lbernstone
Copy link
Contributor

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){

@Rob58329
Copy link
Contributor

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

@bojh
Copy link

bojh commented Jun 16, 2020

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

mouridis added a commit to mouridis/arduino-esp32 that referenced this issue Jun 24, 2020
This commit fixes issue espressif#3522 where WiFi service fails to start after a WiFi.disconnect(true) or a WiFi.mode(WIFI_OFF).
@stale
Copy link

stale bot commented Aug 15, 2020

[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 stale bot added the Status: Stale Issue is stale stage (outdated/stuck) label Aug 15, 2020
@stale
Copy link

stale bot commented Aug 29, 2020

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

@stale stale bot closed this as completed Aug 29, 2020
me-no-dev pushed a commit that referenced this issue Sep 30, 2020
This commit fixes issue #3522 where WiFi service fails to start after a WiFi.disconnect(true) or a WiFi.mode(WIFI_OFF).
alorbach added a commit to alorbach/arduino-esp32 that referenced this issue Dec 4, 2020
crossan007 pushed a commit to crossan007/arduino-esp32 that referenced this issue Dec 22, 2020
…ssif#4114)

This commit fixes issue espressif#3522 where WiFi service fails to start after a WiFi.disconnect(true) or a WiFi.mode(WIFI_OFF).
geeksville added a commit to meshtastic/arduino-esp32 that referenced this issue Dec 23, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Stale Issue is stale stage (outdated/stuck)
Projects
None yet
Development

No branches or pull requests

8 participants