WiFiMulti.run: While loop under the void setup() results in extra 7sec delay

241 Views Asked by At

I'm facing an unexpected behaviour while writing sketch for NodeMCU 1.0 (ESP-12E).

I'm trying to show some counter while connecting to the WiFi as a part of my void setup(). The idea is to show counter that increases by one each second. However, upon uploading the script to the board the counter "tick's" once per approx 8 seconds (1000+7000).

I've been playing with it a little bit and for me it looks like something adds extra 7 seconds before repeating the loop

#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>

int seconds = 0;

void setup() {
  while (WiFiMulti.run() != WL_CONNECTED) {
    lcd.clear();
    lcd.print(seconds++);
    lcd.print(" ");
    delay(1000);      // < Here I'm getting _additional_ ~7sec delay before loop repeats. 
    }
}

Everything works perfectly fine if I replace the condition from (WiFiMulti.run() != WL_CONNECTED) to (seconds<=10). That is why I tend to think that the issue is purely with the WiFiMulti.run. Can anyone point me to the right direction?

UPD: https://arduino-esp8266.readthedocs.io/en/latest/esp8266wifi/readme.html#quick-start

I've switched to:

WiFi.begin("SSID", "PASSWD");
  while (WiFi.status() != WL_CONNECTED)
  {
    ...

and it works fine. Digging documentation for the ESP8266WiFiMulti now.

1

There are 1 best solutions below

0
ChipChop Gizmo On

Depends on the ESP8266WiFiMulti implementation and if it's implemented to be fully non-blocking.

One way to try is to shift the code into the loop() rather than the setup, this would also show you if the connection has been lost and you are re-connecting. Here is a very quick rough example that should work in a non-blocking way, not tested but just to give you a general idea.

unsigned long wifi_check = 0; // we will use this to check every 30 sec if we are connected

unsigned long wifi_connection_counter = 0;//used to count every second whilst we are connecting

bool first_connect = 1; //is this the first time we are connecting

int seconds = 0;


void setup(){
    if(wifiMulti.run() != WL_CONNECTED) {
        lcd.clear();
        lcd.print("Connecting to WiFi");
        lcd.print(" ");
    }else{
        first_connect = 0; //we are connected 
    }

}

void loop(){
    if(mills() - wifi_check >= 30000 || first_connect == 1){ //check every 30 sec if we are connected or if it's the initial connection check straight away

       if(wifiMulti.run() != WL_CONNECTED) { //we are not connected
          // print to screen every 1 sec
          if(mills() - wifi_connection_counter >= 1000){
             lcd.clear();
             lcd.print(seconds++);
             lcd.print(" ");

             wifi_connection_counter = mills(); //reset the 1 sec timer
             
          }

       }else{ //we are connected
          first_connect = 0;
       }

        wifi_check = mills(); //reset the 30 sec check

     }

}

As I said, this is a very rough not tested example but it's avoiding the use of delay() which is blocking and I suspect that if the wifiMulti requires something like ".run()" it could be also blocking it from working correctly. Basically, avoid using delay() if you can.

Something like this should also work with the regular WiFi() and if it's too much code in the loop() you could put it all in a separate function and just call that function from the loop().

Hope this helps