Closed vseven closed 5 years ago
definitly the SDK should try to reconnect automotically. That is the whole point of having WiFi.setAutoReconnect(true).
@everslick - I agree completely, it doesn't seem to work which is why I posted this originally 3+ months ago. The WiFi.setAutoReconnect(true) doesn't seem to make it reconnect which is ironic to say the least. The only thing that works is to reboot the controller and let it go back through its normal connect (which isn't going to work for me when controlling LEDs as they turn off) or doing the full disconnect and reconnect.
@zhangyanjiaoesp - So you are saying WiFi.setAutoReconnect(true) simply doesn't work? And to work around we have to call the disconnect and reconnect with the SSID and password again? If this is true will it be fixed or at least the documentation updated to say it doesn't work?
I have a similar issue, After reseting the by software using the following sequence: WiFi.disconnect(); //Ensure current ssid/password is erased delay (1000); ESP.restart(); The ESP reboots but never connects to the AP until an hardware reset. The function Wifi.disconnect () is also not working correctly. Robert
The hard way is to connect a GPIO pin to the EN one and force a System reset (GPIO Low) in case reboot/restart or wifi (re)connection is needed.
Don't do the disconnect. Just restart works for me. But again...shouldn't have to restart if WiFi.setAutoReconnect(true) worked properly.
It should be nice to have the Wifi.disconnect or autoreconnect working, but what's the point, if there is a Wifi connection issue, this is a major one in case of ESP32 (all subsequent applications probably relies on Wifi), so the ultimate solution is to try a hardware reset, if this one fails ... bye bye ESP32 usage.
Rebooting is NOT a solution. I'm using this for RGB LED control and rebooting resets the lights to off. If there is a function that tells the ESP that if it loses WiFi it should keep retrying to connect then that function should actually work as documented.
OK, I have tried to reset the ESP through a GPIO, but it looks that ESP doesn't like suicide, so it doesn't work without an external device. So I agreed the only solution that left is that the WiFi disconnect, the ESP restart or the Wifi auto reconnect are actually working. Another issue for which we have to wait for a functional ESP module (I note that as far I could test it, the I2C protocol is another one for which I am waiting for a solution). ESP32 is far to be reliable until now .... Robert
and I didn't mention the SPI interface ...
esp_restart_noos();
For when ESP.restart() doesn't work.
I am using Arduino IDE to configure a WeMos Lolin32. I use the function:
void unitReset ()
{
#ifdef DEBUGGING
Serial.println ("Coordinator will REBOOT NOW ....");
#endif
WiFi.disconnect(); //Ensure current ssid/password is erased
delay (1000);
ESP.restart();
}
When WeMos connected in WiFi.mode(WIFI_STA), I call this function from MQTT. It actually restarts the system and the sketch starts, but Wifi (can't synchronise from that point, connection attempts goes in a endless loop). A manual reset solves it. However the same function called from with WiFi.mode(WIFI_STA) via telnet, works.
@vseven @everslick @rrobinet
You misunderstand the meaning of the function WiFi.setAutoReconnect(true)
.
In our code, WiFi.setAutoReconnect(true)
is not mean to reconnect wifi utomotically. It means if the ESP32 has connected to wifi before, then when the system restarts next time, it wiil connect the last connected wifi.
So we will add some comments in the code. Sorry to have affected your work.
@zhangyanjiaoesp Sorry for stating it like that: That is just "wrong". That API was introduced for the ESP8266 and it did exactly that: reconnecting wifi automatically. What you describe is what the WiFi.setAutoConnect(); method is for. You cannot change the semantics of a well established API at will.
Besides, even when the API was meant to work like you said, the function naming would be incredible bad and misleading.
Anyway. We are talking IoT devices here. The default should be to stay connected to the network no matter what. If anything, there should be functions to disable automatic reconnects and not to require the API user to jump through hoops to make it behave that way.
@vseven @everslick @rrobinet Please look at here, it tells user this function works when powered on.
ESP.restart issue, correction. Well the script above was working with an ESP8266 and not with an ESP32, however after some tests, the issue is the usage of the WiFi.disconnect (true), before the ESP.restart(). This function for ESP32 should be place at the Wifi initialisation (see https://github.com/espressif/arduino-esp32/pull/466) Something like:
<snip>
WiFi.disconnect(true); // Clear Wifi Credentials
WiFi.persistent(false); // Avoid to store Wifi configuration in Flash
WiFi.mode(WIFI_STA); // Ensure WiFi mode is Station
Serial.println("Now Connecting to Access Point ...");
// Connect to the Access Point
WiFi.begin(ssid,key);
<snip>
and the unit reset should be simply:
void unitReset ()
{
#ifdef DEBUGGING
Serial.println ("Coordinator will REBOOT NOW ....");
#endif
delay (1000);
ESP.restart();
}
Can you confirm the following, which I understand so far when reading this thread:
@Markusenz, I can confirm that https://github.com/espressif/arduino-esp32/issues/653#issuecomment-355659659 seems to always work for me. It seems like the only reference to getAutoReconnect is the link I pasted in the comment, which wouldn't handle disconnects well, if it all.
@zhangyanjiaoesp, thanks for your help on this. :)
You misunderstand the meaning of the function WiFi.setAutoReconnect(true) . In our code, WiFi.setAutoReconnect(true) is not mean to reconnect wifi utomotically. It means if the ESP32 has connected to wifi before, then when the system restarts next time, it wiil connect the last connected wifi.
The method you linked to is setAutoConnect
, not setAutoReconnect
. I think these methods are different. setAutoReconnect
is here. It just sets a flag, and I think the only place that flag is used is here.
Given the name of the method, and how that flag is getting used internally, it seems like this method is supposed to do what people are assuming it does -- enable/disable automatic attempts to reconnect to an AP after a disconnect.
My thought is that this feature is just not working as expected, and I think it's possibly because internally the SDK is using WiFi.begin()
, which will clear the SSID if the saved AP doesn't exist, as I discovered above.
So this is how it seems to be happening. Can the SDK be updated to NOT clear out the AP if it doesn't see it instantly. Or to do a WiFi.Begin using the last known SSID and password if WiFi.setAutoReconnect(true) or am I missing something?
If my thinking/digging is correct, I really doubt this behavior is intentional or expected. It seems likely that setAutoReconnect
is meant to have the functionality that folks in this thread are expecting it to, and it just has some bugs.
My suggestion would be to work around it for now. In my own project I just attach an event handler that does
WiFi.disconnect(true);
WiFi.begin(ssid, passwd);
and it works for me.
It seems like reconnection is currently being handled by the Arduino SDK rather than the underlying stuff. With the ESP8266 Arduino SDK, reconnection is handled by the Non-OS SDK. So a fix to the ESP32 Arduino SDK will probably look a lot like this external workaround would anyway (again -- assuming my thinking is correct. I could certainly be wrong).
edit - here is the relevant section in my code that handles reconnection.
@Markusenz you are right. @vseven @sidoh I agree with @sidoh , you can work around it for now. We will implement the auto connect function, and we have known the importance of this issue, but we need time to provide you a perfect solution.
After some digging I found this to work pretty well:
static bool sta_was_connected = false;
static void poll_connection(void) {
#ifdef ESP32
// this is a crude workaround due to the inability of
// the ESP32 to reconnect to an accesspoint automatically.
//
// https://github.com/espressif/arduino-esp32/issues/653
static uint32_t ms = millis();
if (!WiFi.isConnected() && (millis() - ms) > 1000 * 5) {
ms = millis();
if (sta_was_connected) WiFi.reconnect(); else WiFi.begin();
}
#endif
}
loop() {
poll_connection();
}
In the WiFi event handler for SYSTEM_EVENT_STA_GOT_IP you have to set sta_was_connected to true.
This will also work when the accesspoint was not available when the ESP32 booted.
The advantage is, that it does not clear the STA config. This is especially useful if you have set a static IP configuration (not using DHCP).
do you get a
[D][WiFiGeneric.cpp:293] _eventCallback(): Event: 8 - STA_LOST_IP
if you wait long enough ( there is a delay )
I am gonna try
} else if(event->event_id == SYSTEM_EVENT_STA_LOST_IP) {
if(WiFi.getAutoReconnect()){
WiFi.begin();
}
Here is a working solution that bypasses some issues with the WiFi library. Note the while loops after a WiFi.begin(). I have found the connection delay varies depending on the router and encryption settings, AES, WPA2 seem best, fastest and most reliable.
To that end waiting till you know a connection worked but making sure you don't lock up, pretty much does it.
I noted some are calling WiFi.disconnect(). Be careful to use WiFi.persistent(false); with it or every time you recover you are re-writing the NV FLASH and will brick it when the FLASH dies.
Partial CODE SAMPLE
setup()
{
WiFi.begin( rssiSSID , password );
int WLcount = 0;
while (WiFi.status() != WL_CONNECTED && WLcount < 250 )
{
delay( 100 );
#ifdef DEBUG
Serial.print(".");
#endif
++WLcount;
}
}
void loop()
{
if (WiFi.status() == WL_CONNECTED)
{
// PUT_YOUR_UP_TIME_CODE_HERE
#ifdef DEBUG
Serial.print("C");
if (UpCount >= 20) // just keep terminal from scrolling sideways
{
UpCount = 0;
Serial.println();
}
++UpCount;
#endif
// END WiFi connected loop()
} else
{
// PUT_YOUR_DOWN_TIME_CODE_HERE
// WiFi DOWN loop
#ifdef DEBUG
WFstatus = getWifiStatus( WFstatus );
#endif
WiFi.begin( rssiSSID , password );
int WLcount = 0;
// loop - depending on router, connect can be from 4 - 20 seconds
// usually longer to reconnect than the connect at boot
// lopping till reconnect seems to let it settle
// usually around 80 count to breakout
while (WiFi.status() != WL_CONNECTED && WLcount < 250 )
{
delay( 100 );
#ifdef DEBUG
Serial.print(".");
// just keep terminal from scrolling sideways in test
if (UpCount >= 20)
{
UpCount = 0;
Serial.println();
}
++UpCount;
#endif
++WLcount;
}
delay( 1000 );
} // END WiFi DOWN
} // END loop()
int getWifiStatus( int WiFiStatus )
{
WiFiStatus = WiFi.status();
Serial.print("\tStatus "); Serial.print( WiFiStatus );
switch( WiFiStatus )
{
case WL_IDLE_STATUS : // WL_IDLE_STATUS = 0,
Serial.println(", WiFi IDLE ");
break;
case WL_NO_SSID_AVAIL: // WL_NO_SSID_AVAIL = 1,
Serial.println(", NO SSID AVAIL ");
break;
case WL_SCAN_COMPLETED: // WL_SCAN_COMPLETED = 2,
Serial.println(", WiFi SCAN_COMPLETED ");
break;
case WL_CONNECTED: // WL_CONNECTED = 3,
Serial.println(", WiFi CONNECTED ");
WiFi.persistent(true);
break;
case WL_CONNECT_FAILED: // WL_CONNECT_FAILED = 4,
Serial.println(", WiFi WL_CONNECT FAILED");
break;
case WL_CONNECTION_LOST: // WL_CONNECTION_LOST = 5,
Serial.println(", WiFi CONNECTION LOST");
WiFi.persistent(false); // don't keep writing FLASH
break;
case WL_DISCONNECTED: // WL_DISCONNECTED = 6
Serial.println(", WiFi DISCONNECTED ==");
break;
}
return WiFiStatus;
} // END getWifiStatus()
====== it takes on average 8-15 seconds to detect mode change note "."'s are connecting "C"'s are Connected
OUTPUT
CCCCCCCCC Status 5, WiFi CONNECTION LOST Unplugged Router here
.........
.................... Trying
More lines of dots...
....................
........... Status 1, NO SSID AVAIL Gave up, Changed Modes
......... Replugged Router here
....................
................CCCC TaDa I'm Back...
CCCCCCCCCCCCCCCCCCCC
I am using this, seems to work for me
void WiFiEvent(WiFiEvent_t event){
if(event == SYSTEM_EVENT_STA_DISCONNECTED){
Serial.println("Event: SYSTEM_EVENT_STA_DISCONNECTED, reconnecting");
WiFi.reconnect();
}
}
if(WiFi.getAutoReconnect()) WiFi.onEvent(WiFiEvent);
I guess my apartment with the 50 APs nearby is really a great place to test this issue. The solution from tablatronix causes my esp32 to dump and I don't see how mickeypop's solution would do any good, which it didn't help. I've found that restarting the wifi connection works fairly well but even that requires a hard power reset every once in a while. On the side i've got an esp8266 in the same environment that never requires any manual intervention. I've tried a few other suggestions here without luck.
I think it's amazing all the development that's done. Frankly I don't have the skills to come up with a solution. If anyone has something that they want to try in a harsh environment, feel free to send me tests. We really need the esp32 to have a solid connection and handle intermittent wifi gracefully.
Edit: after trying a lot of stuff: @tablatronix If I run this line too fast it crashes/gives backtrace. Calling every few seconds gave me no problems. Now to let it run for a few days to see what happens
if(WiFi.getAutoReconnect()) WiFi.onEvent(WiFiEvent);
Edit2: lasted 30 minutes before dropping off
@thefatmoop I ran into a WiFi reconnect issue that ended up being a NVS corruption issue. #1147 I rewrote a sketch to dump the nvs data. Try it and capture the output. It may show something. Show NVS Keys
Chuck.
thefatmoop
Both solutions should work. As i noted; "Here is a working solution that bypasses some issues with the WiFi library."
While one bypasses some library issues the other uses the WiFi.onEvent() service, both simply detect when a connection is broken and re-initiate a new connection.
While some have noted after several hours they keep getting bumped, this is almost certainly a function of the lease time of DHCP server in the router.
If the lease time of the router is not the same sometimes devices "forget" to update causing a no IP address even though sometimes the WiFi connect is still there.
WiFi.reconnect() works but often assumes the unit still has an IP and may not do a DHCP request.
The simple way around this is to Ping the DHCP router periodically.
This forces the router to know you are still on the network and keep the lease current.
Rebooting may reconnect, but does not address the WHY of getting disconnected and often applications can get out of sync if you are simply rebooting.
So reconnecting without rebooting is often a necessity.
reconnect does not redo dhcp, I found this out when trying to change hostname and reconnect, was gonna file it as a bug.
Solution from @tablatronix is working for me thanks! @thefatmoop you can check the implementation on OpenMQTTGateway.ino code.
The code is called after MQTT disconnection, if I put the code outside this condition the ESP dump indeed.
If WiFi.reconnect()
reconnects, but MQTT client not, you can make another setup_wifi()
: with disconnect() delay() and begin(), after a few client reconnect attempts and it works great within the new connection. But what happens when the MQTT server is down?
Thats an application level problem..
Added mickeypop code proposal to the Wiki
Sorry. I'm a beginner in arduino/esp programming. I'm also confronting with the bugs/problems of wifi connect and reconnect. My part of code which manages both the WiFi & MQTT client (PubSubClient), and which actually works on an ESP32 from Adafruit/Huzzah32:
void setupWiFi() {
WiFi.disconnect(true);
WiFi.begin(WLAN_SSID, WLAN_PASS);
WiFi.waitForConnectResult();
}
boolean clientReconnect() {
if(client.connect("esp32_client")) {
client.subscribe("/test");
}
return client.connected();
}
boolean wifi_connected_once = false;
unsigned long last_client_reconnect_attempt = 0;
int client_reconnect_attempts = 0;
void setup() {
client.setServer(MQTT_SERVER, 1883);
client.setCallback(client_callback);
}
void loop() {
unsigned long loop_start = millis();
if(WiFi.isConnected()) {
// WiFi connected
if(client.connected()) {
// client connected
// publish data every 5 seconds
if(loop_start - last_client_publish >= 5000) {
client_publish_data();
last_client_publish = loop_start;
}
client.loop();
} else {
// client not connected
// try reconnect a few times every 5 seconds
if(client_reconnect_attempts <= 5) {
if(loop_start - last_client_reconnect_attempt > 5000) {
client_reconnect_attempts++;
if(clientReconnect()) {
// client connected
client_reconnect_attempts = 0;
}
last_client_reconnect_attempt = loop_start;
}
} else {
// maybe MQTT server is down
// try reconnect in 5 minutes
if(loop_start - last_client_reconnect_attempt > 300000) {
last_client_reconnect_attempt = loop_start;
client_reconnect_attempts = 0;
}
}
}
} else {
// WiFi not connected
// try connect for the first time or
// try reconnect every 2 minutes
if((loop_start - last_client_reconnect_attempt > 120000) || wifi_connected_once == false) {
last_client_reconnect_attempt = loop_start;
wifi_connected_once = true;
client_reconnect_attempts = 0;
setupWiFi();
}
}
}
Tested with some router reboots and the code seems working without the need of ESP reboot. Do you have any much better suggestion?
This issue is killing me. It's happening randomly sometimes in the first hour sometimes after six hours while running without issues. I've tried all sorts of configurations and none of them is reliable. Restarting the ESP by software or hardware is the last resort that actually works but that's not a viable solution for my product.
Last time I left it running and tried more than FOUR THOUSANDS attempts, none of them with success.
I have tried so far:
1) Enabling autoReconnect and calling reconnect 2) Disabling autoReconnect and manually disconnecting and reconnecting. In this configuration I've tried both methods of completely switching off the antenna or not. Does not work in any mode.
Here you have some logs (this is actually running right now with more than 600 attempts to reconnect on a perfectly working router (TP-LINK):
WARNING: WiFi lost connection. Trying reconnection attempt 632 on next iteration Triggering WiFi Reconnection attempt 632 I (14944038) wifi: mode : softAP (30:ae:a4:1a:ca:1d) Creating WiFi with SSID 'Nano BAB - Development' and password '#######' Connecting to WiFi 'TP-LINK_A8FB38' [D][WiFiGeneric.cpp:293] _eventCallback(): Event: 3 - STA_STOP [D][WiFiGeneric.cpp:293] _eventCallback(): Event: 2 - STA_START [WiFi-event] event: 2 [D][WiFiGeneric.cpp:293] _eventCallback(): Event: 5 - STA_DISCONNECTED [W][WiFiGeneric.cpp:298] _eventCallback(): Reason: 201 - AUTH_FAIL
As you can see is failing on authentication however the password is correct. On some previous attempt (number 578!!) from the same example is raising error 2:
WARNING: WiFi lost connection. Trying reconnection attempt 578 on next iteration Triggering WiFi Reconnection attempt 578 I (14134199) wifi: mode : softAP (30:ae:a4:1a:ca:1d) Creating WiFi with SSID 'Nano BAB - Development' and password '#########' [D][WiFiGeneric.cpp:293] _eventCallback(): Event: 3 - STA_STOP [WiFi-event] event: 3 Connecting to WiFi 'TP-LINK_A8FB38' [D][WiFiGeneric.cpp:293] _eventCallback(): Event: 13 - AP_START [WiFi-event] event: 13I (14134890) wifi: mode : sta (30:ae:a4:1a:ca:1c) + softAP (30:ae:a4:1a:ca:1d) [D][WiFiGeneric.cpp:293] _eventCallback(): Event: 2 - STA_START*
[WiFi-event] event: 2[D][WiFiGeneric.cpp:293] _eventCallback(): Event: 2 - STA_START [WiFi-event] event: 2I (14137748) wifi: ap channel adjust o:1,1 n:6,1 I (14137749) wifi: n:6 1, o:1 0, ap:6 1, sta:6 1, prof:1 I (14138422) wifi: state: init -> auth (b0) I (14139423) wifi: state: auth -> init (2) I (14139424) wifi: n:6 0, o:6 1, ap:6 1, sta:6 1, prof:6 [D][WiFiGeneric.cpp:293] _eventCallback(): Event: 5 - STA_DISCONNECTED [W][WiFiGeneric.cpp:298] _eventCallback(): Reason: 2 - AUTH_EXPIRE
It's always one of the two errors. In the end is simply that it does not reconnect.
Funny thing is I can disconnect manually the router by pulling the power cord for a few minutes, my code detects the disconnectiong and starts retrying and then my system reconnects OK when back in, however if the router is working normally this issue eventually happens and the ESP simply does not reconnect.
Btw, I am running with:
Running on SDK: 'v3.1-dev-239-g1c3dd23f-dirty' CPU Frequency: 240MHz WiFi both creating its own private WiFi and connecting to another one with access to the internet
When was the last time you pulled in from repo ?
you only posted logs, no sketch or reconnect solution.
Last time was about a week or so. My SDK version is 3.1-dev-239. Sorry I did not add the code because I basically tested all the solutions within the post. At startup I call something similar to:
WiFi.disconnect(true);
WiFi.softAP(wifiName, wifiPassword);
WiFi.begin(connectoToWifiSSID, connectToWifiPassword);
Then I handle WiFi events and especially the event SYSTEM_EVENT_STA_DISCONNECTED. When this event happens, I have tried 3 different ways of reconnection:
1) When Wifi autoreconnect was enabled I left the system to handle itself the reconnection 2) I tried by disabling autoreconnect and on that event calling WiFi.reconnect() 3) Latest one I am trying is to disconnect by turning off the radio and connecting again if no other disconnection as triggered it. I've got something like:
reconnections++;
needsReconnection = true;
reconnectionDetection = millis();
Serial.printf("\r\nWARNING: WiFi lost connection. Trying reconnection attempt %d on next iteration\r\n", reconnections);
needsReconnection is a flag that is checked in the main loop and triggers again the connection by basically running the first 3 lines of code.
Hope it makes sense now ;-)
Not sure if there is another way of doing it.
I forgot to mention, I am running too a mongoose server to implement a Rest API, allowing a max of 3 concurrent connections. Not sure if that could be the cause of it.
I'd suggest pulling in changes and making a simple test case.
josmunpav
your issue may be WiFi mode's
your code
WiFi.softAP(wifiName, wifiPassword);
WiFi.begin(connectoToWifiSSID, connectToWifiPassword);
You are running mixed Modes. WiFi.softAP(); default is WIFI_MODE_AP mode
WiFi.begin(); default is WIFI_AP_STA mode
if you proceed with the WIFI_MODE_APSTA mode (mixed mode) they should not change and WiFi EVENT will not get mixed up with different modes.
WiFi.mode( WIFI_MODE_APSTA );
WiFi.softAP(wifiName, wifiPassword);
WiFi.begin(connectoToWifiSSID, connectToWifiPassword);
REF INFO in esp_wifi_types.h
typedef enum {
WIFI_MODE_NULL = 0, /**< null mode */
WIFI_MODE_STA, /**< WiFi station mode */
WIFI_MODE_AP, /**< WiFi soft-AP mode */
WIFI_MODE_APSTA, /**< WiFi station + soft-AP mode */
WIFI_MODE_MAX
} wifi_mode_t;
in wifitypes.h
typedef enum {
WL_NO_SHIELD = 255, // for compatibility with WiFi Shield library
WL_IDLE_STATUS = 0,
WL_NO_SSID_AVAIL = 1,
WL_SCAN_COMPLETED = 2,
WL_CONNECTED = 3,
WL_CONNECT_FAILED = 4,
WL_CONNECTION_LOST = 5,
WL_DISCONNECTED = 6
} wl_status_t;
Hi mickeypop ,
I am testing your solution of:
WiFi.mode( WIFI_MODE_APSTA );
WiFi.softAP(wifiName, wifiPassword);
WiFi.begin(connectoToWifiSSID, connectToWifiPassword);
I am calling WiFi.reconnect() when event SYSTEM_EVENT_STA_DISCONNECTED happens, which I tried by manually disconnecting the router and seems to be working (that bit worked before too).
So far it has been working overnight for 7 hours non stop on 2 different ESP32. I've been pinging them every 5 seconds and no issues so far. Could not imagine that mixed mode declaration could be the reason, I thought it was automatically enabled when calling WiFi.begin and WiFi.softAP() . Fingers crossed. I will start now with more heavy testing to confirm it is the solution to the problems I am facing.
By the way, THANK YOU so much!!
@mickeypop @josmunpav thanks for sharing your findings. I added it to the Wiki
This makes no sense this indicates that there is a bug in enablesta or enablesoftap if setting mode beforehand changes the outcome. That is why I suggested this is mode specific, workarounds should not be needed. So reproduction code would be nice
A lot of this doesn't make sense as @everslick clearly pointed out above: https://github.com/espressif/arduino-esp32/issues/653#issuecomment-356515973. In fact I cant believe I posted this 6 months ago and were still talking about it when it should have never been a issue in the first place.
Why something is called "autoReconnect" that doesn't auto reconnect is beyond puzzling. Everyone seems to be making up there own code to get through this shortcoming/bug. I'm going to pull a fresh copy of the code and reflash per @tablatronix suggestion but the whole point of this is we shouldn't have to do any of this....it should work like the ESP8266 and reconnect on it's own!
I'm personally still having issue with the chip completely locking up on occasion when it gets into this disconnect loop. I have it counting to 10 and restarting but randomly (1 out of 15 or so reboots) it doesn't reboot and just hard locks which requires a cold reboot. I'd switch to the ESP8266 in a heartbeat if it had better/more analog inputs but it unfortunately doesn't. Not that the ESP32 is very good at that either (https://www.esp32.com/viewtopic.php?f=19&t=2881).
In esp8266 autoreconnect is implemented in SDK, in esp32 there is no implementation, so it was added to the library to bring some form of compatibility, although it is only implemented for WIFI_REASON_AUTH_EXPIRE
.
It can be implemented but it needs to be worked out, and this library is still alpha so there really should be no expectation, the sdk is subject to change, the entire event system is subject to change. So implementing core features like this takes time.
Not to mention, if espressif implements this in SDK , then we just wasted all our time.
When I say it needs to be worked out, I mean there are several outstanding issues that need to be resolved. That is why I ask for test sketches for people the above event solution is failing for.
** reconnect does not enablesta, it just returns false, you should always be checking for return values!
If using my workaround above, I suggest disabling autoreconnect to avoid 2 of those bugs.
Hi guys I am back with a sample that reproduce the issues I am facing. The sample is full of comments but basically consists into:
What I have found so far is that if you disable the dummy tasks (there is a flag for it) then both tasks run fine endlessly. If you enable them, then eventually (sometimes can take hours but normally happens within the first hour) the ESP32 disconnects from the WiFi and cannot reconnect, running the connection attempt every 10 seconds without success all the time.
I think there is some interference between ADC or PWM library (implemented by esp32-hal-ledc.h), because I could not reproduce the issue when the main task does nothing but doing a dummy waiting.
Something else I noticed is when the disconnection happens the WiFi signal for the AP decreases a lot. I checked this on my smartphone.
This is the typical WiFi log messages you can find when it fails:
[WiFi-event] event: 5
Disconnected from WiFi. Trying connection again in 10000ms
Web/Main Task is up and running. Shared counter is 11309, Average ADC Value = 1305.000000, PWM Value = 0
Connecting to WiFi 'TP-LINK_A8FB38' with password: 'C1A8FB38' on connection attempt = 108
Oops, there was a problem when connecting. It returned error: 1[D][WiFiGeneric.cpp:293] _eventCallback(): Event: 5 - STA_DISCONNECTED
[W][WiFiGeneric.cpp:298] _eventCallback(): Reason: 2 - AUTH_EXPIRE
Please find the attached source code and sample pages:
ESP32_APSTA_Mode_Disconnection_Test.zip
PS: My real app is doing kind of the same. Starting APSTA mode with two tasks one for updating sensors, devices and GPIOS and the second for handling WiFi and the webserver implemented by mongoose and facing the very same issue.
I built this sketch to test the connection, get time every 10 seconds 10 times, disconnect wifi, reconnect wifi. Seems to work pretty good so I'm implementing in my other code to run for a few days because I was having re-connection issues.
#include <WiFi.h>
#include "time.h"
const char* ssid = "ssid1";
const char* password = "password1";
const char* ntpServer = "pool.ntp.org";
const long gmtOffset_sec = 3600;
const int daylightOffset_sec = 3600;
byte wfConnectTry = 0;
byte loopCnt = 0;
void printLocalTime()
{
struct tm timeinfo;
if (!getLocalTime(&timeinfo)) {
Serial.println("Failed to obtain time");
return;
}
Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
}
void setup()
{
Serial.begin(115200);
//connect to WiFi
Serial.printf("Connecting to %s ", ssid);
//WiFi.begin(ssid, password);
wifiStart();
//init and get the time
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
if (WiFi.status() == WL_CONNECTED) {
printLocalTime();
}
}
void loop()
{
delay(10000);
printLocalTime();
while (WiFi.status() != WL_CONNECTED || wfConnectTry >=5) {
wfConnectTry++;
wifiReconnect();
}
if (loopCnt >= 10){
wifiReconnect();
}
loopCnt++;
}
void wifiReconnect()
{
Serial.println(F("Disconnecting"));
WiFi.disconnect(true);
delay(500);
Serial.println(F("Starting WiFi!"));
wifiStart();
loopCnt = 0;
}
void wifiStart()
{
unsigned long timer1 = millis();
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED && millis() - timer1 < 5000UL) {
delay(500);
Serial.print(".");
}
if (WiFi.status() == WL_CONNECTED) {
Serial.println(F(" CONNECTED"));
wfConnectTry = 0;
}
else {
Serial.println(F("Could not connect!"));
}
}
....thanks for the code tip @tablatronix
Use code fences three ticks newline before amd after
Here is an interesting piece of information. I tried every trick mentioned in this thread and nothing worked. However, every time I install and run SimpleWiFiServer things get reset and then I can reinstall my app and things work again.
My app connects just fine to WiFi and at some point (days or weeks) it loses the connection and nothing can make it connect. I tried all the tricks on this thread and nada. As I said above, the only way I can make my ESP32 connect again to Wifi is by installing this other app to reset things. I wonder what it does that it makes my ESP32 work again with WiFi.
@gdombiak, do you have any debug information to show what the ESP32 is doing when it locks up? I had a recent issue where one of my sketches worked like a champ except when new day rolled over and there were two lines that put it into a continuous loop and the ESP finally just shit itself down till I reset or reloaded. Another issue I had was that I had another ESP that was up as a AP_STA and it kept trying to connect to it rather than the normal WiFI. Had to reload the other ESP and stipulate WiFi.mode(WIFI_STA) to fix that.
@AIWIndustries
Check out a post I put up at: https://github.com/espressif/arduino-esp32/issues/1100
Search for "SmartConfig / WiFi skeleton"
I wrote a complete skeleton that; saves, set with SmartConfig, deals with WiFi UP and DOWN, auto reconnects if Down.
It's a full structure and has always re-connected when WiFi went down or just disconnected for unknown reasons.
Take note in loop() for "// WiFi DOWN". I use a simple if()/else to track the WiFi status. Because of the espressif libraries, it takes about 30-40 seconds to report when the WiFi is down then starts looking to reconnect.
If the AP is power cycled it takes about 30 seconds for the AP to boot and another 15 seconds to reconnect but always reconnects.
Board: ModeMCU ESP32 Dev Module Core Installation/update date: 15/Sep/2017 IDE name: Arduino IDE
It seems there is no auto reconnect logic allowing the ESP32 to reconnect when the connection drops or if there is its not working properly. I have had completely random results with my ESP32 board, sometimes its up for as little as 30 minutes and at most 18 - 20 hours. WiFi is dropping and doesn't want to reconnect.
The library I am using for WiFi is watching the WiFi event and on a disconnect its trying to reconnect which helps but sometimes it fails the reconnect and then that's it...I have to reboot. There is no sleep/low power mode at all involved and the device is constantly powered by 3.3v in. There was a case opened regarding this, https://github.com/espressif/arduino-esp32/issues/353, but its closed without any real answer (says auto connect is kind of implemented...not sure what that means).
I guess the question comes down to is auto reconnect implemented in the code itself, reliably, and if not what is the best Arduino code way of making sure it is connected?
-Allan