espressif / arduino-esp32

Arduino core for the ESP32
GNU Lesser General Public License v2.1
13.65k stars 7.41k forks source link

WiFi.disconnect(true) problem #400

Closed bbx10 closed 7 years ago

bbx10 commented 7 years ago

WiFi.disconnect(true) does not erase stored SSID and password.

The connection should fail because WiFi.disconnect(true) should erase the stored SSID and password. But the connection succeeds. Two error messages also appear. See the end.

#include <WiFi.h>

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

  WiFi.disconnect(true);

  WiFi.begin();
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print('.');
  }
  Serial.println();
  Serial.println("Connected");
}

void loop() {
}

Console output.

E (289) wifi: esp_wifi_set_config 977 wifi is not init
E (289) wifi: esp_wifi_set_config 977 wifi is not init
..
Connected
WioSwitch commented 7 years ago

include

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

//WiFi.disconnect(true); //WiFi.disconnect();

WiFi.begin(); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print('.'); } Serial.println(); Serial.println("Connected"); Serial.print("IP Address: "); Serial.println(WiFi.localIP()); WiFi.disconnect(); }

void loop() { ESP.restart(); }

bbx10 commented 7 years ago

@me-no-dev The commit eliminates the error messages but the SSID and password are not erased. The test program connects successfully. The same test code on ESP8266 erases SSID/password so the connection attempt fails. Some programs such as WiFiManager use WiFi.disconnect(true) in a similar way.

me-no-dev commented 7 years ago

I know what it's supposed to do, it's strange that it does not. https://github.com/espressif/arduino-esp32/blob/master/libraries/WiFi/src/WiFiSTA.cpp#L257-L263 you can see i the code that first bytes of ssid and pass are set to 0 (strange that I do it twice... did not notice) and that should effectively erase the old values

bbx10 commented 7 years ago

@me-no-dev I found WiFi.disconnect(true) erases ssid and password when it is called after connecting to the AP.

  //WiFi.disconnect(true);  // FAILS

  WiFi.begin();
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print('.');
  }
  Serial.println();
  Serial.println("Connected");

  WiFi.disconnect(true);  // Erases SSID/password
me-no-dev commented 7 years ago

OK this is a good clue!

me-no-dev commented 7 years ago

Can you try the latest code please?

bbx10 commented 7 years ago

@me-no-dev Thanks, I tried the fix but the SSID and password are still present. Here is a complete program in case anyone else wants to try.

#ifdef ESP8266
#include <ESP8266WiFi.h>
#else
#include <WiFi.h>
#endif

void setup() {
  Serial.begin(115200);
  Serial.println("\nTesting WiFi.disconnect(true)");

  // This should erase the SSID and password so the connection
  // attempt fails. This works on ESP8266
  WiFi.disconnect(true);

//  WiFi.begin("yourSSID", "password");
  WiFi.begin();
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print('.');
  }
  Serial.println();
  Serial.println("Connected: FAIL because SSID/password should have been erased.");

  //WiFi.disconnect(true);  // Erases SSID/password on ESP32
}

void loop() {
  // Nothing to see here.
}
gjt211 commented 7 years ago

@me-no-dev , Sorry to comment on a closed issue, but I am not able to identify why this has been closed? The problem still exists and WiFi.disconnect(true); still does not erase ssid & password on ESP32.

Maybe I am missing something?

The @bbx10 helpful version of wifiManager still have the same problem of not being able to clear the values. There is a comment in bbx10's wifimanager.cpp on line 355 indicating such and references this exact issue for reference. https://github.com/bbx10/WiFiManager/blob/901692a0329b7d36f9e10c18a30faee1fc1b69cc/WiFiManager.cpp#L355

I would like to help fix this, but don't know how or where to start. Thank you for taking your time to read my question.

bbx10 commented 7 years ago

@gjt211 @me-no-dev I found calling WiFi.disconnect(true) after a successful connection erases the SSID/password so the next connection attempt fails. But calling it before the connection attempt has no effect.

gjt211 commented 7 years ago

@bbx10, thank you for the info. I have been digging further into the source files and your comments appear to be the expected results. I will confirm tonight.

Just to clarify, What would happen if there is no successful connection?

As an example, say I set the SSID and password at my home (using your wifiManager), then I power down and take it to a new location. At the new location, I am not able to connect because I need to enter the new SSID and password. I have a button I press on the ESP32 that I want to erase the previous SSID & password so it would then become an AP and allow reconfiguration.

bbx10 commented 7 years ago

@gjt211 When the connection fails, WiFiManager goes into softAP mode with its HTTP interface and waits for the user to enter SSID/password. An erase button is mostly useful for testing so you can force the ESP32 into a fresh-out-of-the-box mode.

me-no-dev commented 7 years ago

in essence WiFi.disconnect sets the ssid and password to empty strings... maybe the issue is deeper into the ESP WiFi stack...

me-no-dev commented 7 years ago

OK had a conversation with the WiFi guys and they will fix this after the Chinese national holiday (ends october 8th) :) So look for it in the middle of next month :P

gjt211 commented 7 years ago

@bbx10, thanks again. The fresh-out-of-box mode sounds exactly right. It is a way for a user to reset the device to 'factory defaults' which is something you would expect in a commercial product.

The problem with the "When the connection fails" is not the only consideration from my point of view. Lets say I am connected to one access point, but I want to reset the device and connect to a different access point at the same location. I would need to turn off the currently connected access point just so the softAP mode would start.

@me-no-dev, that sounds fantastic. My ESP32 based boards will be arriving about then, so fingers crossed my updated sensor hardware will do what I think they should. Does that mean this issue that has been closed should be reopened? From what it seems, the problem is not yet fixed, or have I missed something?

me-no-dev commented 7 years ago

do as you wish but make sure you close it after it's fixed :D

carbocation commented 6 years ago

Checking in to see if progress has been made here. Thanks!

salocinx commented 6 years ago

Had experienced same problems. Is the fix already online?

eirikso commented 6 years ago

I am currently setting up several ESP32 where I need a WiFiManager. So I have started testing tis port: https://github.com/zhouhan0126/WIFIMANAGER-ESP32

It works pretty OK. I have done two edits to make it work properly:

1. A change in WiFiAP.cpp so that the captive portal pops up automatically (it is not very user friendly to have people entering 192.168.4.1 in their browser). This edit fixed it on all the devices I have tested. The problem is described here: https://github.com/zhouhan0126/WIFIMANAGER-ESP32/issues/2

You simply paste these three lines from line 95 in WiFiAP.cpp:

tcpip_adapter_dns_info_t dns_info; dns_info.ip.u_addr.ip4.addr = IPAddress(192,168,4,1); tcpip_adapter_set_dns_info(TCPIP_ADAPTER_IF_AP, TCPIP_ADAPTER_DNS_MAIN, &dns_info);

2. A change in WiFiManager.cpp to make sure that the ESP32 connects automatically after the user have entered SSID and PWD. Before this change I had to reset the ESP32 after entering the credentials.

Add this at line 216: ESP.restart(); delay(1000);

This problem is described here: https://github.com/zhouhan0126/WIFIMANAGER-ESP32/issues/1

With these two edits it seems like WIFIMANAGER-ESP32 works good. My only problem is the fact that it is impossible to delete the credentials before a connection is OK. I would very much like to be able to set up the ESP32 so that there is a "factory reset" option at startup.

Does anyone here know if there is a fix for that now?

eirikso commented 6 years ago

I don't know if this helps anyone, but it is the same for these:

Serial.println( WiFi.SSID() ); Serial.println( WiFi.psk() );

They return rubbish if called before a connection is made and return what they are supposed to do if called after the connection is made.

JoranoP commented 6 years ago

I have make a mistake by testing. The WiFiManager work well on esp32!

jwktje commented 6 years ago

@eirikso What would be your best advice at this point? I've been developing an ESP32 based solution that needs WifiManager and found this Github issue after looking around for a solution. Just stick with ESP8266 for now?

tferrin commented 6 years ago

@me-no-dev, you wrote:

OK had a conversation with the WiFi guys and they will fix this after the Chinese national holiday (ends october 8th) :) So look for it in the middle of next month :P

I don't think this ever happened. Behavior is the same today using the latest version from the repository.

paulobriennz commented 6 years ago

hi @eirikso - thanks for your feedback on using the ESP32 port of WifiManager - what board are you using? I'm using a Wemos Lolin and cant get the thing to save the credentials, it always says connection fails

anwarbashir commented 6 years ago

@eirikso, I can not find the file WiFiAP.cpp in this repository, please could you advise where to look for it?

anwarbashir commented 6 years ago

Can anyone help, I was connecting to WiFI via AP fine on my local WiFI network, then I moved elsewhere and managed to get a connection, but now I am unable to get my local connection to work again. I think the controller is holding onto the previous details and I need to remove them, tried using and then commenting out wifiManager.resetSettings but this has not worked, see console output below and my code below that. Can anyone help?

G.VGQe@�B␏{ k�&@"␇�9&�A�rG6�0�WM: settings invalidated WM: THIS MAY CAUSE AP NOT TO START UP PROPERLY. YOU NEED TO COMMENT IT OUT AFTER ERASING THE DATA. WM: WM: AutoConnect WM: Connecting as wifi client... WM: Using last saved values, should be faster WM: Connection result: WM: 1 WM: SET AP STA WM: WM: Configuring access point... WM: AutoConnectAP WM: AP IP address: WM: 192.168.4.1 WM: HTTP server started WM: Request redirected to captive portal WM: Request redirected to captive portal WM: Handle root WM: Request redirected to captive portal WM: Scan done WM: DUP AP: Virgin Media WM: VM575052-2G WM: -37 WM: Virgin Media WM: -38 WM: BTHomeSpot-RS2 WM: -86 WM: VM281786-2G WM: -93 WM: VM2949610 WM: -94 WM: Sent config page WM: WiFi save WM: Sent wifi save page WM: Connecting to new AP WM: Connecting as wifi client... WM: Connection result: WM: 1 WM: Failed to connect. WM: Request redirected to captive portal WM: Request redirected to captive portal WM: Request redirected to captive portal WM: Request redirected to captive portal WM: Request redirected to captive portal

After commenting out wifiManger.resetSetting();

�4����F�V#␏␑�T�n4"�AD$Wdd~ ���#�WM: WM: AutoConnect WM: Connecting as wifi client... WM: Using last saved values, should be faster WM: Connection result: WM: 1 WM: SET AP STA WM: WM: Configuring access point... WM: AutoConnectAP WM: AP IP address: WM: 192.168.4.1 WM: HTTP server started WM: Request redirected to captive portal WM: Request redirected to captive portal WM: Request redirected to captive portal WM: Handle root WM: Request redirected to captive portal WM: Request redirected to captive portal WM: Handle root WM: Request redirected to captive portal WM: WiFi save WM: Sent wifi save page WM: Connecting to new AP WM: Connecting as wifi client... WM: Connection result: WM: 1 WM: Failed to connect.

My code is simply as follows running on ESP32DEV:

//Coded for ESP32 only

include

include

include //https://github.com/tzapu/WiFiManager

void setup() { // put your setup code here, to run once: Serial.begin(9600);

//WiFiManager
//Local intialization. Once its business is done, there is no need to keep it around
WiFiManager wifiManager;
//reset saved settings
//wifiManager.resetSettings();
wifiManager.autoConnect("AutoConnectAP");
Serial.println("connected...yeey :)");

}

void loop() { // put your main code here, to run repeatedly:

}

RobbesU commented 6 years ago

@bbx10, @me-no-dev, This issue seems to be still happening. Maybe this helps finding the root. I can workaround to the WiFi.disconnect(true) still not forgetting the ssid/pwd, by adding this line to bbx10's test code 22-June-17 above

  WiFi.disconnect(true);   // still not erasing the ssid/pw. Will happily reconnect on next start
  WiFi.begin("0","0");       // adding this effectively seems to erase the previous stored SSID/PW
  ESP.restart();
  delay(1000);

I also use this with wifiManager and this does the trick for me to force wifiManager to go into AP mode and fresh setup. WiFiManager library the latest (tzapu) WiFiManager in latest development branch.

wzaggle commented 6 years ago

I linked to the core esp_wifi.h and then did an esp_wifi_set_auto_connect(false); prior to calling wifiManager and it does cause the ESP32 to skip trying to use prior credentials.

wei48221 commented 6 years ago

Thanks to the tip from RobbesU. I was struggling with this issue and I solved it with WiFi.begin("0","0");

androdlang commented 6 years ago

Same to me, solved with WiFi.begin("0","0"); Thanks to the tip from RobbesU.

saigajul commented 6 years ago

I have found the clean and best and 100% working solution for it esp_wifi_restore(); delay(1000); ESP.restart(); this will remove all previous saved credentials if your are using wifimanager make handleReset() public to make that fuction avaliable anywhere

void WiFiManager::handleReset() {

if(server != NULL) { DEBUG_WM(F("Reset"));

String page = FPSTR(HTTP_HEAD_W); page.replace("{v}", "Info"); page += FPSTR(HTTP_SCRIPT); page += FPSTR(HTTP_STYLE); page += _customHeadElement; page += FPSTR(HTTP_HEAD_END); page += F("Module will reset in a few seconds."); page += FPSTR(HTTP_END);

server->sendHeader("Content-Length", String(page.length())); server->send(200, "text/html", page);

DEBUG_WM(F("Sent reset page")); delay(5000); }

if defined(ESP8266)

WiFi.disconnect(true); delay(1000); ESP.reset();

else

esp_wifi_restore(); delay(1000);** ESP.restart();

endif

delay(2000); }

it will work ...

Daemach commented 5 years ago

How did this thread get hijacked to wifimanager support?

Daemach commented 5 years ago

WiFi.disconnect(true, true); AFTER wifi is connected works.

n4rf commented 5 years ago

After reverse-engineering the ESP32 library I found a "quick-n-dirty" way to erase the saved WiFi Credentials.

Initially, WiFi.disconnect() does not work unless, your are connected, of course, but I needed a way to erase credentials because I am using Wifimanager and since I was not connected, and needed to save a new one, old credentials messed up the AP and STA mode, hence, I needed to erase previous saved credentials.

the trick is quite simple and it was in front of my eyes the whole time.

        wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); //load the flash-saved configs
        esp_wifi_init(&cfg); //initiate and allocate wifi resources (does not matter if connection fails)
        delay(2000); //wait a bit
        if(esp_wifi_restore()!=ESP_OK)
        {
            Serial.println("WiFi is not initialized by esp_wifi_init ");
         }else{
             Serial.println("WiFi Configurations Cleared!");
         }
         //continue
        delay(1000);
        esp_restart(); //just my reset configs routine...

And that will erase the previously saved WiFi credentials.

4ngelica commented 3 years ago

After reverse-engineering the ESP32 library I found a "quick-n-dirty" way to erase the saved WiFi Credentials.

Initially, WiFi.disconnect() does not work unless, your are connected, of course, but I needed a way to erase credentials because I am using Wifimanager and since I was not connected, and needed to save a new one, old credentials messed up the AP and STA mode, hence, I needed to erase previous saved credentials.

the trick is quite simple and it was in front of my eyes the whole time.

        wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); //load the flash-saved configs
        esp_wifi_init(&cfg); //initiate and allocate wifi resources (does not matter if connection fails)
        delay(2000); //wait a bit
        if(esp_wifi_restore()!=ESP_OK)
        {
            Serial.println("WiFi is not initialized by esp_wifi_init ");
         }else{
             Serial.println("WiFi Configurations Cleared!");
         }
         //continue
        delay(1000);
        esp_restart(); //just my reset configs routine...

And that will erase the previously saved WiFi credentials.

Do you have the complete sketch?

thenicnic commented 3 years ago
        wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); //load the flash-saved configs
        esp_wifi_init(&cfg); //initiate and allocate wifi resources (does not matter if connection fails)
        delay(2000); //wait a bit
        if(esp_wifi_restore()!=ESP_OK)
        {
            Serial.println("WiFi is not initialized by esp_wifi_init ");
         }else{
             Serial.println("WiFi Configurations Cleared!");
         }
         //continue
        delay(1000);
        esp_restart(); //just my reset configs routine...

And that will erase the previously saved WiFi credentials.

Thank you! You're the man! Works like a charme.

Do you have the complete sketch?

It does work out of the box, you just need to include "esp_wifi.h". In my example, credentials will be cleared when a blank cable ending from pin 4 ("touch") is hold with your finger on reset:

#include "esp_wifi.h" [...] const int touchPin = 4; [...]

in "setup" method:

  if(touchRead(touchPin) < 20) {
    Serial.println("Enforced WiFi credentials clearup triggered");
    clearWifiCredentials();
  } else
  {
    wifiManager.autoConnect("Setup ESP32 WiFi");
  }
void clearWifiCredentials() { //load the flash-saved configs
  wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
  esp_wifi_init(&cfg); //initiate and allocate wifi resources (does not matter if connection fails)
  delay(2000); //wait a bit
  if(esp_wifi_restore()!=ESP_OK)
  {
    Serial.println("WiFi is not initialized by esp_wifi_init ");
  } else {
    Serial.println("WiFi Configurations Cleared!");
  }
  delay(1000);
  esp_restart(); //just my reset configs routine...
}

Made my day!

fernandobelissimo-60 commented 3 years ago

Eu encontrei a solução limpa, melhor e 100% funcional para isso esp_wifi_restore (); atraso (1000); ESP.restart (); isto irá remover todas as credenciais salvas anteriormente se você estiver usando wifimanager, torne handleReset () public para tornar essa função disponível em qualquer lugar

void WiFiManager :: handleReset () {

if (servidor! = NULL) { DEBUG_WM (F ("Reset"));

Página de string = FPSTR (HTTP_HEAD_W); page.replace ("{v}", "Info"); página + = FPSTR (HTTP_SCRIPT); página + = FPSTR (HTTP_STYLE); page + = _customHeadElement; página + = FPSTR (HTTP_HEAD_END); page + = F ("O módulo será reiniciado em alguns segundos."); página + = FPSTR (HTTP_END);

server-> sendHeader ("Content-Length", String (page.length ())); servidor-> enviar (200, "texto / html", página);

DEBUG_WM (F ("Página de redefinição enviada")); atraso (5000); }

if definido (ESP8266)

WiFi.disconnect (true); atraso (1000); ESP.reset ();

else

esp_wifi_restore (); atraso (1000); ** ESP.restart ();

endif

delay (2000); }

vai funcionar ...

fernandobelissimo-60 commented 3 years ago

Working!! Congratulations!!!