How to eliminate ESP8266 WIFI drop-outs
Just when it seemed like the ESP8266 was operating rock-solid, indeed running continuously for days now without resetting, or worse, fatally crashing, a sign that something was wrong appeared…
Out of the corner of my eye, a flash of light seemed to originate from the up ’till now reliably running ESP8266 based circuit. As my gaze turned directly towards the module, the blue LED started flashing. Not just once, but several times with a silent couple of seconds between illuminations…
“Uh-Ohh”, I thought, “looks like the ESP8266 is once again in a reset loop!” First thing to check was the ESP8266 web server response to a http GET request. The server did respond with a JSON string, just like it was programmed to do. And much to my surprise, the status (seconds running since last reset), indicated the module had been continuously running for days.
So why the flashing blue LED?
I noticed that sending a http GET request around the time the flashing occurs required considerable time (up to 10 seconds) before the ESP8266 returned a JSON response string. This could only mean one thing…
A WIFI Connectivity Check and Recover is Essential
The application firmware had detected a loss in WIFI connectivity and was attempting to reconnect. I had added a WIFI check to the top of the Arduino IDE loop() function. It never seemed to detect a loss of WIFI. That is, until now…
While the following code was developed using the Arduino IDE, the same check should be included for the SDK or NodeMCU code as well.
//connect wifi if not connected if (WiFi.status() != WL_CONNECTED) { delay(1); startWIFI(); return; }
So the setup() function initially establishes the WIFI conection with a call to startWIFI(). The WIFI status is subsequently checked each iteration of the loop() to maintain the connection.
Fortunately, I had included some status messages in the startWIFI() function sent out the serial port just in case some troubleshooting was needed. This came in handy to confirm the root cause of the flashing blue LED.
void startWIFI(void) { //set IP if not correct IPAddress ip = WiFi.localIP(); if( ip!= ipadd) { WiFi.config(ipadd, ipgat, ipsub); //dsa added 12.04.2015 Serial.println(); delay(10); Serial.print("ESP8266 IP:"); delay(10); Serial.println(ip); delay(10); Serial.print("Fixed IP:"); delay(10); Serial.println(ipadd); delay(10); Serial.print("IP now set to: "); delay(10); Serial.println(WiFi.localIP()); delay(10); } // Connect to WiFi network Serial.println(); delay(10); Serial.println(); delay(10); Serial.print("Connecting to "); delay(10); Serial.println(ssid); delay(10); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { Serial.print("."); delay(500); } Serial.println(""); Serial.println("WiFi connected"); // Start the server server.begin(); Serial.println("Server started"); // Print the IP address Serial.print("ESP8266 IP: "); Serial.println(WiFi.localIP()); // Print the server port Serial.print("ESP8266 WebServer Port: "); Serial.println(SVRPORT); delay(300); }
As I mentioned, the my ESP8266 web server returns status, along with sensor readings in a JSON string upon receiving http GET request. This data is logged to a mySQL database, once every hour. A CRON php script pulls the ESP8266 data and saves it to the database.
The next step
In order to assess how frequent WIFI connectivity is lost and restarted, I am going to add a static counter to my startWIFI() function. This will identify the number of times the WifFi connection was lost and reestablished since the last reset. That value will be recorded to mySQL along with the other values. It will be interesting to see how often this occurs. Once a day? Several times per hour? We shall see…
If you have had any issues maintaining WIFI connectivity, or your server stops responding to request, consider this as a solution.
I hope you find this information useful…
Update: July 5, 2015
The ESP8266 supporting my weather sensor webserver did reset 23 days ago. I took that opportunity to add a static counter to the startWIFI() function. A ThingSpeak channel has also been established to share the live results publicly. As of this update, the Wifi connectivity was lost 537 times.
Recovery was successful every time as no ESP resets have occurred yet.
This empirical data shows the Wifi connectivity is lost on average 23 times per day.
Excellent post. Never knew this, appreciate it for letting me know.
I feel this is among the most important information for me.
And i’m satisfied reading your article. However
should remark on some basic things, The website taste is great, the articles is in reality nice : D.
Good job, cheers
Thanks for the post.
What is the purpose of the return after the call to startWIFI()?
Thanks for the question Greg. The function to reconnect “startWIFI()” could consume a significant amount of the Watchdog Timer (WDT) timeout period. The return relinquishes control to the ESP OS to perform other/non-sketch tasks and resets the WDT. This will start the loop() function over again. Since we just reconnected to the WIFI, it should drop through that code and execute whatever else is in the loop() function with the full WDT period available.
Prior to including the return, I found the ESP to intermittently reset, a very frustrating event which disrupts the intended function.
Please check out my post regarding Structure of the Arduino IDE loop() for more info.
Thanks for this, I added a similar check/reconnect to my code.
I have found that much of the development time is spent finding ways to automatically recover from failures.
BTW, I was also concerned about WDT reset, but my startWifi() routine includes delay() calls while it waits for reconnect (so does yours), and I learned a while ago that calling delay() will reset the WDT. I tested this: I shut off my WiFi router and my code went into "while (WiFi.status() != WL_CONNECTED){…}" and sat there for 30-40 seconds calmly printing dots ….. and not WDT resetting.
I am having similar issues.
Fortunately, my code had also some debugging messages and I have seen that, before hanging, the ESP had tried to connect to the wifi network several times.
So… I have added in my code a new Wifi connection line…
I have a question: How many time (in weeks or even months) is able to run your ESP without hangs?
Regards!
The longest interval without a reset I have experienced was 28 days. During that time, I also recorded WIFI reconnects. It averaged to be about 3 WIFI reconnects required per day. But my system has always recovered after a reset. An external CRON script running on my host server pulls data from the ESP8266 every 20 minutes and records it in a mySQL database. This preserves the data regardless of what happens to the ESP8266.
Hi Dave,
Instead of calling it in the loop(), I am calling my startWiFi() in a 15 min timer (do you see any problems with that?):
void timer15minAlarm() {
timer15Cnt++;
DEBUG1 Serial.print(“Timer4: Wifi Status: “);
DEBUG1 Serial.println(WiFi.status());
if(WiFi.status() != WL_CONNECTED) {
DEBUG1 Serial.println(“Wifi got disconnected – Reconnecting”);
startWifi();
disconnectCnt++;
DEBUG1 Serial.print(“Disconnect Count = “);
DEBUG1 Serial.println(disconnectCnt);
}
}
I have been collecting data for about a year now from an ESP running continuously, measuring sensors and logging the values to a mySQL database. The time between WIFI resets is one of the parameters recorded. What I have observed is that the WIFI drop-outs (The need to run your timer callback) comes in bunches. You can go days without resets, and then 1,2,or even several dozen could occur back-to-back before the system settles down again. If your setup can tolerate a possible 15-minute window without WIFI, then what you have will meet your needs. otherwise, you might consider reducing your timer callback period to the length of time you are willing to tolerate a loss of WIFI.
If your code (loop or separate threads) have dependencies on a WIFI connection, you could have problems during the 15-minute window should you lose WIFI connectivity.
Any idea why the wifi disconnects, I have the same problem… the wifi units are very close…. ?
Thanks
I think is happens when you use an http server that polls for external requests in the loop() function. That was my approach at the time of this post. It is my suspicion that servicing the http server in loop() intermittently interferes with the WIFI connection, causing it to disconnect.
Since then, I have evolved to using a better approach and have not experienced ANY WIFI drop-outs since the change. The change uses a callback function to service http requests. Internally, I suspect the OS has the callback running in a separate thread, thereby decoupling it from the loop() function. I am currently running a long-term test which counts WIFI drop-outs and ESP8266 module resets, storing the results in a ThingSpeak channel. <a href="http://internetofhomethings.com/homethings/?p=1698" target="_blank">Here</a> is the post about this test. Be sure and click on the "This post" link in the article I just referenced if you want to grab the code and try it in your own project.
I am currently in the process of acquiring a UPS (uninterruptible power supply) to improve the test. The only glitches I have experienced are power company disruption, which are causing the ESP8266 to be reset and the test to start over. That should eliminate that annoyance. I expect once that is in place, the ESP8266 will run indefinitely without any WIFI dropouts or module resets. The UPS will also keep my internet connection powered. I just hope the cable (high-speed internet) service does not fail me. It has been very hot here in Southern California lately and the grid just cannot handle the load sometimes.