Skip to content
This repository has been archived by the owner on Feb 4, 2023. It is now read-only.

Starting WiFIManger is very slow (2000ms) #6

Closed
CrappyTan opened this issue Feb 9, 2020 · 11 comments
Closed

Starting WiFIManger is very slow (2000ms) #6

CrappyTan opened this issue Feb 9, 2020 · 11 comments
Labels
enhancement New feature or request

Comments

@CrappyTan
Copy link

Hi,

The original WiFIManager manager was very slow at connecting. A workaround was to try connect with normal WiFI and if that failed after 1000ms, invoke WiFi Manager. This work around does not seem to work with your library on the ESP32.

The debug:

[34 ] Hello
[34 ] Starting WiFiManager
[2249 ] Starting WiFiManager. Done
[2249 ] Stored: SSID = XXXXX, Pass = XXXXXXXXXXX
[2249 ] Starting WiFiManager. Finished all setup
[2250 ] Got stored Credentials. Timeout 60s
[2254 ] Trying to connect.
[2668 ] WiFi connected!

The delay happens here:

 printDebug("Starting WiFiManager");

 ESP_WiFiManager ESP_wifiManager("ConfigOnDoubleReset");
 printDebug("Starting WiFiManager. Done");

The normal duration to connect to my wifi, with and without DHCP is around 200-250ms.
All my other ESP8266 do this with a few exceptions when they bounce to another bssid.

Sample code to show duration.

#define ESP32

  #include <esp_wifi.h>
  #include <WiFiClient.h>

  #define ESP_getChipId()   ((uint32_t)ESP.getEfuseMac())

  #define LED_ON      HIGH
  #define LED_OFF     LOW  

String ssid = "ESP_" + String(ESP_getChipId(), HEX);
const char* password = "your_password";

// SSID and PW for your Router
String Router_SSID;
String Router_Pass;

// Use false if you don't like to display Available Pages in Information Page of Config Portal
// Comment out or use true to display Available Pages in Information Page of Config Portal
// Must be placed before #include <ESP_WiFiManager.h> 
#define USE_AVAILABLE_PAGES     false

#include <ESP_WiFiManager.h>              //https://github.com/khoih-prog/ESP_WiFiManager


// Indicates whether ESP has WiFi credentials saved from previous session, or double reset detected
bool initialConfig = false;


void printDebug(String msg){
    Serial.print("[");
    Serial.print(millis());
    Serial.print("\t\t]\t");
    Serial.println(msg);    
}

void setup() 
{
  // put your setup code here, to run once:
  // initialize the LED digital pin as an output.
 
  Serial.begin(115200);
  printDebug("Hello");

 //Local intialization. Once its business is done, there is no need to keep it around
   printDebug("Starting WiFiManager");

 ESP_WiFiManager ESP_wifiManager("ConfigOnDoubleReset");
 printDebug("Starting WiFiManager. Done");

  ESP_wifiManager.setMinimumSignalQuality(-1);

  // We can't use WiFi.SSID() in ESP32 as it's only valid after connected. 
  // SSID and Password stored in ESP32 wifi_ap_record_t and wifi_config_t are also cleared in reboot
  // Have to create a new function to store in EEPROM/SPIFFS for this purpose
  Router_SSID = ESP_wifiManager.WiFi_SSID();
  Router_Pass = ESP_wifiManager.WiFi_Pass();
  
  //Remove this line if you do not want to see WiFi password printed
  printDebug("Stored: SSID = " + Router_SSID + ", Pass = " + Router_Pass);

  // SSID to uppercase 
  ssid.toUpperCase();
   printDebug("Starting WiFiManager. Finished all setup");

  if (Router_SSID != "")
  {
    printDebug("Got stored Credentials. Timeout 60s");
    ESP_wifiManager.setConfigPortalTimeout(60); //If no access point name has been previously entered disable timeout.
  }
  else
  {
    printDebug("No stored Credentials. No timeout");
    initialConfig = true;
  }
    
  if (initialConfig) 
  {
    printDebug("Starting configuration portal.");

    //sets timeout in seconds until configuration portal gets turned off.
    //If not specified device will remain in configuration mode until
    //switched off via webserver or device is restarted.
    //ESP_wifiManager.setConfigPortalTimeout(600);

    //it starts an access point 
    //and goes into a blocking loop awaiting configuration
    if (!ESP_wifiManager.startConfigPortal((const char *) ssid.c_str(), password)) 
      printDebug("Not connected to WiFi but continuing anyway.");
    else 
      printDebug("WiFi connected...yeey :)");    
  }

  #define WIFI_CONNECT_TIMEOUT        30000L
  #define WHILE_LOOP_DELAY            10
  #define WHILE_LOOP_STEPS            (WIFI_CONNECT_TIMEOUT / ( 3 * WHILE_LOOP_DELAY ))
  
  unsigned long startedAt = millis();
  printDebug("Trying to connect.");

  while ( (WiFi.status() != WL_CONNECTED) && (millis() - startedAt < WIFI_CONNECT_TIMEOUT ) )
  {   
    WiFi.mode(WIFI_STA);
    WiFi.persistent (true);
  
    WiFi.begin(Router_SSID.c_str(), Router_Pass.c_str());

    int i = 0;
    while((!WiFi.status() || WiFi.status() >= WL_DISCONNECTED) && i++ < WHILE_LOOP_STEPS)
    {
      delay(WHILE_LOOP_DELAY);
    }    
  }

  
  if (WiFi.status() == WL_CONNECTED)
  {
    printDebug("WiFi connected!");
  }
  else
    printDebug("Failed to connect");
}

void loop() 
{
 
}

Running on batteries and sleeping for most of of the time, the wasted 1500ms is crucial. My whole program goes to sleep in around 400ms. :)

WorkAround for the esp8266:


void WIFI_Connect(){
    printDebug(F("WiFI setup starting"));

    IPAddress ip(10,10,30,19) ;    //WeatherStationESP
    IPAddress gateway(10,10,30,1);   
    IPAddress subnet(255,255,255,0);   
    IPAddress dns(10,10,50,2);  //Google dns  

    //Serial.setDebugOutput(true);
    //WiFi.printDiag(Serial);

    WiFi.config(ip, gateway, subnet, dns);


    WiFi.mode(WIFI_STA);
    unsigned long wifiConnectStart = millis();
    WiFi.hostname(_HOST_NAME); 

    while (WiFi.status() != WL_CONNECTED) {
      if (WiFi.status() == WL_CONNECT_FAILED) {
        printDebug(F("WiFI connection failed"));
        return;
      }
      if (millis() - wifiConnectStart > 1000) {
        WiFiManager wifiManager;
        printDebug(F("Could not connect with normal wifi. Starting WiFi Manager."));
        wifiManager.autoConnect(_HOST_NAME);
      }
      delay(10);
    }
Serial.print("mac:");
Serial.println(WiFi.softAPmacAddress());
Serial.print("IP Address:");
Serial.println(WiFi.localIP());
    printDebug(F("WiFI setup complete"));    
}

Options / Questions:

  1. Why does WiFi not work on the ESP32? Are the credentials stored elsewhere?
  2. Can it either be improved so the connect time is reasonable (and that change merged back into the original library 👍 )
  3. Can it be changed so that the original workaround also works?

thanks!

@khoih-prog
Copy link
Owner

khoih-prog commented Feb 10, 2020

Hi @CrispinP
The delay was caused by unnecessary call at constructor initialization, in ESP_WiFiManager.cpp, line 194

numberOfNetworks = scanWifiNetworks(&networkIndices);

I'll move that to when it's just-in-time necessary, in function handleWifi()

void ESP_WiFiManager::handleWifi() 
{
  ...
  
  //  KH, New, v1.0.6+
  numberOfNetworks = scanWifiNetworks(&networkIndices);
  
  //Print list of WiFi networks that were found in earlier scan
  if (numberOfNetworks == 0) 

This will be included in future new v1.0.7. In the mean time, I'll update the master version, you can just download and use.

New debug output:

[36		]	Hello
[36		]	Starting WiFiManager
[151		]	Starting WiFiManager. Done
[151		]	Stored: SSID = ***, Pass = ****
[151		]	Starting WiFiManager. Finished all setup
[152		]	Got stored Credentials. Timeout 60s
[155		]	Trying to connect.   <= while loop taken care by ESP32 WiFi
[1614		]	WiFi connected!      <= ESP32 done connected, no WiFiManager control here

You can see that the total time in WiFiManager is only ~150ms.
It'll take 1.5s for ESP32 to connect to WiFi, and we have no control unless we modify the ESP32 library.
The WIFI_Connect() function is using some functions specific for ESP8266, but it won't improve the ESP32 WiFi connection time as it's using similar function calls.

@khoih-prog
Copy link
Owner

Your contribution is noted in README.md

  1. Thanks to CrispinP for idea to add HostName (v1.0.4) and request to reduce the unnecessary waiting time in ESP_WiFiManager constructor (v1.0.6+).

@khoih-prog
Copy link
Owner

To answer your question

  1. Why does WiFi not work on the ESP32? Are the credentials stored elsewhere?

The ESP32 WiFi Credentials are also stored in Flash, the same as ESP8266.
But it's a little bit more complicated on ESP32 to get credentials.
In ESP8266, it's much simpler with functions:
WiFi.SSID() and WiFi.psk().
You can see, in ESP32, we have to write to have the following similar functions:

In ESP_WiFiManager.cpp

#ifdef ESP32
// We can't use WiFi.SSID() in ESP32 as it's only valid after connected. 
// SSID and Password stored in ESP32 wifi_ap_record_t and wifi_config_t are also cleared in reboot
// Have to create a new function to store in EEPROM/SPIFFS for this purpose

String ESP_WiFiManager::getStoredWiFiSSID()
{
  if(WiFi.getMode() == WIFI_MODE_NULL)
  {
    return String();
  }
  
  wifi_ap_record_t info;
  
  if(!esp_wifi_sta_get_ap_info(&info)) 
  {
    return String(reinterpret_cast<char*>(info.ssid));
  }
  else
  {
    wifi_config_t conf;
    esp_wifi_get_config(WIFI_IF_STA, &conf);
    return String(reinterpret_cast<char*>(conf.sta.ssid));    
  }
  
  return String();
}

String ESP_WiFiManager::getStoredWiFiPass()
{
  if(WiFi.getMode() == WIFI_MODE_NULL)
  {
    return String();
  }
  
  wifi_config_t conf;
  esp_wifi_get_config(WIFI_IF_STA, &conf);
  return String(reinterpret_cast<char*>(conf.sta.password));    
}
#endif

@CrappyTan
Copy link
Author

Awesome! Thank you. I got the latest version and can confirm it's a lot faster :D

[34 ] Hello
[34 ] Starting WiFiManager
[128 ] Starting WiFiManager. Done
[129 ] Stored: SSID = xxx, Pass = xxx
[129 ] Starting WiFiManager. Finished all setup
[129 ] Got stored Credentials. Timeout 60s
[133 ] Trying to connect.
[347 ] WiFi connected!

That's 214ms to connect. I've tried it a number of times and it is mostly around that. Sometimes it faults to around 1600ms but that is when, for rssi reasons, it jumps to another AP (I have multiple APs in the house).

Thank you for your library and your response!!

Question:
While it might not be something you can solve with your library, I wonder if that 200ms can be improved? Is it the beaconing of the AP which, at 100ms, it has to wait for the next beacon to login?
Reason for asking - the whole process, logging on to mqtt, publishing a packet and disconnecting is sub-50ms. WiFi connection is still very slow.

I've asked the same question over at the ubnt forums. Maybe they can help too :)

Thanks again :)

@khoih-prog
Copy link
Owner

Hi @CrispinP
That's encouraging. I'll spend some time researching to see where and why ESP32/ESP8266 libraries keeping the connecting time so long.
It's possible router related, as you can see my results is 1500ms, not 200 ms as yours (some reason is I'm using my extremely old router for testing purpose).
Hopefully, something can be improved in WiFi libraries.
Cheers,

@CrappyTan
Copy link
Author

I've asked a question here: https://community.ui.com/questions/Reduce-connection-duration/ee97e943-9c6d-4b6a-a85c-f9c5a24bc4f2

I did a wireshark on the dhcp server I have, pfsense, and see that it is taking around 37ms from request to response. So, that leaves me with around 160ms "lost".
If my understanding is correct around the DTIM beacons, it means that I could be waiting up to 100ms before anything actually can happen. If that is the case then in reality, the ESP is only using around 70ms to negotiate the PSK and manage the connection. I don't think that is an unfair time really.

I'll set up another SSID for testing and mess around with the DTIM and see if I can reduce it without any ill effect.

I'm wondering if I am nearing what is reasonable with WiFi. If I wanted quicker then something like Z-Wave might be a better suited option.

If you do find anything I would be interested in trying it 😄

@khoih-prog
Copy link
Owner

Can you try to reduce the Router's

  1. Beacon Interval to 10-20ms
  2. DTIM interval to 1-2

to see if it's improving and to isolate if the problem is in WiFi libraries or Router's settings ?

Certainly, we have to find the balanced and optimized solutions / settings.

@CrappyTan
Copy link
Author

Yup, I will try that.
To show I am not going mad 😃

[33 ] ULP wakeup, saving pulse count
[33 ] Pulse count from ULP:4
[33 ] Wifi Setup - Starting
[68 ] Wifi Setup - Setting up WiFi Manager.....
[69 ] Wifi Setup - Setting up WiFi Manager.....done
[69 ] Got stored Credentials. Timeout 60s
[70 ] Wifi Setup - Done
[72 ] Wifi Setup - Connecting
[75 ] Connecting to CrappyIoTconnected! Local IP: 337512970
[259 ] Setting up MQTT Starting
[259 ] Attempting MQTT connection...
[292 ] MQTT connected!
[292 ] Leaving MQTT connect
[292 ] Setting up MQTT Complete
[296 ] Disconnecting from MQTT.
[297 ] MQTT disconnected.
[297 ] Finished. Going to sleep
[297 ] Entering deep sleep

You can see the main work is actually completed in around 60ms. The preamble to get to do work takes 230ms 😆

@khoih-prog
Copy link
Owner

khoih-prog commented Feb 11, 2020

I just had a preliminary test, and it seems that the real culprit is the Router DHCP server. Certainly, it will help if you have faster Router with lighter load.

This is the terminal debug output, showing

  1. @250ms, ESP32 started WiFi
  2. @440ms, ESP32 connected to Router : STA_CONNECTED
  3. @1600ms, ESP32 got IP and WL_CONNECTED : STA_GOT_IP
    This is quite a bit longer (1200ms to get IP) as I'm using my old testing Router as a Bridge, and DHCP server is in another 1-tier Router.
[35		]	Hello
[35		]	Starting WiFiManager
[D][WiFiGeneric.cpp:76] _network_event_task(): _network_event_task: for
[D][WiFiGeneric.cpp:206] espWiFiStart(): espWiFiStart: _eventCallback in
[D][WiFiGeneric.cpp:410] _eventCallback(): Event: 0 - WIFI_READY - core 1
[D][WiFiGeneric.cpp:84] _network_event_task(): _network_event_task: _eventCallback, event 0, event_id 1073505604
[D][WiFiGeneric.cpp:410] _eventCallback(): Event: 2 - STA_START - core 1
[D][WiFiGeneric.cpp:423] _eventCallback(): STA_START: 1
[D][WiFiSTA.cpp:87] _setStatus(): _setStatus 1: 6
[D][WiFiSTA.cpp:94] _setStatus(): _setStatus 2: 6
[D][WiFiGeneric.cpp:428] _eventCallback(): STA_START: 2
[D][WiFiGeneric.cpp:433] _eventCallback(): STA_START: 3
[D][WiFiGeneric.cpp:651] _eventCallback(): _eventCallback: 2
[D][WiFiGeneric.cpp:670] _eventCallback(): _eventCallback: 3 ESP_OK
[D][WiFiGeneric.cpp:90] _network_event_task(): _network_event_task: after _eventCallback
[D][WiFiGeneric.cpp:76] _network_event_task(): _network_event_task: for
[D][WiFiGeneric.cpp:637] _eventCallback(): _eventCallback: SYSTEM_EVENT_WIFI_READY
[D][WiFiGeneric.cpp:651] _eventCallback(): _eventCallback: 2
[D][WiFiGeneric.cpp:670] _eventCallback(): _eventCallback: 3 ESP_OK
[D][WiFiGeneric.cpp:212] espWiFiStart(): espWiFiStart: _eventCallback out
[243		]	Starting WiFiManager. Done
[243		]	Stored: SSID = ****, Pass =****
[245		]	Starting WiFiManager. Finished all setup
[249		]	Got stored Credentials. Timeout 60s
[253		]	Trying to connect SSID = ****, Pass = ****
[258		]	status 2: = WL_DISCONNECTED
[263		]	status 2: = WL_DISCONNECTED
[265		]	status 2: = WL_DISCONNECTED
...
[418		]	status 2: = WL_DISCONNECTED
[443		]	status 2: = WL_DISCONNECTED
[D][WiFiGeneric.cpp:84] _network_event_task(): _network_event_task: _eventCallback, event 44430484, event_id 3
[D][WiFiGeneric.cpp:410] _eventCallback(): Event: 4 - STA_CONNECTED - core 1
[D][WiFiGeneric.cpp:453] _eventCallback(): STA_CONNECTED: 1
[D][WiFiSTA.cpp:87] _setStatus(): _setStatus 1: 0
[D][WiFiGeneric.cpp:458] _eventCallback(): STA_CONNECTED: 2
[D][WiFiGeneric.cpp:463] _eventCallback(): STA_CONNECTED: 3
[D][WiFiGeneric.cpp:651] _eventCallback(): _eventCallback: 2
[D][WiFiGeneric.cpp:670] _eventCallback(): _eventCallback: 3 ESP_OK
[D][WiFiGeneric.cpp:90] _network_event_task(): _network_event_task: after _eventCallback
[D][WiFiGeneric.cpp:76] _network_event_task(): _network_event_task: for
[497		]	status 2: = WL_IDLE_STATUS
[525		]	status 2: = WL_IDLE_STATUS
...
[1550		]	status 2: = WL_IDLE_STATUS
[1575		]	status 2: = WL_IDLE_STATUS
[D][WiFiGeneric.cpp:84] _network_event_task(): _network_event_task: _eventCallback, event 1073410480, event_id 1073537916
[D][WiFiGeneric.cpp:410] _eventCallback(): Event: 7 - STA_GOT_IP - core 1
[D][WiFiGeneric.cpp:539] _eventCallback(): STA IP: 192.168.2.109, MASK: 255.255.0.0, GW: 192.168.2.1
[D][WiFiGeneric.cpp:543] _eventCallback(): STA_GOT_IP: 1
[D][WiFiSTA.cpp:87] _setStatus(): _setStatus 1: 3
[D][WiFiGeneric.cpp:548] _eventCallback(): STA_GOT_IP: 2
[D][WiFiGeneric.cpp:553] _eventCallback(): STA_GOT_IP: 3
[D][WiFiGeneric.cpp:651] _eventCallback(): _eventCallback: 2
[D][WiFiGeneric.cpp:670] _eventCallback(): _eventCallback: 3 ESP_OK
[D][WiFiGeneric.cpp:90] _network_event_task(): _network_event_task: after _eventCallback
[D][WiFiGeneric.cpp:76] _network_event_task(): _network_event_task: for
[1656		]	status 2: = WL_CONNECTED
[1660		]	WiFi connected!

I almost copied / modified the ESP32 WiFi code and saw no issue yet with the slow WiFi connection.

I also tested by modifying Beacon Interval and DTIM Interval without better result.

If you're interested, I'll post the whole (a little bit long) code of this test.

@CrappyTan
Copy link
Author

You need a faster router / dhcp server 😸

Thanks for digging into this. I'd be interested in seeing the code you used as a comparison.

BTW - you posted your WiFi creds in the post above

@khoih-prog
Copy link
Owner

khoih-prog commented Feb 11, 2020

Hi,
This is the test code I used to debug.

  1. You can see all WiFi calls were replaced with local calls
  • WiFi.begin() => WiFi_begin()
  • WiFi.status() => WiFi_status()
    so that we can use local printDebug to know the timeline.
  1. You can use my modified ESP32 WiFi Library for better info
    https://github.com/khoih-prog/arduino-esp32/tree/master/libraries/WiFi/src

  2. You also have to turn on Tools->Core Debug Level -> Debug

//#define ESP32"

// #include <esp_wifi.h>
// #include <WiFiClient.h>

#define ESP_getChipId()   ((uint32_t)ESP.getEfuseMac())

#define LED_ON      HIGH
#define LED_OFF     LOW

String ssid       = "ESP_" + String(ESP_getChipId(), HEX);
String password   = "";

// SSID and PW for your Router
String Router_SSID;
String Router_Pass;

// Use false if you don't like to display Available Pages in Information Page of Config Portal
// Comment out or use true to display Available Pages in Information Page of Config Portal
// Must be placed before #include <ESP_WiFiManager.h>
#define USE_AVAILABLE_PAGES     false

#include <ESP_WiFiManager.h>              //https://github.com/khoih-prog/ESP_WiFiManager

// Indicates whether ESP has WiFi credentials saved from previous session, or double reset detected
bool initialConfig = false;

IPAddress ip(192, 168, 2, 199) ; //WeatherStationESP
IPAddress gateway(192, 168, 2, 1);
IPAddress subnet(255, 255, 255, 0);
IPAddress dns(10, 10, 50, 2); //Google dns

void printDebug(String msg)
{
  Serial.print("[");
  Serial.print(millis());
  Serial.print("\t\t]\t");
  Serial.println(msg);
}

// You have to remove static from these 2 vars declaration in WiFiSTA.cpp
// From
//static wl_status_t _sta_status = WL_NO_SHIELD;
//static EventGroupHandle_t _sta_status_group = NULL;
// To
//wl_status_t _sta_status = WL_NO_SHIELD;
//EventGroupHandle_t _sta_status_group = NULL;
//

extern wl_status_t _sta_status;
extern EventGroupHandle_t _sta_status_group;

bool _autoReconnect = true;
bool _useStaticIp = false;

const char * status_names[] = { "WL_IDLE_STATUS", "WL_NO_SSID_AVAIL", "WL_SCAN_COMPLETED",
                                "WL_CONNECTED", "WL_CONNECT_FAILED", "WL_CONNECTION_LOST", "WL_DISCONNECTED"
                              };
/*
  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;
*/

wl_status_t WiFi_status()
{
  if (!_sta_status_group)
  {
    //printDebug("status 1: = " + String(_sta_status));
    return _sta_status;
  }

  wl_status_t status = (wl_status_t) xEventGroupClearBits(_sta_status_group, 0);

  //printDebug("status 2: = " + String(status_names[status]));

  return status;
}

bool sta_config_equal(const wifi_config_t& lhs, const wifi_config_t& rhs)
{
  if (memcmp(&lhs, &rhs, sizeof(wifi_config_t)) != 0)
  {
    return false;
  }
  return true;
}

wl_status_t WiFi_begin(const char* ssid, const char *passphrase = NULL, int32_t channel = 0, const uint8_t* bssid = NULL, bool connect = true)
{
  //printDebug("WiFi_begin: 1");

  if (!WiFi.enableSTA(true))
  {
    printDebug("STA enable failed!");
    return WL_CONNECT_FAILED;
  }

  //printDebug("WiFi_begin: 2");

  if (!ssid || *ssid == 0x00 || strlen(ssid) > 31)
  {
    printDebug("SSID too long or missing!");
    return WL_CONNECT_FAILED;
  }

  //printDebug("WiFi_begin: 3");

  if (passphrase && strlen(passphrase) > 64)
  {
    printDebug("passphrase too long!");
    return WL_CONNECT_FAILED;
  }

  //printDebug("WiFi_begin: 4");

  wifi_config_t conf;
  memset(&conf, 0, sizeof(wifi_config_t));
  strcpy(reinterpret_cast<char*>(conf.sta.ssid), ssid);

  //printDebug("WiFi_begin: 5");

  if (passphrase) {
    if (strlen(passphrase) == 64)
    {
      // it's not a passphrase, is the PSK
      memcpy(reinterpret_cast<char*>(conf.sta.password), passphrase, 64);
    }
    else
    {
      strcpy(reinterpret_cast<char*>(conf.sta.password), passphrase);
    }
  }

  //printDebug("WiFi_begin: 6");

  if (bssid)
  {
    conf.sta.bssid_set = 1;
    memcpy((void *) &conf.sta.bssid[0], (void *) bssid, 6);
  }

  //printDebug("WiFi_begin: 7");

  if (channel > 0 && channel <= 13)
  {
    conf.sta.channel = channel;
  }

  //printDebug("WiFi_begin: 8");

  wifi_config_t current_conf;
  esp_wifi_get_config(WIFI_IF_STA, &current_conf);

  //printDebug("WiFi_begin: 9");

  if (!sta_config_equal(current_conf, conf))
  {
    if (esp_wifi_disconnect())
    {
      printDebug("disconnect failed!");
      return WL_CONNECT_FAILED;
    }

    esp_wifi_set_config(WIFI_IF_STA, &conf);
  }
  else if (WiFi_status() == WL_CONNECTED)
  {
    return WL_CONNECTED;
  }

  //KH
  // Espressif added this
  else
  {
    esp_wifi_set_config(WIFI_IF_STA, &conf);
  }
  //

  //printDebug("WiFi_begin: 10");

  if (!_useStaticIp)
  {
    if (tcpip_adapter_dhcpc_start(TCPIP_ADAPTER_IF_STA) == ESP_ERR_TCPIP_ADAPTER_DHCPC_START_FAILED) {
      printDebug("dhcp client start failed!");
      return WL_CONNECT_FAILED;
    }
  }
  else
  {
    tcpip_adapter_dhcpc_stop(TCPIP_ADAPTER_IF_STA);
  }

  //printDebug("WiFi_begin: 11");

  if (connect && esp_wifi_connect())
  {
    printDebug("connect failed!");
    return WL_CONNECT_FAILED;
  }

  //printDebug("WiFi_begin: 12");

  return WiFi_status();
}

void setup()
{
  // put your setup code here, to run once:
  // initialize the LED digital pin as an output.

  Serial.begin(115200);
  printDebug("Hello");

  //Local intialization. Once its business is done, there is no need to keep it around
  printDebug("Starting WiFiManager");

  ESP_WiFiManager ESP_wifiManager("ConfigOnDoubleReset");
  printDebug("Starting WiFiManager. Done");

  ESP_wifiManager.setMinimumSignalQuality(-1);

  // We can't use WiFi.SSID() in ESP32 as it's only valid after connected.
  // SSID and Password stored in ESP32 wifi_ap_record_t and wifi_config_t are also cleared in reboot
  // Have to create a new function to store in EEPROM/SPIFFS for this purpose
  Router_SSID = ESP_wifiManager.WiFi_SSID();
  Router_Pass = ESP_wifiManager.WiFi_Pass();

  //Remove this line if you do not want to see WiFi password printed
  printDebug("Stored: SSID = " + Router_SSID + ", Pass = " + Router_Pass);

  // SSID to uppercase
  ssid.toUpperCase();
  printDebug("Starting WiFiManager. Finished all setup");

  if (Router_SSID != "")
  {
    printDebug("Got stored Credentials. Timeout 60s");
    ESP_wifiManager.setConfigPortalTimeout(60); //If no access point name has been previously entered disable timeout.
  }
  else
  {
    printDebug("No stored Credentials. No timeout");
    initialConfig = true;
  }

  // Remove this to force into Config Portal
  //initialConfig = true;

  if (initialConfig)
  {
    ssid.toUpperCase();
    password = "My" + ssid;

    printDebug("Starting configuration portal: AP SSID = " + ssid + ", Pass = " + password );

    //sets timeout in seconds until configuration portal gets turned off.
    //If not specified device will remain in configuration mode until
    //switched off via webserver or device is restarted.
    //ESP_wifiManager.setConfigPortalTimeout(600);

    //it starts an access point
    //and goes into a blocking loop awaiting configuration
    if (!ESP_wifiManager.startConfigPortal((const char *) ssid.c_str(), password.c_str()))
      printDebug("Not connected to WiFi but continuing anyway.");
    else
      printDebug("WiFi connected...yeey :)");
  }

#define WIFI_CONNECT_TIMEOUT        30000L
#define WHILE_LOOP_DELAY            25
#define WHILE_LOOP_STEPS            (WIFI_CONNECT_TIMEOUT / ( 3 * WHILE_LOOP_DELAY ))

  // To force connecting to new Router
  Router_SSID = "New-Router";
  Router_Pass = "New-Pass";

  unsigned long startedAt = millis();

  WiFi.mode(WIFI_STA);
  WiFi.persistent (true);

  printDebug("Trying to connect SSID = " + Router_SSID + ", Pass = " + Router_Pass);

  //wl_status_t connectStatus = WiFi.status();
  wl_status_t connectStatus = WiFi_status();

  while ( (connectStatus != WL_CONNECTED) && (millis() - startedAt < WIFI_CONNECT_TIMEOUT ) )
  {
    //WiFi.begin(Router_SSID.c_str(), Router_Pass.c_str());
    WiFi_begin(Router_SSID.c_str(), Router_Pass.c_str());

    //printDebug("WiFi_begin done");

    int i = 0;

    while (i++ < WHILE_LOOP_STEPS)
    {
      //printDebug("Retry" + String(i));
      connectStatus = WiFi_status();

      if (connectStatus == WL_CONNECTED)
        break;
      else
        delay(WHILE_LOOP_DELAY);
    }
  }

  if (connectStatus == WL_CONNECTED)
  {
    printDebug("WiFi connected!");
  }
  else
    printDebug("Failed to connect");

  printDebug("WiFi done");
}

void loop()
{

}

khoih-prog added a commit that referenced this issue Apr 13, 2020
### Releases 1.0.7

1. Use `just-in-time` scanWiFiNetworks() to reduce connection time necessary for battery-operated DeepSleep application. Thanks to [CrispinP](https://github.com/CrispinP) for identifying, requesting and testing. See [Starting WiFIManger is very slow (2000ms)](#6)
2. Fix bug relating SPIFFS in examples :
 - [ConfigOnSwitchFS](examples/ConfigOnSwitchFS)
 - [ConfigPortalParamsOnSwitch](examples/ConfigPortalParamsOnSwitch)  (now support ArduinoJson 6.0.0+ as well as 5.13.5-)
 - [AutoConnectWithFSParameters](examples/AutoConnectWithFSParameters)
 See [Having issue to read the SPIFF file](#14), Thanks to [OttoKlaasen](https://github.com/OttoKlaasen) to report.
3. Fix [README](README.md). See [Accessing manager after connection](#15)
@khoih-prog khoih-prog added the enhancement New feature or request label Apr 13, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants