diff --git a/WiFiManager.cpp b/WiFiManager.cpp index b2b4f36..2f1619d 100644 --- a/WiFiManager.cpp +++ b/WiFiManager.cpp @@ -17,291 +17,310 @@ WiFiServer server(80); WiFiManager::WiFiManager(int eepromStart) { - _eepromStart = eepromStart; + _eepromStart = eepromStart; } void WiFiManager::begin() { - begin("NoNetESP"); + begin("NoNetESP"); } void WiFiManager::begin(char const *apName) { - _apName = apName; - - EEPROM.begin(512); - delay(10); + _apName = apName; + start = millis(); + EEPROM.begin(512); + delay(10); } boolean WiFiManager::autoConnect() { - autoConnect("NoNetESP"); + return autoConnect("NoNetESP"); } boolean WiFiManager::autoConnect(char const *apName) { - begin(apName); - - - DEBUG_PRINT(""); - DEBUG_PRINT("AutoConnect"); - // read eeprom for ssid and pass - String ssid = getSSID(); - String pass = getPassword(); - - if ( ssid.length() > 1 ) { - DEBUG_PRINT("Waiting for Wifi to connect"); + begin(apName); - WiFi.mode(WIFI_STA); - WiFi.begin(ssid.c_str(), pass.c_str()); - if ( hasConnected() ) { - return true; - } + + DEBUG_PRINT(""); + DEBUG_PRINT("AutoConnect"); + // read eeprom for ssid and pass + String ssid = getSSID(); + String pass = getPassword(); + + if ( ssid.length() > 1 ) { + DEBUG_PRINT("Waiting for Wifi to connect"); + + WiFi.mode(WIFI_STA); + WiFi.begin(ssid.c_str(), pass.c_str()); + if ( hasConnected() ) { + return true; } - //setup AP - beginConfigMode(); - //start portal and loop - startWebConfig(); - return false; + } + //setup AP + beginConfigMode(); + //start portal and loop + startWebConfig(); + return false; } String WiFiManager::getSSID() { - if(_ssid == "") { - DEBUG_PRINT("Reading EEPROM SSID"); - _ssid = getEEPROMString(0, 32); - DEBUG_PRINT("SSID: "); - DEBUG_PRINT(_ssid); - } - return _ssid; + if (_ssid == "") { + DEBUG_PRINT("Reading EEPROM SSID"); + _ssid = getEEPROMString(0, 32); + DEBUG_PRINT("SSID: "); + DEBUG_PRINT(_ssid); + } + return _ssid; } String WiFiManager::getPassword() { - if(_pass == "") { - DEBUG_PRINT("Reading EEPROM Password"); - _pass = getEEPROMString(32, 64); - DEBUG_PRINT("Password: "); - DEBUG_PRINT(_pass); - } - return _pass; + if (_pass == "") { + DEBUG_PRINT("Reading EEPROM Password"); + _pass = getEEPROMString(32, 64); + DEBUG_PRINT("Password: "); + DEBUG_PRINT(_pass); + } + return _pass; } String WiFiManager::getEEPROMString(int start, int len) { - String string = ""; - for (int i = _eepromStart + start; i < _eepromStart + start + len; i++) { - //DEBUG_PRINT(i); - string += char(EEPROM.read(i)); - } - return string; + String string = ""; + for (int i = _eepromStart + start; i < _eepromStart + start + len; i++) { + //DEBUG_PRINT(i); + string += char(EEPROM.read(i)); + } + return string; } void WiFiManager::setEEPROMString(int start, int len, String string) { - int si = 0; - for (int i = _eepromStart + start; i < _eepromStart + start + len; i++) { - char c; - if(si < string.length()) { - c = string[si]; - DEBUG_PRINT("Wrote: "); - DEBUG_PRINT(c); - - } else { - c = 0; - } - EEPROM.write(i, c); - si++; + int si = 0; + for (int i = _eepromStart + start; i < _eepromStart + start + len; i++) { + char c; + if (si < string.length()) { + c = string[si]; + DEBUG_PRINT("Wrote: "); + DEBUG_PRINT(c); + } else { + c = 0; } - + EEPROM.write(i, c); + si++; + } + } boolean WiFiManager::hasConnected(void) { - int c = 0; - while ( c < 50 ) { - if (WiFi.status() == WL_CONNECTED) { - return true; - } - delay(200); - DEBUG_PRINT("."); - c++; + int c = 0; + while ( c < 50 ) { + if (WiFi.status() == WL_CONNECTED) { + return true; } - DEBUG_PRINT(""); - DEBUG_PRINT("Could not connect to WiFi"); - return false; + delay(200); + DEBUG_PRINT("."); + c++; + } + DEBUG_PRINT(""); + DEBUG_PRINT("Could not connect to WiFi"); + return false; } void WiFiManager::startWebConfig() { - DEBUG_PRINT(""); - DEBUG_PRINT("WiFi connected"); - DEBUG_PRINT(WiFi.localIP()); - DEBUG_PRINT(WiFi.softAPIP()); - if (!mdns.begin(_apName, WiFi.localIP())) { - DEBUG_PRINT("Error setting up MDNS responder!"); - while(1) { - delay(1000); - } + DEBUG_PRINT(""); + DEBUG_PRINT("WiFi connected"); + DEBUG_PRINT(WiFi.localIP()); + DEBUG_PRINT(WiFi.softAPIP()); + if (!mdns.begin(_apName, WiFi.localIP())) { + DEBUG_PRINT("Error setting up MDNS responder!"); + while (1) { + delay(1000); } - DEBUG_PRINT("mDNS responder started"); - // Start the server - server.begin(); - DEBUG_PRINT("Server started"); + } + DEBUG_PRINT("mDNS responder started"); + // Start the server + server.begin(); + DEBUG_PRINT("Server started"); - while(serverLoop() == WM_WAIT) { - //looping + while (serverLoop() == WM_WAIT) { + //looping + if(timeout > 0 && start + timeout < millis()) { + //we passed timeout value, release + DEBUG_PRINT("timeout reached"); + return; } + } - DEBUG_PRINT("Setup done"); - delay(10000); - ESP.reset(); + DEBUG_PRINT("Setup done"); + delay(5000); + ESP.reset(); } String WiFiManager::beginConfigMode(void) { - - WiFi.softAP(_apName); - DEBUG_PRINT("Started Soft Access Point"); - IPAddress apIp = WiFi.softAPIP(); - char ip[24]; - sprintf(ip, "%d.%d.%d.%d", apIp[0], apIp[1], apIp[2], apIp[3]); - return ip; + + WiFi.softAP(_apName); + DEBUG_PRINT("Started Soft Access Point"); + IPAddress apIp = WiFi.softAPIP(); + char ip[24]; + sprintf(ip, "%d.%d.%d.%d", apIp[0], apIp[1], apIp[2], apIp[3]); + return ip; } int WiFiManager::serverLoop() { - // Check for any mDNS queries and send responses - mdns.update(); - - // Check if a client has connected - WiFiClient client = server.available(); - if (!client) { - return(WM_WAIT); + // Check for any mDNS queries and send responses + mdns.update(); + + // Check if a client has connected + WiFiClient client = server.available(); + if (!client) { + return (WM_WAIT); + } + + DEBUG_PRINT("New client"); + + // Wait for data from client to become available + while (client.connected() && !client.available()) { + delay(1); + } + + // Read the first line of HTTP request + String req = client.readStringUntil('\r'); + + // First line of HTTP request looks like "GET /path HTTP/1.1" + // Retrieve the "/path" part by finding the spaces + int addr_start = req.indexOf(' '); + int addr_end = req.indexOf(' ', addr_start + 1); + if (addr_start == -1 || addr_end == -1) { + DEBUG_PRINT("Invalid request: "); + DEBUG_PRINT(req); + return (WM_WAIT); + } + req = req.substring(addr_start + 1, addr_end); + DEBUG_PRINT("Request: "); + DEBUG_PRINT(req); + client.flush(); + + String s; + if (req == "/") + { + + s = HTTP_200; + String head = HTTP_HEAD; + head.replace("{v}", "Config ESP"); + s += head; + s += HTTP_SCRIPT; + s += HTTP_STYLE; + s += HTTP_HEAD_END; + + int n = WiFi.scanNetworks(); + DEBUG_PRINT("scan done"); + if (n == 0) { + DEBUG_PRINT("no networks found"); + s += "
No networks found. Refresh to scan again.
"; + } + else { + for (int i = 0; i < n; ++i) + { + DEBUG_PRINT(WiFi.SSID(i)); + DEBUG_PRINT(WiFi.RSSI(i)); + String item = HTTP_ITEM; + item.replace("{v}", WiFi.SSID(i)); + s += item; + delay(10); + } } - DEBUG_PRINT("New client"); - - // Wait for data from client to become available - while(client.connected() && !client.available()){ - delay(1); - } - - // Read the first line of HTTP request - String req = client.readStringUntil('\r'); - - // First line of HTTP request looks like "GET /path HTTP/1.1" - // Retrieve the "/path" part by finding the spaces - int addr_start = req.indexOf(' '); - int addr_end = req.indexOf(' ', addr_start + 1); - if (addr_start == -1 || addr_end == -1) { - DEBUG_PRINT("Invalid request: "); - DEBUG_PRINT(req); - return(WM_WAIT); - } - req = req.substring(addr_start + 1, addr_end); - DEBUG_PRINT("Request: "); - DEBUG_PRINT(req); - client.flush(); - - String s; - if (req == "/") - { - - s = HTTP_200; - String head = HTTP_HEAD; - head.replace("{v}", "Config ESP"); - s += head; - s += HTTP_SCRIPT; - s += HTTP_STYLE; - s += HTTP_HEAD_END; - - int n = WiFi.scanNetworks(); - DEBUG_PRINT("scan done"); - if (n == 0) { - DEBUG_PRINT("no networks found"); - s += "
No networks found. Refresh to scan again.
"; - } - else { - for (int i = 0; i < n; ++i) - { - DEBUG_PRINT(WiFi.SSID(i)); - DEBUG_PRINT(WiFi.RSSI(i)); - String item = HTTP_ITEM; - item.replace("{v}", WiFi.SSID(i)); - s += item; - delay(10); - } - } - - s += HTTP_FORM; - s += HTTP_END; - - DEBUG_PRINT("Sending config page"); - } - else if ( req.startsWith("/s") ) { - String qssid; - qssid = urldecode(req.substring(8,req.indexOf('&')).c_str()); - DEBUG_PRINT(qssid); - DEBUG_PRINT(""); - String qpass; - qpass = urldecode(req.substring(req.lastIndexOf('=')+1).c_str()); - DEBUG_PRINT(qpass); - DEBUG_PRINT(""); - - setEEPROMString(0, 32, qssid); - setEEPROMString(32, 64, qpass); - - EEPROM.commit(); - - s = HTTP_200; - String head = HTTP_HEAD; - head.replace("{v}", "Saved config"); - s += HTTP_STYLE; - s += HTTP_HEAD_END; - s += "saved to eeprom...
resetting in 10 seconds"; - s += HTTP_END; - client.print(s); - client.flush(); - - DEBUG_PRINT("Saved WiFiConfig...restarting."); - return WM_DONE; - } - else - { - s = HTTP_404; - DEBUG_PRINT("Sending 404"); - } - + s += HTTP_FORM; + s += HTTP_END; + + DEBUG_PRINT("Sending config page"); + } + else if ( req.startsWith("/s") ) { + String qssid; + qssid = urldecode(req.substring(8, req.indexOf('&')).c_str()); + DEBUG_PRINT(qssid); + DEBUG_PRINT(""); + String qpass; + qpass = urldecode(req.substring(req.lastIndexOf('=') + 1).c_str()); + DEBUG_PRINT(qpass); + DEBUG_PRINT(""); + + setEEPROMString(0, 32, qssid); + setEEPROMString(32, 64, qpass); + + EEPROM.commit(); + + s = HTTP_200; + String head = HTTP_HEAD; + head.replace("{v}", "Saved config"); + s += HTTP_STYLE; + s += HTTP_HEAD_END; + s += "saved to eeprom...
resetting in 10 seconds"; + s += HTTP_END; client.print(s); - DEBUG_PRINT("Done with client"); - return(WM_WAIT); + client.flush(); + + DEBUG_PRINT("Saved WiFiConfig...restarting."); + return WM_DONE; + } + else + { + s = HTTP_404; + DEBUG_PRINT("Sending 404"); + } + + client.print(s); + DEBUG_PRINT("Done with client"); + return (WM_WAIT); } String WiFiManager::urldecode(const char *src) { - String decoded = ""; - char a, b; - while (*src) { - if ((*src == '%') && - ((a = src[1]) && (b = src[2])) && - (isxdigit(a) && isxdigit(b))) { - if (a >= 'a') - a -= 'a'-'A'; - if (a >= 'A') - a -= ('A' - 10); - else - a -= '0'; - if (b >= 'a') - b -= 'a'-'A'; - if (b >= 'A') - b -= ('A' - 10); - else - b -= '0'; - - decoded += char(16*a+b); - src+=3; - } else if (*src == '+') { - decoded += ' '; - *src++; - } else { - decoded += *src; - *src++; - } + String decoded = ""; + char a, b; + while (*src) { + if ((*src == '%') && + ((a = src[1]) && (b = src[2])) && + (isxdigit(a) && isxdigit(b))) { + if (a >= 'a') + a -= 'a' - 'A'; + if (a >= 'A') + a -= ('A' - 10); + else + a -= '0'; + if (b >= 'a') + b -= 'a' - 'A'; + if (b >= 'A') + b -= ('A' - 10); + else + b -= '0'; + + decoded += char(16 * a + b); + src += 3; + } else if (*src == '+') { + decoded += ' '; + *src++; + } else { + decoded += *src; + *src++; } - decoded += '\0'; - - return decoded; + } + decoded += '\0'; + + return decoded; +} + +void WiFiManager::resetSettings() { + //need to call it only after lib has been started with autoConnect or begin + setEEPROMString(0, 32, "-"); + setEEPROMString(32, 64, "-"); + + EEPROM.commit(); + DEBUG_PRINT("settings invalidated"); + delay(200); + WiFi.disconnect(); +} + +void WiFiManager::setTimeout(unsigned long seconds) { + timeout = seconds * 1000; } diff --git a/WiFiManager.h b/WiFiManager.h index a082fc1..4ba1177 100644 --- a/WiFiManager.h +++ b/WiFiManager.h @@ -44,8 +44,15 @@ public: String getSSID(); String getPassword(); + void resetSettings(); //for conveniennce String urldecode(const char*); + + //sets timeout before webserver loop ends and exits even if there has been no setup. + //usefully for devices that failed to connect at some point and got stuck in a webserver loop + //in seconds + void setTimeout(unsigned long seconds); + private: const int WM_DONE = 0; const int WM_WAIT = 10; @@ -64,17 +71,17 @@ private: const char* _apName = "no-net"; String _ssid = ""; String _pass = ""; + unsigned long timeout = 0; + unsigned long start = 0; + String getEEPROMString(int start, int len); void setEEPROMString(int start, int len, String string); int serverLoop(); - - - }; -#endif \ No newline at end of file +#endif diff --git a/examples/AutoConnectWithTimeout/AutoConnectWithTimeout.ino b/examples/AutoConnectWithTimeout/AutoConnectWithTimeout.ino new file mode 100644 index 0000000..0821eb7 --- /dev/null +++ b/examples/AutoConnectWithTimeout/AutoConnectWithTimeout.ino @@ -0,0 +1,42 @@ +#include //https://github.com/esp8266/Arduino + +//needed for library +#include +#include +#include //https://github.com/tzapu/WiFiManager + +//this intitilises the library, parameter is eeprom start +WiFiManager wifi(0); + +void setup() { + // put your setup code here, to run once: + Serial.begin(115200); + + + //WiFiManager + //sets timeout until configuration portal gets turned off + //useful to make it all retry or go to sleep + //in seconds + wifi.setTimeout(120); + + //fetches ssid and pass from eeprom and tries to connect + //if it does not connect it starts an access point with the specified name + //here "AutoConnectAP" + //and goes into a blocking loop awaiting configuration + if(!wifi.autoConnect("AutoConnectAP")) { + Serial.println("failed to connect and hit timeout"); + delay(5000); + //reset and try again, or maybe put it to deep sleep + ESP.reset(); + delay(5000); + } + + //if you get here you have connected to the WiFi + Serial.println("connected...yeey :)"); + +} + +void loop() { + // put your main code here, to run repeatedly: + +}