Hello @khoih
Firstly thank you for contributing this library. I was having difficulty successfully running other WiFi manager libraries on my ESP32 wroom dev board and finally found success using and adapting your ConfigOnStartup.ino example, however I am a little stuck now.
On its first ever startup I need the program to run the Wifi portal segment of code and wait for Wifi credentials to be entered before proceeding with the rest of the code. Thereafter, on subsequent bootups the ESP32 must be able to detect that there are stored wifi credentials and simply use the stored Wifi credentials without starting up the Wifi portal. The only time it must run the Wifi portal again is when a hardware pushbutton is pressed. I have adapted the program as follows:
/****************************************************************************************************************************
ConfigOnStartup.ino
For ESP8266 / ESP32 boards
ESP_WiFiManager is a library for the ESP8266/ESP32 platform (https://github.com/esp8266/Arduino) to enable easy
configuration and reconfiguration of WiFi credentials using a Captive Portal. Inspired by:
http://www.esp8266.com/viewtopic.php?f=29&t=2520
https://github.com/chriscook8/esp-arduino-apboot
https://github.com/esp8266/Arduino/blob/master/libraries/DNSServer/examples/CaptivePortalAdvanced/
Modified from Tzapu https://github.com/tzapu/WiFiManager
and from Ken Taylor https://github.com/kentaylor
Built by Khoi Hoang https://github.com/khoih-prog/ESP_WiFiManager
Licensed under MIT license
Version: 1.0.8
Version Modified By Date Comments
------- ----------- ---------- -----------
1.0.0 K Hoang 07/10/2019 Initial coding
1.0.1 K Hoang 13/12/2019 Fix bug. Add features. Add support for ESP32
1.0.2 K Hoang 19/12/2019 Fix bug thatkeeps ConfigPortal in endless loop if Portal/Router SSID or Password is NULL.
1.0.3 K Hoang 05/01/2020 Option not displaying AvailablePages in Info page. Enhance README.md. Modify examples
1.0.4 K Hoang 07/01/2020 Add RFC952 setHostname feature.
1.0.5 K Hoang 15/01/2020 Add configurable DNS feature. Thanks to @Amorphous of https://community.blynk.cc
1.0.6 K Hoang 03/02/2020 Add support for ArduinoJson version 6.0.0+ ( tested with v6.14.1 )
1.0.7 K Hoang 13/04/2020 Reduce start time, fix SPIFFS bug in examples, update README.md
1.0.8 K Hoang 10/06/2020 Fix STAstaticIP issue. Restructure code. Add LittleFS support for ESP8266 core 2.7.1+
*****************************************************************************************************************************/
/****************************************************************************************************************************
This example will open a configuration portal for 60 seconds when first powered up if the boards has stored WiFi Credentials.
Otherwise, it'll stay indefinitely in ConfigPortal until getting WiFi Credentials and connecting to WiFi
ConfigOnSwitch is a a bettter example for most situations but this has the advantage
that no pins or buttons are required on the ESP32/ESP8266 device at the cost of delaying
the user sketch for the period that the configuration portal is open.
Also in this example a password is required to connect to the configuration portal
network. This is inconvenient but means that only those who know the password or those
already connected to the target WiFi network can access the configuration portal and
the WiFi network credentials will be sent from the browser over an encrypted connection and
can not be read by observers.
*****************************************************************************************************************************/
#if !( defined(ESP8266) || defined(ESP32) )
#error This code is intended to run only on the ESP8266 and ESP32 boards ! Please check your Tools->Board setting.
#endif
// Use from 0 to 4. Higher nimber, more debugging messages and memory usage.
#define _WIFIMGR_LOGLEVEL_ 4
//For ESP32, To use ESP32 Dev Module, QIO, Flash 4MB/80MHz, Upload 921600
//Ported to ESP32
#include <esp_wifi.h>
#include <WiFi.h>
#include <WiFiClient.h>
#define ESP_getChipId() ((uint32_t)ESP.getEfuseMac())
#define LED_ON HIGH
#define LED_OFF LOW
// SSID and PW for Config Portal
String ssid = "ESP_" + String(ESP_getChipId(), HEX);
const char* password = "your_password";
// SSID and PW for your Router
String Router_SSID="";
String Router_Pass="";
IPAddress stationIP = IPAddress(192, 168, 2, 114);
IPAddress gatewayIP = IPAddress(192, 168, 2, 1);
IPAddress netMask = IPAddress(255, 255, 255, 0);
IPAddress dns1IP = gatewayIP;
IPAddress dns2IP = IPAddress(8, 8, 8, 8);
// 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
//https://github.com/khoih-prog/ESP_WiFiManager
#include <ESP_WiFiManager.h>
// Onboard LED I/O pin on NodeMCU board
const int PIN_LED = 2; // D4 on NodeMCU and WeMos. GPIO2/ADC12 of ESP32. Controls the onboard LED.
//Function responsible for connecting ESP32 to WifiNetwork via webportal
void ConnectToWifiNetwork();
// Use this to default DHCP hostname to ESP8266-XXXXXX or ESP32-XXXXXX
//ESP_WiFiManager ESP_wifiManager; //**1 Initialising Wifi Manager here allows program to compile successfully however credentials are erased on every bootup of the ESP32
bool WebServerFlag=0;
bool CheckWifiCredentials=1;
//Checks if project is still connected to a WiFi network
void heartBeatPrint(void)
{
if (WiFi.status() == WL_CONNECTED)
Serial.println("Connected"); //Connected to WiFi
else{
Serial.println("Failed"); //Not connected to WiFi
ConnectToWifiNetwork();
}
}
void check_status()
{
static ulong checkstatus_timeout = 0;
#define HEARTBEAT_INTERVAL 10000L
// Print hearbeat every HEARTBEAT_INTERVAL (10) seconds.
if ((millis() > checkstatus_timeout) || (checkstatus_timeout == 0))
{
heartBeatPrint();
checkstatus_timeout = millis() + HEARTBEAT_INTERVAL;
}
}
void setup(){
//Initialize the LED digital pin as an output.
pinMode(PIN_LED, OUTPUT);
//Initialise pin D18 as input to trigger WifiManager code
pinMode(18, INPUT_PULLUP);
Serial.begin(115200);
ConnectToWifiNetwork();
}
void ConnectToWifiNetwork(){
Serial.println("\nConnectToWifiNetwork() executed");
unsigned long startedAt = millis();
//Check if credentials are available. Connect the ESP32 to Wifi network with previously stored credentials
//**2. This segment of code does not work unless "ESP_WiFiManager ESP_wifiManager;" is declared first. However, when this is defined here it opens the wifi portal even before checking if wifi credentials are available
if(CheckWifiCredentials==1){
Serial.println("Checking stored wifi credentials");
Router_SSID = ESP_wifiManager.WiFi_SSID();
Router_Pass = ESP_wifiManager.WiFi_Pass();
Serial.println("Stored: SSID=" + Router_SSID + ", Pass=" + Router_Pass);
}
//Only start the WifiManager web page requesting wifi credentials if credentials are not available
if(Router_SSID==""){
Serial.println("Opening configuration portal.");
//Use this to default DHCP hostname to ESP32-XXXXXX
//ESP_WiFiManager ESP_wifiManager;
ESP_wifiManager.setMinimumSignalQuality(-1);
ESP_wifiManager.setSTAStaticIPConfig(stationIP, gatewayIP, netMask, dns1IP, dns2IP);
//Device will remain in configuration mode until switched off via webserver.
digitalWrite(PIN_LED, LED_ON); // turn the LED on by making the voltage LOW to tell us we are in configuration mode.
// SSID to uppercase
ssid.toUpperCase();
}
if (!ESP_wifiManager.startConfigPortal((const char *) ssid.c_str(), password)){
Serial.println("Failed to connect to WiFi network. Please check credentials and try again.");
Router_SSID=""; //To bypass the stored Wifi credentials and force the ESP32 to open the Wifi portal so that a new network with new Wifi credentials can be selected if the previous network is not available or incorrect credentials were entered then they can be rectified
CheckWifiCredentials=0;
ConnectToWifiNetwork();
}
else
Serial.println("Connection to Wifi network is successful");
digitalWrite(PIN_LED, LED_OFF); // Turn led off as we are not in configuration mode.
// For some unknown reason webserver can only be started once per boot up
// so webserver can not be used again in the sketch.
if(WebServerFlag==0){ //Used a flag to make sure it only runs once
#define WIFI_CONNECT_TIMEOUT 30000L
#define WHILE_LOOP_DELAY 200L
#define WHILE_LOOP_STEPS (WIFI_CONNECT_TIMEOUT / ( 3 * WHILE_LOOP_DELAY ))
WebServerFlag=1;
}
//This segment of code is responsible for assigning the ESP32 a IP address connecting the ESP32 to the Wifi network selected on the webpage
startedAt = millis();
while ( (WiFi.status() != WL_CONNECTED) && (millis() - startedAt < WIFI_CONNECT_TIMEOUT ) ){
WiFi.mode(WIFI_STA);
WiFi.persistent (true);
// We start by connecting to a WiFi network
Serial.print("Connecting to ");
Serial.println(Router_SSID);
WiFi.config(stationIP, gatewayIP, netMask);
//WiFi.config(stationIP, gatewayIP, netMask, dns1IP, dns2IP);
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);
}
}
Serial.print("After waiting ");
Serial.print((millis() - startedAt) / 1000);
Serial.print(" secs more in setup(), connection result is ");
if (WiFi.status() == WL_CONNECTED)
{
Serial.print("Connected. Local IP: ");
Serial.println(WiFi.localIP());
}
else{
Serial.println("Failed to connect to network. Please try again");
Serial.println(ESP_wifiManager.getStatus(WiFi.status()));
ConnectToWifiNetwork();
}
}
void loop()
{
// put your main code here, to run repeatedly
Serial.println("Void loop executed");
check_status();
//External pushbutton used to change Wifi credentials using Wifi portal
if (digitalRead(18)==LOW) {
Serial.println("ESP32 has been disconnected. Wifi credentials are still saved");
WiFi.disconnect(true);
Router_SSID=""; //To bypass the stored Wifi credentials and force the ESP32 to open the Wifi portal so that a new network with new Wifi credentials can be selected
//ESP_wifiManager.resetSettings(); //Does not erase wifi credentials
delay(2000);
}
delay(1000);
}
I am looking for a way to enable the ESP32 to check if it has stored credentials first before running the portal but am unable to use the commands, mentioned in point 2 ( Router_SSID = ESP_wifiManager.WiFi_SSID(); Router_Pass = ESP_wifiManager.WiFi_Pass();
) in above code, because it requires ESP_WiFiManager ESP_wifiManager;
to be declared before it. If I declare ESP_WiFiManager ESP_wifiManager;
anywhere before point 2 then, although credentials entered are stored and are not erased every time the ESP32 is booted up (which is what I want to happen), it opens up the wifi portal without even checking if stored credentials are available (because it opens up the portal as soon as it executes the ESP_WiFiManager ESP_wifiManager;
which I obviously do not want happening) . If I declare ESP_WiFiManager ESP_wifiManager;
globally, as i have shown in point 1, then there is no issue of the wifi portal opening when its not suppose to, however wifi credentials are then not being stored permanently (or more accurately speaking, the credentials are being erased everytime the ESP32 is booted). So this means I cannot declare ESP_WiFiManager ESP_wifiManager;
globally and neither can I declare it in the program for the reasons mentioned above. I am hoping that there is another function or method of checking if any credentials are stored in ESP32 memory without needing to use Router_SSID = ESP_wifiManager.WiFi_SSID(); Router_Pass = ESP_wifiManager.WiFi_Pass();
because it looks as if this might solve my problem. Please advise.