diff --git a/src/WiFiManager_RP2040W_Lite.h b/src/WiFiManager_RP2040W_Lite.h index 3b92c2d..a5b3fce 100644 --- a/src/WiFiManager_RP2040W_Lite.h +++ b/src/WiFiManager_RP2040W_Lite.h @@ -9,11 +9,11 @@ Built by Khoi Hoang https://github.com/khoih-prog/WiFiManager_RP2040W_Lite Licensed under MIT license - Version: 1.0.0 + Version: 1.6.0 Version Modified By Date Comments ------- ----------- ---------- ----------- - 1.0.0 K Hoang 11/09/2021 Add support to RP2040W using arduino-pico core + 1.6.0 K Hoang 11/09/2021 Add support to RP2040W using arduino-pico core v2.4.0+ ********************************************************************************************************************************/ #ifndef WiFiManager_RP2040W_Lite_h @@ -26,23 +26,35 @@ #endif #ifndef WIFI_MANAGER_RP2040W_LITE_VERSION - #define WIFI_MANAGER_RP2040W_LITE_VERSION "WiFiManager_RP2040W_Lite v1.0.0" + #define WIFI_MANAGER_RP2040W_LITE_VERSION "WiFiManager_RP2040W_Lite v1.6.0" #define WIFI_MANAGER_RP2040W_LITE_VERSION_MAJOR 1 - #define WIFI_MANAGER_RP2040W_LITE_VERSION_MINOR 0 + #define WIFI_MANAGER_RP2040W_LITE_VERSION_MINOR 6 #define WIFI_MANAGER_RP2040W_LITE_VERSION_PATCH 0 - #define WIFI_MANAGER_RP2040W_LITE_VERSION_INT 1000000 + #define WIFI_MANAGER_RP2040W_LITE_VERSION_INT 1006000 #endif +#include + +#include + #include #include WiFiMulti_Generic wifiMulti; +//Use LittleFS for RPI Pico +#include +#include + +#define FileFS LittleFS + ////////////////////////////////////////// -#warning Using LittleFS in WiFiManager_RP2040W_Lite.h +#if (_WIFI_GENERIC_LOGLEVEL_ > 3) + #warning Using LittleFS in WiFiManager_RP2040W_Lite.h +#endif ////////////////////////////////////////// @@ -122,7 +134,11 @@ typedef struct // #if USE_DYNAMIC_PARAMETERS - #warning Using Dynamic Parameters + + #if (_WIFI_GENERIC_LOGLEVEL_ > 3) + #warning Using Dynamic Parameters + #endif + ///NEW extern uint16_t NUM_MENU_ITEMS; extern MenuItem myMenuItems []; @@ -246,15 +262,15 @@ String IPAddressToString(const IPAddress& _address) class WiFiManager_RP2040W_Lite { - public: - + public: + WiFiManager_RP2040W_Lite() - { + { // check for the presence of the shield if (WiFi.status() == WL_NO_SHIELD) { - WG_LOGERROR(F("NoWiFi")); - } + WG_LOGERROR("NoWiFi"); + } } ~WiFiManager_RP2040W_Lite() @@ -271,46 +287,46 @@ class WiFiManager_RP2040W_Lite #endif } } - + bool connectWiFi(const char* ssid, const char* pass) { - WG_LOGERROR1(F("Con2:"), ssid); - + WG_LOGERROR1("Con2:", ssid); + setHostname(); - if ( WiFi.begin(ssid, pass) == WL_CONNECTED ) + if ( WiFi.begin(ssid, pass) == WL_CONNECTED ) { displayWiFiData(); } else { - WG_LOGERROR(F("NoW")); + WG_LOGERROR("NoW"); return false; } - WG_LOGERROR(F("WOK")); + WG_LOGERROR("WOK"); wifi_connected = true; return true; } - + void begin(const char* ssid, const char* pass ) { - WG_LOGERROR(F("conW")); + WG_LOGERROR("conW"); connectWiFi(ssid, pass); } void begin(const char *iHostname = "") { - #define RETRY_TIMES_CONNECT_WIFI 3 - +#define RETRY_TIMES_CONNECT_WIFI 3 + if (iHostname[0] == 0) { String randomNum = String(random(0xFFFFFF), HEX); randomNum.toUpperCase(); - + String _hostname = "RP2040W-H7-WIFI-" + randomNum; _hostname.toUpperCase(); @@ -321,69 +337,69 @@ class WiFiManager_RP2040W_Lite // Prepare and store the hostname only not NULL getRFC952_hostname(iHostname); } - - WG_LOGERROR1(F("Hostname="), RFC952_hostname); + + WG_LOGERROR1("Hostname=", RFC952_hostname); ////// - + //// New DRD //// - drd = new DoubleResetDetector_Generic(DRD_TIMEOUT, DRD_ADDRESS); + drd = new DoubleResetDetector_Generic(DRD_TIMEOUT, DRD_ADDRESS); bool noConfigPortal = true; - + if (drd->detectDoubleReset()) { - WG_LOGERROR(F("Double Reset Detected")); - + WG_LOGERROR("Double Reset Detected"); + noConfigPortal = false; } //// New DRD //// - + if (LOAD_DEFAULT_CONFIG_DATA) { - WG_LOGERROR(F("======= Start Default Config Data =======")); + WG_LOGERROR("======= Start Default Config Data ======="); displayConfigData(defaultConfig); } - + hadConfigData = getConfigData(); - + isForcedConfigPortal = isForcedCP(); - + //// New DRD/MRD //// // noConfigPortal when getConfigData() OK and no MRD/DRD'ed if (hadConfigData && noConfigPortal && (!isForcedConfigPortal) ) { hadConfigData = true; - + wifiMulti_addAP(); if (connectMultiWiFi(RETRY_TIMES_CONNECT_WIFI)) { - WG_LOGERROR(F("b:WOK")); + WG_LOGERROR("b:WOK"); } else { - WG_LOGERROR(F("b:NoW")); + WG_LOGERROR("b:NoW"); // failed to connect to WiFi, will start configuration mode startConfigurationMode(); } } else - { - WG_LOGERROR(isForcedConfigPortal? F("bg: isForcedConfigPortal = true") : F("bg: isForcedConfigPortal = false")); - + { + WG_LOGERROR(isForcedConfigPortal ? "bg: isForcedConfigPortal = true" : "bg: isForcedConfigPortal = false"); + // If not persistent => clear the flag so that after reset. no more CP, even CP not entered and saved if (persForcedConfigPortal) { - WG_LOGERROR1(F("bg:Stay forever in CP:"), isForcedConfigPortal ? F("Forced-Persistent") : (noConfigPortal ? F("No ConfigDat") : F("DRD/MRD"))); + WG_LOGERROR1("bg:Stay forever in CP:", isForcedConfigPortal ? "Forced-Persistent" : (noConfigPortal ? "No ConfigDat" : "DRD/MRD")); } else { - WG_LOGERROR1(F("bg:Stay forever in CP:"), isForcedConfigPortal ? F("Forced-non-Persistent") : (noConfigPortal ? F("No ConfigDat") : F("DRD/MRD"))); + WG_LOGERROR1("bg:Stay forever in CP:", isForcedConfigPortal ? "Forced-non-Persistent" : (noConfigPortal ? "No ConfigDat" : "DRD/MRD")); clearForcedCP(); } - - //To permit autoreset after timeout if DRD/MRD or non-persistent forced-CP + + //To permit autoreset after timeout if DRD/MRD or non-persistent forced-CP hadConfigData = isForcedConfigPortal ? true : (noConfigPortal ? false : true); - + // failed to connect to WiFi, will start configuration mode startConfigurationMode(); } @@ -424,7 +440,7 @@ class WiFiManager_RP2040W_Lite #endif -#if !defined(WIFI_RECON_INTERVAL) +#if !defined(WIFI_RECON_INTERVAL) #define WIFI_RECON_INTERVAL 0 // default 0s between reconnecting WiFi #else #if (WIFI_RECON_INTERVAL < 0) @@ -438,17 +454,17 @@ class WiFiManager_RP2040W_Lite { static int retryTimes = 0; static bool wifiDisconnectedOnce = false; - + // Lost connection in running. Give chance to reconfig. // Check WiFi status every 5s and update status // Check twice to be sure wifi disconnected is real static unsigned long checkstatus_timeout = 0; - #define WIFI_STATUS_CHECK_INTERVAL 5000L - +#define WIFI_STATUS_CHECK_INTERVAL 5000L + static uint32_t curMillis; - + curMillis = millis(); - + //// New DRD //// // Call the double reset detector loop method every so often, // so that it can recognise when the timeout expires. @@ -456,9 +472,9 @@ class WiFiManager_RP2040W_Lite // consider the next reset as a double reset. drd->loop(); //// New DRD //// - + if ( !configuration_mode && (curMillis > checkstatus_timeout) ) - { + { if ( WiFiConnected() ) { wifi_connected = true; @@ -469,16 +485,16 @@ class WiFiManager_RP2040W_Lite { wifiDisconnectedOnce = false; wifi_connected = false; - WG_LOGERROR(F("r:Check&WLost")); + WG_LOGERROR("r:Check&WLost"); } else { wifiDisconnectedOnce = true; } } - + checkstatus_timeout = curMillis + WIFI_STATUS_CHECK_INTERVAL; - } + } // Lost connection in running. Give chance to reconfig. if ( !wifi_connected ) @@ -491,10 +507,10 @@ class WiFiManager_RP2040W_Lite if (server) { - //WG_LOGDEBUG(F("r:handleClient")); + //WG_LOGDEBUG("r:handleClient"); server->handleClient(); } - + return; } else @@ -506,7 +522,7 @@ class WiFiManager_RP2040W_Lite { if (++retryTimes <= CONFIG_TIMEOUT_RETRYTIMES_BEFORE_RESET) { - WG_LOGERROR1(F("r:WLost&TOut.ConW.Retry#"), retryTimes); + WG_LOGERROR1("r:WLost&TOut.ConW.Retry#", retryTimes); } else { @@ -518,73 +534,59 @@ class WiFiManager_RP2040W_Lite // Not in config mode, try reconnecting before forcing to config mode if ( !wifi_connected ) { - - #if (WIFI_RECON_INTERVAL > 0) static uint32_t lastMillis = 0; - + if ( (lastMillis == 0) || (curMillis - lastMillis) > WIFI_RECON_INTERVAL ) { lastMillis = curMillis; - - WG_LOGERROR(F("r:WLost.ReconW")); - + + WG_LOGERROR("r:WLost.ReconW"); + if (connectMultiWiFi(RETRY_TIMES_RECONNECT_WIFI)) { - WG_LOGERROR(F("r:WOK")); + WG_LOGERROR("r:WOK"); } } #else - WG_LOGERROR(F("r:WLost.ReconW")); - + WG_LOGERROR("r:WLost.ReconW"); + if (connectMultiWiFi(RETRY_TIMES_RECONNECT_WIFI)) { - WG_LOGERROR(F("r:WOK")); + WG_LOGERROR("r:WOK"); } -#endif +#endif } } } else if (configuration_mode) { configuration_mode = false; - WG_LOGERROR(F("r:gotWBack")); + WG_LOGERROR("r:gotWBack"); } } - + ////////////////////////////////////////////// - + void setHostname() { if (RFC952_hostname[0] != 0) { -#if USE_WIFI101 - WiFi.hostname(RFC952_hostname); -#elif USE_WIFI_NINA WiFi.setHostname(RFC952_hostname); -#endif } } - + ////////////////////////////////////////////// - // Very bad that the core now can't permit to change AP IP address via function - // Have to change via #define - // #define DEFAULT_IP_ADDRESS "192.168.3.1" - // This function is obsolete from core v2.7.2 + // Very bad that the core now can't permit to change AP IP address via function + // Have to change via #define +#define DEFAULT_IP_ADDRESS "192.168.42.1" -#if 0 - void setConfigPortalIP(const IPAddress& portalIP = IPAddress(192, 168, 3, 1)) - { - portal_apIP = portalIP; - } -#endif - ////////////////////////////////////////////// - #define MIN_WIFI_CHANNEL 1 - #define MAX_WIFI_CHANNEL 11 // Channel 13 is flaky, because of bad number 13 ;-) +#define MIN_WIFI_CHANNEL 1 +#define MAX_WIFI_CHANNEL 11 // Channel 13 is flaky, because of bad number 13 ;-) int setConfigPortalChannel(const int& channel = 1) { @@ -598,57 +600,57 @@ class WiFiManager_RP2040W_Lite return AP_channel; } - + ////////////////////////////////////////////// - + void setConfigPortal(const String& ssid = "", const String& pass = "") { portal_ssid = ssid; portal_pass = pass; } - + ////////////////////////////////////////////// void setSTAStaticIPConfig(const IPAddress& ip) { static_IP = ip; } - + ////////////////////////////////////////////// - + String getWiFiSSID(const uint8_t& index) - { + { if (index >= NUM_WIFI_CREDENTIALS) return String(""); - + if (!hadConfigData) getConfigData(); return (String(WIFI_GENERIC_config.WiFi_Creds[index].wifi_ssid)); } - + ////////////////////////////////////////////// String getWiFiPW(const uint8_t& index) { if (index >= NUM_WIFI_CREDENTIALS) return String(""); - + if (!hadConfigData) getConfigData(); return (String(WIFI_GENERIC_config.WiFi_Creds[index].wifi_pw)); } - + ////////////////////////////////////////////// bool getWiFiStatus() { return wifi_connected; } - + ////////////////////////////////////////////// - + WIFI_GENERIC_Configuration* getFullConfigData(WIFI_GENERIC_Configuration *configData) { if (!hadConfigData) @@ -660,7 +662,7 @@ class WiFiManager_RP2040W_Lite return (configData); } - + ////////////////////////////////////////////// String localIP() @@ -669,14 +671,14 @@ class WiFiManager_RP2040W_Lite return ipAddress; } - + ////////////////////////////////////////////// void clearConfigData() { memset(&WIFI_GENERIC_config, 0, sizeof(WIFI_GENERIC_config)); - -#if USE_DYNAMIC_PARAMETERS + +#if USE_DYNAMIC_PARAMETERS for (uint16_t i = 0; i < NUM_MENU_ITEMS; i++) { // Actual size of pdata is [maxlen + 1] @@ -686,71 +688,72 @@ class WiFiManager_RP2040W_Lite saveConfigData(); } - + ////////////////////////////////////////////// - + bool isConfigDataValid() { return hadConfigData; } - + ////////////////////////////////////////////// - + bool isConfigMode() { return configuration_mode; } - + ////////////////////////////////////////////// - + // Forced CP => Flag = 0xBEEFBEEF. Else => No forced CP - // Flag to be stored at (EEPROM_START + DRD_FLAG_DATA_SIZE + CONFIG_DATA_SIZE) + // Flag to be stored at (EEPROM_START + DRD_FLAG_DATA_SIZE + CONFIG_DATA_SIZE) // to avoid corruption to current data //#define FORCED_CONFIG_PORTAL_FLAG_DATA ( (uint32_t) 0xDEADBEEF) //#define FORCED_PERS_CONFIG_PORTAL_FLAG_DATA ( (uint32_t) 0xBEEFDEAD) - + const uint32_t FORCED_CONFIG_PORTAL_FLAG_DATA = 0xDEADBEEF; const uint32_t FORCED_PERS_CONFIG_PORTAL_FLAG_DATA = 0xBEEFDEAD; - - #define FORCED_CONFIG_PORTAL_FLAG_DATA_SIZE 4 - + +#define FORCED_CONFIG_PORTAL_FLAG_DATA_SIZE 4 + void resetAndEnterConfigPortal() { persForcedConfigPortal = false; - + setForcedCP(false); - + // Delay then reset the RP2040W after save data delay(1000); resetFunc(); } - + ////////////////////////////////////////////// - + // This will keep CP forever, until you successfully enter CP, and Save data to clear the flag. void resetAndEnterConfigPortalPersistent() { persForcedConfigPortal = true; - + setForcedCP(true); - + // Delay then reset the ESP8266 after save data delay(1000); resetFunc(); } - + ////////////////////////////////////////////// void resetFunc() - { - // Restart for RP2040W + { + // Restart for RP2040W, use either one is OK NVIC_SystemReset(); + //rp2040.reboot(); } ////////////////////////////////////// - + // Add customs headers - + // For configure CORS Header, default to WM_HTTP_CORS_ALLOW_ALL = "*" #if USING_CUSTOMS_STYLE @@ -759,54 +762,64 @@ class WiFiManager_RP2040W_Lite // input{width:95%;}body{text-align: center;} // button{background-color:#16A1E7;color:#fff;line-height:2.4rem;font-size:1.2rem;width:100%;} // fieldset{border-radius:0.3rem;margin:0px;}"; - void setCustomsStyle(const char* CustomsStyle = WIFI_GENERIC_HTML_HEAD_STYLE) + void setCustomsStyle(const char* CustomsStyle = WIFI_GENERIC_HTML_HEAD_STYLE) { WIFI_GENERIC_HTML_HEAD_CUSTOMS_STYLE = CustomsStyle; - WG_LOGDEBUG1(F("Set CustomsStyle to : "), WIFI_GENERIC_HTML_HEAD_CUSTOMS_STYLE); + WG_LOGDEBUG1("Set CustomsStyle to : ", WIFI_GENERIC_HTML_HEAD_CUSTOMS_STYLE); } - + const char* getCustomsStyle() { - WG_LOGDEBUG1(F("Get CustomsStyle = "), WIFI_GENERIC_HTML_HEAD_CUSTOMS_STYLE); + WG_LOGDEBUG1("Get CustomsStyle = ", WIFI_GENERIC_HTML_HEAD_CUSTOMS_STYLE); return WIFI_GENERIC_HTML_HEAD_CUSTOMS_STYLE; } #endif -#if USING_CUSTOMS_HEAD_ELEMENT +#if USING_CUSTOMS_HEAD_ELEMENT //sets a custom element to add to head, like a new style tag - void setCustomsHeadElement(const char* CustomsHeadElement = NULL) + void setCustomsHeadElement(const char* CustomsHeadElement = NULL) { _CustomsHeadElement = CustomsHeadElement; - WG_LOGDEBUG1(F("Set CustomsHeadElement to : "), _CustomsHeadElement); + WG_LOGDEBUG1("Set CustomsHeadElement to : ", _CustomsHeadElement); } - + const char* getCustomsHeadElement() { - WG_LOGDEBUG1(F("Get CustomsHeadElement = "), _CustomsHeadElement); + WG_LOGDEBUG1("Get CustomsHeadElement = ", _CustomsHeadElement); return _CustomsHeadElement; } #endif - -#if USING_CORS_FEATURE + +#if USING_CORS_FEATURE void setCORSHeader(const char* CORSHeaders = NULL) - { + { _CORS_Header = CORSHeaders; - WG_LOGDEBUG1(F("Set CORS Header to : "), _CORS_Header); + WG_LOGDEBUG1("Set CORS Header to : ", _CORS_Header); } - + const char* getCORSHeader() - { - WG_LOGDEBUG1(F("Get CORS Header = "), _CORS_Header); + { + WG_LOGDEBUG1("Get CORS Header = ", _CORS_Header); return _CORS_Header; } #endif bool WiFiConnected() { - return ( (WiFi.status() == WL_CONNECTED) && (WiFi.RSSI() != 0) ); + // You can change longer or shorter depending on your network response + // Shorter => more responsive, but more ping traffic + static uint8_t theTTL = 10; + + // Use ping() to test TCP connections + if (WiFi.ping(WiFi.gatewayIP(), theTTL) == theTTL) + { + return true; + } + + return false; } - + ////////////////////////////////////// @@ -814,24 +827,24 @@ class WiFiManager_RP2040W_Lite String ipAddress = "0.0.0.0"; WiFiWebServer* server = NULL; - + bool configuration_mode = false; unsigned long configTimeout; bool hadConfigData = false; - + bool isForcedConfigPortal = false; bool persForcedConfigPortal = false; WIFI_GENERIC_Configuration WIFI_GENERIC_config; - + uint16_t totalDataSize = 0; String macAddress = ""; bool wifi_connected = false; //IPAddress portal_apIP = IPAddress(192, 168, 3, 1); - + int AP_channel = 10; String portal_ssid = ""; @@ -840,29 +853,29 @@ class WiFiManager_RP2040W_Lite IPAddress static_IP = IPAddress(0, 0, 0, 0); ///////////////////////////////////// - + #if USING_CUSTOMS_STYLE const char* WIFI_GENERIC_HTML_HEAD_CUSTOMS_STYLE = NULL; #endif - + #if USING_CUSTOMS_HEAD_ELEMENT const char* _CustomsHeadElement = NULL; #endif - -#if USING_CORS_FEATURE + +#if USING_CORS_FEATURE const char* _CORS_Header = WM_HTTP_CORS_ALLOW_ALL; //"*"; #endif - + ///////////////////////////////////// - + #if SCAN_WIFI_NETWORKS - int WiFiNetworksFound = 0; // Number of SSIDs found by WiFi scan, including low quality and duplicates - int *indices; // WiFi network data, filled by scan (SSID, BSSID) - String ListOfSSIDs = ""; // List of SSIDs found by scan, in HTML