AutoConnect icon indicating copy to clipboard operation
AutoConnect copied to clipboard

Unable to connect to main router once ESP32 using Autoconnect goes into broadcasting its SoftIP(captive portal)

Open shaikhfk opened this issue 6 years ago • 28 comments

Hello Hieromon,

Greetings! Chip: ESP32 IDE: Arduino 1.8.9 Developing level: Beginner

I am using Autoconnect library to perform OTA and remember the WiFi Credentials of main router (D-Link router, net gear or mobile hotspot) and help me connect to it directly rather then hard coding the ''SSID'' and ''Password''. This functionality is working fine.

ISSUE 1) When the ESP32 doesn't have credentials configured or the main router is not turned ON, it gets into AP mode and then am able to select the desired router and puts its credentials and it get connected to my main router and i can see that in my mobile, showing "1 device connected", but even after connecting to the main router it keeps on showing the captive portal(As a wifi access point), unless if i remove and plug back the power to ESP32, now as my main router was already ON now it gets directly connected to it and now the captive portal is not shown (if i scan for available Wifi devices) I tried using Config.autoReconnect = true; No difference it makes!

What I want is: When my ESP gets into AP mode (as it couldn't connect to my router) and in between if my main router becomes available it should try to connect to it [automatically] and should get back into ST mode i.e connected to that router.

Can this be done? : If ESP32 is in AP mode and after every 2 mins it can check for that particular router which it was previously connected to and if its available it should try connecting to it and get back into ST mode and hide the Access Point which it was broadcasting.

shaikhfk avatar Nov 19 '19 06:11 shaikhfk

As your requirements are themes of how to implement sketch applications, not AutoConnect feature challenges. The operation to maintain AP_STA after establishing the connection with AP_STA is an intentional specification and is not an issue of AutoConnect.

  1. Change state AP_STA to STA automatically after connection establishment. To shift the mode AP_STA to STA after connection establishment, you can use the onDetect exit routine.

  2. The second part of your requirements

    What I want is: When my ESP gets into AP mode (as it couldn't connect to my router) and in between if my main router becomes available it should try to connect to it [automatically] and should get back into ST mode i.e connected to that router. Can this be done? : If ESP32 is in AP mode and after every 2 mins it can check for that particular router which it was previously connected to and if its available it should try connecting to it and get back into ST mode and hide the Access Point which it was broadcasting.

    I find it difficult to guess how you are going to use AutoConnect. What the meaning of the main or particular router? Is it an access point? Anyway, if you want to check a specific router is available, you can use WiFi.scanNetworks. Also, if you want to check it every 2 minutes, its logic is as follows:

    #include <Arduino.h>
    #include <WiFi.h>
    #include <WebServer.h>
    #include <AutoConnect.h>
    
    AutoConnect       Portal;
    AutoConnectConfig Config;
    bool DetectCP = false;
    unsigned long Tm;
    
    bool detectCaptivePortal(IPAddress apip) {
      DetectCP = true;
      return true;
    }
    
    void setup() {
      Config.autoReconnect = true;
      Portal.config(Config);
      Portal.onDetect(detectCaptivePortal);
      if (Portal.begin()) {
        if (DetectCP) {
          WiFi.mode(WIFI_MODE_STA);
          while (WiFi.getMode() != WIFI_MODE_STA)
            delay(10);
        }
      }
    }
    
    void loop() {
      if (WiFi.status() != WL_CONNECTED) {
        if (millis() - Tm > 2*60*1000) {
          Tm = millis();
          int n = WiFi.scanNetworks(false, true);
          for (int i = 0; i < n; i++) {
            if (WiFi.SSID(i) == String("Your SSID you want")) {
              station_config_t config;
              AutoConnectCredential credt;
              if (credt.load(WiFi.SSID(i).c_str(), &config) >= 0) {
                WiFi.begin((const char*)config.ssid, (const char*)config.password);
                WiFi.waitForConnectResult();
              }
              break;
            }
          }
        }
      }
      else
        Portal.handleClient();
    }
    

Hieromon avatar Nov 20 '19 17:11 Hieromon

Thanks for a quick revert.

What the meaning of the main or particular router? Is it an access point?

Answering to your question: Main/particular router i mean AP [D-link router] on which my ESP will connect. And by specific router i don't mean a static SSID. It should try to connect to last stored SSID and Password (Access Point) even in captive portal only after every 2 mins it should scan and if AP is available then it should connect to AP and now itself should not be AP now it should become ST.

shaikhfk avatar Nov 21 '19 16:11 shaikhfk

Here is my interpretation, can you correct it? I feel your requirements have an important tip for enhancing a library. If it is useful to other users, I will start considering the implementation.

What you want to realize:

  • You have multiple access points that can be used. (they may be in the vicinity or far away)
  • AutoConnect keeps the credentials of those access points. (you have connected in the past)
  • ESP32 will carry across those access points.
  • Use the captive portal when you want to connect to an unknown access point as a new one.
  • When the ESP32 lost WIFI connection, ESP32 will enter the captive portal automatically and starts a detection for the known access points.
    In other words, when the captive portal is active, it scans the SSID broadcast every 2 minutes automatically, and if it detects a known access point, ESP32 will connects to it and automatically transition to STA mode and closes the captive portal.
  • Each access point has a priority. When ESP32 be into an available range of known access points as multiple, it will use the D-Link WiFi router as "main" that has the highest priority.

Assuming my interpretation is correct:

  • After all, you hope to automate the Open SSIDs menu. Its behavior is similar to the WiFi connection feature of iOS and Android smartphones, but it will involve a lot of power consumption. I think that it is not suitable for mobility operation on the premise of a battery drive.
    During in the captive portal, does ESP32 in deep sleep? and will wake up periodically in the 2-minute cycle to scan? If so, you will not be able to operate the captive portal with the web browser. An external stimulus is required to wake ESP32 from deep sleep to operate the captive portal within this case.
  • AutoConnect's Open SSIDs menu achieves the above operations manually. It is not “Auto” but it is still “AutoConnect”. Because you can achieve the above without any library modifications. ("main" priority and deep sleep are not implemented, it will be your pleasure)
#include <memory>
#include <thread>
#include <Arduino.h>
#include <WiFi.h>
#include <WebServer.h>
#include <AutoConnect.h>

#define SCANINTERVAL_MS  (2*60*1000)

AutoConnect       portal;
AutoConnectConfig config;
std::unique_ptr<std::thread>  scanWiFi;

void autoConnect(void) {
  while (1) {
    delay(SCANINTERVAL_MS);
    Serial.print("Probing... ");
    AutoConnectCredential credt;
    station_config_t  staConfig;
    int n = WiFi.scanNetworks(false , true);
    if (n < 0)
      n = 0;
    Serial.printf("%d network(s) found\n", n);
    for (int i = 0; i < credt.entries(); i++) {
      credt.load(i, &staConfig);
      for (uint8_t e = 0; e < n; e++) {
        if (!memcmp(staConfig.bssid, WiFi.BSSID(e), sizeof(station_config_t::bssid))) {
          Serial.printf("%s found, connecting...", (const char*)staConfig.ssid);
          WiFi.begin((const char*)staConfig.ssid, (const char*)staConfig.password);
          WiFi.waitForConnectResult();
          if (WiFi.status() == WL_CONNECTED) {
            Serial.println("connected, restart");
            delay(100);
            ESP.restart();
            delay(1000);
          }
          else {
            Serial.println("failed");
            WiFi.disconnect(false);
          }
        }
      }
    }
    WiFi.scanDelete();
  }
}

void setup() {  
  delay(1000);
  Serial.begin(115200);
  Serial.println();

  portal.onDetect([&](IPAddress apip) {
    Serial.print("Captive portal started, ");
    scanWiFi.reset(new std::thread(autoConnect));
    std::thread*  t1 = scanWiFi.get();
    t1->detach();
    return true;
  });

  portal.begin();
}

void loop() {
  if (WiFi.status() == WL_DISCONNECTED) {
    WiFi.disconnect(true, true);
    delay(1000);
    ESP.restart();
    delay(1000);
  }
  portal.handleClient();
}

Hieromon avatar Nov 22 '19 05:11 Hieromon

This interpreation is correct!

  • You have multiple access points that can be used. (they may be in the vicinity or far away)
  • AutoConnect keeps the credentials of those access points. (you have connected in the past)
  • ESP32 will carry across those access points.
  • Use the captive portal when you want to connect to an unknown access point as a new one.
  • When the ESP32 lost WIFI connection, ESP32 will enter the captive portal automatically and starts a detection for the known access points. In other words, when the captive portal is active, it scans the SSID broadcast every 2 minutes automatically, and if it detects a known access point, ESP32 will connects to it and automatically transition to STA mode and closes the captive portal.
  • Each access point has a priority. When ESP32 be into an available range of known access points as multiple, it will use the D-Link WiFi router as "main" that has the highest priority.

Now answering your question:

During in the captive portal, does ESP32 in deep sleep? and will wake up periodically in the 2-minute cycle to scan?

No, while in captive portal the user can connect to ESP32 and try to either provide the credentials to new AP or can connect to already exisitng AP using OpenSSIDs (NOTE: now while using OpenSSIDs and connecting to pre-stored AP the ESP should get back to STATION mode which is also not happening in current library.) and still if user is not doing any thing in captive mode the ESP should not sleep it should be active and should keep on executing the code written in void loop() {} and when timer is 2mins then it should check for broadcast and should connect to that AP.

I am using your webupdate example could you help me acheive what i want using this example?

shaikhfk avatar Nov 22 '19 16:11 shaikhfk

I understand your request in general, but honestly, I don't think this feature works well for many users.

  • Why do you need to change the state automatically from AP_STA to STA?
  • It seems that you are carrying ESP32 and moving frequently. What are you trying to control with ESP32? What kind of IoT application is it? Can you tell me to the extent you can permit?

If it is far from the commonly used form, I have to give up incorporating this feature into the library.
The feature for the unique form jeopardizes the consistency of the library specifications and the purpose. If the library function adopts many specific requests, the library will be a disguise component for only you. I avoid doing it. The library should be as flat and generic as possible.

First of all, I encourage you to try my proposed code above. If it meets your wishes, consider incorporating only the features you really needed at primitive into the library.

could you help me acheive what i want using this example?

To whom can the act contribute? Here is a community for the open sources, not a place to work for the benefit of a specific person else. If my help is published as an open source and useful to more people, I will help you as much as my time allows. But otherwise, I don't do it except for matters related to how to use AutoConnect.

Hieromon avatar Nov 22 '19 22:11 Hieromon

I tried implementing the code. Its checking for SSID every 2mins and if found it tries to connect it and gets connected, however there are two issues which i am having:

  1. Once the ESP is in captive portal it doesn't keep the code working which was in loop{} i tried as you mentioned on issue 149
AutoConnectConfig::portalTimeout
AutoConnectConfig::retainPortal 
  1. If i once connect to captive portal access point and bring back my main Dlink router online it does not connect to the main router, i can see its checking for SSID on serial monitor every 2 mins it shows

Connecting.. SSID

and then it says

failed

and the cycle continues.

shaikhfk avatar Dec 05 '19 05:12 shaikhfk

Once the ESP is in captive portal it doesn't keep the code working which was in loop{} i tried as you mentioned on issue 149

There is a mistake in my mention. portalTimeout = 1 is correct. AutoConnect::begin will exit in 1[ms] after the station connects when in AP_STA state. The portalTimeout = 0 means no time limit since the portal loop entered. But I think these options I mentioned do not match your requirements. The portalTime measures the time since the station unconnected when AP_STA. If the station as your browser connects once, the portal will continue to loop and AutoConnect:: begin will not exit.

If i once connect to captive portal access point and bring back my main Dlink router online it does not connect to the main router, i can see its checking for SSID on serial monitor every 2 mins it shows

I think there is only a way to monitor nearby SSIDs with sketches. I cannot understand this point. If I should do something, please provide the minimum code that can reproduce the problem. (The sketch code with formatted by the code block tag (Reduce to the reproducible minimum code for the problem)

Hieromon avatar Dec 12 '19 00:12 Hieromon

Hieromon is it possible to have a 2-3mins talk over skype where i can share my screen and update you my concern?

shaikhfk avatar Dec 26 '19 10:12 shaikhfk

Hieromon, there is also one more issue to which i need your help: I want to save data of 5 input pins to remember the last know state into ESP32 without affecting your autoconnect and autocredentials stored data format. Could you help me with this so that i can store my pin values as well as saved credentials?

shaikhfk avatar Jan 07 '20 11:01 shaikhfk

You can save them simply by using the Preferences class of the arduino-esp32. AutoConnect reserves AC_CREDT as the name and key in Preferences. You should use other names and keys for a preference of pin's data.

Hieromon avatar Jan 08 '20 01:01 Hieromon

I tried as you said in order to read it, below is the code

void preferencecheck(){
 Preferences preferences;
 preferences.begin("AC_CREDT", false);
 unsigned int data = preferences.getUInt("AC_CREDT", 0);
 Serial.printf("DATA: %d\n", data);
 /* Close the Preferences */
 preferences.end();
}

But the output i get is DATA: 0 because if key not exist return default value 0 in second argument is passed. What am i doing wrong? I want to read all data written in my EEPROM with respect to name e.g i want to print the following in serial monitor based on stored vales in EEPROM here AC_CREDIT and SSID are just example, in EEPROM it should scan and give me names as well as data. The code i shared is for single AC_CREDIT only is there a way where i can use a for loop instead of defining each name to get the data stored?

AC_CREDIT- DATA : xyx 123. 
SSID- DATA: ssid.

shaikhfk avatar Jan 16 '20 03:01 shaikhfk

I said:

AutoConnect reserves AC_CREDT as the name and key in Preferences. You should use other names and keys for a preference of pin's data.

Why you use AC_CREDT? you cannot access it properly without AutoConnectCredential. You need to use a certain namespace for the pins data you want to save, not AC_CREDT.

Hieromon avatar Jan 16 '20 05:01 Hieromon

I wanted to understand the whole AutoConnectCredential saving process so i wanted to see what all data is stored against which key. I understood your point

AutoConnect reserves AC_CREDT as the name and key in Preferences. You should use other names and keys for a preference of pin's data.

I will use other keywords to store my data its just i want to see all the data stored on ESP.

shaikhfk avatar Jan 16 '20 05:01 shaikhfk

Here: https://hieromon.github.io/AutoConnect/credit.html#the-credential-entry and https://github.com/Hieromon/AutoConnect/blob/c70275d5f48749782b9b7a21517a5e5187432673/src/AutoConnectCredential.cpp#L342-L364

Hieromon avatar Jan 16 '20 06:01 Hieromon

Yes i want to view all data stored to each value on my serial monitor. How can i get all data using for loop? How can i view all the data of key values you shared above?

  • +-+--+-----------------+-+--+--+--+----+----+-----------------+--+
  • |e|ss|ssid\0pass\0bssid|d|ip|gw|nm|dns1|dns2|ssid\0pass\0bssid|\0|
  • +-+--+-----------------+-+--+--+--+----+----+-----------------+--+

shaikhfk avatar Jan 16 '20 06:01 shaikhfk

If you want to dump the native data saved by Preferences to the nvs, you have to use ESP-IDF, not Arduino. The Preferences library of the esp32-arduino is just an nvs wrapper for ESP-IDF. https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/storage/nvs_flash.html Also, you need to understand the allocation structure of ESP32 flash which behaves as Arduino framework. https://github.com/espressif/arduino-esp32/blob/master/tools/partitions/default.csv

Hieromon avatar Jan 16 '20 06:01 Hieromon

To save and view my data i will use the below code:

void setup() {
  Serial.begin(115200);
  Serial.println();
  preferences.begin("iotsharing", false);
  unsigned int reset_times = preferences.getUInt("reset_times", 0);
  reset_times++;
  Serial.printf("Number of restart times: %d\n", reset_times);
  /* Store reset_times to the Preferences */
  preferences.putUInt("reset_times", reset_times);
  preferences.end();
}
void loop() 
{
}

Currently what am asking from you is how can I see all the data saved by AutoConnectCredential on serial monitor?

shaikhfk avatar Jan 17 '20 02:01 shaikhfk

Via Preferences API natively without AutoConnectCredential API?

Hieromon avatar Jan 17 '20 02:01 Hieromon

Whichever is convenient.

shaikhfk avatar Jan 17 '20 04:01 shaikhfk

Begins Preferences with namespace: AC_CREDT, key: AC_CREDT and get size by Preferences::getBytesLength. Then, fetch consecutive bytes by Preferences::getBytes until the size. Refer to the code of AutoConnectCredential below:

https://github.com/Hieromon/AutoConnect/blob/c70275d5f48749782b9b7a21517a5e5187432673/src/AutoConnectCredential.cpp#L601-L658

Hieromon avatar Jan 17 '20 05:01 Hieromon

I am a beginner here so if you could help me print the data on serial monitor using above code will be a big help.

shaikhfk avatar Jan 17 '20 07:01 shaikhfk

It is not an AutoConnect issue, also does not match this topic. However, I introduce the part of the sketch to print the stored credentials as below:

void printCredential(void) {
  AutoConnectCredential  ac;
  station_config_t  entry;

  uint8_t  count = ac.entries();
  if (count > 0) {
    for (int8_t i = 0; i < count; i++) {
      ac.load(i, &entry);
      Serial.printf("\nSSID:%.*s\n", sizeof(entry.ssid), (const char*)entry.ssid);
      Serial.printf("BSSID:");
      for (uint8_t b = 0; b < sizeof(entry.bssid); b++)
        Serial.printf("%02x", entry.bssid[b]);
      Serial.printf("\nPassword:%.*s\n", sizeof(entry.password), (const char*)entry.password);
      Serial.printf("DHCP:%d\n", entry.dhcp);
      Serial.printf("IP:0x%08" PRIx32 "\n", entry.config.sta.ip);
      Serial.printf("Gateway:0x%08" PRIx32 "\n", entry.config.sta.gateway);
      Serial.printf("Netmask:0x%08" PRIx32 "\n", entry.config.sta.netmask);
      Serial.printf("DNS1:0x%08" PRIx32 "\n", entry.config.sta.dns1);
      Serial.printf("DNS2:0x%08" PRIx32 "\n", entry.config.sta.dns2);
    }
    Serial.printf("---\n");
  }
  else
    Serial.println("No entries");
}

AutoConnectCredential is stored by the Preferences API. I also provided an API for access and published the documentation. You need to use that API for proper access. The API allows you to easily print your credentials.

Closed due to it is no longer relevant to this topic.

Hieromon avatar Jan 17 '20 19:01 Hieromon

Regarding captive portal conversation earlier

There is a mistake in my mention. portalTimeout = 1 is correct. AutoConnect::begin will exit in 1[ms] after the station connects when in AP_STA state. The portalTimeout = 0 means no time limit since the portal loop entered.

The issue here is it works fine for the first time, but second time it doesnt tries to open the captive portal nor tries to connect to pre saved SSID. NOTE: Am using your given code it works fine only one time

#include <memory>
#include <thread>
#include <Arduino.h>
#include <WiFi.h>
#include <WebServer.h>
#include <AutoConnect.h>

#define SCANINTERVAL_MS  (2*60*1000)

AutoConnect       portal;
AutoConnectConfig config;
std::unique_ptr<std::thread>  scanWiFi;

void autoConnect(void) {
  while (1) {
    delay(SCANINTERVAL_MS);
    Serial.print("Probing... ");
    AutoConnectCredential credt;
    station_config_t  staConfig;
    int n = WiFi.scanNetworks(false , true);
    if (n < 0)
      n = 0;
    Serial.printf("%d network(s) found\n", n);
    for (int i = 0; i < credt.entries(); i++) {
      credt.load(i, &staConfig);
      for (uint8_t e = 0; e < n; e++) {
        if (!memcmp(staConfig.bssid, WiFi.BSSID(e), sizeof(station_config_t::bssid))) {
          Serial.printf("%s found, connecting...", (const char*)staConfig.ssid);
          WiFi.begin((const char*)staConfig.ssid, (const char*)staConfig.password);
          WiFi.waitForConnectResult();
          if (WiFi.status() == WL_CONNECTED) {
            Serial.println("connected, restart");
            delay(100);
            ESP.restart();
            delay(1000);
          }
          else {
            Serial.println("failed");
            WiFi.disconnect(false);
          }
        }
      }
    }
    WiFi.scanDelete();
  }
}

void setup() {  
  delay(1000);
  Serial.begin(115200);
  Serial.println();

  portal.onDetect([&](IPAddress apip) {
    Serial.print("Captive portal started, ");
    scanWiFi.reset(new std::thread(autoConnect));
    std::thread*  t1 = scanWiFi.get();
    t1->detach();
    return true;
  });

  portal.begin();
}

void loop() {
  if (WiFi.status() == WL_DISCONNECTED) {
    WiFi.disconnect(true, true);
    delay(1000);
    ESP.restart();
    delay(1000);
  }
  portal.handleClient();
}

Then on serial monitor it loops as i wanted by here second time if IP is lost it does not tries to reconnect nor opens the captive portal. Its prints D][WiFiGeneric.cpp:337] _eventCallback(): Event: 8 - STA_LOST_IP on serial monitor.

shaikhfk avatar Jan 23 '20 04:01 shaikhfk

Here is my interpretation, can you correct it? I feel your requirements have an important tip for enhancing a library. If it is useful to other users, I will start considering the implementation.

What you want to realize:

  • You have multiple access points that can be used. (they may be in the vicinity or far away)
  • AutoConnect keeps the credentials of those access points. (you have connected in the past)
  • ESP32 will carry across those access points.
  • Use the captive portal when you want to connect to an unknown access point as a new one.
  • When the ESP32 lost WIFI connection, ESP32 will enter the captive portal automatically and starts a detection for the known access points. In other words, when the captive portal is active, it scans the SSID broadcast every 2 minutes automatically, and if it detects a known access point, ESP32 will connects to it and automatically transition to STA mode and closes the captive portal.
  • Each access point has a priority. When ESP32 be into an available range of known access points as multiple, it will use the D-Link WiFi router as "main" that has the highest priority.

Assuming my interpretation is correct:

  • After all, you hope to automate the Open SSIDs menu. Its behavior is similar to the WiFi connection feature of iOS and Android smartphones, but it will involve a lot of power consumption. I think that it is not suitable for mobility operation on the premise of a battery drive. During in the captive portal, does ESP32 in deep sleep? and will wake up periodically in the 2-minute cycle to scan? If so, you will not be able to operate the captive portal with the web browser. An external stimulus is required to wake ESP32 from deep sleep to operate the captive portal within this case.
  • AutoConnect's Open SSIDs menu achieves the above operations manually. It is not “Auto” but it is still “AutoConnect”. Because you can achieve the above without any library modifications. ("main" priority and deep sleep are not implemented, it will be your pleasure)
#include <memory>
#include <thread>
#include <Arduino.h>
#include <WiFi.h>
#include <WebServer.h>
#include <AutoConnect.h>

#define SCANINTERVAL_MS  (2*60*1000)

AutoConnect       portal;
AutoConnectConfig config;
std::unique_ptr<std::thread>  scanWiFi;

void autoConnect(void) {
  while (1) {
    delay(SCANINTERVAL_MS);
    Serial.print("Probing... ");
    AutoConnectCredential credt;
    station_config_t  staConfig;
    int n = WiFi.scanNetworks(false , true);
    if (n < 0)
      n = 0;
    Serial.printf("%d network(s) found\n", n);
    for (int i = 0; i < credt.entries(); i++) {
      credt.load(i, &staConfig);
      for (uint8_t e = 0; e < n; e++) {
        if (!memcmp(staConfig.bssid, WiFi.BSSID(e), sizeof(station_config_t::bssid))) {
          Serial.printf("%s found, connecting...", (const char*)staConfig.ssid);
          WiFi.begin((const char*)staConfig.ssid, (const char*)staConfig.password);
          WiFi.waitForConnectResult();
          if (WiFi.status() == WL_CONNECTED) {
            Serial.println("connected, restart");
            delay(100);
            ESP.restart();
            delay(1000);
          }
          else {
            Serial.println("failed");
            WiFi.disconnect(false);
          }
        }
      }
    }
    WiFi.scanDelete();
  }
}

void setup() {  
  delay(1000);
  Serial.begin(115200);
  Serial.println();

  portal.onDetect([&](IPAddress apip) {
    Serial.print("Captive portal started, ");
    scanWiFi.reset(new std::thread(autoConnect));
    std::thread*  t1 = scanWiFi.get();
    t1->detach();
    return true;
  });

  portal.begin();
}

void loop() {
  if (WiFi.status() == WL_DISCONNECTED) {
    WiFi.disconnect(true, true);
    delay(1000);
    ESP.restart();
    delay(1000);
  }
  portal.handleClient();
}

Hello,

I just wanted to add that I had to modify this skeleton code just a bit to make it work.

Given an ESP that has previous WiFi library credentials stored, And AutoConnect attempts autoReconnect routine on Boot, And AUtoConnect does not find the ssid, so moves to captive portal

When the skeleton sketch launches thread to scan

Then, reconnection will fail with WiFi.event() == 1

I just modified the skeleton if statement slightly as such to work around this issue:

if (WiFi.status() == WL_CONNECTED) {
            Serial.println("connected, restart");
            delay(100);
            ESP.restart();
            delay(1000);
          }
          else if (WiFi.status() == WL_NO_SSID_AVAIL) 
          {
            Serial.println("Error, WL_NO_SSID_AVAIL. Resetting ESP WiFi cache and trying again...");
            WiFi.disconnect();
            WiFi.begin((const char*)staConfig.ssid, (const char*)staConfig.password);
            WiFi.waitForConnectResult();
          }
          else {
            Serial.println("failed");
            Serial.printf("[scanforNets] WiFi.status() = %d\n",WiFi.status());
            WiFi.disconnect(false);
          }

@Hieromon could you please advise what docs to read to understand why this behavior happens?

Thanks!

ark02 avatar Jan 14 '21 04:01 ark02

@ark02 It might be better to consider using Captive portal on-demand starting. Have you? Launch the captive portal on-demand at losing WiFi

Hieromon avatar Jan 15 '21 10:01 Hieromon

these thread detach / scanning function no longer work with latest esp32 core, I get pthread exception and bootloop

Can we replace all of the std::thread code and instead call the same logic as whileCaptivePortal exit routine?

Thanks

ark02 avatar Aug 04 '22 05:08 ark02

@ark02 I have not yet fully tested esp32 2.0.4 and am not aware of your reported limitation regarding std::threads, but I will re-open this topic and resume tracking the issue. Which ESP32 module type occurs the above limitations you have?

Hieromon avatar Aug 05 '22 09:08 Hieromon

Hi,

We are using ESP32D and ESP32E DevkitC

We switched to using the implementation you quoted here

Not sure if it is working in the same way, as I am also confused from the API docs how to use autoRise and retainPortal together to ensure that, upon disconnect, the above function will still run while AP is being served

I assume if portalTimeout is set, the rest of the main loop() function will be allowed to run while AP and DNS are still being served in the background?

Also, what would be the purpose of

    WiFi.setAutoReconnect(true);
    WiFi.persistent(true);

And do we need them anymore with the new whileCaptivePortal implementation?

ark02 avatar Aug 12 '22 02:08 ark02