Why is it not good practice to call esp_wifi_connect() after esp_wifi_disconnect()?
Why is it not good practice to call esp_wifi_connect() after esp_wifi_disconnect()?
Looking at the wifi provisioning example code and the wifi_provisioning component code, it seems at some point, manager.c calls esp_wifi_disconnect(), resulting in the WIFI_EVENT_STA_DISCONNECTED event. But the event handler also calls esp_wifi_connect() each time the WIFI_EVENT_STA_DISCONNECTED event is called. At the same time, ESP_IDF documentation on WiFi clearly states that esp_wifi_connect() shouldn't be called after esp_wifi_disconnect() is called, but doesn't explain why.
1. Can someone explain why Espressif recommends against calling esp_wifi_connect() after esp_wifi_disconnect()?
2. Under what circumstances would be appropriate to call esp_wifi_connect() after esp_wifi_disconnect() results in WiFi disconnect event?
1. Can someone explain why Espressif recommends against calling esp_wifi_connect() after esp_wifi_disconnect()?
2. Under what circumstances would be appropriate to call esp_wifi_connect() after esp_wifi_disconnect() results in WiFi disconnect event?
-
- Posts: 9727
- Joined: Thu Nov 26, 2015 4:08 am
Re: Why is it not good practice to call esp_wifi_connect() after esp_wifi_disconnect()?
Just guessing here, but esp_wifi_disconnect() probably returns before the actual disconnect is done; it simply sets up the disconnect to happen in the background (which after some time culminates in WIFI_EVENT_STA_DISCONNECTED getting called). If you were to connect esp_wifi_connect() directly after, it would 'short circuit' the actual disconnect routine, rather immediately trying to connect to a (possibly different) AP.
Re: Why is it not good practice to call esp_wifi_connect() after esp_wifi_disconnect()?
I understand that Karunt talks about the discrepancy between what the actual given example and component code does in reality and what the documentation recommends, for a may be good reason as stated.
-
- Posts: 9727
- Joined: Thu Nov 26, 2015 4:08 am
Re: Why is it not good practice to call esp_wifi_connect() after esp_wifi_disconnect()?
I don't think there is a discrepancy. I can't find the docs section they're refering to, but I imagine it warns against calling the connect() function *immediately* after the disconnect function. On the other hand, the example waits for the WIFI_EVENT_STA_DISCONNECTED to happen before connecting again.
Re: Why is it not good practice to call esp_wifi_connect() after esp_wifi_disconnect()?
Here's the link to the specific documentation I'm referring to: https://docs.espressif.com/projects/esp ... -reconnect
Go down to the ESP32 Wi-Fi Event Description section.
Go down to the ESP32 Wi-Fi Event Description section.
WIFI_EVENT_STA_DISCONNECTED
This event can be generated in the following scenarios:
When esp_wifi_disconnect() or esp_wifi_stop() is called and the station is already connected to the AP.
Without access to the code underlying esp_wifi_disconnect(), how can I know whether WIFI_EVENT_STA_DISCONNECTED is raised because of esp_wifi_disconnect() or not? And if WIFI_EVENT_STA_DISCONNECTED is raised as a result of esp_wifi_disconnect(), what should an application do instead to reconnect? Start the wifi provisioning process all over again?The most common event handle code for this event in application is to call esp_wifi_connect() to reconnect the Wi-Fi. However, if the event is raised because esp_wifi_disconnect() is called, the application should not call esp_wifi_connect() to reconnect. It is the application's responsibility to distinguish whether the event is caused by esp_wifi_disconnect() or other reasons.
-
- Posts: 9727
- Joined: Thu Nov 26, 2015 4:08 am
Re: Why is it not good practice to call esp_wifi_connect() after esp_wifi_disconnect()?
I think that this refers to the fact that in practice, you don't want the behaviour that the example does: if you always call esp_wifi_connect() when you get the WIFI_EVENT_STA_DISCONNECTED event, you will reconnect to the access point every time a disconnect happens, even when that was a disconnect that you wanted to happen and initiated yourself by calling esp_wifi_disconnect(). So in practice, when your app decides it wants to disconnect without reconnecting, you could set a flag that the event handler checks for to skip the connect.
I think the wifi provision manager doesn't allow for a disconnect without a reconnect, hence the flag is not needed there.
I think the wifi provision manager doesn't allow for a disconnect without a reconnect, hence the flag is not needed there.
Re: Why is it not good practice to call esp_wifi_connect() after esp_wifi_disconnect()?
(content removed)
Last edited by mbratch on Wed Jan 10, 2024 2:45 am, edited 1 time in total.
Re: Why is it not good practice to call esp_wifi_connect() after esp_wifi_disconnect()?
Figured out why the wifi provisioning example is set up to call esp_wifi_connect() after the WIFI_EVENT_STA_DISCONNECTED event in the event handler. Without calling esp_wifi_connect() after the WIFI_EVENT_STA_DISCONNECTED event, every alternate attempt at provisioning the device fails because wifi provisioning manager isn't able to connect to the ssid after successfully receiving wifi credentials.
Without the esp_wifi_connect() call after the WIFI_EVENT_STA_DISCONNECTED event, this is how wifi provisioning works:
Attempt 1 - Successful at connecting to ssid whose credentials are provided
Attempt 2 - Fail at connecting to ssid whose credentials are provided (resulting in WIFI_PROV_CRED_FAIL event)
Attempt 3 - Successful at connecting to ssid whose credentials are provided
Attempt 4 - Fail ... and so on
My guess is that in order to successfully connect to a ssid after receiving wifi credentials, the device should be disconnected from the ssid to begin with. But the wifi provisioning example doesn't call esp_wifi_disconnect() after successful provisioning and wifi connection (which makes sense because the whole point of provisioning is to then connect to wifi). So the next attempt at wifi provisioning fails. I think I know why this might be happening.
Each time esp_wifi_connect() fails to connect the device to a ssid, it calls esp_wifi_disconnect(). But it retries the wifi connection if failure_retry_cnt (part of WIFI STA config object) is set to something greater than 0. Without setting this variable, esp_wifi_connect() attempts to connect to the ssid only once and calls esp_wifi_disconnect() if it fails that single time. If failure_retry_cnt is set to a non-zero number, the second attempt at connecting to the ssid is successful because esp_wifi_disconnect() was called after the first (failed) attempt.
With the wifi provisioning example, however, manager.c in the wifi_provisioning component only sets up the ssid and password it receives from the user. failure_retry_cnt is not set and is left at 0 by default. It would be nice if manager.c somehow set this by default to a non-zero number.
My work around this issue is to manually set failure_retry_cnt to something like 3 after the WIFI_PROV_CRED_RECV event so that esp_wifi_connect() reattempts a connection to the ssid after a failed attempt, thus making sure the wifi provisioning example works every single time without having to call esp_wifi_connect() after the WIFI_EVENT_STA_DISCONNECTED event.
Without the esp_wifi_connect() call after the WIFI_EVENT_STA_DISCONNECTED event, this is how wifi provisioning works:
Attempt 1 - Successful at connecting to ssid whose credentials are provided
Attempt 2 - Fail at connecting to ssid whose credentials are provided (resulting in WIFI_PROV_CRED_FAIL event)
Attempt 3 - Successful at connecting to ssid whose credentials are provided
Attempt 4 - Fail ... and so on
My guess is that in order to successfully connect to a ssid after receiving wifi credentials, the device should be disconnected from the ssid to begin with. But the wifi provisioning example doesn't call esp_wifi_disconnect() after successful provisioning and wifi connection (which makes sense because the whole point of provisioning is to then connect to wifi). So the next attempt at wifi provisioning fails. I think I know why this might be happening.
Each time esp_wifi_connect() fails to connect the device to a ssid, it calls esp_wifi_disconnect(). But it retries the wifi connection if failure_retry_cnt (part of WIFI STA config object) is set to something greater than 0. Without setting this variable, esp_wifi_connect() attempts to connect to the ssid only once and calls esp_wifi_disconnect() if it fails that single time. If failure_retry_cnt is set to a non-zero number, the second attempt at connecting to the ssid is successful because esp_wifi_disconnect() was called after the first (failed) attempt.
With the wifi provisioning example, however, manager.c in the wifi_provisioning component only sets up the ssid and password it receives from the user. failure_retry_cnt is not set and is left at 0 by default. It would be nice if manager.c somehow set this by default to a non-zero number.
My work around this issue is to manually set failure_retry_cnt to something like 3 after the WIFI_PROV_CRED_RECV event so that esp_wifi_connect() reattempts a connection to the ssid after a failed attempt, thus making sure the wifi provisioning example works every single time without having to call esp_wifi_connect() after the WIFI_EVENT_STA_DISCONNECTED event.
Re: Why is it not good practice to call esp_wifi_connect() after esp_wifi_disconnect()?
Great work Karunt, thank you for sharing. Just if I understand right and for the records, so the example never worked out of the box correct? so very likely it was not tested for the environment it was supposed to run fine, correct?
How many hours did it cost you to figure the problem out? and did you get the time paid without trouble from your boss? Our supervisors assume and expect that Espressif stuff works right?
Great job !
How many hours did it cost you to figure the problem out? and did you get the time paid without trouble from your boss? Our supervisors assume and expect that Espressif stuff works right?
Great job !
Re: Why is it not good practice to call esp_wifi_connect() after esp_wifi_disconnect()?
Ralph, the example wifi provisioning example works right as is. But that's because it calls esp_wifi_connect() function each time the WIFI_EVENT_STA_DISCONNECTED event occurs. But that approach is contrary to what ESP recommends. ESP recommends distinguishing between what causes the WIFI_EVENT_STA_DISCONNECTED event to occur. If it's esp_wifi_disconnect, then ESP recommends not calling esp_wifi_connect() after that, without adequately explaining why or giving any guidance on how to figure out when esp_wifi_disconnect causes this event to occur. Once I removed the esp_wifi_connect() call from the WIFI_EVENT_STA_DISCONNECTED event, the wifi provisioning example began to fail on every alternate try.
Clearly, there seems to be a disconnect between ESP guidance and their examples. If you're a newbie like me, then the navigating task becomes even more challenging and time consuming. Took me about 2 days to navigate and figure the work around out. Fortunately, no boss issues, but doesn't take away from the fact that ESP documentation and support on issues is less than optimal.
Clearly, there seems to be a disconnect between ESP guidance and their examples. If you're a newbie like me, then the navigating task becomes even more challenging and time consuming. Took me about 2 days to navigate and figure the work around out. Fortunately, no boss issues, but doesn't take away from the fact that ESP documentation and support on issues is less than optimal.
Who is online
Users browsing this forum: No registered users and 89 guests