- Notifications
You must be signed in to change notification settings - Fork99
This is an ESP32 / ESP8266 WiFi Connection Manager with fallback web configuration portal. Use this library for configuring ESP32 (including ESP32-S2 and ESP32-C3), ESP8266 modules' WiFi, etc. Credentials at runtime. You can also specify static DNS servers, personalized HostName, fixed or random AP WiFi channel. With examples supporting ArduinoJson
License
khoih-prog/ESP_WiFiManager
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
- Important Breaking Change from v1.8.0
- Important Note
- Why do we need this ESP_WiFiManager library
- Changelog
- Prerequisites
- Installation
- Note for Platform IO using ESP32 LittleFS
- HOWTO Fix
Multiple DefinitionsLinker Error - HOWTO Use analogRead() with ESP32 running WiFi and/or BlueTooth (BT/BLE)
- How It Works
- HOWTO Basic configurations
- 1. Using default for every configurable parameter
- 2. Using many configurable parameters
- 3. Using STA-mode DHCP, but don't like to change to static IP or display in Config Portal
- 4. Using STA-mode DHCP, but permit to change to static IP and display in Config Portal
- 5. Using STA-mode StaticIP, and be able to change to DHCP IP and display in Config Portal
- 6. Using STA-mode StaticIP and configurable DNS, and be able to change to DHCP IP and display in Config Portal
- 7. Using STA-mode StaticIP and auto DNS, and be able to change to DHCP IP and display in Config Portal
- 8. Not using NTP to avoid issue with some WebBrowsers, especially in CellPhone or Tablets.
- 9. Using NTP feature with CloudFlare. System can hang until you have Internet access for CloudFlare.
- 10. Using NTP feature without CloudFlare to avoid system hang if no Internet access for CloudFlare.
- 11. Using random AP-mode channel to avoid conflict
- 12. Using fixed AP-mode channel, for example channel 3
- 13. Setting STA-mode static IP
- 14. Using AUTOCONNECT_NO_INVALIDATE feature
- 15. Using CORS (Cross-Origin Resource Sharing) feature
- 16. Using MultiWiFi auto(Re)connect feature
- 17. How to auto getting _timezoneName
- 18. How to get TZ variable to configure Timezone
- 19. How to use the TZ variable to configure Timezone
- HOWTO Open Config Portal
- HOWTO Add Dynamic Parameters
- 1. Determine the variables to be configured via Config Portal (CP)
- 2. Initialize the variables to prepare for Config Portal (CP)
- 2.1 Use the following simple constructor for simple variables such as
thingspeakApiKey,pinSdaandpinScl - 2.2 For example, to create a new
ESP_WMParameterobjectp_thingspeakApiKeyforthingspeakApiKey - 2.3 Use the more complex following constructor for variables such as
sensorDht22 - 2.4 For example, to create a new
ESP_WMParameterobjectp_sensorDht22forsensorDht22
- 2.1 Use the following simple constructor for simple variables such as
- 3. Add the variables to Config Portal (CP)
- 4. Save the variables configured in Config Portal (CP)
- 5. Write to FS (SPIFFS, LittleFS, etc.) using JSON format
- 6. Read from FS using JSON format
- So, how it works?
- Documentation
- Examples
- Example ConfigOnDRD_FS_MQTT_Ptr
- Debug Terminal Output Samples
- 1. ConfigOnSwitchFS_MQTT_Ptr on ESP8266_NODEMCU_ESP12E
- 2. ESP32_FSWebServer_DRD on ESP32_DEV
- 3. ESP32_FSWebServer_DRD on ESP32_DEV using newly-supported LittleFS
- 4. ConfigOnDRD_FS_MQTT_Ptr_Complex on ESP32_DEV
- 5. ConfigOnDRD_FS_MQTT_Ptr_Medium on ESP8266_NODEMCU_ESP12E
- 6. ConfigOnDoubleReset on ESP32S2_DEV
- 7. ConfigOnDoubleReset on ESP32_DEV
- 8. ConfigOnDoubleReset on ESP32S2_DEV
- 9. ESP32_FSWebServer_DRD on ESP32C3_DEV using SPIFFS
- 10. ConfigOnDoubleReset on ESP32S3_DEV
- 11. ConfigOnDoubleReset using LittleFS on ESP32C3_DEV
- Debug
- Troubleshooting
- Issues
- Contributions and Thanks
- Contributing
- License and credits
- Copyright
ESP32chipID is now correct and unique. The previous releases' 32-bit wrongchipID is mainly the 24-bitOrganizational Unique Identifier (OUI) plus 8 bits from the correct chipID. That's whyESP_getChipId() function can return duplicated values if the boards are from the same batch.
For example
Chip_ID_64 : 0x98F4AB085288chipOUI : 0x98F4ABchipId : 0x85288getEfuseMac: 0x885208ABF498
Please have a look atHOWTO FixMultiple Definitions Linker Error
From v1.9.0, you just use
#include<ESP_WiFiManager.h>//https://github.com/khoih-prog/ESP_WiFiManager
instead of both
#include<ESP_WiFiManager.h>//https://github.com/khoih-prog/ESP_WiFiManager// To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error#include<ESP_WiFiManager-Impl.h>//https://github.com/khoih-prog/ESP_WiFiManager
For complex project havingMultiple Definitions Linker Error issue, you can use in many files (Be careful:.hpp, not.h)
#include<ESP_WiFiManager.hpp>//https://github.com/khoih-prog/ESP_WiFiManager
but only in main(), .ino with setup() to avoidMultiple Definitions Linker Error
#include<ESP_WiFiManager.h>//https://github.com/khoih-prog/ESP_WiFiManager
It's advisable to use v1.9.0+
Please have a look atHOWTO FixMultiple Definitions Linker Error
From v1.8.0, you must use
#include<ESP_WiFiManager.h>//https://github.com/khoih-prog/ESP_WiFiManager// To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error#include<ESP_WiFiManager-Impl.h>//https://github.com/khoih-prog/ESP_WiFiManager
instead of only
#include<ESP_WiFiManager.h>//https://github.com/khoih-prog/ESP_WiFiManager
ThisESP_WiFiManager has just been modified to create the newESPAsync_WiFiManager Library in order to use the better and more efficientESPAsyncWebServer Library, instead of the (ESP8266)WebServer library.
The newESPAsync_WiFiManager library is based on and sync'ed withESP_WiFiManager. Therefore, all the features currently supported by thisESP_WiFiManager will be available to the new library. The code change is to port to the new library is also very negligible,mostly just changing the Class name from ESP_WiFiManager to ESPAsync_WiFiManager.
Why do we need the new AsyncESPAsync_WiFiManager library
- Using asynchronous network means that you can handlemore than one connection at the same time
- You are called once the request is ready and parsed
- When you send the response, you areimmediately ready to handle other connections while the server is taking care of sending the response in the background
- Speed is OMG
- Easy to use API, HTTP Basic and Digest MD5 Authentication (default), ChunkedResponse
- Easily extendible to handleany type of content
- Supports Continue 100
- Async WebSocket plugin offering different locations without extra servers or ports
- Async EventSource (Server-Sent Events) plugin to send events to the browser
- URL Rewrite plugin for conditional and permanent url rewrites
- ServeStatic plugin that supports cache, Last-Modified, default index and more
- Simple template processing engine to handle templates
To appreciate the power of theESPAsyncWebServer and underlying Async libraries, please compare the more efficientAsync_ESP32_FSWebServer example example code against the code of its complicated twinESP32_FSWebServer.
Thanks tocancodr for requesting an enhancement inIssue #29: Is it possible to use AsyncWebServer.h instead of WebServer.h?, leading to the newESPAsync_WiFiManager Library.
Why do we need thisESP_WiFiManager library
This is a WiFiManager Library for configuring/auto(re)connectingESP8266/ESP32 modules to the best or availableMultiWiFi APs at runtime. Configuration data to be saved in eitherLittleFS,SPIFFS orEEPROM. Default Credentials as well as Dynamic custom parameters can be added and modified easily.DoubleResetDetector is used to force Config Portal opening even if the Credentials are still valid.
This library is designed to help you to eliminatehardcoding your Wifi credentials for ESP8266 and ESP32, and updating/reflashing every time you need to change them.
With versionv1.3.0 or later, you can use:
LittleFS for ESP32
With versionv1.1.0 or later, you can configure:
Multiple WiFi Credentials (SSID, Password) and system will autoconnect to the best and available WiFi SSID.
ThisESP_WiFiManager library currently supports these following boards:
- ESP8266 and ESP32-based boards using EEPROM, SPIFFS or LittleFS.
- ESP32-S2 (ESP32-S2 Saola, AI-Thinker ESP-12K, etc.) using EEPROM, SPIFFS or LittleFS.
- ESP32-C3 (ARDUINO_ESP32C3_DEV) using EEPROM, SPIFFS or LittleFS.
- ESP32-S3 (ESP32S3_DEV, ESP32_S3_BOX, UM TINYS3, UM PROS3, UM FEATHERS3, etc.) using EEPROM, SPIFFS or LittleFS.
This library is based on, modified, bug-fixed and improved from:
to add support toESP32 besidesESP8266.
This is anESP32 / ESP8266 WiFi Connection manager with fallback web ConfigPortal.It's using a web ConfigPortal, served from theESP32 / ESP8266, and operating as an access point.
Arduino IDE 1.8.19+for Arduino.ESP8266 Core 3.0.2+for ESP8266-based boards.. To use ESP8266 core 2.7.1+ for LittleFS.
ESP32 Core 2.0.5+for ESP32-based boards.ESP_DoubleResetDetector v1.3.2+if using DRD feature. To install, check. Use v1.1.0+ if using LittleFS for ESP32.
ESP_MultiResetDetector v1.3.2+if using MRD feature. To install, check.
LittleFS_esp32 v1.0.6+for ESP32-based boards using LittleFS with ESP32 corev1.0.5-. To install, check.Notice: This
LittleFS_esp32 libraryhas been integrated to ArduinoESP32 core v1.0.6+ andyou don't need to install it if using ESP32 core v1.0.6+
The best and easiest way is to useArduino Library Manager. Search forESP_WiFiManager, then select / install the latest version. You can also use this link for more detailed instructions.
- Navigate toESP_WiFiManager page.
- Download the latest release
ESP_WiFiManager-master.zip. - Extract the zip file to
ESP_WiFiManager-masterdirectory - Copy the whole
ESP_WiFiManager-masterfolder to Arduino libraries' directory such as~/Arduino/libraries/.
- InstallVS Code
- InstallPlatformIO
- InstallLatest ESP_WiFiManager library by usingLibrary Manager. Search forESP_WiFiManager inPlatform.io Author's Libraries
- Use includedplatformio.ini file from examples to ensure that all dependent libraries will installed automatically. Please visit documentation for the other options and examples atProject Configuration File
From esp32 corev1.0.6+,LittleFS_esp32 v1.0.6 has been included and this step is not necessary anymore.
In Platform IO, to fix the error when usingLittleFS_esp32 v1.0 for ESP32-based boards with ESP32 core v1.0.4- (ESP-IDF v3.2-), uncomment the following line
from
//#define CONFIG_LITTLEFS_FOR_IDF_3_2 /* For old IDF - like in release 1.0.4 */to
#defineCONFIG_LITTLEFS_FOR_IDF_3_2/* For old IDF - like in release 1.0.4*/
It's advisable to use the latestLittleFS_esp32 v1.0.5+ to avoid the issue.
Thanks toRoshan to report the issue inError esp_littlefs.c 'utime_p'
The current library implementation, usingxyz-Impl.h instead of standardxyz.cpp, possibly creates certainMultiple Definitions Linker error in certain use cases.
You can use
#include<ESP_WiFiManager.hpp>//https://github.com/khoih-prog/ESP_WiFiManager
in many files. But be sure to use the following#include <ESP_WiFiManager.h>in just 1.h,.cpp or.ino file, which mustnot be included in any other file, to avoidMultiple Definitions Linker Error
// To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error#include<ESP_WiFiManager.h>//https://github.com/khoih-prog/ESP_WiFiManager
CheckConfigOnDoubleReset_Multi for an example how and where to do so.
Have a look at the discussion inDifferent behaviour using the src_cpp or src_h lib #80
Please have a look atESP_WiFiManager Issue 39: Not able to read analog port when using the autoconnect example to have more detailed description and solution of the issue.
ADC1controls ADC function for pinsGPIO32-GPIO39ADC2controls ADC function for pinsGPIO0, 2, 4, 12-15, 25-27
Look in fileadc_common.c
In
ADC2, there're two locks used for different cases:
lock shared with app and Wi-Fi:ESP32:When Wi-Fi using the
ADC2, we assume it will never stop, so app checks the lock and returns immediately if failed.ESP32S2:The controller's control over theADCis determined by the arbiter. There is no need to control by lock.lock shared between tasks:when several tasks sharing the
ADC2, we want to guaranteeall the requests will be handled.Since conversions are short (about 31us), app returns the lock very soon,we use a spinlock to stand there waiting to do conversions one by one.adc2_spinlock should be acquired first, then adc2_wifi_lock or rtc_spinlock.
- In order to use
ADC2for other functions, we have toacquire complicated firmware locks and very difficult to do - So, it's not advisable to use
ADC2with WiFi/BlueTooth (BT/BLE). - Use
ADC1, and pins GPIO32-GPIO39 - If somehow it's a must to use those pins serviced by
ADC2(GPIO0, 2, 4, 12, 13, 14, 15, 25, 26 and 27), use thefix mentioned at the end ofESP_WiFiManager Issue 39: Not able to read analog port when using the autoconnect example to work with ESP32 WiFi/BlueTooth (BT/BLE).
- TheConfigOnSwitch example shows how it works and should be used as the basis for a sketch that uses this library.
- The concept of ConfigOnSwitch is that a new
ESP32 / ESP8266will start a WiFi ConfigPortal when powered up and save the configuration data in non volatile memory. Thereafter, the ConfigPortal will only be started again if a button is pushed on theESP32 / ESP8266module. - Using any WiFi enabled device with a browser (computer, phone, tablet) connect to the newly created Access Point (AP) using configurable SSID and Password (specified in sketch)
// SSID and PW for Config PortalString ssid ="ESP_" + String(ESP_getChipId(), HEX);constchar* password ="your_password";
then connect WebBrowser to configurable ConfigPortal IP address, default is192.168.4.1
- Choose one of the access points scanned, enter password, clickSave.
- ESP will restart, then try to connect to the WiFi netwotk using STA-only mode,without running the ConfigPortal WebServer and WiFi AP. SeeAccessing manager after connection.
- Include in your sketch
#ifdef ESP32 #include<esp_wifi.h> #include<WiFi.h> #include<WiFiClient.h> #include<WiFiMulti.h> WiFiMulti wifiMulti;// LittleFS has higher priority than SPIFFS #if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 2) ) #defineUSE_LITTLEFStrue #defineUSE_SPIFFSfalse #elif defined(ARDUINO_ESP32C3_DEV)// For core v1.0.6-, ESP32-C3 only supporting SPIFFS and EEPROM. To use v2.0.0+ for LittleFS #defineUSE_LITTLEFSfalse #defineUSE_SPIFFStrue #endif #if USE_LITTLEFS// Use LittleFS #include"FS.h"// Check cores/esp32/esp_arduino_version.h and cores/esp32/core_version.h//#if ( ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(2, 0, 0) ) //(ESP_ARDUINO_VERSION_MAJOR >= 2) #if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 2) ) #warning Using ESP32 Core 1.0.6 or 2.0.0+// The library has been merged into esp32 core from release 1.0.6 #include<LittleFS.h>// https://github.com/espressif/arduino-esp32/tree/master/libraries/LittleFS FS* filesystem = &LittleFS; #defineFileFS LittleFS #defineFS_Name"LittleFS" #else #warning Using ESP32 Core 1.0.5-. You must install LITTLEFS library// The library has been merged into esp32 core from release 1.0.6 #include<LITTLEFS.h>// https://github.com/lorol/LITTLEFS FS* filesystem = &LITTLEFS; #defineFileFS LITTLEFS #defineFS_Name"LittleFS" #endif #elif USE_SPIFFS #include<SPIFFS.h> FS* filesystem = &SPIFFS; #defineFileFS SPIFFS #defineFS_Name"SPIFFS" #else// Use FFat #include<FFat.h> FS* filesystem = &FFat; #defineFileFS FFat #defineFS_Name"FFat" #endif////// #defineLED_BUILTIN2 #defineLED_ON HIGH #defineLED_OFF LOW#else#include<ESP8266WiFi.h>//https://github.com/esp8266/Arduino//needed for library #include<DNSServer.h> #include<ESP8266WebServer.h> #include<ESP8266WiFiMulti.h> ESP8266WiFiMulti wifiMulti; #defineUSE_LITTLEFStrue #if USE_LITTLEFS #include<LittleFS.h> FS* filesystem = &LittleFS; #defineFileFS LittleFS #defineFS_Name"LittleFS" #else FS* filesystem = &SPIFFS; #defineFileFS SPIFFS #defineFS_Name"SPIFFS" #endif////// #defineESP_getChipId() (ESP.getChipId()) #defineLED_ON LOW #defineLED_OFF HIGH#endif// You only need to format the filesystem once//#define FORMAT_FILESYSTEM true#defineFORMAT_FILESYSTEMfalse#defineMIN_AP_PASSWORD_SIZE8#defineSSID_MAX_LEN32//WPA2 passwords can be up to 63 characters long.#definePASS_MAX_LEN64typedefstruct{char wifi_ssid[SSID_MAX_LEN];char wifi_pw [PASS_MAX_LEN];} WiFi_Credentials;typedefstruct{ String wifi_ssid; String wifi_pw;} WiFi_Credentials_String;#defineNUM_WIFI_CREDENTIALS2typedefstruct{ WiFi_Credentials WiFi_Creds [NUM_WIFI_CREDENTIALS];} WM_Config;WM_Config WM_config;#defineCONFIG_FILENAMEF("/wifi_cred.dat")//////#include<ESP_WiFiManager.h>//https://github.com/khoih-prog/ESP_WiFiManager// SSID and PW for Config PortalString ssid ="ESP_" + String(ESP_getChipId(), HEX);constchar* password ="your_password";// SSID and PW for your RouterString Router_SSID;String Router_Pass;
- Include in your sketch
#ifdef ESP32 #include<esp_wifi.h> #include<WiFi.h> #include<WiFiClient.h> #include<WiFiMulti.h> WiFiMulti wifiMulti;// LittleFS has higher priority than SPIFFS #defineUSE_LITTLEFStrue #defineUSE_SPIFFSfalse #if USE_LITTLEFS// Use LittleFS #include"FS.h"// Check cores/esp32/esp_arduino_version.h and cores/esp32/core_version.h//#if ( ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(2, 0, 0) ) //(ESP_ARDUINO_VERSION_MAJOR >= 2) #if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 2) ) #warning Using ESP32 Core 1.0.6 or 2.0.0+// The library has been merged into esp32 core from release 1.0.6 #include<LittleFS.h> FS* filesystem = &LittleFS; #defineFileFS LittleFS #defineFS_Name"LittleFS" #else #warning Using ESP32 Core 1.0.5-. You must install LITTLEFS library// The library has been merged into esp32 core from release 1.0.6 #include<LITTLEFS.h>// https://github.com/lorol/LITTLEFS FS* filesystem = &LITTLEFS; #defineFileFS LITTLEFS #defineFS_Name"LittleFS" #endif #elif USE_SPIFFS #include<SPIFFS.h> FS* filesystem = &SPIFFS; #defineFileFS SPIFFS #defineFS_Name"SPIFFS" #else// Use FFat #include<FFat.h> FS* filesystem = &FFat; #defineFileFS FFat #defineFS_Name"FFat" #endif////// #defineLED_BUILTIN2 #defineLED_ON HIGH #defineLED_OFF LOW#else#include<ESP8266WiFi.h>//https://github.com/esp8266/Arduino//needed for library #include<DNSServer.h> #include<ESP8266WebServer.h> #include<ESP8266WiFiMulti.h> ESP8266WiFiMulti wifiMulti; #defineUSE_LITTLEFStrue #if USE_LITTLEFS #include<LittleFS.h> FS* filesystem = &LittleFS; #defineFileFS LittleFS #defineFS_Name"LittleFS" #else FS* filesystem = &SPIFFS; #defineFileFS SPIFFS #defineFS_Name"SPIFFS" #endif////// #defineESP_getChipId() (ESP.getChipId()) #defineLED_ON LOW #defineLED_OFF HIGH#endif// You only need to format the filesystem once//#define FORMAT_FILESYSTEM true#defineFORMAT_FILESYSTEMfalse#defineMIN_AP_PASSWORD_SIZE8#defineSSID_MAX_LEN32// WPA2 passwords can be up to 63 characters long.#definePASS_MAX_LEN64typedefstruct{char wifi_ssid[SSID_MAX_LEN];char wifi_pw [PASS_MAX_LEN];} WiFi_Credentials;typedefstruct{ String wifi_ssid; String wifi_pw;} WiFi_Credentials_String;#defineNUM_WIFI_CREDENTIALS2typedefstruct{ WiFi_Credentials WiFi_Creds [NUM_WIFI_CREDENTIALS];} WM_Config;WM_Config WM_config;#defineCONFIG_FILENAMEF("/wifi_cred.dat")//////// Indicates whether ESP has WiFi credentials saved from previous sessionbool initialConfig = false;// 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>#defineUSE_AVAILABLE_PAGESfalse// From v1.0.10 to permit disable/enable StaticIP configuration in Config Portal from sketch. Valid only if DHCP is used.// You'll loose the feature of dynamically changing from DHCP to static IP, or vice versa// You have to explicitly specify false to disable the feature.//#define USE_STATIC_IP_CONFIG_IN_CP false// Use false to disable NTP config. Advisable when using Cellphone, Tablet to access Config Portal.// See Issue 23: On Android phone ConfigPortal is unresponsive (https://github.com/khoih-prog/ESP_WiFiManager/issues/23)#defineUSE_ESP_WIFIMANAGER_NTPfalse// Use true to enable CloudFlare NTP service. System can hang if you don't have Internet access while accessing CloudFlare// See Issue #21: CloudFlare link in the default portal (https://github.com/khoih-prog/ESP_WiFiManager/issues/21)#defineUSE_CLOUDFLARE_NTPfalse// New in v1.0.11#defineUSING_CORS_FEATUREtrue//////// Use USE_DHCP_IP == true for dynamic DHCP IP, false to use static IP which you have to change accordingly to your network#if (defined(USE_STATIC_IP_CONFIG_IN_CP) && !USE_STATIC_IP_CONFIG_IN_CP)// Force DHCP to be true #if defined(USE_DHCP_IP) #undef USE_DHCP_IP #endif #defineUSE_DHCP_IPtrue#else// You can select DHCP or Static IP here//#define USE_DHCP_IP true #defineUSE_DHCP_IPfalse#endif#if ( USE_DHCP_IP )// Use DHCP #warning Using DHCP IP IPAddress stationIP = IPAddress(0,0,0,0); IPAddress gatewayIP = IPAddress(192,168,2,1); IPAddress netMask = IPAddress(255,255,255,0);#else// Use static IP #warning Using static IP #ifdef ESP32 IPAddress stationIP = IPAddress(192,168,2,232); #else IPAddress stationIP = IPAddress(192,168,2,186); #endif IPAddress gatewayIP = IPAddress(192,168,2,1); IPAddress netMask = IPAddress(255,255,255,0);#endif#defineUSE_CONFIGURABLE_DNStrueIPAddress dns1IP = gatewayIP;IPAddress dns2IP = IPAddress(8,8,8,8);IPAddress APStaticIP = IPAddress(192,168,100,1);IPAddress APStaticGW = IPAddress(192,168,100,1);IPAddress APStaticSN = IPAddress(255,255,255,0);#include<ESP_WiFiManager.h>//https://github.com/khoih-prog/ESP_WiFiManager// SSID and PW for Config PortalString ssid ="ESP_" + String(ESP_getChipId(), HEX);constchar* password ="your_password";// SSID and PW for your RouterString Router_SSID;String Router_Pass;////////////////////////////////////////////****************************************** * // Defined in ESP_WiFiManager.htypedef struct{ IPAddress _ap_static_ip; IPAddress _ap_static_gw; IPAddress _ap_static_sn;} WiFi_AP_IPConfig;typedef struct{ IPAddress _sta_static_ip; IPAddress _sta_static_gw; IPAddress _sta_static_sn;#if USE_CONFIGURABLE_DNS IPAddress _sta_static_dns1; IPAddress _sta_static_dns2;#endif} WiFi_STA_IPConfig;******************************************/WiFi_AP_IPConfig WM_AP_IPconfig;WiFi_STA_IPConfig WM_STA_IPconfig;
// From v1.0.10 to permit disable/enable StaticIP configuration in Config Portal from sketch. Valid only if DHCP is used.// You'll loose the feature of dynamically changing from DHCP to static IP, or vice versa// You have to explicitly specify false to disable the feature.#defineUSE_STATIC_IP_CONFIG_IN_CPfalse
// From v1.0.10 to permit disable/enable StaticIP configuration in Config Portal from sketch. Valid only if DHCP is used.// You'll loose the feature of dynamically changing from DHCP to static IP, or vice versa// You have to explicitly specify false to disable the feature.//#define USE_STATIC_IP_CONFIG_IN_CP false// Use USE_DHCP_IP == true for dynamic DHCP IP, false to use static IP which you have to change accordingly to your network#if (defined(USE_STATIC_IP_CONFIG_IN_CP) && !USE_STATIC_IP_CONFIG_IN_CP)// Force DHCP to be true #if defined(USE_DHCP_IP) #undef USE_DHCP_IP #endif #defineUSE_DHCP_IPtrue#else// You can select DHCP or Static IP here #defineUSE_DHCP_IPtrue#endif
// From v1.0.10 to permit disable/enable StaticIP configuration in Config Portal from sketch. Valid only if DHCP is used.// You'll loose the feature of dynamically changing from DHCP to static IP, or vice versa// You have to explicitly specify false to disable the feature.//#define USE_STATIC_IP_CONFIG_IN_CP false// Use USE_DHCP_IP == true for dynamic DHCP IP, false to use static IP which you have to change accordingly to your network#if (defined(USE_STATIC_IP_CONFIG_IN_CP) && !USE_STATIC_IP_CONFIG_IN_CP)// Force DHCP to be true #if defined(USE_DHCP_IP) #undef USE_DHCP_IP #endif #defineUSE_DHCP_IPtrue#else// You can select DHCP or Static IP here #defineUSE_DHCP_IPfalse#endif
6. Using STA-mode StaticIP and configurable DNS, and be able to change to DHCP IP and display in Config Portal
// From v1.0.10 to permit disable/enable StaticIP configuration in Config Portal from sketch. Valid only if DHCP is used.// You'll loose the feature of dynamically changing from DHCP to static IP, or vice versa// You have to explicitly specify false to disable the feature.//#define USE_STATIC_IP_CONFIG_IN_CP false// Use USE_DHCP_IP == true for dynamic DHCP IP, false to use static IP which you have to change accordingly to your network#if (defined(USE_STATIC_IP_CONFIG_IN_CP) && !USE_STATIC_IP_CONFIG_IN_CP)// Force DHCP to be true #if defined(USE_DHCP_IP) #undef USE_DHCP_IP #endif #defineUSE_DHCP_IPtrue#else// You can select DHCP or Static IP here #defineUSE_DHCP_IPfalse#endif#defineUSE_CONFIGURABLE_DNStrueIPAddress dns1IP = gatewayIP;IPAddress dns2IP = IPAddress(8,8,8,8);
7. Using STA-mode StaticIP and auto DNS, and be able to change to DHCP IP and display in Config Portal
// From v1.0.10 to permit disable/enable StaticIP configuration in Config Portal from sketch. Valid only if DHCP is used.// You'll loose the feature of dynamically changing from DHCP to static IP, or vice versa// You have to explicitly specify false to disable the feature.//#define USE_STATIC_IP_CONFIG_IN_CP false// Use USE_DHCP_IP == true for dynamic DHCP IP, false to use static IP which you have to change accordingly to your network#if (defined(USE_STATIC_IP_CONFIG_IN_CP) && !USE_STATIC_IP_CONFIG_IN_CP)// Force DHCP to be true #if defined(USE_DHCP_IP) #undef USE_DHCP_IP #endif #defineUSE_DHCP_IPtrue#else// You can select DHCP or Static IP here #defineUSE_DHCP_IPfalse#endif#defineUSE_CONFIGURABLE_DNSfalse
// Use false to disable NTP config. Advisable when using Cellphone, Tablet to access Config Portal.// See Issue 23: On Android phone ConfigPortal is unresponsive (https://github.com/khoih-prog/ESP_WiFiManager/issues/23)#defineUSE_ESP_WIFIMANAGER_NTPfalse
9. Using NTP feature with CloudFlare. System can hang until you have Internet access for CloudFlare.
// Use false to disable NTP config. Advisable when using Cellphone, Tablet to access Config Portal.// See Issue 23: On Android phone ConfigPortal is unresponsive (https://github.com/khoih-prog/ESP_WiFiManager/issues/23)#defineUSE_ESP_WIFIMANAGER_NTPtrue// Use true to enable CloudFlare NTP service. System can hang if you don't have Internet access while accessing CloudFlare// See Issue #21: CloudFlare link in the default portal (https://github.com/khoih-prog/ESP_WiFiManager/issues/21)#defineUSE_CLOUDFLARE_NTPtrue
// Use false to disable NTP config. Advisable when using Cellphone, Tablet to access Config Portal.// See Issue 23: On Android phone ConfigPortal is unresponsive (https://github.com/khoih-prog/ESP_WiFiManager/issues/23)#defineUSE_ESP_WIFIMANAGER_NTPtrue// Use true to enable CloudFlare NTP service. System can hang if you don't have Internet access while accessing CloudFlare// See Issue #21: CloudFlare link in the default portal (https://github.com/khoih-prog/ESP_WiFiManager/issues/21)#defineUSE_CLOUDFLARE_NTPfalse
// From v1.0.10 only// Set config portal channel, default = 1. Use 0 => random channel from 1-13ESP_wifiManager.setConfigPortalChannel(0);//////
// From v1.0.10 only// Set config portal channel, default = 1. Use 0 => random channel from 1-13ESP_wifiManager.setConfigPortalChannel(3);//////
// Set static IP, Gateway, Subnetmask, DNS1 and DNS2//ESP_wifiManager.setSTAStaticIPConfig(stationIP, gatewayIP, netMask, dns1IP, dns2IP);ESP_wifiManager.setSTAStaticIPConfig(WM_STA_IPconfig);
- Don't invalidate WiFi SSID/PW when calling
autoConnect()(default)
#defineAUTOCONNECT_NO_INVALIDATEtrue
- To invalidate WiFi SSID/PW when calling autoConnect()
#defineAUTOCONNECT_NO_INVALIDATEfalse
- To use
CORSfeature withdefaultCORS Header"". Some WebBrowsers won't accept this allowing-all "" CORS Header.
// Default false for using only whenever necessary to avoid security issue#defineUSING_CORS_FEATUREtrue
- To use
CORSfeature with specificCORS Header"Your Access-Control-Allow-Origin".To be modified according to your specific Allowed-Origin.
// Default false for using only whenever necessary to avoid security issue#defineUSING_CORS_FEATUREtrue...#if USING_CORS_FEATURE ESP_wifiManager.setCORSHeader("Your Access-Control-Allow-Origin");#endif
- Not use
CORSfeature (default)
// Default false for using only whenever necessary to avoid security issue#defineUSING_CORS_FEATUREfalse
- In
loop()
voidcheck_WiFi(){if ( (WiFi.status() != WL_CONNECTED) ) { Serial.println("\nWiFi lost. Call connectMultiWiFi in loop");connectMultiWiFi(); }}voidcheck_status(){static ulong checkwifi_timeout =0;static ulong current_millis;#defineWIFICHECK_INTERVAL1000L current_millis =millis();// Check WiFi every WIFICHECK_INTERVAL (1) seconds.if ((current_millis > checkwifi_timeout) || (checkwifi_timeout ==0)) {check_WiFi(); checkwifi_timeout = current_millis + WIFICHECK_INTERVAL; }}voidloop(){// put your main code here, to run repeatedlycheck_status();}
- Turn on auto
NTPconfiguration by
// Use false to disable NTP config. Advisable when using Cellphone, Tablet to access Config Portal.// See Issue 23: On Android phone ConfigPortal is unresponsive (https://github.com/khoih-prog/ESP_WiFiManager/issues/23)#defineUSE_ESP_WIFIMANAGER_NTPtrue
- The
_timezoneName, in the format similar toAmerica/New_York, America/Toronto, Europe/London, etc., can be retrieved by using
String tempTZ = ESP_wifiManager.getTimezoneName();- ESP32 and ESP8266
TZcan be configured, using the similar toEST5EDT,M3.2.0,M11.1.0(for America/New_York), as follows:
// EST5EDT,M3.2.0,M11.1.0 (for America/New_York)// EST5EDT is the name of the time zone// EST is the abbreviation used when DST is off// 6 hours is the time difference from GMT// EDT is the abbreviation used when DST is on// ,M3 is the third month// .2 is the second occurrence of the day in the month// .0 is Sunday// ,M11 is the eleventh month// .1 is the first occurrence of the day in the month// .0 is Sunday#if ESP8266configTime(WM_config.TZ,"pool.ntp.org"); #else//configTzTime(WM_config.TZ, "pool.ntp.org" );configTzTime(WM_config.TZ,"time.nist.gov","0.pool.ntp.org","1.pool.ntp.org");#endif
- To convert from
_timezoneNametoTZ, use the functiongetTZ()as follows:
constchar * TZ_Result = ESP_wifiManager.getTZ(_timezoneName);
The conversion depends on the stored TZs, which is using some memory, and can cause issue forESP8266 in certain cases. Therefore, enable just the region you're interested.
For example, your application is used in America continent, you need just
#defineUSING_AMERICAtrue
Hereafter is the regions' list
// Just use enough to save memory. On ESP8266, can cause blank ConfigPortal screen// if using too much memory#defineUSING_AFRICAfalse#defineUSING_AMERICAtrue#defineUSING_ANTARCTICAfalse#defineUSING_ASIAfalse#defineUSING_ATLANTICfalse#defineUSING_AUSTRALIAfalse#defineUSING_EUROPEfalse#defineUSING_INDIANfalse#defineUSING_PACIFICfalse#defineUSING_ETC_GMTfalse
#if ESP8266configTime(WM_config.TZ,"pool.ntp.org");#else//configTzTime(WM_config.TZ, "pool.ntp.org" );configTzTime(WM_config.TZ,"time.nist.gov","0.pool.ntp.org","1.pool.ntp.org");#endif
then to print local time
voidprintLocalTime(){#if ESP8266statictime_t now; now =time(nullptr);if ( now >1451602800 ) { Serial.print("Local Date/Time:"); Serial.print(ctime(&now)); }#elsestructtm timeinfo;getLocalTime( &timeinfo );// Valid only if year > 2000.// You can get from timeinfo : tm_year, tm_mon, tm_mday, tm_hour, tm_min, tm_secif (timeinfo.tm_year >100 ) { Serial.print("Local Date/Time:"); Serial.print(asctime( &timeinfo ) ); }#endif}
- When you want to open a config portal, with default DHCP hostname
ESP8266-XXXXXXorESP32-XXXXXX, just add
ESP_WiFiManager ESP_wifiManager;
If you'd like to have a personalized hostname(RFC952-conformed,- 24 chars max,- only a..z A..Z 0..9 '-' and no '-' as last char)
add
ESP_WiFiManagerESP_wifiManager("Personalized-HostName");
then later call
ESP_wifiManager.startConfigPortal()
While in AP mode, connect to it using itsSSID (ESP_XXXXXX) /Password ("your_password"), then open a browser to the AP IP, default192.168.4.1, configure wifi then save. The WiFi connection information will be saved in non volatile memory. It will then reboot and autoconnect.
You can also change the AP IP by:
//set custom ip for portal//ESP_wifiManager.setAPStaticIPConfig(IPAddress(10,0,1,1), IPAddress(10,0,1,1), IPAddress(255,255,255,0));ESP_wifiManager.setAPStaticIPConfig(WM_AP_IPconfig);
and use fixed / dynamic / random AP channel by:
// From v1.0.10 only// Set config portal channel, default = 1. Use 0 => random channel from 1-13ESP_wifiManager.setConfigPortalChannel(0);//////
Once WiFi network information is saved in theESP32 / ESP8266, it will try to autoconnect to WiFi every time it is started, without requiring any function calls in the sketch.
These illustrating steps is based on the exampleConfigOnSwitchFS
The application will:
- use DHT sensor (either DHT11 or DHT22) and
- need to connect to ThingSpeak with unique user's API Key.
The DHT sensor is connected to the ESP boards using SDA/SCL pins which also need to be configurable.
So this is the list of variables to be dynamically configured using CP
1. `thingspeakApiKey`, type `char array`, max length 17 chars, and just arbitrarily selected default value to be "" or "ThingSpeak-APIKey"2. `sensorDht22`, type `bool`, default to be `true` (DHT22)3. `pinSda`, type `int`, default to be `PIN_D2`4. `pinScl`, type `int`, default to be `PIN_D1`The Label can be any arbitrary string that help you identify the variable, but must be unique in your application
The initial code will be
#defineAPI_KEY_LEN17// Default configuration valueschar thingspeakApiKey[API_KEY_LEN] ="";bool sensorDht22 =true;int pinSda = PIN_D2;// Pin D2 mapped to pin GPIO4 of ESP8266int pinScl = PIN_D1;// Pin D1 mapped to pin GPIO5 of ESP8266// Any unique string helping you identify the vars#defineThingSpeakAPI_Label"thingspeakApiKey"#defineSensorDht22_Label"SensorDHT22"#definePinSDA_Label"PinSda"#definePinSCL_Label"PinScl"
The exampleConfigOnSwitchFS will open the CP whenever a SW press is detected in loop(). So the code to adddynamic variables will be there, just after the CPESP_WiFiManager class initialization to createESP_wifiManager object.
voidloop(){// is configuration portal requested?if ((digitalRead(TRIGGER_PIN) == LOW) || (digitalRead(TRIGGER_PIN2) == LOW)) { Serial.println("\nConfiguration portal requested.");digitalWrite(PIN_LED, LED_ON);// turn the LED on by making the voltage LOW to tell us we are in configuration mode.//Local initialization. Once its business is done, there is no need to keep it around ESP_WiFiManagerESP_wifiManager("ConfigOnSwitchFS");//Check if there is stored WiFi router/password credentials.//If not found, device will remain in configuration mode until switched off via webserver. Serial.print("Opening configuration portal."); ...// The addition of dynamic vars will be somewhere here }
TheESP_WMParameter class constructor will be used to initialize each newly-added parameter object.
2.1 Use the following simple constructor for simple variables such asthingspeakApiKey,pinSda andpinScl :
ESP_WMParameter(constchar *id,constchar *placeholder,constchar *defaultValue,int length);
The command to use will be
ESP_WMParameterp_thingspeakApiKey(ThingSpeakAPI_Label,"Thingspeak API Key", thingspeakApiKey, API_KEY_LEN);
where
- p_thingspeakApiKey : ESP_WMParameter class object reference that stores the new Custom Parameter- id => ThingSpeakAPI_Label : var ref to Json associative name and HTML element ID for the new Custom Paramerter you just defined in step 1- placeholder => "Thingspeak API Key" : HTML input placeholder and/or label element text the user sees in the configuration interface for this Custom Parameter- defaultValue => thingspeakApiKey : variable for storing the value of your Custom Parameter in the file system or default value when no data is entered- length => API_KEY_LEN : max allowed length you want for this Custom Parameter to haveForpinSda andpinScl, the command will be similar
// I2C SCL and SDA parameters are integers so we need to convert them to char array but// no other special considerationschar convertedValue[3];sprintf(convertedValue,"%d", pinSda);ESP_WMParameterp_pinSda(PinSDA_Label,"I2C SDA pin", convertedValue,3);sprintf(convertedValue,"%d", pinScl);ESP_WMParameterp_pinScl(PinSCL_Label,"I2C SCL pin", convertedValue,3);
where
- p_pinSda / p_pinScl : ESP_WMParameter class object reference that stores the new Custom Parameter- id => PinSDA_Label/PinSCL_Label : var ref to Json associative name and HTML element ID for the new Custom Paramerter you just defined in step 1- placeholder => "I2C SDA pin"/"I2C SCL pin" : HTML input placeholder and/or label element text the user sees in the configuration interface for this Custom Parameter- defaultValue => convertedValue : variable for storing the value of your Custom Parameter in the file system or default value when no data is entered- length => 3 : max allowed length you want for this Custom Parameter to haveESP_WMParameter(constchar *id,constchar *placeholder,constchar *defaultValue,int length,constchar *custom,int labelPlacement);
The command to use will be
ESP_WMParameterp_sensorDht22(SensorDht22_Label,"DHT-22 Sensor","T",2, customhtml, WFM_LABEL_AFTER);
where
- p_sensorDht22 : ESP_WMParameter class object reference that stores the new Custom Parameter- id => SensorDht22_Label : var ref to Json associative name and HTML element ID for the new Custom Paramerter you just defined in step 1- placeholder => "DHT-22 Sensor" : HTML input placeholder and/or label element text the user sees in the configuration interface for this Custom Parameter- defaultValue => "T" : variable for storing the value of your Custom Parameter in the file system or default value when no data is entered ("T" means `true`)- length => 2 : max allowed length you want for this Custom Parameter to have- custom => customhtml : custom HTML code to add element type, e.g. `checkbox`, and `checked` when `sensorDht22 == true`- labelPlacement => WFM_LABEL_AFTER : to place label afterand customhtml Code is:
char customhtml[24] ="type=\"checkbox\"";if (sensorDht22){strcat(customhtml," checked");}
Adding thoseESP_WMParameter objects created in Step 2 using the functionaddParameter() of objectESP_wifiManager
//adds a custom parameterbooladdParameter(ESP_WMParameter *p);
Add parameter objects, previously created in Step 2, such as :p_thingspeakApiKey,p_sensorDht22,p_pinSda andp_pinScl
//add all parameters hereESP_wifiManager.addParameter(&p_thingspeakApiKey);ESP_wifiManager.addParameter(&p_sensorDht22);ESP_wifiManager.addParameter(&p_pinSda);ESP_wifiManager.addParameter(&p_pinScl);When the CP exits, we have to store the parameters' values that users input via CP to use later.
For ESP32, that can beEEPROM orSPIFFS. While on ESP8266,LittleFS can be used besidesEEPROM ordeprecated SPIFFS.
We can write directly to awell-defined structure of our choice, but the current example is usingJSON to be portable butmuch more complicated and not advised for new users.
After users selectSave, the CPESP_wifiManager object will save the user input data into relatedESP_WMParameter objects.
We can now retrieve the data, usinggetValue() function, for eachESP_WMParameter object. Then we can utilize the data for our purpose, such asthingspeakApiKey to log in,sensorDht22 type to know how to handle the sensor,pinSda andpinSda to know which pins to use to communicate with the DHT sensor.
The code is as follows:
// Getting posted form values and overriding local variables parameters// Config file is written regardless the connection statestrcpy(thingspeakApiKey, p_thingspeakApiKey.getValue());sensorDht22 = (strncmp(p_sensorDht22.getValue(),"T",1) ==0);pinSda = atoi(p_pinSda.getValue());pinScl = atoi(p_pinScl.getValue());
We can also save to FS file to use later in next boot.
// Writing JSON config file to flash for next bootwriteConfigFile();
First, you have to familiarize yourself withArduinoJson library, its functions, the disruptive differences betweenArduinoJson version 5.x.x- andv6.0.0+. The best documentation can be found atThe best JSON library for embedded C++.
This documentation will discuss only ArduinoJson v6.x.x+ (ARDUINOJSON_VERSION_MAJOR >= 6)
Then have a look at the code snippet ofwriteConfigFile() function and the following step-by-step explanations.
boolwriteConfigFile(){ Serial.println("Saving config file");#if (ARDUINOJSON_VERSION_MAJOR >= 6) DynamicJsonDocumentjson(1024);#else DynamicJsonBuffer jsonBuffer; JsonObject& json = jsonBuffer.createObject();#endif// JSONify local configuration parameters json[ThingSpeakAPI_Label] = thingspeakApiKey; json[SensorDht22_Label] = sensorDht22; json[PinSDA_Label] = pinSda; json[PinSCL_Label] = pinScl;// Open file for writing File f = FileFS.open(CONFIG_FILE,"w");if (!f) { Serial.println("Failed to open config file for writing");returnfalse; }#if (ARDUINOJSON_VERSION_MAJOR >= 6)serializeJsonPretty(json, Serial);// Write data to file and close itserializeJson(json, f);#else json.prettyPrintTo(Serial);// Write data to file and close it json.printTo(f);#endif f.close(); Serial.println("\nConfig file was successfully saved");returntrue;}
We'll create an object with size 1024 bytes, enough to hold our data:
DynamicJsonDocumentjson(1024);
ThenJSONify all local parameters we've just received from CP and wish to store into FS by using the function prototype:
json[Unique_Label] = Value_For_Unique_Label;
as follows:
// JSONify local configuration parametersjson[ThingSpeakAPI_Label] = thingspeakApiKey;json[SensorDht22_Label] = sensorDht22;json[PinSDA_Label] = pinSda;json[PinSCL_Label] = pinScl;This is theCONFIG_FILE file name we already declared at the beginning of the sketch (for ESP32):
#include<SPIFFS.h>FS* filesystem = &SPIFFS;#defineFileFS SPIFFSconstchar* CONFIG_FILE ="/ConfigSW.json";
Now just open the file for writing, and abort if open-for-writing error:
// Open file for writingFile f = FileFS.open(CONFIG_FILE,"w");if (!f){ Serial.println("Failed to open config file for writing");returnfalse;}
As simple as this single command to write the wholejson object we declared then filled with data in steps 5.1 and 5.2
// Write data to file and close itserializeJson(json, f);
Soooo simple !!! Now everybody can do it.
f.close();
ButHOWTO use the saved data in the next startup ???? That's in next step 6.
Now, you have familiarized yourself withArduinoJson library, its functions. We'll discuss HOWTO read data from theCONFIG_FILE inJsonified format, then HOWTO parse the to use.
The documentation will discuss only ArduinoJson v6.x.x+ (ARDUINOJSON_VERSION_MAJOR >= 6)
First, have a look at the code snippet ofreadConfigFile() function.
boolreadConfigFile(){// this opens the config file in read-mode File f = FileFS.open(CONFIG_FILE,"r");if (!f) { Serial.println("Configuration file not found");returnfalse; }else {// we could open the filesize_t size = f.size();// Allocate a buffer to store contents of the file. std::unique_ptr<char[]>buf(newchar[size +1]);// Read and store file contents in buf f.readBytes(buf.get(), size);// Closing file f.close();// Using dynamic JSON buffer which is not the recommended memory model, but anyway// See https://github.com/bblanchon/ArduinoJson/wiki/Memory%20model#if (ARDUINOJSON_VERSION_MAJOR >= 6) DynamicJsonDocumentjson(1024);auto deserializeError =deserializeJson(json, buf.get());if ( deserializeError ) { Serial.println("JSON parseObject() failed");returnfalse; }serializeJson(json, Serial);#else DynamicJsonBuffer jsonBuffer;// Parse JSON string JsonObject& json = jsonBuffer.parseObject(buf.get());// Test if parsing succeeds.if (!json.success()) { Serial.println("JSON parseObject() failed");returnfalse; } json.printTo(Serial);#endif// Parse all config file parameters, override// local config variables with parsed valuesif (json.containsKey(ThingSpeakAPI_Label)) {strcpy(thingspeakApiKey, json[ThingSpeakAPI_Label]); }if (json.containsKey(SensorDht22_Label)) { sensorDht22 = json[SensorDht22_Label]; }if (json.containsKey(PinSDA_Label)) { pinSda = json[PinSDA_Label]; }if (json.containsKey(PinSCL_Label)) { pinScl = json[PinSCL_Label]; } } Serial.println("\nConfig file was successfully parsed");returntrue;}
and the following step-by-step explanations.
As simple as this
// this opens the config file in read-modeFile f = FileFS.open(CONFIG_FILE,"r");
We'll inform and abort if theCONFIG_FILE can't be opened (file not found, can't be opened, etc.)
if (!f){ Serial.println("Configuration file not found");returnfalse;}
Now we have to determine the file size to create a buffer large enough to store the to-be-read data
// we could open the filesize_t size = f.size();// Allocate a buffer to store contents of the file.std::unique_ptr<char[]>buf(newchar[size +1]);
Remember always add 1 to the buffer length to store the terminating0.
Then just read the file into the buffer, and close the file to be safe
// Read and store file contents in buff.readBytes(buf.get(), size);// Closing filef.close();
We again use the sameDynamicJsonDocument json object to store the data we've just read fromCONFIG_FILE.
Why the same complicatedDynamicJsonDocument json object ?? Because in steps 5, we did storeJsonified data using the sameDynamicJsonDocument json object. It's much easier we now use it again to facilitate the parsing ofJsonified data back to the data we can use easily.
We first create the object with enough size
DynamicJsonDocumentjson(1024);
then populate it with data from buffer we read from CONFIG_FILE in step 6.2, pre-parse and check for error. All is done just by one commanddeserializeJson()
auto deserializeError = deserializeJson(json, buf.get());Abort if there is any data error in the process of writing, storing, reading back. If OK, just nicely print out to the Debug Terminal
if ( deserializeError ){ Serial.println("JSON parseObject() failed");returnfalse;}serializeJson(json, Serial);
6.4 Parse the Jsonified data from the DynamicJsonDocument json object to store into corresponding parameters
This is as simple as in the step 5.2, but in reverse direction.
To be sure there is good corresponding data, not garbage, for each variable, we have to performsanity checks byverifying theDynamicJsonDocument json object still contains the correct keys we passed to it when we wrote intoCONFIG_FILE.
For example:
if (json.containsKey(ThingSpeakAPI_Label))Then proceed to get every parameter we know we stored there from last CPSave.
// Parse all config file parameters, override// local config variables with parsed valuesif (json.containsKey(ThingSpeakAPI_Label)){strcpy(thingspeakApiKey, json[ThingSpeakAPI_Label]);}if (json.containsKey(SensorDht22_Label)){ sensorDht22 = json[SensorDht22_Label];}if (json.containsKey(PinSDA_Label)){ pinSda = json[PinSDA_Label];}if (json.containsKey(PinSCL_Label)){ pinScl = json[PinSCL_Label];}
Just use those parameters for whatever purpose you designed them for in step 1:
The application will use DHTsensor (either DHT11or DHT22) and need to connect to ThingSpeak with unique user's API Key. The DHT sensor is connected to the ESP boards using SDA/SCL pins which also need to be configurable.
InConfigPortal Mode, it starts an access point calledESP_XXXXXX. Connect to it using theconfigurable password you can define in the code. For example,your_password (see examples):
// SSID and PW for Config PortalString ssid ="ESP_" + String(ESP_getChipId(), HEX);constchar* password ="your_password";
After you connected, please, go tohttp://192.168.4.1, you'll see thisMain page:
SelectInformation to enter the Info page where the board info will be shown (long page)
or short page (default)
SelectConfiguration to enter this page where you can select an AP and specify its WiFi Credentials
Enter your credentials, then clickSave. The WiFi Credentials will be saved and the board reboots to connect to the selected WiFi AP.
If you're already connected to a listed WiFi AP and don't want to change anything, just selectExit Portal from theMain page to reboot the board and connect to the previously-stored AP. The WiFi Credentials are still intact.
You can password protect the ConfigPortal AP. Simply add an SSID as the first parameter and the password as a second parameter tostartConfigPortal. See the above examples.A short password seems to have unpredictable results so use one that's around 8 characters or more in length.The guidelines are that a wifi password must consist of 8 to 63 ASCII-encoded characters in the range of 32 to 126 (decimal)
ESP_wifiManager.startConfigPortal( SSID , password )
This gets called when custom parameters have been setAND a connection has been established. Use it to set a flag, so when all the configuration finishes, you can save the extra parameters somewhere.
ESP_wifiManager.setSaveConfigCallback(saveConfigCallback);
saveConfigCallback declaration and example
//flag for saving databool shouldSaveConfig =false;//callback notifying us of the need to save configvoidsaveConfigCallback () { Serial.println("Should save config"); shouldSaveConfig =true;}
If you need to set a timeout so theESP32 / ESP8266 doesn't hang waiting to be configured for ever.
ESP_wifiManager.setConfigPortalTimeout(120);which will wait 2 minutes (120 seconds). When the time passes, thestartConfigPortal() function will return and continue the sketch,unless you're accessing the Config Portal. In this case, thestartConfigPortal() function will stay until you save config data or exitthe Config Portal.
Example usage
voidloop(){// is configuration portal requested?if ((digitalRead(TRIGGER_PIN) == LOW) || (digitalRead(TRIGGER_PIN2) == LOW)) { Serial.println(F("\nConfiguration portal requested."));digitalWrite(PIN_LED, LED_ON);// turn the LED on by making the voltage LOW to tell us we are in configuration mode.//Local initialization. Once its business is done, there is no need to keep it around ESP_WiFiManagerESP_wifiManager("ConfigOnSwitch"); ESP_wifiManager.setMinimumSignalQuality(-1);// From v1.0.10 only// Set config portal channel, default = 1. Use 0 => random channel from 1-13 ESP_wifiManager.setConfigPortalChannel(0);////////set custom ip for portal//ESP_wifiManager.setAPStaticIPConfig(IPAddress(192, 168, 100, 1), IPAddress(192, 168, 100, 1), IPAddress(255, 255, 255, 0));#if !USE_DHCP_IP #if USE_CONFIGURABLE_DNS// Set static IP, Gateway, Subnetmask, DNS1 and DNS2 ESP_wifiManager.setSTAStaticIPConfig(stationIP, gatewayIP, netMask, dns1IP, dns2IP); #else// Set static IP, Gateway, Subnetmask, Use auto DNS1 and DNS2. ESP_wifiManager.setSTAStaticIPConfig(stationIP, gatewayIP, netMask); #endif #endif #if USING_CORS_FEATURE ESP_wifiManager.setCORSHeader("Your Access-Control-Allow-Origin");#endif//Check if there is stored WiFi router/password credentials.//If not found, device will remain in configuration mode until switched off via webserver. Serial.println(F("Opening configuration portal.")); 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 Serial.println("ESP Self-Stored: SSID =" + Router_SSID +", Pass =" + Router_Pass);// Don't permit NULL passwordif ( (Router_SSID !="") && (Router_Pass !="") ) {LOGERROR3(F("* Add SSID ="), Router_SSID,F(", PW ="), Router_Pass); wifiMulti.addAP(Router_SSID.c_str(), Router_Pass.c_str()); ESP_wifiManager.setConfigPortalTimeout(120);//If no access point name has been previously entered disable timeout. Serial.println(F("Got ESP Self-Stored Credentials. Timeout 120s for Config Portal")); }elseif (loadConfigData()) { ESP_wifiManager.setConfigPortalTimeout(120);//If no access point name has been previously entered disable timeout. Serial.println(F("Got stored Credentials. Timeout 120s for Config Portal")); }else {// Enter CP only if no stored SSID on flash and file Serial.println(F("Open Config Portal without Timeout: No stored Credentials.")); initialConfig =true; }//Starts an access point//and goes into a blocking loop awaiting configurationif (!ESP_wifiManager.startConfigPortal((constchar *) ssid.c_str(), password)) { Serial.println(F("Not connected to WiFi but continuing anyway.")); }else {//if you get here you have connected to the WiFi Serial.println(F("connected...yeey :)")); Serial.print(F("Local IP:")); Serial.println(WiFi.localIP()); }// Only clear then save data if CP entered and with new valid Credentials// No CP => stored getSSID() = ""if (String(ESP_wifiManager.getSSID(0)) !="" &&String(ESP_wifiManager.getSSID(1)) !="" ) {// Stored for later usage, from v1.1.0, but clear firstmemset(&WM_config,0,sizeof(WM_config));for (uint8_t i =0; i < NUM_WIFI_CREDENTIALS; i++) { String tempSSID = ESP_wifiManager.getSSID(i); String tempPW = ESP_wifiManager.getPW(i);if (strlen(tempSSID.c_str()) <sizeof(WM_config.WiFi_Creds[i].wifi_ssid) -1)strcpy(WM_config.WiFi_Creds[i].wifi_ssid, tempSSID.c_str());elsestrncpy(WM_config.WiFi_Creds[i].wifi_ssid, tempSSID.c_str(),sizeof(WM_config.WiFi_Creds[i].wifi_ssid) -1);if (strlen(tempPW.c_str()) <sizeof(WM_config.WiFi_Creds[i].wifi_pw) -1)strcpy(WM_config.WiFi_Creds[i].wifi_pw, tempPW.c_str());elsestrncpy(WM_config.WiFi_Creds[i].wifi_pw, tempPW.c_str(),sizeof(WM_config.WiFi_Creds[i].wifi_pw) -1);// Don't permit NULL SSID and password len < MIN_AP_PASSWORD_SIZE (8)if ( (String(WM_config.WiFi_Creds[i].wifi_ssid) !="") && (strlen(WM_config.WiFi_Creds[i].wifi_pw) >= MIN_AP_PASSWORD_SIZE) ) {LOGERROR3(F("* Add SSID ="), WM_config.WiFi_Creds[i].wifi_ssid,F(", PW ="), WM_config.WiFi_Creds[i].wifi_pw ); wifiMulti.addAP(WM_config.WiFi_Creds[i].wifi_ssid, WM_config.WiFi_Creds[i].wifi_pw); } } ESP_wifiManager.getSTAStaticIPConfig(WM_STA_IPconfig);//////saveConfigData(); }digitalWrite(PIN_LED, LED_OFF);// Turn led off as we are not in configuration mode. }// put your main code here, to run repeatedlycheck_status();}
SeeConfigOnSwitch example for a more complex version.
Many applications need configuration parameters likeMQTT host and port,Blynk oremoncms tokens, etc. While it is possible to useESP_WiFiManager to collect additional parameters it is better to read these parameters from a web service onceESP_WiFiManager has been used to connect to the internet.
To capture other parameters withESP_WiFiManager is a lot more involved than all the other features and requires adding custom HTML to your form. If you want to do it withESP_WiFiManager see the exampleConfigOnSwitchFS
You can set a custom IP for both AP (access point, config mode) and STA (station mode, client mode, normal project state)
This will set your captive portal to a specific IP should you need/want such a feature. Add the following snippet beforestartConfigPortal()
//set custom ip for portal//ESP_wifiManager.setAPStaticIPConfig(IPAddress(10,0,1,1), IPAddress(10,0,1,1), IPAddress(255,255,255,0));ESP_wifiManager.setAPStaticIPConfig(WM_AP_IPconfig);
This will use the specified IP configuration instead of usingDHCP in station mode
//ESP_wifiManager.setSTAStaticIPConfig(IPAddress(192,168,0,99), IPAddress(192,168,0,1), IPAddress(255,255,255,0));ESP_wifiManager.setSTAStaticIPConfig(WM_STA_IPconfig);There are various ways in which you can inject customHTML,CSS orJavascript into the ConfigPortal.
The options are:
- inject custom head element
You can use this to any html bit to the head of the ConfigPortal. If you add a<style> element, bare in mind it overwrites the included css, not replaces.
ESP_wifiManager.setCustomHeadElement("<style>html{filter: invert(100%); -webkit-filter: invert(100%);}</style>");- inject a custom bit of html in the configuration form
ESP_WMParametercustom_text("<p>This is just a text paragraph</p>");ESP_wifiManager.addParameter(&custom_text);
- inject a custom bit of html in a configuration form elementJust add the bit you want added as the last parameter to the custom parameter constructor.
ESP_WMParametercustom_mqtt_server("server","mqtt server","iot.eclipse",40," readonly");
You can filter networks based on signal quality and show/hide duplicate networks.
- If you would like to filter low signal quality networks you can tell WiFiManager to not show networks below an arbitrary quality %;
ESP_wifiManager.setMinimumSignalQuality(10);will not show networks under 10% signal quality. If you omit the parameter it defaults to 8%;
- You can also remove or show duplicate networks (default is remove).Use this function to show (or hide) all networks.
ESP_wifiManager.setRemoveDuplicateAPs(false);- AutoConnect
- AutoConnectWithFeedback
- AutoConnectWithFeedbackLED
- AutoConnectWithFSParameters
- ConfigOnDoubleReset (now support ArduinoJson 6.0.0+ as well as 5.13.5-)
- ConfigOnDRD_FS_MQTT_Ptr
- ConfigOnStartup
- ConfigOnSwitch
- ConfigOnSwitchFS
- ConfigOnSwitchFS_MQTT_Ptr
- ConfigPortalParamsOnSwitch (now support ArduinoJson 6.0.0+ as well as 5.13.5-)
- ESP32_FSWebServer
- ESP32_FSWebServer_DRD
- ESP_FSWebServer
- ESP_FSWebServer_DRD
ExampleConfigOnDRD_FS_MQTT_Ptr
ESP_WiFiManager/examples/ConfigOnDRD_FS_MQTT_Ptr/ConfigOnDRD_FS_MQTT_Ptr.ino
Lines 17 to 1422 infca2fcd
| /**************************************************************************************************************************** | |
| This example will open a Config Portal when there is no stored WiFi Credentials or when a DRD is detected. | |
| You can reconfigure to use another pin, such as the convenience FLASH / BOOT button @ PIN_D0;. | |
| A password is required to connect to the Config Portal so that only who know the password can access the Config Portal. | |
| The Credentials, being input via Config Portal, will then be saved into LittleFS / SPIFFS file, and be used to connect to | |
| Adafruit MQTT Server at "io.adafruit.com" and publish a Temperature Topic | |
| Based on original sketch posted by "Marko"(https://github.com/wackoo-arduino) on https://forum.arduino.cc/index.php?topic=692108 | |
| *****************************************************************************************************************************/ | |
| #if !( defined(ESP8266) || defined(ESP32) ) | |
| #error This code is intended to run on the ESP8266 or ESP32 platform! Please check your Tools->Board setting. | |
| #endif | |
| #defineESP_WIFIMANAGER_VERSION_MIN_TARGET"ESP_WiFiManager v1.12.0" | |
| #defineESP_WIFIMANAGER_VERSION_MIN1012000 | |
| // Use from 0 to 4. Higher number, more debugging messages and memory usage. | |
| #define_WIFIMGR_LOGLEVEL_1 | |
| // To not display stored SSIDs and PWDs on Config Portal, select false. Default is true | |
| // Even the stored Credentials are not display, just leave them all blank to reconnect and reuse the stored Credentials | |
| //#define DISPLAY_STORED_CREDENTIALS_IN_CP false | |
| #include<Arduino.h>// for button | |
| #include<OneButton.h>// for button | |
| #include<FS.h> | |
| // Now support ArduinoJson 6.0.0+ ( tested with v6.15.2 to v6.16.1 ) | |
| #include<ArduinoJson.h>// get it from https://arduinojson.org/ or install via Arduino library manager | |
| //For ESP32, To use ESP32 Dev Module, QIO, Flash 4MB/80MHz, Upload 921600 | |
| //Ported to ESP32 | |
| #ifdef ESP32 | |
| #include<esp_wifi.h> | |
| #include<WiFi.h> | |
| #include<WiFiClient.h> | |
| // From v1.1.0 | |
| #include<WiFiMulti.h> | |
| WiFiMulti wifiMulti; | |
| // LittleFS has higher priority than SPIFFS | |
| #if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 2) ) | |
| #defineUSE_LITTLEFStrue | |
| #defineUSE_SPIFFSfalse | |
| #elif defined(ARDUINO_ESP32C3_DEV) | |
| // For core v1.0.6-, ESP32-C3 only supporting SPIFFS and EEPROM. To use v2.0.0+ for LittleFS | |
| #defineUSE_LITTLEFSfalse | |
| #defineUSE_SPIFFStrue | |
| #endif | |
| #if USE_LITTLEFS | |
| // Use LittleFS | |
| #include"FS.h" | |
| // Check cores/esp32/esp_arduino_version.h and cores/esp32/core_version.h | |
| //#if ( ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(2, 0, 0) ) //(ESP_ARDUINO_VERSION_MAJOR >= 2) | |
| #if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 2) ) | |
| #if (_WIFIMGR_LOGLEVEL_ > 3) | |
| #warning Using ESP32 Core 1.0.6 or 2.0.0+ | |
| #endif | |
| // The library has been merged into esp32 core from release 1.0.6 | |
| #include<LittleFS.h>// https://github.com/espressif/arduino-esp32/tree/master/libraries/LittleFS | |
| FS* filesystem = &LittleFS; | |
| #defineFileFS LittleFS | |
| #defineFS_Name"LittleFS" | |
| #else | |
| #if (_WIFIMGR_LOGLEVEL_ > 3) | |
| #warning Using ESP32 Core 1.0.5-. You must install LITTLEFS library | |
| #endif | |
| // The library has been merged into esp32 core from release 1.0.6 | |
| #include<LITTLEFS.h>// https://github.com/lorol/LITTLEFS | |
| FS* filesystem = &LITTLEFS; | |
| #defineFileFS LITTLEFS | |
| #defineFS_Name"LittleFS" | |
| #endif | |
| #elif USE_SPIFFS | |
| #include<SPIFFS.h> | |
| FS* filesystem = &SPIFFS; | |
| #defineFileFS SPIFFS | |
| #defineFS_Name"SPIFFS" | |
| #else | |
| // Use FFat | |
| #include<FFat.h> | |
| FS* filesystem = &FFat; | |
| #defineFileFS FFat | |
| #defineFS_Name"FFat" | |
| #endif | |
| ////// | |
| #defineLED_BUILTIN2 | |
| #defineLED_ON HIGH | |
| #defineLED_OFF LOW | |
| #else | |
| #include<ESP8266WiFi.h>//https://github.com/esp8266/Arduino | |
| //needed for library | |
| #include<DNSServer.h> | |
| #include<ESP8266WebServer.h> | |
| // From v1.1.0 | |
| #include<ESP8266WiFiMulti.h> | |
| ESP8266WiFiMulti wifiMulti; | |
| #defineUSE_LITTLEFStrue | |
| #if USE_LITTLEFS | |
| #include<LittleFS.h> | |
| FS* filesystem = &LittleFS; | |
| #defineFileFS LittleFS | |
| #defineFS_Name"LittleFS" | |
| #else | |
| FS* filesystem = &SPIFFS; | |
| #defineFileFS SPIFFS | |
| #defineFS_Name"SPIFFS" | |
| #endif | |
| ////// | |
| #defineESP_getChipId() (ESP.getChipId()) | |
| #defineLED_ON LOW | |
| #defineLED_OFF HIGH | |
| #endif | |
| // These defines must be put before #include <ESP_DoubleResetDetector.h> | |
| // to select where to store DoubleResetDetector's variable. | |
| // For ESP32, You must select one to be true (EEPROM or SPIFFS) | |
| // For ESP8266, You must select one to be true (RTC, EEPROM, SPIFFS or LITTLEFS) | |
| // Otherwise, library will use default EEPROM storage | |
| #ifdef ESP32 | |
| // These defines must be put before #include <ESP_DoubleResetDetector.h> | |
| // to select where to store DoubleResetDetector's variable. | |
| // For ESP32, You must select one to be true (EEPROM or SPIFFS) | |
| // Otherwise, library will use default EEPROM storage | |
| #if USE_LITTLEFS | |
| #defineESP_DRD_USE_LITTLEFStrue | |
| #defineESP_DRD_USE_SPIFFSfalse | |
| #defineESP_DRD_USE_EEPROMfalse | |
| #elif USE_SPIFFS | |
| #defineESP_DRD_USE_LITTLEFSfalse | |
| #defineESP_DRD_USE_SPIFFStrue | |
| #defineESP_DRD_USE_EEPROMfalse | |
| #else | |
| #defineESP_DRD_USE_LITTLEFSfalse | |
| #defineESP_DRD_USE_SPIFFSfalse | |
| #defineESP_DRD_USE_EEPROMtrue | |
| #endif | |
| #else//ESP8266 | |
| // For DRD | |
| // These defines must be put before #include <ESP_DoubleResetDetector.h> | |
| // to select where to store DoubleResetDetector's variable. | |
| // For ESP8266, You must select one to be true (RTC, EEPROM, SPIFFS or LITTLEFS) | |
| // Otherwise, library will use default EEPROM storage | |
| #if USE_LITTLEFS | |
| #defineESP_DRD_USE_LITTLEFStrue | |
| #defineESP_DRD_USE_SPIFFSfalse | |
| #else | |
| #defineESP_DRD_USE_LITTLEFSfalse | |
| #defineESP_DRD_USE_SPIFFStrue | |
| #endif | |
| #defineESP_DRD_USE_EEPROMfalse | |
| #defineESP8266_DRD_USE_RTCfalse | |
| #endif | |
| #defineDOUBLERESETDETECTOR_DEBUGtrue//false | |
| #include<ESP_DoubleResetDetector.h>//https://github.com/khoih-prog/ESP_DoubleResetDetector | |
| // Number of seconds after reset during which a | |
| // subseqent reset will be considered a double reset. | |
| #defineDRD_TIMEOUT10 | |
| // RTC Memory Address for the DoubleResetDetector to use | |
| #defineDRD_ADDRESS0 | |
| DoubleResetDetector* drd =NULL; | |
| #include"Adafruit_MQTT.h"//https://github.com/adafruit/Adafruit_MQTT_Library | |
| #include"Adafruit_MQTT_Client.h"//https://github.com/adafruit/Adafruit_MQTT_Library | |
| constchar* CONFIG_FILE ="/ConfigMQTT.json"; | |
| // Default configuration values for Adafruit IO MQTT | |
| // This actually works | |
| #defineAIO_SERVER"io.adafruit.com" | |
| #defineAIO_SERVERPORT"1883"//1883, or 8883 for SSL | |
| #defineAIO_USERNAME"private"//Adafruit IO | |
| #defineAIO_KEY"private" | |
| // Labels for custom parameters in WiFi manager | |
| #defineAIO_SERVER_Label"AIO_SERVER_Label" | |
| #defineAIO_SERVERPORT_Label"AIO_SERVERPORT_Label" | |
| #defineAIO_USERNAME_Label"AIO_USERNAME_Label" | |
| #defineAIO_KEY_Label"AIO_KEY_Label" | |
| // Just dummy topics. To be updated later when got valid data from FS or Config Portal | |
| String MQTT_Pub_Topic ="private/feeds/Temperature"; | |
| // Variables to save custom parameters to... | |
| // I would like to use these instead of #defines | |
| #definecustom_AIO_SERVER_LEN20 | |
| #definecustom_AIO_PORT_LEN5 | |
| #definecustom_AIO_USERNAME_LEN20 | |
| #definecustom_AIO_KEY_LEN40 | |
| char custom_AIO_SERVER[custom_AIO_SERVER_LEN]; | |
| char custom_AIO_SERVERPORT[custom_AIO_PORT_LEN]; | |
| char custom_AIO_USERNAME[custom_AIO_USERNAME_LEN]; | |
| char custom_AIO_KEY[custom_AIO_KEY_LEN]; | |
| // Function Prototypes | |
| voidMQTT_connect(); | |
| boolreadConfigFile(); | |
| boolwriteConfigFile(); | |
| // From v1.1.1 | |
| // You only need to format the filesystem once | |
| //#define FORMAT_FILESYSTEM true | |
| #defineFORMAT_FILESYSTEMfalse | |
| #defineMIN_AP_PASSWORD_SIZE8 | |
| #defineSSID_MAX_LEN32 | |
| //From v1.0.10, WPA2 passwords can be up to 63 characters long. | |
| #definePASS_MAX_LEN64 | |
| typedefstruct | |
| { | |
| char wifi_ssid[SSID_MAX_LEN]; | |
| char wifi_pw [PASS_MAX_LEN]; | |
| } WiFi_Credentials; | |
| typedefstruct | |
| { | |
| String wifi_ssid; | |
| String wifi_pw; | |
| } WiFi_Credentials_String; | |
| #defineNUM_WIFI_CREDENTIALS2 | |
| // Assuming max 491 chars | |
| #defineTZNAME_MAX_LEN50 | |
| #defineTIMEZONE_MAX_LEN50 | |
| typedefstruct | |
| { | |
| WiFi_Credentials WiFi_Creds [NUM_WIFI_CREDENTIALS]; | |
| char TZ_Name[TZNAME_MAX_LEN];// "America/Toronto" | |
| char TZ[TIMEZONE_MAX_LEN];// "EST5EDT,M3.2.0,M11.1.0" | |
| uint16_t checksum; | |
| } WM_Config; | |
| WM_Config WM_config; | |
| #defineCONFIG_FILENAMEF("/wifi_cred.dat") | |
| ////// | |
| // Indicates whether ESP has WiFi credentials saved from previous session, or double reset detected | |
| bool initialConfig = false; | |
| // 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 <ESPAsync_WiFiManager.h> | |
| #defineUSE_AVAILABLE_PAGESfalse | |
| // From v1.0.10 to permit disable/enable StaticIP configuration in Config Portal from sketch. Valid only if DHCP is used. | |
| // You'll loose the feature of dynamically changing from DHCP to static IP, or vice versa | |
| // You have to explicitly specify false to disable the feature. | |
| //#define USE_STATIC_IP_CONFIG_IN_CP false | |
| // Use false to disable NTP config. Advisable when using Cellphone, Tablet to access Config Portal. | |
| // See Issue 23: On Android phone ConfigPortal is unresponsive (https://github.com/khoih-prog/ESP_WiFiManager/issues/23) | |
| #defineUSE_ESP_WIFIMANAGER_NTPtrue | |
| // Just use enough to save memory. On ESP8266, can cause blank ConfigPortal screen | |
| // if using too much memory | |
| #defineUSING_AFRICAfalse | |
| #defineUSING_AMERICAtrue | |
| #defineUSING_ANTARCTICAfalse | |
| #defineUSING_ASIAfalse | |
| #defineUSING_ATLANTICfalse | |
| #defineUSING_AUSTRALIAfalse | |
| #defineUSING_EUROPEfalse | |
| #defineUSING_INDIANfalse | |
| #defineUSING_PACIFICfalse | |
| #defineUSING_ETC_GMTfalse | |
| // Use true to enable CloudFlare NTP service. System can hang if you don't have Internet access while accessing CloudFlare | |
| // See Issue #21: CloudFlare link in the default portal (https://github.com/khoih-prog/ESP_WiFiManager/issues/21) | |
| #defineUSE_CLOUDFLARE_NTPfalse | |
| // New in v1.0.11 | |
| #defineUSING_CORS_FEATUREtrue | |
| //////////////////////////////////////////// | |
| // Use USE_DHCP_IP == true for dynamic DHCP IP, false to use static IP which you have to change accordingly to your network | |
| #if (defined(USE_STATIC_IP_CONFIG_IN_CP) && !USE_STATIC_IP_CONFIG_IN_CP) | |
| // Force DHCP to be true | |
| #if defined(USE_DHCP_IP) | |
| #undef USE_DHCP_IP | |
| #endif | |
| #defineUSE_DHCP_IPtrue | |
| #else | |
| // You can select DHCP or Static IP here | |
| #defineUSE_DHCP_IPtrue | |
| //#define USE_DHCP_IP false | |
| #endif | |
| #if ( USE_DHCP_IP ) | |
| // Use DHCP | |
| #if (_WIFIMGR_LOGLEVEL_ > 3) | |
| #warning Using DHCP IP | |
| #endif | |
| IPAddress stationIP = IPAddress(0,0,0,0); | |
| IPAddress gatewayIP = IPAddress(192,168,2,1); | |
| IPAddress netMask = IPAddress(255,255,255,0); | |
| #else | |
| // Use static IP | |
| #if (_WIFIMGR_LOGLEVEL_ > 3) | |
| #warning Using static IP | |
| #endif | |
| #ifdef ESP32 | |
| IPAddress stationIP = IPAddress(192,168,2,232); | |
| #else | |
| IPAddress stationIP = IPAddress(192,168,2,186); | |
| #endif | |
| IPAddress gatewayIP = IPAddress(192,168,2,1); | |
| IPAddress netMask = IPAddress(255,255,255,0); | |
| #endif | |
| //////////////////////////////////////////// | |
| #defineUSE_CONFIGURABLE_DNStrue | |
| IPAddress dns1IP = gatewayIP; | |
| IPAddress dns2IP = IPAddress(8,8,8,8); | |
| #defineUSE_CUSTOM_AP_IPfalse | |
| // New in v1.4.0 | |
| IPAddress APStaticIP = IPAddress(192,168,100,1); | |
| IPAddress APStaticGW = IPAddress(192,168,100,1); | |
| IPAddress APStaticSN = IPAddress(255,255,255,0); | |
| // Must be placed before #include <ESP_WiFiManager.h>, or default port 80 will be used | |
| //#define HTTP_PORT 8080 | |
| #include<ESP_WiFiManager.h>//https://github.com/khoih-prog/ESP_WiFiManager | |
| // Redundant, for v1.8.0 only | |
| //#include <ESP_WiFiManager-Impl.h> //https://github.com/khoih-prog/ESP_WiFiManager | |
| // For Config Portal | |
| // SSID and PW for Config Portal | |
| String ssid ="ESP_" + String(ESP_getChipId(), HEX); | |
| String password; | |
| // SSID and PW for your Router | |
| String Router_SSID; | |
| String Router_Pass; | |
| ///////////////////////////////////////////////////// | |
| #defineHTTP_PORT80 | |
| // Create an ESP32 WiFiClient class to connect to the MQTT server | |
| WiFiClient *client =NULL; | |
| Adafruit_MQTT_Client *mqtt =NULL; | |
| Adafruit_MQTT_Publish *Temperature =NULL; | |
| /////////////////////////////////////////// | |
| // New in v1.4.0 | |
| /****************************************** | |
| * // Defined in ESPAsync_WiFiManager.h | |
| typedef struct | |
| { | |
| IPAddress _ap_static_ip; | |
| IPAddress _ap_static_gw; | |
| IPAddress _ap_static_sn; | |
| } WiFi_AP_IPConfig; | |
| typedef struct | |
| { | |
| IPAddress _sta_static_ip; | |
| IPAddress _sta_static_gw; | |
| IPAddress _sta_static_sn; | |
| #if USE_CONFIGURABLE_DNS | |
| IPAddress _sta_static_dns1; | |
| IPAddress _sta_static_dns2; | |
| #endif | |
| } WiFi_STA_IPConfig; | |
| ******************************************/ | |
| WiFi_AP_IPConfig WM_AP_IPconfig; | |
| WiFi_STA_IPConfig WM_STA_IPconfig; | |
| voidinitAPIPConfigStruct(WiFi_AP_IPConfig &in_WM_AP_IPconfig) | |
| { | |
| in_WM_AP_IPconfig._ap_static_ip = APStaticIP; | |
| in_WM_AP_IPconfig._ap_static_gw = APStaticGW; | |
| in_WM_AP_IPconfig._ap_static_sn = APStaticSN; | |
| } | |
| voidinitSTAIPConfigStruct(WiFi_STA_IPConfig &in_WM_STA_IPconfig) | |
| { | |
| in_WM_STA_IPconfig._sta_static_ip = stationIP; | |
| in_WM_STA_IPconfig._sta_static_gw = gatewayIP; | |
| in_WM_STA_IPconfig._sta_static_sn = netMask; | |
| #if USE_CONFIGURABLE_DNS | |
| in_WM_STA_IPconfig._sta_static_dns1 = dns1IP; | |
| in_WM_STA_IPconfig._sta_static_dns2 = dns2IP; | |
| #endif | |
| } | |
| voiddisplayIPConfigStruct(WiFi_STA_IPConfig in_WM_STA_IPconfig) | |
| { | |
| LOGERROR3(F("stationIP ="), in_WM_STA_IPconfig._sta_static_ip,", gatewayIP =", in_WM_STA_IPconfig._sta_static_gw); | |
| LOGERROR1(F("netMask ="), in_WM_STA_IPconfig._sta_static_sn); | |
| #if USE_CONFIGURABLE_DNS | |
| LOGERROR3(F("dns1IP ="), in_WM_STA_IPconfig._sta_static_dns1,", dns2IP =", in_WM_STA_IPconfig._sta_static_dns2); | |
| #endif | |
| } | |
| voidconfigWiFi(WiFi_STA_IPConfig in_WM_STA_IPconfig) | |
| { | |
| #if USE_CONFIGURABLE_DNS | |
| // Set static IP, Gateway, Subnetmask, DNS1 and DNS2. New in v1.0.5 | |
| WiFi.config(in_WM_STA_IPconfig._sta_static_ip, in_WM_STA_IPconfig._sta_static_gw, in_WM_STA_IPconfig._sta_static_sn, in_WM_STA_IPconfig._sta_static_dns1, in_WM_STA_IPconfig._sta_static_dns2); | |
| #else | |
| // Set static IP, Gateway, Subnetmask, Use auto DNS1 and DNS2. | |
| WiFi.config(in_WM_STA_IPconfig._sta_static_ip, in_WM_STA_IPconfig._sta_static_gw, in_WM_STA_IPconfig._sta_static_sn); | |
| #endif | |
| } | |
| /////////////////////////////////////////// | |
| uint8_tconnectMultiWiFi() | |
| { | |
| #if ESP32 | |
| // For ESP32, this better be 0 to shorten the connect time. | |
| // For ESP32-S2/C3, must be > 500 | |
| #if ( USING_ESP32_S2 || USING_ESP32_C3 ) | |
| #defineWIFI_MULTI_1ST_CONNECT_WAITING_MS500L | |
| #else | |
| // For ESP32 core v1.0.6, must be >= 500 | |
| #defineWIFI_MULTI_1ST_CONNECT_WAITING_MS800L | |
| #endif | |
| #else | |
| // For ESP8266, this better be 2200 to enable connect the 1st time | |
| #defineWIFI_MULTI_1ST_CONNECT_WAITING_MS2200L | |
| #endif | |
| #defineWIFI_MULTI_CONNECT_WAITING_MS500L | |
| uint8_t status; | |
| //WiFi.mode(WIFI_STA); | |
| LOGERROR(F("ConnectMultiWiFi with :")); | |
| if ( (Router_SSID !="") && (Router_Pass !="") ) | |
| { | |
| LOGERROR3(F("* Flash-stored Router_SSID ="), Router_SSID,F(", Router_Pass ="), Router_Pass ); | |
| LOGERROR3(F("* Add SSID ="), Router_SSID,F(", PW ="), Router_Pass ); | |
| wifiMulti.addAP(Router_SSID.c_str(), Router_Pass.c_str()); | |
| } | |
| for (uint8_t i =0; i < NUM_WIFI_CREDENTIALS; i++) | |
| { | |
| // Don't permit NULL SSID and password len < MIN_AP_PASSWORD_SIZE (8) | |
| if ( (String(WM_config.WiFi_Creds[i].wifi_ssid) !="") && (strlen(WM_config.WiFi_Creds[i].wifi_pw) >= MIN_AP_PASSWORD_SIZE) ) | |
| { | |
| LOGERROR3(F("* Additional SSID ="), WM_config.WiFi_Creds[i].wifi_ssid,F(", PW ="), WM_config.WiFi_Creds[i].wifi_pw ); | |
| } | |
| } | |
| LOGERROR(F("Connecting MultiWifi...")); | |
| //WiFi.mode(WIFI_STA); | |
| #if !USE_DHCP_IP | |
| // New in v1.4.0 | |
| configWiFi(WM_STA_IPconfig); | |
| ////// | |
| #endif | |
| int i =0; | |
| status = wifiMulti.run(); | |
| delay(WIFI_MULTI_1ST_CONNECT_WAITING_MS); | |
| while ( ( i++ <20 ) && ( status != WL_CONNECTED ) ) | |
| { | |
| status = WiFi.status(); | |
| if ( status == WL_CONNECTED ) | |
| break; | |
| else | |
| delay(WIFI_MULTI_CONNECT_WAITING_MS); | |
| } | |
| if ( status == WL_CONNECTED ) | |
| { | |
| LOGERROR1(F("WiFi connected after time:"), i); | |
| LOGERROR3(F("SSID:"), WiFi.SSID(),F(",RSSI="), WiFi.RSSI()); | |
| LOGERROR3(F("Channel:"), WiFi.channel(),F(",IP address:"), WiFi.localIP() ); | |
| } | |
| else | |
| { | |
| LOGERROR(F("WiFi not connected")); | |
| // To avoid unnecessary DRD | |
| drd->loop(); | |
| #if ESP8266 | |
| ESP.reset(); | |
| #else | |
| ESP.restart(); | |
| #endif | |
| } | |
| return status; | |
| } | |
| voidtoggleLED() | |
| { | |
| //toggle state | |
| digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); | |
| } | |
| #if USE_ESP_WIFIMANAGER_NTP | |
| voidprintLocalTime() | |
| { | |
| #if ESP8266 | |
| statictime_t now; | |
| now =time(nullptr); | |
| if ( now >1451602800 ) | |
| { | |
| Serial.print("Local Date/Time:"); | |
| Serial.print(ctime(&now)); | |
| } | |
| #else | |
| structtm timeinfo; | |
| getLocalTime( &timeinfo ); | |
| // Valid only if year > 2000. | |
| // You can get from timeinfo : tm_year, tm_mon, tm_mday, tm_hour, tm_min, tm_sec | |
| if (timeinfo.tm_year >100 ) | |
| { | |
| Serial.print("Local Date/Time:"); | |
| Serial.print(asctime( &timeinfo ) ); | |
| } | |
| #endif | |
| } | |
| #endif | |
| voidheartBeatPrint() | |
| { | |
| #if USE_ESP_WIFIMANAGER_NTP | |
| printLocalTime(); | |
| #else | |
| staticint num =1; | |
| if (WiFi.status() == WL_CONNECTED) | |
| Serial.print(F("W"));// W means connected to WiFi | |
| else | |
| Serial.print(F("N"));// N means not connected to WiFi | |
| if (num ==40) | |
| { | |
| Serial.println(); | |
| num =1; | |
| } | |
| elseif (num++ %5 ==0) | |
| { | |
| Serial.print(F("")); | |
| } | |
| #endif | |
| } | |
| voidpublishMQTT() | |
| { | |
| float some_number =25.0 + (float) (millis() %100 ) /100; | |
| // For debug only | |
| //Serial.print(F("Published Temp = ")); | |
| //Serial.println(some_number); | |
| MQTT_connect(); | |
| if (Temperature->publish(some_number)) | |
| { | |
| Serial.print(F("T"));// T means publishing OK | |
| } | |
| else | |
| { | |
| Serial.print(F("F"));// F means publishing failure | |
| } | |
| } | |
| voidcheck_WiFi() | |
| { | |
| if ( (WiFi.status() != WL_CONNECTED) ) | |
| { | |
| Serial.println(F("\nWiFi lost. Call connectMultiWiFi in loop")); | |
| connectMultiWiFi(); | |
| } | |
| } | |
| voidcheck_status() | |
| { | |
| static ulong checkstatus_timeout =0; | |
| static ulong LEDstatus_timeout =0; | |
| static ulong checkwifi_timeout =0; | |
| static ulong mqtt_publish_timeout =0; | |
| ulong current_millis =millis(); | |
| #defineLED_INTERVAL2000L | |
| #definePUBLISH_INTERVAL90000L | |
| #defineWIFICHECK_INTERVAL1000L | |
| #if USE_ESP_WIFIMANAGER_NTP | |
| #defineHEARTBEAT_INTERVAL60000L | |
| #else | |
| #defineHEARTBEAT_INTERVAL10000L | |
| #endif | |
| // Check WiFi every WIFICHECK_INTERVAL (1) seconds. | |
| if ((current_millis > checkwifi_timeout) || (checkwifi_timeout ==0)) | |
| { | |
| check_WiFi(); | |
| checkwifi_timeout = current_millis + WIFICHECK_INTERVAL; | |
| } | |
| if ((current_millis > LEDstatus_timeout) || (LEDstatus_timeout ==0)) | |
| { | |
| // Toggle LED at LED_INTERVAL = 2s | |
| toggleLED(); | |
| LEDstatus_timeout = current_millis + LED_INTERVAL; | |
| } | |
| // Print hearbeat every HEARTBEAT_INTERVAL (10) seconds. | |
| if ((current_millis > checkstatus_timeout) || (checkstatus_timeout ==0)) | |
| { | |
| heartBeatPrint(); | |
| checkstatus_timeout = current_millis + HEARTBEAT_INTERVAL; | |
| } | |
| // Check every PUBLISH_INTERVAL (60) seconds. | |
| if ((current_millis > mqtt_publish_timeout) || (mqtt_publish_timeout ==0)) | |
| { | |
| if (WiFi.status() == WL_CONNECTED) | |
| { | |
| publishMQTT(); | |
| } | |
| mqtt_publish_timeout = current_millis + PUBLISH_INTERVAL; | |
| } | |
| } | |
| intcalcChecksum(uint8_t* address,uint16_t sizeToCalc) | |
| { | |
| uint16_t checkSum =0; | |
| for (uint16_t index =0; index < sizeToCalc; index++) | |
| { | |
| checkSum += * ( ( (byte*) address ) + index); | |
| } | |
| return checkSum; | |
| } | |
| boolloadConfigData() | |
| { | |
| File file = FileFS.open(CONFIG_FILENAME,"r"); | |
| LOGERROR(F("LoadWiFiCfgFile")); | |
| memset((void *) &WM_config,0,sizeof(WM_config)); | |
| // New in v1.4.0 | |
| memset((void *) &WM_STA_IPconfig,0,sizeof(WM_STA_IPconfig)); | |
| ////// | |
| if (file) | |
| { | |
| file.readBytes((char *) &WM_config,sizeof(WM_config)); | |
| // New in v1.4.0 | |
| file.readBytes((char *) &WM_STA_IPconfig,sizeof(WM_STA_IPconfig)); | |
| ////// | |
| file.close(); | |
| LOGERROR(F("OK")); | |
| if ( WM_config.checksum !=calcChecksum( (uint8_t*) &WM_config,sizeof(WM_config) -sizeof(WM_config.checksum) ) ) | |
| { | |
| LOGERROR(F("WM_config checksum wrong")); | |
| returnfalse; | |
| } | |
| // New in v1.4.0 | |
| displayIPConfigStruct(WM_STA_IPconfig); | |
| ////// | |
| returntrue; | |
| } | |
| else | |
| { | |
| LOGERROR(F("failed")); | |
| returnfalse; | |
| } | |
| } | |
| voidsaveConfigData() | |
| { | |
| File file = FileFS.open(CONFIG_FILENAME,"w"); | |
| LOGERROR(F("SaveWiFiCfgFile")); | |
| if (file) | |
| { | |
| WM_config.checksum =calcChecksum( (uint8_t*) &WM_config,sizeof(WM_config) -sizeof(WM_config.checksum) ); | |
| file.write((uint8_t*) &WM_config,sizeof(WM_config)); | |
| displayIPConfigStruct(WM_STA_IPconfig); | |
| // New in v1.4.0 | |
| file.write((uint8_t*) &WM_STA_IPconfig,sizeof(WM_STA_IPconfig)); | |
| ////// | |
| file.close(); | |
| LOGERROR(F("OK")); | |
| } | |
| else | |
| { | |
| LOGERROR(F("failed")); | |
| } | |
| } | |
| voiddeleteOldInstances() | |
| { | |
| // Delete previous instances | |
| if (mqtt) | |
| { | |
| delete mqtt; | |
| mqtt =NULL; | |
| Serial.println(F("Deleting old MQTT object")); | |
| } | |
| if (Temperature) | |
| { | |
| delete Temperature; | |
| Temperature =NULL; | |
| Serial.println(F("Deleting old Temperature object")); | |
| } | |
| } | |
| voidcreateNewInstances() | |
| { | |
| if (!client) | |
| { | |
| client =new WiFiClient; | |
| Serial.print(F("\nCreating new WiFi client object :")); | |
| Serial.println(client?F("OK") :F("failed")); | |
| } | |
| // Create new instances from new data | |
| if (!mqtt) | |
| { | |
| // Setup the MQTT client class by passing in the WiFi client and MQTT server and login details. | |
| mqtt =newAdafruit_MQTT_Client(client, custom_AIO_SERVER,atoi(custom_AIO_SERVERPORT), custom_AIO_USERNAME, custom_AIO_KEY); | |
| Serial.print(F("Creating new MQTT object :")); | |
| if (mqtt) | |
| { | |
| Serial.println(F("OK")); | |
| Serial.println(String("AIO_SERVER =") + custom_AIO_SERVER +", AIO_SERVERPORT =" + custom_AIO_SERVERPORT); | |
| Serial.println(String("AIO_USERNAME =") + custom_AIO_USERNAME +", AIO_KEY =" + custom_AIO_KEY); | |
| } | |
| else | |
| Serial.println(F("Failed")); | |
| } | |
| if (!Temperature) | |
| { | |
| Serial.print(F("Creating new MQTT_Pub_Topic, Temperature =")); | |
| Serial.println(MQTT_Pub_Topic); | |
| Temperature =newAdafruit_MQTT_Publish(mqtt, MQTT_Pub_Topic.c_str()); | |
| Serial.print(F("Creating new Temperature object :")); | |
| if (Temperature) | |
| { | |
| Serial.println(F("OK")); | |
| Serial.println(String("Temperature MQTT_Pub_Topic =") + MQTT_Pub_Topic); | |
| } | |
| else | |
| Serial.println(F("Failed")); | |
| } | |
| } | |
| voidwifi_manager() | |
| { | |
| Serial.println(F("\nConfig Portal requested.")); | |
| digitalWrite(LED_BUILTIN, LED_ON);// turn the LED on by making the voltage LOW to tell us we are in configuration mode. | |
| //Local intialization. Once its business is done, there is no need to keep it around | |
| ESP_WiFiManagerESP_wifiManager("ConfigOnDRD_FS-MQTT");; | |
| //Check if there is stored WiFi router/password credentials. | |
| //If not found, device will remain in configuration mode until switched off via webserver. | |
| Serial.print(F("Opening Configuration Portal.")); | |
| Router_SSID = ESP_wifiManager.WiFi_SSID(); | |
| Router_Pass = ESP_wifiManager.WiFi_Pass(); | |
| // From v1.1.1, Don't permit NULL password | |
| if ( !initialConfig && (Router_SSID !="") && (Router_Pass !="") ) | |
| { | |
| //If valid AP credential and not DRD, set timeout 120s. | |
| ESP_wifiManager.setConfigPortalTimeout(120); | |
| Serial.println(F("Got stored Credentials. Timeout 120s")); | |
| } | |
| else | |
| { | |
| ESP_wifiManager.setConfigPortalTimeout(0); | |
| Serial.print(F("No timeout :")); | |
| if (initialConfig) | |
| { | |
| Serial.println(F("DRD or No stored Credentials..")); | |
| } | |
| else | |
| { | |
| Serial.println(F("No stored Credentials.")); | |
| } | |
| } | |
| //Local intialization. Once its business is done, there is no need to keep it around | |
| // Extra parameters to be configured | |
| // After connecting, parameter.getValue() will get you the configured value | |
| // Format: <ID> <Placeholder text> <default value> <length> <custom HTML> <label placement> | |
| // (*** we are not using <custom HTML> and <label placement> ***) | |
| // AIO_SERVER | |
| ESP_WMParameterAIO_SERVER_FIELD(AIO_SERVER_Label,"AIO SERVER", custom_AIO_SERVER, custom_AIO_SERVER_LEN +1); | |
| // AIO_SERVERPORT | |
| ESP_WMParameterAIO_SERVERPORT_FIELD(AIO_SERVERPORT_Label,"AIO SERVER PORT", custom_AIO_SERVERPORT, custom_AIO_PORT_LEN +1); | |
| // AIO_USERNAME | |
| ESP_WMParameterAIO_USERNAME_FIELD(AIO_USERNAME_Label,"AIO USERNAME", custom_AIO_USERNAME, custom_AIO_USERNAME_LEN +1); | |
| // AIO_KEY | |
| ESP_WMParameterAIO_KEY_FIELD(AIO_KEY_Label,"AIO KEY", custom_AIO_KEY, custom_AIO_KEY_LEN +1); | |
| // add all parameters here | |
| // order of adding is not important | |
| ESP_wifiManager.addParameter(&AIO_SERVER_FIELD); | |
| ESP_wifiManager.addParameter(&AIO_SERVERPORT_FIELD); | |
| ESP_wifiManager.addParameter(&AIO_USERNAME_FIELD); | |
| ESP_wifiManager.addParameter(&AIO_KEY_FIELD); | |
| // 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(120); | |
| ESP_wifiManager.setMinimumSignalQuality(-1); | |
| // From v1.0.10 only | |
| // Set config portal channel, default = 1. Use 0 => random channel from 1-13 | |
| ESP_wifiManager.setConfigPortalChannel(0); | |
| ////// | |
| #if USE_CUSTOM_AP_IP | |
| //set custom ip for portal | |
| // New in v1.4.0 | |
| ESP_wifiManager.setAPStaticIPConfig(WM_AP_IPconfig); | |
| ////// | |
| #endif | |
| #if !USE_DHCP_IP | |
| // Set (static IP, Gateway, Subnetmask, DNS1 and DNS2) or (IP, Gateway, Subnetmask). New in v1.0.5 | |
| // New in v1.4.0 | |
| ESP_wifiManager.setSTAStaticIPConfig(WM_STA_IPconfig); | |
| ////// | |
| #endif | |
| // New from v1.1.1 | |
| #if USING_CORS_FEATURE | |
| ESP_wifiManager.setCORSHeader("Your Access-Control-Allow-Origin"); | |
| #endif | |
| // Start an access point | |
| // and goes into a blocking loop awaiting configuration. | |
| // Once the user leaves the portal with the exit button | |
| // processing will continue | |
| // SSID to uppercase | |
| ssid.toUpperCase(); | |
| password ="My" + ssid; | |
| Serial.print(F("Starting configuration portal @")); | |
| #if USE_CUSTOM_AP_IP | |
| Serial.print(APStaticIP); | |
| #else | |
| Serial.print(F("192.168.4.1")); | |
| #endif | |
| #if defined(HTTP_PORT_TO_USE) | |
| Serial.print(F(":")); Serial.print(HTTP_PORT_TO_USE); | |
| #endif | |
| Serial.print(F(", SSID =")); | |
| Serial.print(ssid); | |
| Serial.print(F(", PWD =")); | |
| Serial.println(password); | |
| #if DISPLAY_STORED_CREDENTIALS_IN_CP | |
| // New. Update Credentials, got from loadConfigData(), to display on CP | |
| ESP_wifiManager.setCredentials(WM_config.WiFi_Creds[0].wifi_ssid, WM_config.WiFi_Creds[0].wifi_pw, | |
| WM_config.WiFi_Creds[1].wifi_ssid, WM_config.WiFi_Creds[1].wifi_pw); | |
| #endif | |
| if (!ESP_wifiManager.startConfigPortal((constchar *) ssid.c_str(), password.c_str())) | |
| { | |
| Serial.println(F("Not connected to WiFi but continuing anyway.")); | |
| } | |
| else | |
| { | |
| // If you get here you have connected to the WiFi | |
| Serial.println(F("Connected...yeey :)")); | |
| Serial.print(F("Local IP:")); | |
| Serial.println(WiFi.localIP()); | |
| } | |
| // Only clear then save data if CP entered and with new valid Credentials | |
| // No CP => stored getSSID() = "" | |
| if (String(ESP_wifiManager.getSSID(0)) !="" &&String(ESP_wifiManager.getSSID(1)) !="" ) | |
| { | |
| // Stored for later usage, from v1.1.0, but clear first | |
| memset(&WM_config,0,sizeof(WM_config)); | |
| for (uint8_t i =0; i < NUM_WIFI_CREDENTIALS; i++) | |
| { | |
| String tempSSID = ESP_wifiManager.getSSID(i); | |
| String tempPW = ESP_wifiManager.getPW(i); | |
| if (strlen(tempSSID.c_str()) <sizeof(WM_config.WiFi_Creds[i].wifi_ssid) -1) | |
| strcpy(WM_config.WiFi_Creds[i].wifi_ssid, tempSSID.c_str()); | |
| else | |
| strncpy(WM_config.WiFi_Creds[i].wifi_ssid, tempSSID.c_str(),sizeof(WM_config.WiFi_Creds[i].wifi_ssid) -1); | |
| if (strlen(tempPW.c_str()) <sizeof(WM_config.WiFi_Creds[i].wifi_pw) -1) | |
| strcpy(WM_config.WiFi_Creds[i].wifi_pw, tempPW.c_str()); | |
| else | |
| strncpy(WM_config.WiFi_Creds[i].wifi_pw, tempPW.c_str(),sizeof(WM_config.WiFi_Creds[i].wifi_pw) -1); | |
| // Don't permit NULL SSID and password len < MIN_AP_PASSWORD_SIZE (8) | |
| if ( (String(WM_config.WiFi_Creds[i].wifi_ssid) !="") && (strlen(WM_config.WiFi_Creds[i].wifi_pw) >= MIN_AP_PASSWORD_SIZE) ) | |
| { | |
| LOGERROR3(F("* Add SSID ="), WM_config.WiFi_Creds[i].wifi_ssid,F(", PW ="), WM_config.WiFi_Creds[i].wifi_pw ); | |
| wifiMulti.addAP(WM_config.WiFi_Creds[i].wifi_ssid, WM_config.WiFi_Creds[i].wifi_pw); | |
| } | |
| } | |
| #if USE_ESP_WIFIMANAGER_NTP | |
| String tempTZ = ESP_wifiManager.getTimezoneName(); | |
| if (strlen(tempTZ.c_str()) <sizeof(WM_config.TZ_Name) -1) | |
| strcpy(WM_config.TZ_Name, tempTZ.c_str()); | |
| else | |
| strncpy(WM_config.TZ_Name, tempTZ.c_str(),sizeof(WM_config.TZ_Name) -1); | |
| constchar * TZ_Result = ESP_wifiManager.getTZ(WM_config.TZ_Name); | |
| if (strlen(TZ_Result) <sizeof(WM_config.TZ) -1) | |
| strcpy(WM_config.TZ, TZ_Result); | |
| else | |
| strncpy(WM_config.TZ, TZ_Result,sizeof(WM_config.TZ_Name) -1); | |
| if (strlen(WM_config.TZ_Name) >0 ) | |
| { | |
| LOGERROR3(F("Saving current TZ_Name ="), WM_config.TZ_Name,F(", TZ ="), WM_config.TZ); | |
| #if ESP8266 | |
| configTime(WM_config.TZ,"pool.ntp.org"); | |
| #else | |
| //configTzTime(WM_config.TZ, "pool.ntp.org" ); | |
| configTzTime(WM_config.TZ,"time.nist.gov","0.pool.ntp.org","1.pool.ntp.org"); | |
| #endif | |
| } | |
| else | |
| { | |
| LOGERROR(F("Current Timezone Name is not set. Enter Config Portal to set.")); | |
| } | |
| #endif | |
| // New in v1.4.0 | |
| ESP_wifiManager.getSTAStaticIPConfig(WM_STA_IPconfig); | |
| ////// | |
| saveConfigData(); | |
| } | |
| // Getting posted form values and overriding local variables parameters | |
| // Config file is written regardless the connection state | |
| strcpy(custom_AIO_SERVER, AIO_SERVER_FIELD.getValue()); | |
| strcpy(custom_AIO_SERVERPORT, AIO_SERVERPORT_FIELD.getValue()); | |
| strcpy(custom_AIO_USERNAME, AIO_USERNAME_FIELD.getValue()); | |
| strcpy(custom_AIO_KEY, AIO_KEY_FIELD.getValue()); | |
| // Writing JSON config file to flash for next boot | |
| writeConfigFile(); | |
| digitalWrite(LED_BUILTIN, LED_OFF);// Turn LED off as we are not in configuration mode. | |
| deleteOldInstances(); | |
| MQTT_Pub_Topic =String(custom_AIO_USERNAME) +"/feeds/Temperature"; | |
| createNewInstances(); | |
| } | |
| boolreadConfigFile() | |
| { | |
| // this opens the config file in read-mode | |
| File f = FileFS.open(CONFIG_FILE,"r"); | |
| if (!f) | |
| { | |
| Serial.println(F("Config File not found")); | |
| returnfalse; | |
| } | |
| else | |
| { | |
| // we could open the file | |
| size_t size = f.size(); | |
| // Allocate a buffer to store contents of the file. | |
| std::unique_ptr<char[]>buf(newchar[size +1]); | |
| // Read and store file contents in buf | |
| f.readBytes(buf.get(), size); | |
| // Closing file | |
| f.close(); | |
| // Using dynamic JSON buffer which is not the recommended memory model, but anyway | |
| // See https://github.com/bblanchon/ArduinoJson/wiki/Memory%20model | |
| #if (ARDUINOJSON_VERSION_MAJOR >= 6) | |
| DynamicJsonDocumentjson(1024); | |
| auto deserializeError =deserializeJson(json, buf.get()); | |
| if ( deserializeError ) | |
| { | |
| Serial.println(F("JSON parseObject() failed")); | |
| returnfalse; | |
| } | |
| serializeJson(json, Serial); | |
| #else | |
| DynamicJsonBuffer jsonBuffer; | |
| // Parse JSON string | |
| JsonObject& json = jsonBuffer.parseObject(buf.get()); | |
| // Test if parsing succeeds. | |
| if (!json.success()) | |
| { | |
| Serial.println(F("JSON parseObject() failed")); | |
| returnfalse; | |
| } | |
| json.printTo(Serial); | |
| #endif | |
| // Parse all config file parameters, override | |
| // local config variables with parsed values | |
| if (json.containsKey(AIO_SERVER_Label)) | |
| { | |
| strcpy(custom_AIO_SERVER, json[AIO_SERVER_Label]); | |
| } | |
| if (json.containsKey(AIO_SERVERPORT_Label)) | |
| { | |
| strcpy(custom_AIO_SERVERPORT, json[AIO_SERVERPORT_Label]); | |
| } | |
| if (json.containsKey(AIO_USERNAME_Label)) | |
| { | |
| strcpy(custom_AIO_USERNAME, json[AIO_USERNAME_Label]); | |
| } | |
| if (json.containsKey(AIO_KEY_Label)) | |
| { | |
| strcpy(custom_AIO_KEY, json[AIO_KEY_Label]); | |
| } | |
| } | |
| Serial.println(F("\nConfig File successfully parsed")); | |
| returntrue; | |
| } | |
| boolwriteConfigFile() | |
| { | |
| Serial.println(F("Saving Config File")); | |
| #if (ARDUINOJSON_VERSION_MAJOR >= 6) | |
| DynamicJsonDocumentjson(1024); | |
| #else | |
| DynamicJsonBuffer jsonBuffer; | |
| JsonObject& json = jsonBuffer.createObject(); | |
| #endif | |
| // JSONify local configuration parameters | |
| json[AIO_SERVER_Label] = custom_AIO_SERVER; | |
| json[AIO_SERVERPORT_Label] = custom_AIO_SERVERPORT; | |
| json[AIO_USERNAME_Label] = custom_AIO_USERNAME; | |
| json[AIO_KEY_Label] = custom_AIO_KEY; | |
| // Open file for writing | |
| File f = FileFS.open(CONFIG_FILE,"w"); | |
| if (!f) | |
| { | |
| Serial.println(F("Failed to open Config File for writing")); | |
| returnfalse; | |
| } | |
| #if (ARDUINOJSON_VERSION_MAJOR >= 6) | |
| serializeJsonPretty(json, Serial); | |
| // Write data to file and close it | |
| serializeJson(json, f); | |
| #else | |
| json.prettyPrintTo(Serial); | |
| // Write data to file and close it | |
| json.printTo(f); | |
| #endif | |
| f.close(); | |
| Serial.println(F("\nConfig File successfully saved")); | |
| returntrue; | |
| } | |
| // this function is just to display newly saved data, | |
| // it is not necessary though, because data is displayed | |
| // after WiFi manager resets ESP32 | |
| voidnewConfigData() | |
| { | |
| Serial.println(); | |
| Serial.print(F("custom_AIO_SERVER:")); | |
| Serial.println(custom_AIO_SERVER); | |
| Serial.print(F("custom_SERVERPORT:")); | |
| Serial.println(custom_AIO_SERVERPORT); | |
| Serial.print(F("custom_USERNAME_KEY:")); | |
| Serial.println(custom_AIO_USERNAME); | |
| Serial.print(F("custom_KEY:")); | |
| Serial.println(custom_AIO_KEY); | |
| Serial.println(); | |
| } | |
| voidMQTT_connect() | |
| { | |
| int8_t ret; | |
| MQTT_Pub_Topic =String(custom_AIO_USERNAME) +"/feeds/Temperature"; | |
| createNewInstances(); | |
| // Return if already connected | |
| if (mqtt->connected()) | |
| { | |
| return; | |
| } | |
| Serial.println(F("Connecting to MQTT (3 attempts)...")); | |
| uint8_t attempt =3; | |
| while ((ret = mqtt->connect()) !=0) | |
| { | |
| // connect will return 0 for connected | |
| Serial.println(mqtt->connectErrorString(ret)); | |
| Serial.println(F("Another attemtpt to connect to MQTT in 2 seconds...")); | |
| mqtt->disconnect(); | |
| delay(2000);// wait 2 seconds | |
| attempt--; | |
| if (attempt ==0) | |
| { | |
| Serial.println(F("MQTT connection failed. Continuing with program...")); | |
| return; | |
| } | |
| } | |
| Serial.println(F("MQTT connection successful!")); | |
| } | |
| // Setup function | |
| voidsetup() | |
| { | |
| // Initialize the LED digital pin as an output. | |
| pinMode(LED_BUILTIN, OUTPUT); | |
| // Put your setup code here, to run once | |
| Serial.begin(115200); | |
| while (!Serial); | |
| delay(200); | |
| Serial.print(F("\nStarting ConfigOnDRD_FS_MQTT_Ptr using")); Serial.print(FS_Name); | |
| Serial.print(F(" on")); Serial.println(ARDUINO_BOARD); | |
| Serial.println(ESP_WIFIMANAGER_VERSION); | |
| Serial.println(ESP_DOUBLE_RESET_DETECTOR_VERSION); | |
| #if defined(ESP_WIFIMANAGER_VERSION_MIN) | |
| if (ESP_WIFIMANAGER_VERSION_INT < ESP_WIFIMANAGER_VERSION_MIN) | |
| { | |
| Serial.print("Warning. Must use this example on Version later than :"); | |
| Serial.println(ESP_WIFIMANAGER_VERSION_MIN_TARGET); | |
| } | |
| #endif | |
| Serial.setDebugOutput(false); | |
| // Mount the filesystem | |
| if (FORMAT_FILESYSTEM) | |
| { | |
| Serial.println(F("Forced Formatting.")); | |
| FileFS.format(); | |
| } | |
| // Format FileFS if not yet | |
| #ifdef ESP32 | |
| if (!FileFS.begin(true)) | |
| #else | |
| if (!FileFS.begin()) | |
| #endif | |
| { | |
| #ifdef ESP8266 | |
| FileFS.format(); | |
| #endif | |
| Serial.println(F("SPIFFS/LittleFS failed! Already tried formatting.")); | |
| if (!FileFS.begin()) | |
| { | |
| // prevents debug info from the library to hide err message. | |
| delay(100); | |
| #if USE_LITTLEFS | |
| Serial.println(F("LittleFS failed!. Please use SPIFFS or EEPROM. Stay forever")); | |
| #else | |
| Serial.println(F("SPIFFS failed!. Please use LittleFS or EEPROM. Stay forever")); | |
| #endif | |
| while (true) | |
| { | |
| delay(1); | |
| } | |
| } | |
| } | |
| // New in v1.4.0 | |
| initAPIPConfigStruct(WM_AP_IPconfig); | |
| initSTAIPConfigStruct(WM_STA_IPconfig); | |
| ////// | |
| if (!readConfigFile()) | |
| { | |
| Serial.println(F("Can't read Config File, using default values")); | |
| } | |
| drd =newDoubleResetDetector(DRD_TIMEOUT, DRD_ADDRESS); | |
| if (!drd) | |
| { | |
| Serial.println(F("Can't instantiate. Disable DRD feature")); | |
| } | |
| elseif (drd->detectDoubleReset()) | |
| { | |
| // DRD, disable timeout. | |
| //ESP_wifiManager.setConfigPortalTimeout(0); | |
| Serial.println(F("Open Config Portal without Timeout: Double Reset Detected")); | |
| initialConfig =true; | |
| } | |
| if (initialConfig) | |
| { | |
| loadConfigData(); | |
| wifi_manager(); | |
| } | |
| else | |
| { | |
| // Pretend CP is necessary as we have no AP Credentials | |
| initialConfig =true; | |
| // Load stored data, the addAP ready for MultiWiFi reconnection | |
| if (loadConfigData()) | |
| { | |
| #if USE_ESP_WIFIMANAGER_NTP | |
| if (strlen(WM_config.TZ_Name) >0 ) | |
| { | |
| LOGERROR3(F("Current TZ_Name ="), WM_config.TZ_Name,F(", TZ ="), WM_config.TZ); | |
| #if ESP8266 | |
| configTime(WM_config.TZ,"pool.ntp.org"); | |
| #else | |
| //configTzTime(WM_config.TZ, "pool.ntp.org" ); | |
| configTzTime(WM_config.TZ,"time.nist.gov","0.pool.ntp.org","1.pool.ntp.org"); | |
| #endif | |
| } | |
| else | |
| { | |
| Serial.println(F("Current Timezone is not set. Enter Config Portal to set.")); | |
| } | |
| #endif | |
| for (uint8_t i =0; i < NUM_WIFI_CREDENTIALS; i++) | |
| { | |
| // Don't permit NULL SSID and password len < MIN_AP_PASSWORD_SIZE (8) | |
| if ( (String(WM_config.WiFi_Creds[i].wifi_ssid) !="") && (strlen(WM_config.WiFi_Creds[i].wifi_pw) >= MIN_AP_PASSWORD_SIZE) ) | |
| { | |
| LOGERROR3(F("* Add SSID ="), WM_config.WiFi_Creds[i].wifi_ssid,F(", PW ="), WM_config.WiFi_Creds[i].wifi_pw ); | |
| wifiMulti.addAP(WM_config.WiFi_Creds[i].wifi_ssid, WM_config.WiFi_Creds[i].wifi_pw); | |
| initialConfig =false; | |
| } | |
| } | |
| } | |
| if (initialConfig) | |
| { | |
| Serial.println(F("Open Config Portal without Timeout: No stored WiFi Credentials")); | |
| wifi_manager(); | |
| } | |
| elseif ( WiFi.status() != WL_CONNECTED ) | |
| { | |
| Serial.println(F("ConnectMultiWiFi in setup")); | |
| connectMultiWiFi(); | |
| } | |
| } | |
| digitalWrite(LED_BUILTIN, LED_OFF);// Turn led off as we are not in configuration mode. | |
| } | |
| // Loop function | |
| voidloop() | |
| { | |
| // Call the double reset detector loop method every so often, | |
| // so that it can recognise when the timeout expires. | |
| // You can also call drd.stop() when you wish to no longer | |
| // consider the next reset as a double reset. | |
| if (drd) | |
| drd->loop(); | |
| // this is just for checking if we are connected to WiFi | |
| check_status(); | |
| } |
1.ConfigOnSwitchFS_MQTT_Ptr on ESP8266_NODEMCU_ESP12E
This is terminal debug output when runningConfigOnSwitchFS_MQTT_Ptr onESP8266_NODEMCU_ESP12E. Config Portal was requested to input and saveMQTT Credentials. The boards then connected toAdafruit MQTT Server successfully
Starting ConfigOnSwichFS_MQTT_Ptr using LittleFS on ESP8266_NODEMCU_ESP12EESP_WiFiManager v1.12.1Configuration file not foundFailed to read configuration file, using default values[WM] RFC925 Hostname = ConfigOnSwichFS-MQTT[WM] setSTAStaticIPConfig for USE_CONFIGURABLE_DNS[WM] Set CORS Header to : Your Access-Control-Allow-OriginESP Self-Stored: SSID = HueNet, Pass = 12345678[WM] * Add SSID = HueNet , PW = 12345678Got stored Credentials. Timeout 120s for Config PortalStarting configuration portal.[WM] WiFi.waitForConnectResult Done[WM] SET AP_STA[WM] Configuring AP SSID = ESP_119055[WM] AP PWD = your_password[WM] AP Channel = 3[WM] AP IP address = 192.168.4.1[WM] HTTP server started[WM] ESP_WiFiManager::startConfigPortal : Enter loop[WM] Custom STA IP/GW/Subnet[WM] DNS1 and DNS2 set[WM] setWifiStaticIP IP = 192.168.2.186[WM] Connected after waiting (s) : 0.12[WM] Local ip = 192.168.2.186[WM] Timed out connection result: WL_CONNECTEDWiFi connected...yeey :)[WM] SaveWiFiCfgFile [WM] OKAfter waiting 0.00 secs more in setup(), connection result is connected. Local IP: 192.168.2.186[WM] freeing allocated params!Creating new WiFi client object OKCreating new MQTT object OKAIO_SERVER = , AIO_SERVERPORT = 0AIO_USERNAME = , AIO_KEY = Creating new MQTT_Pub_Topic, Temperature = /feeds/TemperatureCreating new Temperature object OKTemperature MQTT_Pub_Topic = /feeds/TemperatureConnecting to WiFi MQTT (3 attempts)...Connection failedAnother attemtpt to connect to MQTT in 2 seconds...Connection failedAnother attemtpt to connect to MQTT in 2 seconds...Connection failedAnother attemtpt to connect to MQTT in 2 seconds...WiFi MQTT connection failed. Continuing with program...FW...FWConnecting to WiFi MQTT (3 attempts)...Connection failedAnother attemtpt to connect to MQTT in 2 seconds...Connection failedAnother attemtpt to connect to MQTT in 2 seconds...Connection failedAnother attemtpt to connect to MQTT in 2 seconds...WiFi MQTT connection failed. Continuing with program...FWButton clicked!Configuration Portal requested.[WM] RFC925 Hostname = ConfigOnSwitchFS-MQTTOpening Configuration Portal. Got stored Credentials. Timeout 120s[WM] Adding parameter [WM] Adding parameter AIO_SERVER_Label[WM] Adding parameter AIO_SERVERPORT_Label[WM] Adding parameter AIO_USERNAME_Label[WM] Adding parameter AIO_KEY_Label[WM] setSTAStaticIPConfig for USE_CONFIGURABLE_DNS[WM] Set CORS Header to : Your Access-Control-Allow-Origin[WM] WiFi.waitForConnectResult Done[WM] SET AP_STA[WM] Configuring AP SSID = ESP_119055[WM] AP PWD = your_password[WM] AP Channel = 6[WM] AP IP address = 192.168.4.1[WM] HTTP server started[WM] ESP_WiFiManager::startConfigPortal : Enter loop[WM] Connecting to new AP[WM] Already connected. Bailing out.Connected...yeey :)Local IP: 192.168.2.186[WM] * Add SSID = HueNet1 , PW = 12345678[WM] * Add SSID = HueNet2 , PW = 12345678[WM] SaveWiFiCfgFile [WM] OKSaving config file{ "AIO_SERVER_Label": "io.adafruit.com", "AIO_SERVERPORT_Label": "1883", "AIO_USERNAME_Label": "account", "AIO_KEY_Label": "aio_key"}Config file was successfully savedDeleting old MQTT objectDeleting old Temperature objectCreating new MQTT object OKAIO_SERVER = io.adafruit.com, AIO_SERVERPORT = 1883AIO_USERNAME = account, AIO_KEY = aio_keyCreating new MQTT_Pub_Topic, Temperature = account/feeds/TemperatureCreating new Temperature object OKTemperature MQTT_Pub_Topic = account/feeds/Temperature[WM] freeing allocated params!Connecting to WiFi MQTT (3 attempts)...WiFi MQTT connection successful!TWWWW WTWWWW WWTWWW WWWTWW WWWWTW2.ESP32_FSWebServer_DRD on ESP32_DEV
This is terminal debug output when runningESP32_FSWebServer_DRD onESP32 ESP32_DEV using SPIFFS..Config Portal was requested byDRD to input and save Credentials. The boards then connected to WiFi APHueNet1 using new Static IP successfully. WiFi APHueNet1 is then lost, and boardautoreconnects itself to backup WiFi APHueNet2.
Starting ESP32_FSWebServer_DRD with DoubleResetDetect using SPIFFS on ESP32_DEVESP_WiFiManager v1.12.1ESP_DoubleResetDetector v1.3.2FS File: /ConfigSW.json, size: 150BFS File: /CanadaFlag_1.png, size: 40.25KBFS File: /CanadaFlag_2.png, size: 8.12KBFS File: /CanadaFlag_3.jpg, size: 10.89KBFS File: /edit.htm.gz, size: 4.02KBFS File: /favicon.ico, size: 1.12KBFS File: /graphs.js.gz, size: 1.92KBFS File: /index.htm, size: 3.63KBFS File: /drd.dat, size: 4BFS File: /wifi_cred.dat, size: 192B[WM] RFC925 Hostname = ESP32-FSWebServerDRD[WM] setAPStaticIPConfig[WM] setSTAStaticIPConfig for USE_CONFIGURABLE_DNS[WM] Set CORS Header to : Your Access-Control-Allow-OriginESP Self-Stored: SSID = HueNet2, Pass = 12345678[WM] * Add SSID = HueNet2 , PW = 12345678Got stored Credentials. Timeout 120s for Config PortalSPIFFS Flag read = 0xd0d04321No doubleResetDetectedSaving config file...Saving config file OK[WM] LoadWiFiCfgFile [WM] OK[WM] * Add SSID = HueNet1 , PW = 12345678[WM] * Add SSID = HueNet2 , PW = 12345678ConnectMultiWiFi in setup[WM] ConnectMultiWiFi with :[WM] * Flash-stored Router_SSID = HueNet2 , Router_Pass = 12345678[WM] * Additional SSID = HueNet1 , PW = 12345678[WM] * Additional SSID = HueNet2 , PW = 12345678[WM] Connecting MultiWifi...[WM] WiFi connected after time: 1[WM] SSID: HueNet1 ,RSSI= -27[WM] Channel: 2 ,IP address: 192.168.2.232After waiting 3.16 secs more in setup(), connection result is connected. Local IP: 192.168.2.232HTTP server started @ 192.168.2.232Open http://esp32-fs-browser.local/edit to see the file browser[WM] freeing allocated params!Stop doubleResetDetectingSaving config file...Saving config file OKWiFi lost. Call connectMultiWiFi in loop[WM] ConnectMultiWiFi with :[WM] * Flash-stored Router_SSID = HueNet2 , Router_Pass = 12345678[WM] * Additional SSID = HueNet1 , PW = 12345678[WM] * Additional SSID = HueNet2 , PW = 12345678[WM] Connecting MultiWifi...[WM] WiFi connected after time: 3[WM] SSID: HueNet2 ,RSSI= -59[WM] Channel: 4 ,IP address: 192.168.2.232HHHHHHHHHH HHHHHHHHHH HHHHHHHHHH HHHHHHHHHH3.ESP32_FSWebServer_DRD on ESP32_DEV using newly-supported LittleFS
This is terminal debug output when runningESP32_FSWebServer_DRD onESP32 ESP32_DEV using newly-supported LittleFS..Config Portal was requested byDRD to input and save Credentials. The boards then connected to WiFi APHueNet1 using new Static IP successfully.
Starting ESP32_FSWebServer_DRD with DoubleResetDetect using LittleFS on ESP32_DEVESP_WiFiManager v1.12.1ESP_DoubleResetDetector v1.3.2FS File: /CanadaFlag_1.png, size: 40.25KBFS File: /CanadaFlag_2.png, size: 8.12KBFS File: /CanadaFlag_3.jpg, size: 10.89KBFS File: /Credentials.txt, size: 192BFS File: /drd.dat, size: 4BFS File: /edit.htm.gz, size: 4.02KBFS File: /favicon.ico, size: 1.12KBFS File: /graphs.js.gz, size: 1.92KBFS File: /index.htm, size: 3.63KBFS File: /wifi_cred.dat, size: 192B[WM] RFC925 Hostname = ESP32-FSWebServerDRD[WM] setAPStaticIPConfig[WM] setSTAStaticIPConfig for USE_CONFIGURABLE_DNS[WM] Set CORS Header to : Your Access-Control-Allow-OriginESP Self-Stored: SSID = HueNet1, Pass = 12345678[WM] * Add SSID = HueNet1 , PW = 12345678Got stored Credentials. Timeout 120s for Config PortalLittleFS Flag read = 0xd0d01234doubleResetDetectedSaving config file...Saving config file OKOpen Config Portal without Timeout: Double Reset Detected[WM] WiFi.waitForConnectResult Done[WM] SET AP[WM] Configuring AP SSID = ESP_85288[WM] AP PWD = your_password[WM] AP Channel = 10[WM] Custom AP IP/GW/Subnet = 192.168.232.1 192.168.232.1 255.255.255.0[WM] AP IP address = 192.168.232.1[WM] HTTP server started[WM] ESP_WiFiManager::startConfigPortal : Enter loop[WM] WiFi connected after time: 1[WM] SSID: HueNet1 ,RSSI= -33[WM] Channel: 2 ,IP address: 192.168.2.232After waiting 2.92 secs more in setup(), connection result is connected. Local IP: 192.168.2.232HTTP server started @ 192.168.2.232Open http://esp32-fs-browser.local/edit to see the file browser[WM] freeing allocated params!HStop doubleResetDetectingSaving config file...Saving config file OKHHHHHHHHH HHHHHHHHHH HHHHHHHHHH HHHHHHHHHH HHHHHHHHHH HHHHHHHHHH HHHHHHHHHH HHHHHHHHHHHHHHHHHHHH HHHHHHHHHH HHHHHHHHHH HHHHHHHHHH HHHHHHHHHH HHHHHHHHHH HHHHHHHHHH HHHHHHHHHHHHHHHHHHHH HHHHHHHHHH HHH4.ConfigOnDRD_FS_MQTT_Ptr_Complex on ESP32_DEV
This is terminal debug output when runningConfigOnDRD_FS_MQTT_Ptr_Complex onESP32 ESP32_DEV using LittleFS..Config Portal was then requested byDRD to input and saveMQTT Credentials. The boards then connected toAdafruit MQTT Server successfully.
Starting ConfigOnDRD_FS_MQTT_Ptr_Complex using LittleFS on ESP32_DEVESP_WiFiManager v1.12.1ESP_DoubleResetDetector v1.3.2{"AIO_KEY_Label":"aio_key","AIO_SERVER_Label":"io.adafruit.com","AIO_SERVERPORT_Label":"1883","AIO_USERNAME_Label":"user_name"}Config File successfully parsedLittleFS Flag read = 0xd0d04321No doubleResetDetectedSaving config file...Saving config file OK[WM] LoadWiFiCfgFile [WM] OK[WM] stationIP = 192.168.2.235 , gatewayIP = 192.168.2.1[WM] netMask = 255.255.255.0[WM] dns1IP = 192.168.2.1 , dns2IP = 8.8.8.8[WM] * Add SSID = HueNet1 , PW = 12345678[WM] * Add SSID = HueNet2 , PW = 12345678ConnectMultiWiFi in setup[WM] ConnectMultiWiFi with :[WM] * Additional SSID = HueNet1 , PW = 12345678[WM] * Additional SSID = HueNet2 , PW = 12345678[WM] Connecting MultiWifi...[WM] WiFi connected after time: 1[WM] SSID: HueNet1 ,RSSI= -35[WM] Channel: 2 ,IP address: 192.168.2.235WCreating new WiFi client object : OKCreating new MQTT object : OKAIO_SERVER = io.adafruit.com, AIO_SERVERPORT = 1883AIO_USERNAME = user_name, AIO_KEY = aio_keyCreating new MQTT_Pub_Topic, Temperature = user_name/feeds/TemperatureCreating new Temperature object : OKTemperature MQTT_Pub_Topic = user_name/feeds/TemperatureConnecting to MQTT (3 attempts)...MQTT connection successful!TStop doubleResetDetectingSaving config file...Saving config file OKWWWW WTWWWW WWTWWW WWWTWW WWWWTW WWWWWStarting ConfigOnDRD_FS_MQTT_Ptr_Complex using LittleFS on ESP32_DEVESP_WiFiManager v1.12.1ESP_DoubleResetDetector v1.3.2{"AIO_KEY_Label":"aio_key","AIO_SERVER_Label":"io.adafruit.com","AIO_SERVERPORT_Label":"1883","AIO_USERNAME_Label":"user_name"}Config File successfully parsedLittleFS Flag read = 0xd0d01234doubleResetDetectedSaving config file...Saving config file OKOpen Config Portal without Timeout: Double Reset DetectedConfig Portal requested.[WM] RFC925 Hostname = ConfigOnSwichFS-MQTTOpening Configuration Portal. No timeout : DRD or No stored Credentials..[WM] Adding parameter AIO_KEY_Label[WM] Adding parameter AIO_SERVER_Label[WM] Adding parameter AIO_SERVERPORT_Label[WM] Adding parameter AIO_USERNAME_Label[WM] setAPStaticIPConfig[WM] setSTAStaticIPConfig[WM] Set CORS Header to : Your Access-Control-Allow-Origin[WM] WiFi.waitForConnectResult Done[WM] SET AP[WM] Configuring AP SSID = ESP_85288[WM] AP PWD = your_password[WM] AP Channel = 4[WM] Custom AP IP/GW/Subnet = 192.168.100.1 192.168.100.1 255.255.255.0[WM] AP IP address = 192.168.100.1[WM] HTTP server started[WM] ESP_WiFiManager::startConfigPortal : Enter loop[WM] Connecting to new AP[WM] Previous settings invalidated[WM] Custom STA IP/GW/Subnet[WM] DNS1 and DNS2 set[WM] setWifiStaticIP IP = 192.168.2.235[WM] Connect to new WiFi using new IP parameters[WM] Connected after waiting (s) : 0.60[WM] Local ip = 192.168.2.235[WM] Connection result: WL_CONNECTEDConnected...yeey :)Local IP: 192.168.2.235[WM] * Add SSID = HueNet1 , PW = 12345678[WM] * Add SSID = HueNet2 , PW = 12345678[WM] getSTAStaticIPConfig[WM] stationIP = 192.168.2.235 , gatewayIP = 192.168.2.1[WM] netMask = 255.255.255.0[WM] dns1IP = 192.168.2.1 , dns2IP = 8.8.8.8[WM] SaveWiFiCfgFile [WM] OKSaving Config File{ "AIO_KEY_Label": "aio_key", "AIO_SERVER_Label": "io.adafruit.com", "AIO_SERVERPORT_Label": "1883", "AIO_USERNAME_Label": "user_name"}Config File successfully savedCreating new WiFi client object : OKCreating new MQTT object : OKAIO_SERVER = io.adafruit.com, AIO_SERVERPORT = 1883AIO_USERNAME = user_name, AIO_KEY = aio_keyCreating new MQTT_Pub_Topic, Temperature = user_name/feeds/TemperatureCreating new Temperature object : OKTemperature MQTT_Pub_Topic = user_name/feeds/Temperature[WM] freeing allocated params!WConnecting to MQTT (3 attempts)...MQTT connection successful!TWWWW WTWWWW WWTWWW WWWTWW WWWWTW WWWWW5.ConfigOnDRD_FS_MQTT_Ptr_Medium on ESP8266_NODEMCU_ESP12E
This is terminal debug output when runningConfigOnDRD_FS_MQTT_Ptr_Complex onESP8266_NODEMCU_ESP12E using LittleFS..Config Portal was then requested byDRD to input and saveMQTT Credentials. The boards then connected toAdafruit MQTT Server successfully.
Starting ConfigOnDRD_FS_MQTT_Ptr_Medium using LittleFS on ESP8266_NODEMCU_ESP12EESP_WiFiManager v1.12.1ESP_DoubleResetDetector v1.3.2{"AIO_KEY_Label":"aio_key","AIO_SERVER_Label":"io.adafruit.com","AIO_SERVERPORT_Label":"1883","AIO_USERNAME_Label":"user_name"}Config File successfully parsedLittleFS Flag read = 0xd0d04321No doubleResetDetectedSaving config file...Saving config file OK[WM] LoadWiFiCfgFile [WM] OK[WM] stationIP = 192.168.2.188 , gatewayIP = 192.168.2.1[WM] netMask = 255.255.255.0[WM] dns1IP = 192.168.2.1 , dns2IP = 8.8.8.8[WM] * Add SSID = HueNet1 , PW = 12345678[WM] * Add SSID = HueNet2 , PW = 12345678ConnectMultiWiFi in setup[WM] ConnectMultiWiFi with :[WM] * Additional SSID = HueNet1 , PW = 12345678[WM] * Additional SSID = HueNet2 , PW = 12345678[WM] Connecting MultiWifi...[WM] WiFi connected after time: 1[WM] SSID: HueNet1 ,RSSI= -32[WM] Channel: 2 ,IP address: 192.168.2.188WCreating new WiFi client object : OKCreating new MQTT object : OKAIO_SERVER = io.adafruit.com, AIO_SERVERPORT = 1883AIO_USERNAME = user_name, AIO_KEY = aio_keyCreating new MQTT_Pub_Topic, Temperature = user_name/feeds/TemperatureCreating new Temperature object : OKTemperature MQTT_Pub_Topic = user_name/feeds/TemperatureConnecting to MQTT (3 attempts)...MQTT connection successful!TWWWW WTWWWW WWTWWW WWWTWW WWWWTW WWWWWStarting ConfigOnDRD_FS_MQTT_Ptr_Medium using LittleFS on ESP8266_NODEMCU_ESP12EESP_WiFiManager v1.12.1ESP_DoubleResetDetector v1.3.2{"AIO_KEY_Label":"aio_key","AIO_SERVER_Label":"io.adafruit.com","AIO_SERVERPORT_Label":"1883","AIO_USERNAME_Label":"user_name"}Config File successfully parsedLittleFS Flag read = 0xd0d01234doubleResetDetectedSaving config file...Saving config file OKOpen Config Portal without Timeout: Double Reset DetectedConfig Portal requested.[WM] RFC925 Hostname = ConfigOnSwichFS-MQTTOpening Configuration Portal. No timeout : DRD or No stored Credentials..[WM] Adding parameter AIO_SERVER_Label[WM] Adding parameter AIO_SERVERPORT_Label[WM] Adding parameter AIO_USERNAME_Label[WM] Adding parameter AIO_KEY_Label[WM] setAPStaticIPConfig[WM] setSTAStaticIPConfig[WM] Set CORS Header to : Your Access-Control-Allow-Origin[WM] WiFi.waitForConnectResult Done[WM] SET AP_STA[WM] Configuring AP SSID = ESP_702FF3[WM] AP PWD = your_password[WM] AP Channel = 3[WM] Custom AP IP/GW/Subnet = 192.168.100.1 192.168.100.1 255.255.255.0[WM] AP IP address = 192.168.100.1[WM] HTTP server started[WM] ESP_WiFiManager::startConfigPortal : Enter loop[WM] Connecting to new AP[WM] Already connected. Bailing out.Connected...yeey :)Local IP: 192.168.2.166[WM] * Add SSID = HueNet1 , PW = 12345678[WM] * Add SSID = HueNet2 , PW = 12345678[WM] getSTAStaticIPConfig[WM] stationIP = 192.168.2.185 , gatewayIP = 192.168.2.1[WM] netMask = 255.255.255.0[WM] dns1IP = 192.168.2.1 , dns2IP = 8.8.8.8[WM] SaveWiFiCfgFile [WM] OKSaving Config File{ "AIO_SERVER_Label": "io.adafruit.com", "AIO_SERVERPORT_Label": "1883", "AIO_USERNAME_Label": "user_name", "AIO_KEY_Label": "aio_key"}Config File successfully savedCreating new WiFi client object : OKCreating new MQTT object : OKAIO_SERVER = io.adafruit.com, AIO_SERVERPORT = 1883AIO_USERNAME = user_name, AIO_KEY = aio_keyCreating new MQTT_Pub_Topic, Temperature = user_name/feeds/TemperatureCreating new Temperature object : OKTemperature MQTT_Pub_Topic = user_name/feeds/Temperature[WM] freeing allocated params!WConnecting to MQTT (3 attempts)...MQTT connection successful!TWWWW WTWWWW WWTWWW WWWTWW WWWWTW WWWWW6.ConfigOnDoubleReset on ESP32S2_DEV
This is terminal debug output when runningConfigOnDoubleReset onESP32S2_DEV.
Starting ConfigOnDoubleReset with DoubleResetDetect using LittleFS on ESP32S2_DEVESP_WiFiManager v1.12.1ESP_DoubleResetDetector v1.3.2[WM] RFC925 Hostname = ConfigOnDoubleReset[WM] setAPStaticIPConfig[WM] Set CORS Header to : Your Access-Control-Allow-OriginESP Self-Stored: SSID = HueNet1, Pass = 12345678[WM] * Add SSID = HueNet1 , PW = 12345678Got ESP Self-Stored Credentials. Timeout 120s for Config PortalLittleFS Flag read = 0xD0D04321No doubleResetDetectedSaving config file...Saving config file OK[WM] LoadWiFiCfgFile [WM] OK[WM] stationIP = 0.0.0.0 , gatewayIP = 192.168.2.1[WM] netMask = 255.255.255.0[WM] dns1IP = 192.168.2.1 , dns2IP = 8.8.8.8[WM] * Add SSID = HueNet1 , PW = 12345678[WM] * Add SSID = HueNet2 , PW = 12345678ConnectMultiWiFi in setup[WM] ConnectMultiWiFi with :[WM] * Flash-stored Router_SSID = HueNet1 , Router_Pass = 12345678[WM] * Additional SSID = HueNet1 , PW = 12345678[WM] * Additional SSID = HueNet2 , PW = 12345678[WM] Connecting MultiWifi...[WM] WiFi connected after time: 1[WM] SSID: HueNet1 ,RSSI= -35[WM] Channel: 2 ,IP address: 192.168.2.157After waiting 7.83 secs more in setup(), connection result is connected. Local IP: 192.168.2.157[WM] freeing allocated params!HStop doubleResetDetectingSaving config file...Saving config file OKHHHHHHHHH HHHHHHHHHH HHHHHHHHHH HHHHHHHHHH HHHHHHHHHH HHHHHHHHHH HHHHHHHHHH HHHHHHHHHHHHHHHHHHHH HHHHHHHHHH HHHHHHHHHH HHHHHHHHHH HHHHHHHHHH HHHHHHHHHH HHHHHHHHHH HHHHHHHHHHHHHHHHHHHH HHHHHHHHHH HHHHHHHHHH HHHHHHHHHH HHHHHHHHHH HHHHHHHHHH HHHHHHHHHH HHHHHHHHHHHHHHHHHHHH HHHHHHHHHH HHHHHHHHHH HHHHHHHHHH HHHHHHHHHH HHHHHHHHHH HHHHHHHHHH HHHHHHHHHH7.ConfigOnDoubleReset on ESP32_DEV
This is terminal debug output when runningConfigOnDoubleReset onESP32_DEV..Config Portal was requested byDRD to input and save Credentials. The boards then connected to WiFi using new Static IP successfully, with correct local time, TZ set and using NTP
Starting ConfigOnDoubleReset with DoubleResetDetect using LittleFS on ESP32_DEVESP_WiFiManager v1.12.1ESP_DoubleResetDetector v1.3.2[WM] RFC925 Hostname = ConfigOnDoubleReset[WM] Set CORS Header to : Your Access-Control-Allow-OriginESP Self-Stored: SSID = HueNet1, Pass = password[WM] * Add SSID = HueNet1 , PW = passwordGot ESP Self-Stored Credentials. Timeout 120s for Config Portal[WM] LoadWiFiCfgFile [WM] OK[WM] stationIP = 192.168.2.232 , gatewayIP = 192.168.2.1[WM] netMask = 255.255.255.0[WM] dns1IP = 192.168.2.1 , dns2IP = 8.8.8.8Got stored Credentials. Timeout 120s for Config Portal[WM] Current TZ_Name = America/New_York , TZ = EST5EDT,M3.2.0,M11.1.0LittleFS Flag read = 0xD0D01234doubleResetDetectedSaving config file...Saving config file OKOpen Config Portal without Timeout: Double Reset DetectedStarting configuration portal @ 192.168.4.1:80, SSID = ESP_85288, PWD = MyESP_85288[WM] WiFi.waitForConnectResult Done[WM] SET AP[WM] Configuring AP SSID = ESP_85288[WM] AP PWD = MyESP_85288[WM] AP Channel = 8[WM] AP IP address = 192.168.4.1[WM] HTTP server started[WM] startConfigPortal : Enter loop[WM] Handle root[WM] captivePortal: hostHeader = test.mosquitto.org[WM] Request redirected to captive portal : 192.168.4.1[WM] Handle root[WM] captivePortal: hostHeader = 192.168.4.1[WM] Info[WM] Sent info page[WM] Handle root[WM] captivePortal: hostHeader = 192.168.4.1[WM] Handle WiFi[WM] Scanning Network[WM] scanWifiNetworks: Done, Scanned Networks n = 8[WM] Sorting[WM] Removing Dup[WM] Index = 0[WM] SSID = HueNet[WM] RSSI = -27[WM] Index = 1[WM] SSID = HueNet1[WM] RSSI = -41[WM] Index = 2[WM] SSID = dragino-1ed63c[WM] RSSI = -45[WM] Index = 3[WM] SSID = HueNetTek[WM] RSSI = -49[WM] Index = 4[WM] SSID = HueNet2[WM] RSSI = -52[WM] Index = 5[WM] SSID = bacau[WM] RSSI = -67[WM] Index = 6[WM] SSID = guest_24[WM] RSSI = -67[WM] Index = 7[WM] SSID = Jessie[WM] RSSI = -85[WM] Static IP = 0.0.0.0[WM] Sent config page[WM] WiFi save[WM] TZ name = America/New_York[WM] New Static IP = 0.0.0.0[WM] New Static Gateway = 192.168.2.1[WM] New Static Netmask = 255.255.255.0[WM] New Static DNS1 = 192.168.2.1[WM] New Static DNS2 = 8.8.8.8[WM] Sent wifi save page[WM] Connecting to new AP[WM] Previous settings invalidated[WM] Can't use Custom STA IP/GW/Subnet[WM] Connect to new WiFi using new IP parameters[WM] Connected after waiting (s) : 6.90[WM] Local ip = 192.168.2.45[WM] Connection result: WL_CONNECTEDWiFi connected...yeey :)[WM] * Add SSID = HueNet1 , PW = password[WM] * Add SSID = HueNet2 , PW = password[WM] Saving current TZ_Name = America/New_York , TZ = EST5EDT,M3.2.0,M11.1.0[WM] getSTAStaticIPConfig[WM] SaveWiFiCfgFile [WM] stationIP = 0.0.0.0 , gatewayIP = 192.168.2.1[WM] netMask = 255.255.255.0[WM] dns1IP = 192.168.2.1 , dns2IP = 8.8.8.8[WM] OKAfter waiting 0.00 secs more in setup(), connection result is connected. Local IP: 192.168.2.45[WM] freeing allocated params!Local Date/Time: Fri Oct 7 15:53:07 2022Local Date/Time: Fri Oct 7 15:54:03 2022Local Date/Time: Fri Oct 7 15:55:03 2022Local Date/Time: Fri Oct 7 15:56:03 2022Starting ConfigOnDoubleReset with DoubleResetDetect using LittleFS on ESP32_DEVESP_WiFiManager v1.12.1ESP_DoubleResetDetector v1.3.2[WM] RFC925 Hostname = ConfigOnDoubleReset[WM] Set CORS Header to : Your Access-Control-Allow-OriginESP Self-Stored: SSID = HueNet1, Pass = password[WM] * Add SSID = HueNet1 , PW = passwordGot ESP Self-Stored Credentials. Timeout 120s for Config Portal[WM] LoadWiFiCfgFile [WM] OK[WM] stationIP = 192.168.2.232 , gatewayIP = 192.168.2.1[WM] netMask = 255.255.255.0[WM] dns1IP = 192.168.2.1 , dns2IP = 8.8.8.8Got stored Credentials. Timeout 120s for Config Portal[WM] Current TZ_Name = America/New_York , TZ = EST5EDT,M3.2.0,M11.1.0LittleFS Flag read = 0xD0D04321No doubleResetDetectedSaving config file...Saving config file OK[WM] * Add SSID = HueNet1 , PW = password[WM] * Add SSID = HueNet2 , PW = passwordConnectMultiWiFi in setup[WM] ConnectMultiWiFi with :[WM] * Flash-stored Router_SSID = HueNet1 , Router_Pass = password[WM] * Add SSID = HueNet1 , PW = password[WM] * Additional SSID = HueNet1 , PW = password[WM] * Additional SSID = HueNet2 , PW = password[WM] Connecting MultiWifi...[WM] WiFi connected after time: 1[WM] SSID: HueNet1 ,RSSI= -46[WM] Channel: 2 ,IP address: 192.168.2.45After waiting 18.87 secs more in setup(), connection result is connected. Local IP: 192.168.2.45[WM] freeing allocated params!Stop doubleResetDetectingSaving config file...Saving config file OKLocal Date/Time: Fri Oct 7 15:57:03 2022Local Date/Time: Fri Oct 7 15:58:03 2022Local Date/Time: Fri Oct 7 15:59:03 2022Local Date/Time: Fri Oct 7 16:00:03 2022Local Date/Time: Fri Oct 7 16:01:03 20228.ConfigOnDoubleReset on ESP32S2_DEV
This is terminal debug output when runningConfigOnDoubleReset onESP32S2_DEV..Config Portal was requested byDRD to input and save Credentials. The boards then connected to WiFi using new Static IP successfully, with correct local time, TZ set and using NTP
Starting ConfigOnDoubleReset with DoubleResetDetect using LittleFS on ESP32S2_DEVESP_WiFiManager v1.12.1ESP_DoubleResetDetector v1.3.2[WM] RFC925 Hostname = ConfigOnDoubleReset[WM] Set CORS Header to : Your Access-Control-Allow-OriginESP Self-Stored: SSID = HueNet1, Pass = password[WM] * Add SSID = HueNet1 , PW = passwordGot ESP Self-Stored Credentials. Timeout 120s for Config Portal[WM] LoadWiFiCfgFile [WM] OK[WM] WM_config checksum wrongOpen Config Portal without Timeout: No stored Credentials.LittleFS Flag read = 0xD0D04321No doubleResetDetectedSaving config file...Saving config file OKStarting configuration portal @ 192.168.4.1:80, SSID = ESP_8A1DF7C, PWD = MyESP_8A1DF7C[WM] WiFi.waitForConnectResult Done[WM] SET AP[WM] Configuring AP SSID = ESP_8A1DF7C[WM] AP PWD = MyESP_8A1DF7C[WM] AP Channel = 4[WM] AP IP address = 192.168.4.1[WM] HTTP server started[WM] startConfigPortal : Enter loop[WM] Handle root[WM] captivePortal: hostHeader = 192.168.4.1[WM] Info[WM] Sent info page[WM] Handle root[WM] captivePortal: hostHeader = 192.168.4.1[WM] Handle WiFi[WM] Scanning Network[WM] scanWifiNetworks: Done, Scanned Networks n = 23[WM] Sorting[WM] Removing Dup[WM] DUP AP: Waterhome[WM] DUP AP: Waterhome[WM] DUP AP: Access 2.0[WM] Index = 0[WM] SSID = HueNet[WM] RSSI = -20[WM] Index = 1[WM] SSID = HueNet1[WM] RSSI = -28[WM] Index = 2[WM] SSID = HueNetTek[WM] RSSI = -31[WM] Index = 3[WM] SSID = dragino-1ed63c[WM] RSSI = -43[WM] Index = 4[WM] SSID = HueNet2[WM] RSSI = -47[WM] Index = 5[WM] SSID = bacau[WM] RSSI = -67[WM] Index = 6[WM] SSID = guest_24[WM] RSSI = -67[WM] Index = 7[WM] SSID = rogers786[WM] RSSI = -72[WM] Index = 8[WM] SSID = dlink-4F96[WM] RSSI = -81[WM] Index = 9[WM] SSID = Waterhome[WM] RSSI = -81[WM] Index = 10[WM] SSID = VIRGIN874[WM] RSSI = -83[WM] Index = 11[WM] SSID = elef[WM] RSSI = -84[WM] Index = 12[WM] SSID = Access 2.0[WM] RSSI = -85[WM] Index = 14[WM] SSID = Jasmine[WM] RSSI = -86[WM] Index = 16[WM] SSID = FishBowl[WM] RSSI = -87[WM] Index = 17[WM] SSID = FishTank[WM] RSSI = -87[WM] Index = 19[WM] SSID = BELL246[WM] RSSI = -89[WM] Index = 20[WM] SSID = BAHFAMILY[WM] RSSI = -89[WM] Index = 21[WM] SSID = madda[WM] RSSI = -91[WM] Index = 22[WM] SSID = BELL040[WM] RSSI = -91[WM] Static IP = 0.0.0.0[WM] Sent config page[WM] WiFi save[WM] TZ name = America/New_York[WM] New Static IP = 0.0.0.0[WM] New Static Gateway = 192.168.2.1[WM] New Static Netmask = 255.255.255.0[WM] New Static DNS1 = 192.168.2.1[WM] New Static DNS2 = 8.8.8.8[WM] Sent wifi save page[WM] Connecting to new AP[WM] Previous settings invalidated[WM] Can't use Custom STA IP/GW/Subnet[WM] Connect to new WiFi using new IP parameters[WM] Connected after waiting (s) : 6.80[WM] Local ip = 192.168.2.157[WM] Connection result: WL_CONNECTEDWiFi connected...yeey :)[WM] * Add SSID = HueNet1 , PW = password[WM] * Add SSID = HueNet2 , PW = password[WM] Saving current TZ_Name = America/New_York , TZ = EST5EDT,M3.2.0,M11.1.0[WM] getSTAStaticIPConfig[WM] SaveWiFiCfgFile [WM] stationIP = 0.0.0.0 , gatewayIP = 192.168.2.1[WM] netMask = 255.255.255.0[WM] dns1IP = 192.168.2.1 , dns2IP = 8.8.8.8[WM] OKAfter waiting 0.00 secs more in setup(), connection result is connected. Local IP: 192.168.2.157[WM] freeing allocated params!Stop doubleResetDetectingSaving config file...Saving config file OKLocal Date/Time: Thu May 6 21:26:18 2021Local Date/Time: Thu May 6 21:27:18 2021Local Date/Time: Thu May 6 21:28:18 2021Local Date/Time: Thu May 6 21:29:18 2021Starting ConfigOnDoubleReset with DoubleResetDetect using LittleFS on ESP32S2_DEVESP_WiFiManager v1.12.1ESP_DoubleResetDetector v1.3.2[WM] RFC925 Hostname = ConfigOnDoubleReset[WM] Set CORS Header to : Your Access-Control-Allow-OriginESP Self-Stored: SSID = HueNet1, Pass = password[WM] * Add SSID = HueNet1 , PW = passwordGot ESP Self-Stored Credentials. Timeout 120s for Config Portal[WM] LoadWiFiCfgFile [WM] OK[WM] stationIP = 0.0.0.0 , gatewayIP = 192.168.2.1[WM] netMask = 255.255.255.0[WM] dns1IP = 192.168.2.1 , dns2IP = 8.8.8.8Got stored Credentials. Timeout 120s for Config Portal[WM] Current TZ_Name = America/New_York , TZ = EST5EDT,M3.2.0,M11.1.0LittleFS Flag read = 0xD0D04321No doubleResetDetectedSaving config file...Saving config file OK[WM] * Add SSID = HueNet1 , PW = password[WM] * Add SSID = HueNet2 , PW = passwordConnectMultiWiFi in setup[WM] ConnectMultiWiFi with :[WM] * Flash-stored Router_SSID = HueNet1 , Router_Pass = password[WM] * Add SSID = HueNet1 , PW = password[WM] * Additional SSID = HueNet1 , PW = password[WM] * Additional SSID = HueNet2 , PW = password[WM] Connecting MultiWifi...[WM] WiFi connected after time: 1[WM] SSID: HueNet1 ,RSSI= -27[WM] Channel: 2 ,IP address: 192.168.2.157After waiting 7.72 secs more in setup(), connection result is connected. Local IP: 192.168.2.157[WM] freeing allocated params!Local Date/Time: Wed Dec 31 19:00:13 1969Stop doubleResetDetectingSaving config file...Saving config file OKLocal Date/Time: Fri Oct 7 16:03:03 2022Local Date/Time: Fri Oct 7 16:04:03 2022Local Date/Time: Fri Oct 7 16:05:03 2022Local Date/Time: Fri Oct 7 16:06:03 2022Local Date/Time: Fri Oct 7 16:07:03 2022Local Date/Time: Fri Oct 7 16:08:03 20229.ESP32_FSWebServer_DRD on ESP32C3_DEV using SPIFFS
This is terminal debug output when runningESP32_FSWebServer_DRD onESP32C3_DEV using SPIFFS and ESP32 core v2.0.0-rc1..Config Portal was requested byDRD to input and save Credentials. The boards then connected to WiFi APHueNet using new Static IP successfully.
Starting ESP32_FSWebServer_DRD with DoubleResetDetect using SPIFFS on ESP32C3_DEVESP_WiFiManager v1.12.1ESP_DoubleResetDetector v1.3.2FS File: wm_cp.dat, size: 4BFS File: wm_cp.bak, size: 4BFS File: wmssl_conf.dat, size: 376BFS File: wmssl_conf.bak, size: 376BFS File: wmssl_cred.dat, size: 180BFS File: wmssl_cred.bak, size: 180BFS File: mrd.dat, size: 4BFS File: wifi_cred.dat, size: 334BFS File: CanadaFlag_1.png, size: 40.25KBFS File: CanadaFlag_2.png, size: 8.12KBFS File: CanadaFlag_3.jpg, size: 10.89KBFS File: edit.htm.gz, size: 4.02KBFS File: favicon.ico, size: 1.12KBFS File: graphs.js.gz, size: 1.92KBFS File: index.htm, size: 3.63KBFS File: drd.dat, size: 4B[WM] RFC925 Hostname = ESP32-FSWebServerDRD[WM] Set CORS Header to : Your Access-Control-Allow-OriginESP Self-Stored: SSID = HueNet, Pass = 12345678[WM] * Add SSID = HueNet , PW = 12345678Got ESP Self-Stored Credentials. Timeout 120s for Config Portal[WM] LoadWiFiCfgFile [WM] OK[WM] stationIP = 0.0.0.0 , gatewayIP = 192.168.2.1[WM] netMask = 255.255.255.0[WM] dns1IP = 192.168.2.1 , dns2IP = 8.8.8.8Got stored Credentials. Timeout 120s for Config Portal[WM] Current TZ_Name = America/New_York , TZ = EST5EDT,M3.2.0,M11.1.0SPIFFS Flag read = 0xD0D04321No doubleResetDetectedSaving config file...Saving config file OK[WM] * Add SSID = HueNet1 , PW = 12345678[WM] * Add SSID = HueNet , PW = 12345678ConnectMultiWiFi in setup[WM] ConnectMultiWiFi with :[WM] * Flash-stored Router_SSID = HueNet , Router_Pass = 12345678[WM] * Add SSID = HueNet , PW = 12345678[WM] * Additional SSID = HueNet1 , PW = 12345678[WM] * Additional SSID = HueNet , PW = 12345678[WM] Connecting MultiWifi...[WM] WiFi connected after time: 4[WM] SSID: HueNet ,RSSI= -27[WM] Channel: 10 ,IP address: 192.168.2.99After waiting 12.34 secs more in setup(), connection result is connected. Local IP: 192.168.2.99HTTP server started @ 192.168.2.99Open http://esp32-fs-browser.local/edit to see the file browser[WM] freeing allocated params!Stop doubleResetDetectingSaving config file...Saving config file OKhandleFileRead: /edit.htmhandleFileRead: /index.htmhandleFileList: /handleFileList: [{"type":"file","name":"wm_cp.dat"},{"type":"file","name":"wm_cp.bak"},{"type":"file","name":"wmssl_conf.dat"},{"type":"file","name":"wmssl_conf.bak"},{"type":"file","name":"wmssl_cred.dat"},{"type":"file","name":"wmssl_cred.bak"},{"type":"file","name":"mrd.dat"},{"type":"file","name":"wifi_cred.dat"},{"type":"file","name":"CanadaFlag_1.png"},{"type":"file","name":"CanadaFlag_2.png"},{"type":"file","name":"CanadaFlag_3.jpg"},{"type":"file","name":"edit.htm.gz"},{"type":"file","name":"favicon.ico"},{"type":"file","name":"graphs.js.gz"},{"type":"file","name":"index.htm"},{"type":"file","name":"drd.dat"}]handleFileRead: /CanadaFlag_1.pngLocal Date/Time: Fri Oct 7 16:12:03 2022Local Date/Time: Fri Oct 7 16:13:03 2022Local Date/Time: Fri Oct 7 16:14:03 2022Local Date/Time: Fri Oct 7 16:15:03 202210.ConfigOnDoubleReset on ESP32S3_DEV
This is terminal debug output when runningConfigOnDoubleReset onESP32S3_DEV.
Starting ConfigOnDoubleReset with DoubleResetDetect using LittleFS on ESP32S3_DEVESP_WiFiManager v1.12.1ESP_DoubleResetDetector v1.3.2[WM] RFC925 Hostname = ConfigOnDoubleReset[WM] Set CORS Header to : Your Access-Control-Allow-OriginESP Self-Stored: SSID = HueNet1, Pass = password[WM] * Add SSID = HueNet1 , PW = passwordGot ESP Self-Stored Credentials. Timeout 120s for Config Portal[WM] LoadWiFiCfgFile [WM] OK[WM] stationIP = 0.0.0.0 , gatewayIP = 192.168.2.1[WM] netMask = 255.255.255.0[WM] dns1IP = 192.168.2.1 , dns2IP = 8.8.8.8Got stored Credentials. Timeout 120s for Config Portal[WM] Current TZ_Name = America/New_York , TZ = EST5EDT,M3.2.0,M11.1.0LittleFS Flag read = 0xD0D04321No doubleResetDetectedSaving config file...Saving config file OK[WM] * Add SSID = HueNet1 , PW = password[WM] * Add SSID = HueNet , PW = passwordConnectMultiWiFi in setup[WM] ConnectMultiWiFi with :[WM] * Flash-stored Router_SSID = HueNet1 , Router_Pass = password[WM] * Add SSID = HueNet1 , PW = password[WM] * Additional SSID = HueNet1 , PW = password[WM] * Additional SSID = HueNet , PW = password[WM] Connecting MultiWifi...[WM] WiFi connected after time: 1[WM] SSID: HueNet1 ,RSSI= -23[WM] Channel: 2 ,IP address: 192.168.2.83After waiting 7.92 secs more in setup(), connection result is connected. Local IP: 192.168.2.83[WM] freeing allocated params!Stop doubleResetDetectingSaving config file...Saving config file OKLocal Date/Time: Fri Oct 7 16:16:03 2022Local Date/Time: Fri Oct 7 16:17:03 2022Local Date/Time: Fri Oct 7 16:18:03 2022Local Date/Time: Fri Oct 7 16:19:03 2022Local Date/Time: Fri Oct 7 16:20:03 2022Local Date/Time: Fri Oct 7 16:21:03 2022Local Date/Time: Fri Oct 7 16:22:03 202211.ConfigOnDoubleReset using LittleFS on ESP32C3_DEV
This is terminal debug output when runningConfigOnDoubleReset onESP32C3_DEV.
Starting ConfigOnDoubleReset with DoubleResetDetect using LittleFS on ESP32C3_DEVESP_WiFiManager v1.12.1ESP_DoubleResetDetector v1.3.2[WM] RFC925 Hostname = ConfigOnDoubleReset[WM] Set CORS Header to : Your Access-Control-Allow-OriginESP Self-Stored: SSID = HueNet1, Pass = password[WM] * Add SSID = HueNet1 , PW = passwordGot ESP Self-Stored Credentials. Timeout 120s for Config Portal[WM] LoadWiFiCfgFile [WM] OK[WM] stationIP = 0.0.0.0 , gatewayIP = 192.168.2.1[WM] netMask = 255.255.255.0[WM] dns1IP = 192.168.2.1 , dns2IP = 8.8.8.8Got stored Credentials. Timeout 120s for Config Portal[WM] Current TZ_Name = America/New_York , TZ = EST5EDT,M3.2.0,M11.1.0LittleFS Flag read = 0xD0D04321No doubleResetDetectedSaving config file...Saving config file OK[WM] * Add SSID = HueNet1 , PW = password[WM] * Add SSID = HueNet2 , PW = passwordConnectMultiWiFi in setup[WM] ConnectMultiWiFi with :[WM] * Flash-stored Router_SSID = HueNet1 , Router_Pass = password[WM] * Add SSID = HueNet1 , PW = password[WM] * Additional SSID = HueNet1 , PW = password[WM] * Additional SSID = HueNet2 , PW = password[WM] Connecting MultiWifi...[WM] WiFi connected after time: 1[WM] SSID: HueNet1 ,RSSI= -20[WM] Channel: 2 ,IP address: 192.168.2.85After waiting 8.31 secs more in setup(), connection result is connected. Local IP: 192.168.2.85[WM] freeing allocated params!Stop doubleResetDetectingSaving config file...Saving config file OKLocal Date/Time: Fri Oct 7 16:24:03 2022Local Date/Time: Fri Oct 7 16:25:03 2022Local Date/Time: Fri Oct 7 16:26:03 2022Local Date/Time: Fri Oct 7 16:27:03 2022Debug is enabled by default on Serial. To disable, add beforestartConfigPortal()
ESP_wifiManager.setDebugOutput(false);You can also change the debugging level from 0 to 4
// Use from 0 to 4. Higher number, more debugging messages and memory usage.#define_WIFIMGR_LOGLEVEL_3
If you get compilation errors, more often than not, you may need to install a newer version of theESP32 / ESP8266 core for Arduino.
Sometimes, the library will only work if you update theESP32 / ESP8266 core to the latest version because I am using some newly added function.
If you connect to the created configuration Access Point but the ConfigPortal does not show up, just open a browser and type in the IP of the web portal, by default192.168.4.1.
Submit issues to:ESP_WiFiManager issues
- Based on and modified fromTzapu andKenTaylor's version
- Thanks toAmorphous for the static DNS feature and code, included in v1.0.5
- Thanks toCrispinP for idea to add HostName (v1.0.4) and request to reduce the unnecessary waiting time in ESP_WiFiManager constructor (v1.0.6+). SeeStarting WiFIManger is very slow (2000ms)
- Thanks toOttoKlaasen for reportingHaving issue to read the SPIFF file bug in examples.
- Thanks toGiuseppe for reportingStatic Station IP doesn't work bug.
- Thanks toAlesSt for reporting then help provide the fixes:
- On Android phone ConfigPortal is unresponsive and request an enhancement (HOWTO disable the static IP inputs on the config page) leading toESP_WiFiManager v1.0.10.
- Issue #25: API call /r doesn't clear credentials,Issue #26: softAP with custom IP not working andIssue #27: CORS protection fires up with AJAX leading toESP_WiFiManager v1.0.11.
- Thanks toMarko for agreeing to contribute the sample code dealing with MQTT which theConfigOnSwitchFS_MQTT_Ptr is based on. SeeCustom MQTT parameters using Wifi Manager.
- Thanks to05prateek for reportingStationmode Static IP changes to dhcp when esp8266 is restarted bug which is fixed in v1.0.11 by enhance autoConnect() function.
- Thanks toEgor andHenrikW to make
Support building in PlatformIO PRand post issueChange Implementation to separate *.h and *.cpp file instead of *.h and *-Impl.hto address themultiple definitionlinker error in certain cases, leading to v1.2.0 - Thanks toMaurice Poos to report issue
ESP_WiFiManager Issue 39: Not able to read analog port when using the autoconnect example. - Thanks toVague Rabbit for requesting, collarborating in creating theHOWTO Add Dynamic Parameters.
- Thanks toRoshan to report the issue inError esp_littlefs.c 'utime_p' to fix PIO error in using ESP32 LittleFS with old
LittleFS_esp32 v1.0 - Thanks toyiancar to report the issue and propose a fix inIn AP, DNS server always redirects to 192.168.4.1 no matter what APStaticIP is set to. #58 leading to v1.6.1
- Thanks toStephen Lavelle andBen Peart for requesting enhancement in_timezoneName never getting set? #51 andHow to retrieve timezone? #51 leading to new v1.7.0
- Thanks toenergise to report the issue inInvalid Json generated #60 leading to new v1.7.1
- Thanks toeth0up to make the PRAdd support for Wifi hidden SSID scanning. #66 leading to v1.7.4
- Thanks toDean Ott for reportingWiFiManager works only on port 80 #75 and providing the solution leading to v1.7.8
- Thanks toTwaste for initiating the discussion inDifferent behaviour using the src_cpp or src_h lib #80 and providing the idea to the solution, to fix
multiple-definitionslinker error, leading to v1.8.0 - Thanks toRichard Hawthorn for reportingCors header not sent when saving wifi details, even when cors is enabled #80 and providing the solution leading to v1.10.2
- Thanks toMattiaCC93 for open discussionHelp for storing variables in memory (non-volatile) #87 and report the ESP32 chipID bug, leading to v1.11.0.
If you want to contribute to this project:
- Report bugs and errors
- Ask for enhancements
- Create issues and pull requests
- Tell other people about this library
- The library is licensed underMIT
Copyright 2019- Khoi Hoang
About
This is an ESP32 / ESP8266 WiFi Connection Manager with fallback web configuration portal. Use this library for configuring ESP32 (including ESP32-S2 and ESP32-C3), ESP8266 modules' WiFi, etc. Credentials at runtime. You can also specify static DNS servers, personalized HostName, fixed or random AP WiFi channel. With examples supporting ArduinoJson
Topics
Resources
License
Contributing
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Packages0
Uh oh!
There was an error while loading.Please reload this page.
Contributors3
Uh oh!
There was an error while loading.Please reload this page.




























