WiFi.disconnect() not disconnecting

PeteBa
Posts: 1
Joined: Fri Jul 21, 2017 10:14 pm

WiFi.disconnect() not disconnecting

Postby PeteBa » Fri Jul 21, 2017 11:34 pm

So I highly suspect this is a mistake on my part as I know this would have been found already if a problem in the ESP32/Arduino code. But WiFi.disconnect() doesn't seem to be disconnecting for me or at least not updating the WiFi.status() code nor generating a disconnect event for the onEvent() handler. So the code snippet below effectively hangs in the disconnect loop.

Replacing WiFi.disconnect() with esp_wifi_disconnect() produces the expected result i.e. WiFi.status() returns disconnected state and I get a corresponding onEvent() call. I've tried this with two different routers to try and rule out external factors. I have copied the serial output with verbose debug level to show that the core library is indeed behaving differently between the two disconnect functions.

Really appreciate any insight on this as it has had me occupied for way longer than I'd hoped!

Code: Select all

#include <WiFi.h>
extern "C" {
#include <esp_wifi.h>
}

void WiFiEventHandler(WiFiEvent_t event) { Serial.printf("Got Event: %d\n", event); }

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

  WiFi.onEvent(WiFiEventHandler);
  WiFi.begin("ssid", "password");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
  }
  Serial.println(WiFi.status() == WL_CONNECTED ? "CONNECTED" : "FAILED");

  Serial.println("DISCONNECTING...");
  //esp_wifi_disconnect();                     // This works
  WiFi.disconnect();                           // This doesnt
  while (WiFi.status() == WL_CONNECTED) {
    delay(500);
  }
  Serial.println(WiFi.status() != WL_CONNECTED ? "DISCONNECTED" : "FAILED");
}

void loop() {}
Output hangs using WiFi.disconnect():

Code: Select all

CONNECTING...
[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 2 - STA_START
Got Event: 2
[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 4 - STA_CONNECTED
Got Event: 4
[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 7 - STA_GOT_IP
Got Event: 7
CONNECTED
DISCONNECTING...
Output using esp_wifi_disconnect():

Code: Select all

CONNECTING...
[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 2 - STA_START
Got Event: 2
[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 4 - STA_CONNECTED
Got Event: 4
[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 7 - STA_GOT_IP
Got Event: 7
CONNECTED
DISCONNECTING...
[D][WiFiGeneric.cpp:182] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:187] _eventCallback(): Reason: 8 - ASSOC_LEAVE
Got Event: 5
DISCONNECTED

flodis
Posts: 12
Joined: Mon Feb 26, 2018 5:09 am

Re: WiFi.disconnect() not disconnecting

Postby flodis » Mon Dec 03, 2018 11:28 pm

The classic delay fix

Not ESP32 Arduino code but a hint what is going on

With an ESP32 connected as STA if I attempt to close wifi in one fast sequence:

Code: Select all

 esp_wifi_disconnect();
 esp_wifi_stop();
 esp_wifi_deinit()
There are no STA events.

If I add 100ms delays between commands when disabling wifi the events fire fine.

It is like old VBA windows progaming where you have to yield to the UI thread using DoEvents() - sorry to remind..

I tested taskYIELD() but it did not work all times. I do not know how wifi is implemented - if it is task based and what priority it has.

Anyway - I can spare a few 100ms since a wifi connection is not turned on and off frequently.

Code: Select all

	   
	ESP_LOGI(WiFi_TAG, "WiFi closing down..");
	ESP_ERROR_CHECK( esp_wifi_disconnect());
	vTaskDelay(100 / portTICK_RATE_MS);
	ESP_ERROR_CHECK( esp_wifi_stop());
	vTaskDelay(100 / portTICK_RATE_MS);
	ESP_ERROR_CHECK( esp_wifi_deinit());
	vTaskDelay(100 / portTICK_RATE_MS);

Maybe closing down and starting wifi using a chain of events would be better?

If I instead just issue a single esp_wifi_stop() and have the SYSTEM_EVENT_STA_STOP event trigger a esp_wifi_deinit() it works much better.

You do not have to keep track of being connected or not - as you call esp_wifi_stop() it will close the connection and SYSTEM_EVENT_STA_DISCONNECTED will be triggered if connected.

Same mechanism when starting wifi - the esp_wifi_connect() can be issued from the SYSTEM_EVENT_STA_START event.

No delay required if events are trusted.

An event handler like this was used for the test:

Code: Select all

esp_err_t event_handler(void *ctx, system_event_t *event)
{

    switch (event->event_id) {
    case SYSTEM_EVENT_STA_START:
 	    ESP_LOGI(WiFi_TAG, "STA_START %s %d\n", __func__, __LINE__);
  	    xEventGroupSetBits(wifi_event_group, ST_INITIALIZED_BIT);
 	    ESP_LOGI(WiFi_TAG, "Connecting..\n");
 	    esp_wifi_connect();
        break;
    case SYSTEM_EVENT_STA_STOP:
 	    ESP_LOGI(WiFi_TAG, "STA_STOP %s %d\n", __func__, __LINE__);
 	   xEventGroupClearBits(wifi_event_group, ST_INITIALIZED_BIT);
 	    ESP_ERROR_CHECK( esp_wifi_deinit());
        break;
    case SYSTEM_EVENT_STA_GOT_IP:
 	    ESP_LOGI(WiFi_TAG, "STA_GOT_IP %s %d\n", __func__, __LINE__);
            xEventGroupSetBits(wifi_event_group, ST_CONNECTED_BIT);
        break;
    case SYSTEM_EVENT_STA_LOST_IP:
 	    ESP_LOGI(WiFi_TAG, "STA_LOST_IP %s %d\n", __func__, __LINE__);
	    xEventGroupClearBits(wifi_event_group, ST_CONNECTED_BIT);
 	    break;
    case SYSTEM_EVENT_STA_CONNECTED:
 	    ESP_LOGI(WiFi_TAG, "STA_CONNECTED %s %d\n", __func__, __LINE__);
 	    break;
    case SYSTEM_EVENT_STA_DISCONNECTED:
 	    ESP_LOGI(WiFi_TAG, "STA_DISCONNECTED %s %d\n", __func__, __LINE__);
	    xEventGroupClearBits(wifi_event_group, ST_CONNECTED_BIT);
        break;
    default:
 	    ESP_LOGI(WiFi_TAG, "XXX_DEFAULT %s %d\n", __func__, __LINE__);
        break;
    }

    return ESP_OK;
}




:) :?:

Who is online

Users browsing this forum: PepeTheGreat and 60 guests