初始化提交
35
arduino-cli/libraries/ESP_WiFiManager/.gitignore
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
# Prerequisites
|
||||
*.d
|
||||
|
||||
# Compiled Object files
|
||||
*.slo
|
||||
*.lo
|
||||
*.o
|
||||
*.obj
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Compiled Dynamic libraries
|
||||
*.so
|
||||
*.dylib
|
||||
*.dll
|
||||
|
||||
# Fortran module files
|
||||
*.mod
|
||||
*.smod
|
||||
|
||||
# Compiled Static libraries
|
||||
*.lai
|
||||
*.la
|
||||
*.a
|
||||
*.lib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
|
||||
# Visual Studio folder and files
|
||||
.vs
|
||||
51
arduino-cli/libraries/ESP_WiFiManager/CONTRIBUTING.md
Normal file
@@ -0,0 +1,51 @@
|
||||
## Contributing to ESP_WiFiManager
|
||||
|
||||
### Reporting Bugs
|
||||
|
||||
Please report bugs in ESP_WiFiManager if you find them.
|
||||
|
||||
However, before reporting a bug please check through the following:
|
||||
|
||||
* [Existing Open Issues](https://github.com/khoih-prog/ESP_WiFiManager/issues) - someone might have already encountered this.
|
||||
|
||||
If you don't find anything, please [open a new issue](https://github.com/khoih-prog/ESP_WiFiManager/issues/new).
|
||||
|
||||
### How to submit a bug report
|
||||
|
||||
Please ensure to specify the following:
|
||||
|
||||
* Arduino IDE version (e.g. 1.8.11) or Platform.io version
|
||||
* `ESP8266` or `ESP32` Core Version (e.g. ESP8266 core v2.6.3 or ESP32 v1.0.4)
|
||||
* Contextual information (e.g. what you were trying to achieve)
|
||||
* Simplest possible steps to reproduce
|
||||
* Anything that might be relevant in your opinion, such as:
|
||||
* Operating system (Windows, Ubuntu, etc.) and the output of `uname -a`
|
||||
* Network configuration
|
||||
|
||||
|
||||
### Example
|
||||
|
||||
```
|
||||
Arduino IDE version: 1.8.11
|
||||
ESP8266 Core Version 2.6.3
|
||||
OS: Ubuntu 16.04 LTS
|
||||
Linux Inspiron 4.4.0-170-generic #199-Ubuntu SMP Thu Nov 14 01:45:04 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
|
||||
|
||||
Context:
|
||||
I encountered an endless loop while trying to connect to Local WiFi.
|
||||
|
||||
Steps to reproduce:
|
||||
1. ...
|
||||
2. ...
|
||||
3. ...
|
||||
4. ...
|
||||
```
|
||||
### Sending Feature Requests
|
||||
|
||||
Feel free to post feature requests. It's helpful if you can explain exactly why the feature would be useful.
|
||||
|
||||
There are usually some outstanding feature requests in the [existing issues list](https://github.com/khoih-prog/ESP_WiFiManager/issues?q=is%3Aopen+is%3Aissue+label%3Aenhancement), feel free to add comments to them.
|
||||
|
||||
### Sending Pull Requests
|
||||
|
||||
Pull Requests with changes and fixes are also welcome!
|
||||
21
arduino-cli/libraries/ESP_WiFiManager/LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Khoi Hoang
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
2513
arduino-cli/libraries/ESP_WiFiManager/README.md
Normal file
@@ -0,0 +1,552 @@
|
||||
/****************************************************************************************************************************
|
||||
AutoConnect.ino
|
||||
For ESP8266 / ESP32 boards
|
||||
|
||||
ESP_WiFiManager is a library for the ESP8266/ESP32 platform (https://github.com/esp8266/Arduino) to enable easy
|
||||
configuration and reconfiguration of WiFi credentials using a Captive Portal.
|
||||
|
||||
Modified from Tzapu https://github.com/tzapu/WiFiManager
|
||||
and from Ken Taylor https://github.com/kentaylor
|
||||
|
||||
Built by Khoi Hoang https://github.com/khoih-prog/ESP_WiFiManager
|
||||
Licensed under MIT license
|
||||
Version: 1.2.0
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 07/10/2019 Initial coding
|
||||
1.0.1 K Hoang 13/12/2019 Fix bug. Add features. Add support for ESP32
|
||||
1.0.2 K Hoang 19/12/2019 Fix bug thatkeeps ConfigPortal in endless loop if Portal/Router SSID or Password is NULL.
|
||||
1.0.3 K Hoang 05/01/2020 Option not displaying AvailablePages in Info page. Enhance README.md. Modify examples
|
||||
1.0.4 K Hoang 07/01/2020 Add RFC952 setHostname feature.
|
||||
1.0.5 K Hoang 15/01/2020 Add configurable DNS feature. Thanks to @Amorphous of https://community.blynk.cc
|
||||
1.0.6 K Hoang 03/02/2020 Add support for ArduinoJson version 6.0.0+ ( tested with v6.14.1 )
|
||||
1.0.7 K Hoang 13/04/2020 Reduce start time, fix SPIFFS bug in examples, update README.md
|
||||
1.0.8 K Hoang 10/06/2020 Fix STAstaticIP issue. Restructure code. Add LittleFS support for ESP8266 core 2.7.1+
|
||||
1.0.9 K Hoang 29/07/2020 Fix ESP32 STAstaticIP bug. Permit changing from DHCP <-> static IP using Config Portal.
|
||||
Add, enhance examples (fix MDNS for ESP32)
|
||||
1.0.10 K Hoang 08/08/2020 Add more features to Config Portal. Use random WiFi AP channel to avoid conflict.
|
||||
1.0.11 K Hoang 17/08/2020 Add CORS feature. Fix bug in softAP, autoConnect, resetSettings.
|
||||
1.1.0 K Hoang 28/08/2020 Add MultiWiFi feature to autoconnect to best WiFi at runtime
|
||||
1.1.1 K Hoang 30/08/2020 Add setCORSHeader function to allow flexible CORS. Fix typo and minor improvement.
|
||||
1.1.2 K Hoang 17/08/2020 Fix bug. Add example.
|
||||
1.2.0 K Hoang 09/10/2020 Restore cpp code besides Impl.h code to use if linker error. Fix bug.
|
||||
*****************************************************************************************************************************/
|
||||
#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
|
||||
|
||||
// Use from 0 to 4. Higher number, more debugging messages and memory usage.
|
||||
#define _WIFIMGR_LOGLEVEL_ 3
|
||||
|
||||
//Ported to ESP32
|
||||
#ifdef ESP32
|
||||
#include <esp_wifi.h>
|
||||
#include <WiFi.h>
|
||||
#include <WiFiClient.h>
|
||||
|
||||
// From v1.1.0
|
||||
#include <WiFiMulti.h>
|
||||
WiFiMulti wifiMulti;
|
||||
|
||||
#define USE_SPIFFS true
|
||||
|
||||
#if USE_SPIFFS
|
||||
#include <SPIFFS.h>
|
||||
FS* filesystem = &SPIFFS;
|
||||
#define FileFS SPIFFS
|
||||
#define FS_Name "SPIFFS"
|
||||
#else
|
||||
// Use FFat
|
||||
#include <FFat.h>
|
||||
FS* filesystem = &FFat;
|
||||
#define FileFS FFat
|
||||
#define FS_Name "FFat"
|
||||
#endif
|
||||
//////
|
||||
|
||||
#define ESP_getChipId() ((uint32_t)ESP.getEfuseMac())
|
||||
|
||||
#define LED_ON HIGH
|
||||
#define LED_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;
|
||||
|
||||
#include <FS.h>
|
||||
|
||||
#define USE_LITTLEFS true
|
||||
|
||||
#if USE_LITTLEFS
|
||||
#include <LittleFS.h>
|
||||
FS* filesystem = &LittleFS;
|
||||
#define FileFS LittleFS
|
||||
#define FS_Name "LittleFS"
|
||||
#else
|
||||
FS* filesystem = &SPIFFS;
|
||||
#define FileFS SPIFFS
|
||||
#define FS_Name "SPIFFS"
|
||||
#endif
|
||||
//////
|
||||
|
||||
#define ESP_getChipId() (ESP.getChipId())
|
||||
|
||||
#define LED_ON LOW
|
||||
#define LED_OFF HIGH
|
||||
#endif
|
||||
|
||||
// You only need to format the filesystem once
|
||||
//#define FORMAT_FILESYSTEM true
|
||||
#define FORMAT_FILESYSTEM false
|
||||
|
||||
// SSID and PW for your Router
|
||||
String Router_SSID;
|
||||
String Router_Pass;
|
||||
|
||||
// From v1.1.0
|
||||
#define MIN_AP_PASSWORD_SIZE 8
|
||||
|
||||
#define SSID_MAX_LEN 32
|
||||
//From v1.0.10, WPA2 passwords can be up to 63 characters long.
|
||||
#define PASS_MAX_LEN 64
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char wifi_ssid[SSID_MAX_LEN];
|
||||
char wifi_pw [PASS_MAX_LEN];
|
||||
} WiFi_Credentials;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
String wifi_ssid;
|
||||
String wifi_pw;
|
||||
} WiFi_Credentials_String;
|
||||
|
||||
#define NUM_WIFI_CREDENTIALS 2
|
||||
|
||||
typedef struct
|
||||
{
|
||||
WiFi_Credentials WiFi_Creds [NUM_WIFI_CREDENTIALS];
|
||||
} WM_Config;
|
||||
|
||||
WM_Config WM_config;
|
||||
|
||||
#define CONFIG_FILENAME F("/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 <ESP_WiFiManager.h>
|
||||
#define USE_AVAILABLE_PAGES false
|
||||
|
||||
// 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)
|
||||
#define USE_ESP_WIFIMANAGER_NTP false
|
||||
|
||||
// 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)
|
||||
#define USE_CLOUDFLARE_NTP false
|
||||
|
||||
// New in v1.0.11
|
||||
#define USING_CORS_FEATURE true
|
||||
//////
|
||||
|
||||
// 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
|
||||
#define USE_DHCP_IP true
|
||||
#else
|
||||
// You can select DHCP or Static IP here
|
||||
//#define USE_DHCP_IP true
|
||||
#define USE_DHCP_IP false
|
||||
#endif
|
||||
|
||||
#if ( USE_DHCP_IP || ( defined(USE_STATIC_IP_CONFIG_IN_CP) && !USE_STATIC_IP_CONFIG_IN_CP ) )
|
||||
// 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
|
||||
|
||||
#define USE_CONFIGURABLE_DNS true
|
||||
|
||||
IPAddress dns1IP = gatewayIP;
|
||||
IPAddress dns2IP = IPAddress(8, 8, 8, 8);
|
||||
|
||||
#include <ESP_WiFiManager.h> //https://github.com/khoih-prog/ESP_WiFiManager
|
||||
|
||||
// Function Prototypes
|
||||
uint8_t connectMultiWiFi(void);
|
||||
|
||||
void heartBeatPrint(void)
|
||||
{
|
||||
static int num = 1;
|
||||
|
||||
if (WiFi.status() == WL_CONNECTED)
|
||||
Serial.print("H"); // H means connected to WiFi
|
||||
else
|
||||
Serial.print("F"); // F means not connected to WiFi
|
||||
|
||||
if (num == 80)
|
||||
{
|
||||
Serial.println();
|
||||
num = 1;
|
||||
}
|
||||
else if (num++ % 10 == 0)
|
||||
{
|
||||
Serial.print(" ");
|
||||
}
|
||||
}
|
||||
|
||||
void check_WiFi(void)
|
||||
{
|
||||
if ( (WiFi.status() != WL_CONNECTED) )
|
||||
{
|
||||
Serial.println("\nWiFi lost. Call connectMultiWiFi in loop");
|
||||
connectMultiWiFi();
|
||||
}
|
||||
}
|
||||
|
||||
void check_status(void)
|
||||
{
|
||||
static ulong checkstatus_timeout = 0;
|
||||
static ulong checkwifi_timeout = 0;
|
||||
|
||||
static ulong current_millis;
|
||||
|
||||
#define WIFICHECK_INTERVAL 1000L
|
||||
#define HEARTBEAT_INTERVAL 10000L
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// Print hearbeat every HEARTBEAT_INTERVAL (10) seconds.
|
||||
if ((current_millis > checkstatus_timeout) || (checkstatus_timeout == 0))
|
||||
{
|
||||
heartBeatPrint();
|
||||
checkstatus_timeout = current_millis + HEARTBEAT_INTERVAL;
|
||||
}
|
||||
}
|
||||
|
||||
void loadConfigData(void)
|
||||
{
|
||||
File file = FileFS.open(CONFIG_FILENAME, "r");
|
||||
LOGERROR(F("LoadWiFiCfgFile "));
|
||||
|
||||
if (file)
|
||||
{
|
||||
file.readBytes((char *) &WM_config, sizeof(WM_config));
|
||||
file.close();
|
||||
LOGERROR(F("OK"));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGERROR(F("failed"));
|
||||
}
|
||||
}
|
||||
|
||||
void saveConfigData(void)
|
||||
{
|
||||
File file = FileFS.open(CONFIG_FILENAME, "w");
|
||||
LOGERROR(F("SaveWiFiCfgFile "));
|
||||
|
||||
if (file)
|
||||
{
|
||||
file.write((uint8_t*) &WM_config, sizeof(WM_config));
|
||||
file.close();
|
||||
LOGERROR(F("OK"));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGERROR(F("failed"));
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t connectMultiWiFi(void)
|
||||
{
|
||||
#if ESP32
|
||||
// For ESP32, this better be 0 to shorten the connect time
|
||||
#define WIFI_MULTI_1ST_CONNECT_WAITING_MS 0
|
||||
#else
|
||||
// For ESP8266, this better be 2200 to enable connect the 1st time
|
||||
#define WIFI_MULTI_1ST_CONNECT_WAITING_MS 2200L
|
||||
#endif
|
||||
|
||||
#define WIFI_MULTI_CONNECT_WAITING_MS 100L
|
||||
|
||||
uint8_t status;
|
||||
|
||||
LOGERROR(F("ConnectMultiWiFi with :"));
|
||||
|
||||
if ( (Router_SSID != "") && (Router_Pass != "") )
|
||||
{
|
||||
LOGERROR3(F("* Flash-stored Router_SSID = "), Router_SSID, F(", Router_Pass = "), Router_Pass );
|
||||
}
|
||||
|
||||
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
|
||||
#if USE_CONFIGURABLE_DNS
|
||||
// Set static IP, Gateway, Subnetmask, DNS1 and DNS2. New in v1.0.5
|
||||
WiFi.config(stationIP, gatewayIP, netMask, dns1IP, dns2IP);
|
||||
#else
|
||||
// Set static IP, Gateway, Subnetmask, Use auto DNS1 and DNS2.
|
||||
WiFi.config(stationIP, gatewayIP, netMask);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
int i = 0;
|
||||
status = wifiMulti.run();
|
||||
delay(WIFI_MULTI_1ST_CONNECT_WAITING_MS);
|
||||
|
||||
while ( ( i++ < 10 ) && ( status != WL_CONNECTED ) )
|
||||
{
|
||||
status = wifiMulti.run();
|
||||
|
||||
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"));
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
// put your setup code here, to run once:
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
|
||||
Serial.print("\nStarting AutoConnectAP using " + String(FS_Name));
|
||||
Serial.println(" on " + String(ARDUINO_BOARD));
|
||||
|
||||
if (FORMAT_FILESYSTEM)
|
||||
FileFS.format();
|
||||
|
||||
// Format FileFS if not yet
|
||||
#ifdef ESP32
|
||||
if (!FileFS.begin(true))
|
||||
#else
|
||||
if (!FileFS.begin())
|
||||
#endif
|
||||
{
|
||||
Serial.print(FS_Name);
|
||||
Serial.println(F(" failed! AutoFormatting."));
|
||||
|
||||
#ifdef ESP8266
|
||||
FileFS.format();
|
||||
#endif
|
||||
}
|
||||
|
||||
unsigned long startedAt = millis();
|
||||
|
||||
// Use this to default DHCP hostname to ESP8266-XXXXXX or ESP32-XXXXXX
|
||||
//ESP_WiFiManager ESP_wifiManager;
|
||||
// Use this to personalize DHCP hostname (RFC952 conformed)
|
||||
ESP_WiFiManager ESP_wifiManager("AutoConnectAP");
|
||||
|
||||
ESP_wifiManager.setDebugOutput(true);
|
||||
|
||||
//reset settings - for testing
|
||||
//ESP_wifiManager.resetSettings();
|
||||
|
||||
//set custom ip for portal
|
||||
ESP_wifiManager.setAPStaticIPConfig(IPAddress(192, 168, 100, 1), IPAddress(192, 168, 100, 1), IPAddress(255, 255, 255, 0));
|
||||
|
||||
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_DHCP_IP
|
||||
#if USE_CONFIGURABLE_DNS
|
||||
// Set static IP, Gateway, Subnetmask, DNS1 and DNS2. New in v1.0.5
|
||||
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
|
||||
|
||||
// New from v1.1.1
|
||||
#if USING_CORS_FEATURE
|
||||
ESP_wifiManager.setCORSHeader("Your Access-Control-Allow-Origin");
|
||||
#endif
|
||||
|
||||
// We can't use WiFi.SSID() in ESP32 as it's only valid after connected.
|
||||
// SSID and Password stored in ESP32 wifi_ap_record_t and wifi_config_t are also cleared in reboot
|
||||
// Have to create a new function to store in EEPROM/SPIFFS for this purpose
|
||||
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("Stored: SSID = " + Router_SSID + ", Pass = " + Router_Pass);
|
||||
|
||||
if (Router_SSID != "")
|
||||
{
|
||||
ESP_wifiManager.setConfigPortalTimeout(120); //If no access point name has been previously entered disable timeout.
|
||||
Serial.println("Got stored Credentials. Timeout 120s");
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println("No stored Credentials. No timeout");
|
||||
}
|
||||
|
||||
String chipID = String(ESP_getChipId(), HEX);
|
||||
chipID.toUpperCase();
|
||||
|
||||
// SSID and PW for Config Portal
|
||||
String AP_SSID = "ESP_" + chipID + "_AutoConnectAP";
|
||||
String AP_PASS = "MyESP_" + chipID;
|
||||
|
||||
// From v1.1.0, Don't permit NULL password
|
||||
if ( (Router_SSID == "") || (Router_Pass == "") )
|
||||
{
|
||||
Serial.println("We haven't got any access point credentials, so get them now");
|
||||
|
||||
initialConfig = true;
|
||||
|
||||
// Starts an access point
|
||||
//if (!ESP_wifiManager.startConfigPortal((const char *) ssid.c_str(), password))
|
||||
if ( !ESP_wifiManager.startConfigPortal(AP_SSID.c_str(), AP_PASS.c_str()) )
|
||||
Serial.println("Not connected to WiFi but continuing anyway.");
|
||||
else
|
||||
Serial.println("WiFi connected...yeey :)");
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
saveConfigData();
|
||||
}
|
||||
else
|
||||
{
|
||||
wifiMulti.addAP(Router_SSID.c_str(), Router_Pass.c_str());
|
||||
}
|
||||
|
||||
startedAt = millis();
|
||||
|
||||
if (!initialConfig)
|
||||
{
|
||||
// Load stored data, the addAP ready for MultiWiFi reconnection
|
||||
loadConfigData();
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
if ( WiFi.status() != WL_CONNECTED )
|
||||
{
|
||||
Serial.println("ConnectMultiWiFi in setup");
|
||||
|
||||
connectMultiWiFi();
|
||||
}
|
||||
}
|
||||
|
||||
Serial.print("After waiting ");
|
||||
Serial.print((float) (millis() - startedAt) / 1000L);
|
||||
Serial.print(" secs more in setup(), connection result is ");
|
||||
|
||||
if (WiFi.status() == WL_CONNECTED)
|
||||
{
|
||||
Serial.print("connected. Local IP: ");
|
||||
Serial.println(WiFi.localIP());
|
||||
}
|
||||
else
|
||||
Serial.println(ESP_wifiManager.getStatus(WiFi.status()));
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// put your main code here, to run repeatedly
|
||||
check_status();
|
||||
}
|
||||
@@ -0,0 +1,795 @@
|
||||
/****************************************************************************************************************************
|
||||
AutoConnectWithFSParameters.ino
|
||||
For ESP8266 / ESP32 boards
|
||||
|
||||
ESP_WiFiManager is a library for the ESP8266/ESP32 platform (https://github.com/esp8266/Arduino) to enable easy
|
||||
configuration and reconfiguration of WiFi credentials using a Captive Portal.
|
||||
|
||||
Modified from Tzapu https://github.com/tzapu/WiFiManager
|
||||
and from Ken Taylor https://github.com/kentaylor
|
||||
|
||||
Built by Khoi Hoang https://github.com/khoih-prog/ESP_WiFiManager
|
||||
Licensed under MIT license
|
||||
Version: 1.2.0
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 07/10/2019 Initial coding
|
||||
1.0.1 K Hoang 13/12/2019 Fix bug. Add features. Add support for ESP32
|
||||
1.0.2 K Hoang 19/12/2019 Fix bug thatkeeps ConfigPortal in endless loop if Portal/Router SSID or Password is NULL.
|
||||
1.0.3 K Hoang 05/01/2020 Option not displaying AvailablePages in Info page. Enhance README.md. Modify examples
|
||||
1.0.4 K Hoang 07/01/2020 Add RFC952 setHostname feature.
|
||||
1.0.5 K Hoang 15/01/2020 Add configurable DNS feature. Thanks to @Amorphous of https://community.blynk.cc
|
||||
1.0.6 K Hoang 03/02/2020 Add support for ArduinoJson version 6.0.0+ ( tested with v6.14.1 )
|
||||
1.0.7 K Hoang 13/04/2020 Reduce start time, fix SPIFFS bug in examples, update README.md
|
||||
1.0.8 K Hoang 10/06/2020 Fix STAstaticIP issue. Restructure code. Add LittleFS support for ESP8266 core 2.7.1+
|
||||
1.0.9 K Hoang 29/07/2020 Fix ESP32 STAstaticIP bug. Permit changing from DHCP <-> static IP using Config Portal.
|
||||
Add, enhance examples (fix MDNS for ESP32)
|
||||
1.0.10 K Hoang 08/08/2020 Add more features to Config Portal. Use random WiFi AP channel to avoid conflict.
|
||||
1.0.11 K Hoang 17/08/2020 Add CORS feature. Fix bug in softAP, autoConnect, resetSettings.
|
||||
1.1.0 K Hoang 28/08/2020 Add MultiWiFi feature to autoconnect to best WiFi at runtime
|
||||
1.1.1 K Hoang 30/08/2020 Add setCORSHeader function to allow flexible CORS. Fix typo and minor improvement.
|
||||
1.1.2 K Hoang 17/08/2020 Fix bug. Add example.
|
||||
1.2.0 K Hoang 09/10/2020 Restore cpp code besides Impl.h code to use if linker error. Fix bug.
|
||||
*****************************************************************************************************************************/
|
||||
#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
|
||||
|
||||
// Use from 0 to 4. Higher number, more debugging messages and memory usage.
|
||||
#define _WIFIMGR_LOGLEVEL_ 3
|
||||
|
||||
#include <FS.h>
|
||||
|
||||
//Ported to ESP32
|
||||
#ifdef ESP32
|
||||
#include <esp_wifi.h>
|
||||
#include <WiFi.h>
|
||||
#include <WiFiClient.h>
|
||||
|
||||
// From v1.1.0
|
||||
#include <WiFiMulti.h>
|
||||
WiFiMulti wifiMulti;
|
||||
|
||||
#define USE_SPIFFS true
|
||||
|
||||
#if USE_SPIFFS
|
||||
#include <SPIFFS.h>
|
||||
FS* filesystem = &SPIFFS;
|
||||
#define FileFS SPIFFS
|
||||
#define FS_Name "SPIFFS"
|
||||
#else
|
||||
// Use FFat
|
||||
#include <FFat.h>
|
||||
FS* filesystem = &FFat;
|
||||
#define FileFS FFat
|
||||
#define FS_Name "FFat"
|
||||
#endif
|
||||
//////
|
||||
|
||||
#define ESP_getChipId() ((uint32_t)ESP.getEfuseMac())
|
||||
|
||||
#define LED_BUILTIN 2
|
||||
#define LED_ON HIGH
|
||||
#define LED_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;
|
||||
|
||||
#define USE_LITTLEFS true
|
||||
|
||||
#if USE_LITTLEFS
|
||||
#include <LittleFS.h>
|
||||
FS* filesystem = &LittleFS;
|
||||
#define FileFS LittleFS
|
||||
#define FS_Name "LittleFS"
|
||||
#else
|
||||
FS* filesystem = &SPIFFS;
|
||||
#define FileFS SPIFFS
|
||||
#define FS_Name "SPIFFS"
|
||||
#endif
|
||||
//////
|
||||
|
||||
#define ESP_getChipId() (ESP.getChipId())
|
||||
|
||||
#define LED_ON LOW
|
||||
#define LED_OFF HIGH
|
||||
#endif
|
||||
|
||||
// Pin D2 mapped to pin GPIO2/ADC12 of ESP32, or GPIO2/TXD1 of NodeMCU control on-board LED
|
||||
#define PIN_LED LED_BUILTIN
|
||||
|
||||
// Now support ArduinoJson 6.0.0+ ( tested with v6.14.1 )
|
||||
#include <ArduinoJson.h> //https://github.com/bblanchon/ArduinoJson
|
||||
|
||||
char configFileName[] = "/config.json";
|
||||
|
||||
// You only need to format the filesystem once
|
||||
//#define FORMAT_FILESYSTEM true
|
||||
#define FORMAT_FILESYSTEM false
|
||||
|
||||
// SSID and PW for your Router
|
||||
String Router_SSID;
|
||||
String Router_Pass;
|
||||
|
||||
// From v1.1.0
|
||||
#define MIN_AP_PASSWORD_SIZE 8
|
||||
|
||||
#define SSID_MAX_LEN 32
|
||||
//From v1.0.10, WPA2 passwords can be up to 63 characters long.
|
||||
#define PASS_MAX_LEN 64
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char wifi_ssid[SSID_MAX_LEN];
|
||||
char wifi_pw [PASS_MAX_LEN];
|
||||
} WiFi_Credentials;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
String wifi_ssid;
|
||||
String wifi_pw;
|
||||
} WiFi_Credentials_String;
|
||||
|
||||
#define NUM_WIFI_CREDENTIALS 2
|
||||
|
||||
typedef struct
|
||||
{
|
||||
WiFi_Credentials WiFi_Creds [NUM_WIFI_CREDENTIALS];
|
||||
} WM_Config;
|
||||
|
||||
WM_Config WM_config;
|
||||
|
||||
#define CONFIG_FILENAME F("/wifi_cred.dat")
|
||||
|
||||
// Indicates whether ESP has WiFi credentials saved from previous session, or double reset detected
|
||||
bool initialConfig = false;
|
||||
//////
|
||||
|
||||
// SSID and PW for Config Portal
|
||||
String AP_SSID;
|
||||
String AP_PASS;
|
||||
|
||||
// Use false if you don't like to display Available Pages in Information Page of Config Portal
|
||||
// Comment out or use true to display Available Pages in Information Page of Config Portal
|
||||
// Must be placed before #include <ESP_WiFiManager.h>
|
||||
#define USE_AVAILABLE_PAGES false
|
||||
|
||||
// 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)
|
||||
#define USE_ESP_WIFIMANAGER_NTP false
|
||||
|
||||
// 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)
|
||||
#define USE_CLOUDFLARE_NTP false
|
||||
|
||||
// New in v1.0.11
|
||||
#define USING_CORS_FEATURE true
|
||||
//////
|
||||
|
||||
// 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
|
||||
#define USE_DHCP_IP true
|
||||
#else
|
||||
// You can select DHCP or Static IP here
|
||||
//#define USE_DHCP_IP true
|
||||
#define USE_DHCP_IP false
|
||||
#endif
|
||||
|
||||
#if ( USE_DHCP_IP || ( defined(USE_STATIC_IP_CONFIG_IN_CP) && !USE_STATIC_IP_CONFIG_IN_CP ) )
|
||||
// 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
|
||||
|
||||
#define USE_CONFIGURABLE_DNS true
|
||||
|
||||
IPAddress dns1IP = gatewayIP;
|
||||
IPAddress dns2IP = IPAddress(8, 8, 8, 8);
|
||||
|
||||
#include <ESP_WiFiManager.h> //https://github.com/khoih-prog/ESP_WiFiManager
|
||||
|
||||
//define your default values here, if there are different values in configFileName (config.json), they are overwritten.
|
||||
#define BLYNK_SERVER_LEN 64
|
||||
#define BLYNK_TOKEN_LEN 32
|
||||
#define BLYNK_SERVER_PORT_LEN 6
|
||||
|
||||
#define MQTT_SERVER_MAX_LEN 40
|
||||
#define MQTT_SERVER_PORT_LEN 6
|
||||
|
||||
char blynk_server [BLYNK_SERVER_LEN] = "account.duckdns.org";
|
||||
char blynk_port [BLYNK_SERVER_PORT_LEN] = "8080";
|
||||
char blynk_token [BLYNK_TOKEN_LEN] = "YOUR_BLYNK_TOKEN";
|
||||
|
||||
char mqtt_server [MQTT_SERVER_MAX_LEN];
|
||||
char mqtt_port [MQTT_SERVER_PORT_LEN] = "8080";
|
||||
|
||||
// Function Prototypes
|
||||
uint8_t connectMultiWiFi(void);
|
||||
|
||||
//flag for saving data
|
||||
bool shouldSaveConfig = false;
|
||||
|
||||
//callback notifying us of the need to save config
|
||||
void saveConfigCallback(void)
|
||||
{
|
||||
Serial.println("Should save config");
|
||||
shouldSaveConfig = true;
|
||||
}
|
||||
|
||||
bool loadFileFSConfigFile(void)
|
||||
{
|
||||
//clean FS, for testing
|
||||
//FileFS.format();
|
||||
|
||||
//read configuration from FS json
|
||||
Serial.println("Mounting FS...");
|
||||
|
||||
if (FileFS.begin())
|
||||
{
|
||||
Serial.println("Mounted file system");
|
||||
|
||||
if (FileFS.exists(configFileName))
|
||||
{
|
||||
//file exists, reading and loading
|
||||
Serial.println("Reading config file");
|
||||
File configFile = FileFS.open(configFileName, "r");
|
||||
|
||||
if (configFile)
|
||||
{
|
||||
Serial.print("Opened config file, size = ");
|
||||
size_t configFileSize = configFile.size();
|
||||
Serial.println(configFileSize);
|
||||
|
||||
// Allocate a buffer to store contents of the file.
|
||||
std::unique_ptr<char[]> buf(new char[configFileSize + 1]);
|
||||
|
||||
configFile.readBytes(buf.get(), configFileSize);
|
||||
|
||||
Serial.print("\nJSON parseObject() result : ");
|
||||
|
||||
#if (ARDUINOJSON_VERSION_MAJOR >= 6)
|
||||
DynamicJsonDocument json(1024);
|
||||
auto deserializeError = deserializeJson(json, buf.get(), configFileSize);
|
||||
|
||||
if ( deserializeError )
|
||||
{
|
||||
Serial.println("failed");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println("OK");
|
||||
|
||||
if (json["blynk_server"])
|
||||
strncpy(blynk_server, json["blynk_server"], sizeof(blynk_server));
|
||||
|
||||
if (json["blynk_port"])
|
||||
strncpy(blynk_port, json["blynk_port"], sizeof(blynk_port));
|
||||
|
||||
if (json["blynk_token"])
|
||||
strncpy(blynk_token, json["blynk_token"], sizeof(blynk_token));
|
||||
|
||||
if (json["mqtt_server"])
|
||||
strncpy(mqtt_server, json["mqtt_server"], sizeof(mqtt_server));
|
||||
|
||||
if (json["mqtt_port"])
|
||||
strncpy(mqtt_port, json["mqtt_port"], sizeof(mqtt_port));
|
||||
}
|
||||
|
||||
//serializeJson(json, Serial);
|
||||
serializeJsonPretty(json, Serial);
|
||||
#else
|
||||
DynamicJsonBuffer jsonBuffer;
|
||||
// Parse JSON string
|
||||
JsonObject& json = jsonBuffer.parseObject(buf.get());
|
||||
// Test if parsing succeeds.
|
||||
|
||||
if (json.success())
|
||||
{
|
||||
Serial.println("OK");
|
||||
|
||||
if (json["blynk_server"])
|
||||
strncpy(blynk_server, json["blynk_server"], sizeof(blynk_server));
|
||||
|
||||
if (json["blynk_port"])
|
||||
strncpy(blynk_port, json["blynk_port"], sizeof(blynk_port));
|
||||
|
||||
if (json["blynk_token"])
|
||||
strncpy(blynk_token, json["blynk_token"], sizeof(blynk_token));
|
||||
|
||||
if (json["mqtt_server"])
|
||||
strncpy(mqtt_server, json["mqtt_server"], sizeof(mqtt_server));
|
||||
|
||||
if (json["mqtt_port"])
|
||||
strncpy(mqtt_port, json["mqtt_port"], sizeof(mqtt_port));
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println("failed");
|
||||
return false;
|
||||
}
|
||||
//json.printTo(Serial);
|
||||
json.prettyPrintTo(Serial);
|
||||
#endif
|
||||
|
||||
configFile.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println("failed to mount FS");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool saveFileFSConfigFile(void)
|
||||
{
|
||||
Serial.println("Saving config");
|
||||
|
||||
#if (ARDUINOJSON_VERSION_MAJOR >= 6)
|
||||
DynamicJsonDocument json(1024);
|
||||
#else
|
||||
DynamicJsonBuffer jsonBuffer;
|
||||
JsonObject& json = jsonBuffer.createObject();
|
||||
#endif
|
||||
|
||||
json["blynk_server"] = blynk_server;
|
||||
json["blynk_port"] = blynk_port;
|
||||
json["blynk_token"] = blynk_token;
|
||||
|
||||
json["mqtt_server"] = mqtt_server;
|
||||
json["mqtt_port"] = mqtt_port;
|
||||
|
||||
File configFile = FileFS.open(configFileName, "w");
|
||||
|
||||
if (!configFile)
|
||||
{
|
||||
Serial.println("Failed to open config file for writing");
|
||||
}
|
||||
|
||||
#if (ARDUINOJSON_VERSION_MAJOR >= 6)
|
||||
//serializeJson(json, Serial);
|
||||
serializeJsonPretty(json, Serial);
|
||||
// Write data to file and close it
|
||||
serializeJson(json, configFile);
|
||||
#else
|
||||
//json.printTo(Serial);
|
||||
json.prettyPrintTo(Serial);
|
||||
// Write data to file and close it
|
||||
json.printTo(configFile);
|
||||
#endif
|
||||
|
||||
configFile.close();
|
||||
//end save
|
||||
}
|
||||
|
||||
void heartBeatPrint(void)
|
||||
{
|
||||
static int num = 1;
|
||||
|
||||
if (WiFi.status() == WL_CONNECTED)
|
||||
Serial.print("H"); // H means connected to WiFi
|
||||
else
|
||||
Serial.print("F"); // F means not connected to WiFi
|
||||
|
||||
if (num == 80)
|
||||
{
|
||||
Serial.println();
|
||||
num = 1;
|
||||
}
|
||||
else if (num++ % 10 == 0)
|
||||
{
|
||||
Serial.print(" ");
|
||||
}
|
||||
}
|
||||
|
||||
void toggleLED()
|
||||
{
|
||||
//toggle state
|
||||
digitalWrite(PIN_LED, !digitalRead(PIN_LED));
|
||||
}
|
||||
|
||||
void check_WiFi(void)
|
||||
{
|
||||
if ( (WiFi.status() != WL_CONNECTED) )
|
||||
{
|
||||
Serial.println("\nWiFi lost. Call connectMultiWiFi in loop");
|
||||
connectMultiWiFi();
|
||||
}
|
||||
}
|
||||
|
||||
void check_status()
|
||||
{
|
||||
static ulong checkstatus_timeout = 0;
|
||||
static ulong LEDstatus_timeout = 0;
|
||||
static ulong checkwifi_timeout = 0;
|
||||
|
||||
static ulong currentMillis;
|
||||
|
||||
#define HEARTBEAT_INTERVAL 10000L
|
||||
#define LED_INTERVAL 2000L
|
||||
#define WIFICHECK_INTERVAL 1000L
|
||||
|
||||
currentMillis = millis();
|
||||
|
||||
// Check WiFi every WIFICHECK_INTERVAL (1) seconds.
|
||||
if ((currentMillis > checkwifi_timeout) || (checkwifi_timeout == 0))
|
||||
{
|
||||
check_WiFi();
|
||||
checkwifi_timeout = currentMillis + WIFICHECK_INTERVAL;
|
||||
}
|
||||
|
||||
if ((currentMillis > LEDstatus_timeout) || (LEDstatus_timeout == 0))
|
||||
{
|
||||
// Toggle LED at LED_INTERVAL = 2s
|
||||
toggleLED();
|
||||
LEDstatus_timeout = currentMillis + LED_INTERVAL;
|
||||
}
|
||||
|
||||
// Print hearbeat every HEARTBEAT_INTERVAL (10) seconds.
|
||||
if ((currentMillis > checkstatus_timeout) || (checkstatus_timeout == 0))
|
||||
{
|
||||
heartBeatPrint();
|
||||
checkstatus_timeout = currentMillis + HEARTBEAT_INTERVAL;
|
||||
}
|
||||
}
|
||||
|
||||
void loadConfigData(void)
|
||||
{
|
||||
File file = FileFS.open(CONFIG_FILENAME, "r");
|
||||
LOGERROR(F("LoadWiFiCfgFile "));
|
||||
|
||||
if (file)
|
||||
{
|
||||
file.readBytes((char *) &WM_config, sizeof(WM_config));
|
||||
file.close();
|
||||
LOGERROR(F("OK"));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGERROR(F("failed"));
|
||||
}
|
||||
}
|
||||
|
||||
void saveConfigData(void)
|
||||
{
|
||||
File file = FileFS.open(CONFIG_FILENAME, "w");
|
||||
LOGERROR(F("SaveWiFiCfgFile "));
|
||||
|
||||
if (file)
|
||||
{
|
||||
file.write((uint8_t*) &WM_config, sizeof(WM_config));
|
||||
file.close();
|
||||
LOGERROR(F("OK"));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGERROR(F("failed"));
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t connectMultiWiFi(void)
|
||||
{
|
||||
#if ESP32
|
||||
// For ESP32, this better be 0 to shorten the connect time
|
||||
#define WIFI_MULTI_1ST_CONNECT_WAITING_MS 0
|
||||
#else
|
||||
// For ESP8266, this better be 2200 to enable connect the 1st time
|
||||
#define WIFI_MULTI_1ST_CONNECT_WAITING_MS 2200L
|
||||
#endif
|
||||
|
||||
#define WIFI_MULTI_CONNECT_WAITING_MS 100L
|
||||
|
||||
uint8_t status;
|
||||
|
||||
LOGERROR(F("ConnectMultiWiFi with :"));
|
||||
|
||||
if ( (Router_SSID != "") && (Router_Pass != "") )
|
||||
{
|
||||
LOGERROR3(F("* Flash-stored Router_SSID = "), Router_SSID, F(", Router_Pass = "), Router_Pass );
|
||||
}
|
||||
|
||||
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
|
||||
#if USE_CONFIGURABLE_DNS
|
||||
// Set static IP, Gateway, Subnetmask, DNS1 and DNS2. New in v1.0.5
|
||||
WiFi.config(stationIP, gatewayIP, netMask, dns1IP, dns2IP);
|
||||
#else
|
||||
// Set static IP, Gateway, Subnetmask, Use auto DNS1 and DNS2.
|
||||
WiFi.config(stationIP, gatewayIP, netMask);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
int i = 0;
|
||||
status = wifiMulti.run();
|
||||
delay(WIFI_MULTI_1ST_CONNECT_WAITING_MS);
|
||||
|
||||
while ( ( i++ < 10 ) && ( status != WL_CONNECTED ) )
|
||||
{
|
||||
status = wifiMulti.run();
|
||||
|
||||
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"));
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
// put your setup code here, to run once:
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
|
||||
Serial.print("\nStarting AutoConnectWithFSParams using " + String(FS_Name));
|
||||
Serial.println(" on " + String(ARDUINO_BOARD));
|
||||
|
||||
if (FORMAT_FILESYSTEM)
|
||||
FileFS.format();
|
||||
|
||||
// Format FileFS if not yet
|
||||
#ifdef ESP32
|
||||
if (!FileFS.begin(true))
|
||||
#else
|
||||
if (!FileFS.begin())
|
||||
#endif
|
||||
{
|
||||
Serial.print(FS_Name);
|
||||
Serial.println(F(" failed! AutoFormatting."));
|
||||
|
||||
#ifdef ESP8266
|
||||
FileFS.format();
|
||||
#endif
|
||||
}
|
||||
|
||||
loadFileFSConfigFile();
|
||||
|
||||
// The extra parameters to be configured (can be either global or just in the setup)
|
||||
// After connecting, parameter.getValue() will get you the configured value
|
||||
// id/name placeholder/prompt default length
|
||||
ESP_WMParameter custom_blynk_server("blynk_server", "blynk_server", blynk_server, BLYNK_SERVER_LEN + 1);
|
||||
ESP_WMParameter custom_blynk_port ("blynk_port", "blynk_port", blynk_port, BLYNK_SERVER_PORT_LEN + 1);
|
||||
ESP_WMParameter custom_blynk_token ("blynk_token", "blynk_token", blynk_token, BLYNK_TOKEN_LEN + 1 );
|
||||
|
||||
ESP_WMParameter custom_mqtt_server("mqtt_server", "mqtt_server", mqtt_server, MQTT_SERVER_MAX_LEN + 1);
|
||||
ESP_WMParameter custom_mqtt_port ("mqtt_port", "mqtt_port", mqtt_port, MQTT_SERVER_PORT_LEN + 1);
|
||||
|
||||
unsigned long startedAt = millis();
|
||||
|
||||
// Use this to default DHCP hostname to ESP8266-XXXXXX or ESP32-XXXXXX
|
||||
//ESP_WiFiManager ESP_wifiManager;
|
||||
// Use this to personalize DHCP hostname (RFC952 conformed)
|
||||
ESP_WiFiManager ESP_wifiManager("AutoConnect-FSParams");
|
||||
|
||||
//set config save notify callback
|
||||
ESP_wifiManager.setSaveConfigCallback(saveConfigCallback);
|
||||
|
||||
//add all your parameters here
|
||||
ESP_wifiManager.addParameter(&custom_blynk_server);
|
||||
ESP_wifiManager.addParameter(&custom_blynk_port);
|
||||
ESP_wifiManager.addParameter(&custom_blynk_token);
|
||||
|
||||
ESP_wifiManager.addParameter(&custom_mqtt_server);
|
||||
ESP_wifiManager.addParameter(&custom_mqtt_port);
|
||||
|
||||
//reset settings - for testing
|
||||
//ESP_wifiManager.resetSettings();
|
||||
|
||||
ESP_wifiManager.setDebugOutput(true);
|
||||
|
||||
//set custom ip for portal
|
||||
ESP_wifiManager.setAPStaticIPConfig(IPAddress(192, 168, 100, 1), IPAddress(192, 168, 100, 1), IPAddress(255, 255, 255, 0));
|
||||
|
||||
//set minimum quality of signal so it ignores AP's under that quality
|
||||
//defaults to 8%
|
||||
//ESP_wifiManager.setMinimumSignalQuality();
|
||||
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_DHCP_IP
|
||||
#if USE_CONFIGURABLE_DNS
|
||||
// Set static IP, Gateway, Subnetmask, DNS1 and DNS2. New in v1.0.5
|
||||
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
|
||||
|
||||
// New from v1.1.1
|
||||
#if USING_CORS_FEATURE
|
||||
ESP_wifiManager.setCORSHeader("Your Access-Control-Allow-Origin");
|
||||
#endif
|
||||
|
||||
// We can't use WiFi.SSID() in ESP32 as it's only valid after connected.
|
||||
// SSID and Password stored in ESP32 wifi_ap_record_t and wifi_config_t are also cleared in reboot
|
||||
// Have to create a new function to store in EEPROM/SPIFFS/LittleFS for this purpose
|
||||
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("\nStored: SSID = " + Router_SSID + ", Pass = " + Router_Pass);
|
||||
|
||||
if (Router_SSID != "")
|
||||
{
|
||||
ESP_wifiManager.setConfigPortalTimeout(120); //If no access point name has been previously entered disable timeout.
|
||||
Serial.println("Got stored Credentials. Timeout 120s");
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println("No stored Credentials. No timeout");
|
||||
}
|
||||
|
||||
String chipID = String(ESP_getChipId(), HEX);
|
||||
chipID.toUpperCase();
|
||||
|
||||
// SSID and PW for Config Portal
|
||||
AP_SSID = "ESP_" + chipID + "_AutoConnectAP";
|
||||
AP_PASS = "MyESP_" + chipID;
|
||||
|
||||
// From v1.1.0, Don't permit NULL password
|
||||
if ( (Router_SSID == "") || (Router_Pass == "") )
|
||||
{
|
||||
Serial.println("We haven't got any access point credentials, so get them now");
|
||||
|
||||
initialConfig = true;
|
||||
|
||||
// Starts an access point
|
||||
//if (!ESP_wifiManager.startConfigPortal((const char *) ssid.c_str(), password))
|
||||
if ( !ESP_wifiManager.startConfigPortal(AP_SSID.c_str(), AP_PASS.c_str()) )
|
||||
Serial.println("Not connected to WiFi but continuing anyway.");
|
||||
else
|
||||
Serial.println("WiFi connected...yeey :)");
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
saveConfigData();
|
||||
}
|
||||
else
|
||||
{
|
||||
wifiMulti.addAP(Router_SSID.c_str(), Router_Pass.c_str());
|
||||
}
|
||||
|
||||
startedAt = millis();
|
||||
|
||||
if (!initialConfig)
|
||||
{
|
||||
// Load stored data, the addAP ready for MultiWiFi reconnection
|
||||
loadConfigData();
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
if ( WiFi.status() != WL_CONNECTED )
|
||||
{
|
||||
Serial.println("ConnectMultiWiFi in setup");
|
||||
|
||||
connectMultiWiFi();
|
||||
}
|
||||
}
|
||||
|
||||
Serial.print("After waiting ");
|
||||
Serial.print((float) (millis() - startedAt) / 1000L);
|
||||
Serial.print(" secs more in setup(), connection result is ");
|
||||
|
||||
if (WiFi.status() == WL_CONNECTED)
|
||||
{
|
||||
Serial.print("connected. Local IP: ");
|
||||
Serial.println(WiFi.localIP());
|
||||
}
|
||||
else
|
||||
Serial.println(ESP_wifiManager.getStatus(WiFi.status()));
|
||||
|
||||
//read updated parameters
|
||||
strncpy(blynk_server, custom_blynk_server.getValue(), sizeof(blynk_server));
|
||||
strncpy(blynk_port, custom_blynk_port.getValue(), sizeof(blynk_port));
|
||||
strncpy(blynk_token, custom_blynk_token.getValue(), sizeof(blynk_token));
|
||||
|
||||
strncpy(mqtt_server, custom_mqtt_server.getValue(), sizeof(mqtt_server));
|
||||
strncpy(mqtt_port, custom_mqtt_port.getValue(), sizeof(mqtt_port));
|
||||
|
||||
//save the custom parameters to FS
|
||||
if (shouldSaveConfig)
|
||||
{
|
||||
saveFileFSConfigFile();
|
||||
}
|
||||
|
||||
Serial.print("Local IP = ");
|
||||
Serial.println(WiFi.localIP());
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
check_status();
|
||||
}
|
||||
@@ -0,0 +1,565 @@
|
||||
/****************************************************************************************************************************
|
||||
AutoConnectWithFeedBack.ino
|
||||
For ESP8266 / ESP32 boards
|
||||
|
||||
ESP_WiFiManager is a library for the ESP8266/ESP32 platform (https://github.com/esp8266/Arduino) to enable easy
|
||||
configuration and reconfiguration of WiFi credentials using a Captive Portal.
|
||||
|
||||
Modified from Tzapu https://github.com/tzapu/WiFiManager
|
||||
and from Ken Taylor https://github.com/kentaylor
|
||||
|
||||
Built by Khoi Hoang https://github.com/khoih-prog/ESP_WiFiManager
|
||||
Licensed under MIT license
|
||||
Version: 1.2.0
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 07/10/2019 Initial coding
|
||||
1.0.1 K Hoang 13/12/2019 Fix bug. Add features. Add support for ESP32
|
||||
1.0.2 K Hoang 19/12/2019 Fix bug thatkeeps ConfigPortal in endless loop if Portal/Router SSID or Password is NULL.
|
||||
1.0.3 K Hoang 05/01/2020 Option not displaying AvailablePages in Info page. Enhance README.md. Modify examples
|
||||
1.0.4 K Hoang 07/01/2020 Add RFC952 setHostname feature.
|
||||
1.0.5 K Hoang 15/01/2020 Add configurable DNS feature. Thanks to @Amorphous of https://community.blynk.cc
|
||||
1.0.6 K Hoang 03/02/2020 Add support for ArduinoJson version 6.0.0+ ( tested with v6.14.1 )
|
||||
1.0.7 K Hoang 13/04/2020 Reduce start time, fix SPIFFS bug in examples, update README.md
|
||||
1.0.8 K Hoang 10/06/2020 Fix STAstaticIP issue. Restructure code. Add LittleFS support for ESP8266 core 2.7.1+
|
||||
1.0.9 K Hoang 29/07/2020 Fix ESP32 STAstaticIP bug. Permit changing from DHCP <-> static IP using Config Portal.
|
||||
Add, enhance examples (fix MDNS for ESP32)
|
||||
1.0.10 K Hoang 08/08/2020 Add more features to Config Portal. Use random WiFi AP channel to avoid conflict.
|
||||
1.0.11 K Hoang 17/08/2020 Add CORS feature. Fix bug in softAP, autoConnect, resetSettings.
|
||||
1.1.0 K Hoang 28/08/2020 Add MultiWiFi feature to autoconnect to best WiFi at runtime
|
||||
1.1.1 K Hoang 30/08/2020 Add setCORSHeader function to allow flexible CORS. Fix typo and minor improvement.
|
||||
1.1.2 K Hoang 17/08/2020 Fix bug. Add example.
|
||||
1.2.0 K Hoang 09/10/2020 Restore cpp code besides Impl.h code to use if linker error. Fix bug.
|
||||
*****************************************************************************************************************************/
|
||||
#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
|
||||
|
||||
// Use from 0 to 4. Higher number, more debugging messages and memory usage.
|
||||
#define _WIFIMGR_LOGLEVEL_ 3
|
||||
|
||||
//Ported to ESP32
|
||||
#ifdef ESP32
|
||||
#include <esp_wifi.h>
|
||||
#include <WiFi.h>
|
||||
#include <WiFiClient.h>
|
||||
|
||||
// From v1.1.0
|
||||
#include <WiFiMulti.h>
|
||||
WiFiMulti wifiMulti;
|
||||
|
||||
#define USE_SPIFFS true
|
||||
|
||||
#if USE_SPIFFS
|
||||
#include <SPIFFS.h>
|
||||
FS* filesystem = &SPIFFS;
|
||||
#define FileFS SPIFFS
|
||||
#define FS_Name "SPIFFS"
|
||||
#else
|
||||
// Use FFat
|
||||
#include <FFat.h>
|
||||
FS* filesystem = &FFat;
|
||||
#define FileFS FFat
|
||||
#define FS_Name "FFat"
|
||||
#endif
|
||||
//////
|
||||
|
||||
#define ESP_getChipId() ((uint32_t)ESP.getEfuseMac())
|
||||
|
||||
#define LED_ON HIGH
|
||||
#define LED_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;
|
||||
|
||||
#include <FS.h>
|
||||
|
||||
#define USE_LITTLEFS true
|
||||
|
||||
#if USE_LITTLEFS
|
||||
#include <LittleFS.h>
|
||||
FS* filesystem = &LittleFS;
|
||||
#define FileFS LittleFS
|
||||
#define FS_Name "LittleFS"
|
||||
#else
|
||||
FS* filesystem = &SPIFFS;
|
||||
#define FileFS SPIFFS
|
||||
#define FS_Name "SPIFFS"
|
||||
#endif
|
||||
//////
|
||||
|
||||
#define ESP_getChipId() (ESP.getChipId())
|
||||
|
||||
#define LED_ON LOW
|
||||
#define LED_OFF HIGH
|
||||
#endif
|
||||
|
||||
// You only need to format the filesystem once
|
||||
//#define FORMAT_FILESYSTEM true
|
||||
#define FORMAT_FILESYSTEM false
|
||||
|
||||
// SSID and PW for your Router
|
||||
String Router_SSID;
|
||||
String Router_Pass;
|
||||
|
||||
// From v1.1.0
|
||||
#define MIN_AP_PASSWORD_SIZE 8
|
||||
|
||||
#define SSID_MAX_LEN 32
|
||||
//From v1.0.10, WPA2 passwords can be up to 63 characters long.
|
||||
#define PASS_MAX_LEN 64
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char wifi_ssid[SSID_MAX_LEN];
|
||||
char wifi_pw [PASS_MAX_LEN];
|
||||
} WiFi_Credentials;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
String wifi_ssid;
|
||||
String wifi_pw;
|
||||
} WiFi_Credentials_String;
|
||||
|
||||
#define NUM_WIFI_CREDENTIALS 2
|
||||
|
||||
typedef struct
|
||||
{
|
||||
WiFi_Credentials WiFi_Creds [NUM_WIFI_CREDENTIALS];
|
||||
} WM_Config;
|
||||
|
||||
WM_Config WM_config;
|
||||
|
||||
#define CONFIG_FILENAME F("/wifi_cred.dat")
|
||||
|
||||
// Indicates whether ESP has WiFi credentials saved from previous session, or double reset detected
|
||||
bool initialConfig = false;
|
||||
//////
|
||||
|
||||
// SSID and PW for Config Portal
|
||||
String AP_SSID;
|
||||
String AP_PASS;
|
||||
|
||||
// Use false if you don't like to display Available Pages in Information Page of Config Portal
|
||||
// Comment out or use true to display Available Pages in Information Page of Config Portal
|
||||
// Must be placed before #include <ESP_WiFiManager.h>
|
||||
#define USE_AVAILABLE_PAGES false
|
||||
|
||||
// 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)
|
||||
#define USE_ESP_WIFIMANAGER_NTP false
|
||||
|
||||
// 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)
|
||||
#define USE_CLOUDFLARE_NTP false
|
||||
|
||||
// New in v1.0.11
|
||||
#define USING_CORS_FEATURE true
|
||||
//////
|
||||
|
||||
// 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
|
||||
#define USE_DHCP_IP true
|
||||
#else
|
||||
// You can select DHCP or Static IP here
|
||||
//#define USE_DHCP_IP true
|
||||
#define USE_DHCP_IP false
|
||||
#endif
|
||||
|
||||
#if ( USE_DHCP_IP || ( defined(USE_STATIC_IP_CONFIG_IN_CP) && !USE_STATIC_IP_CONFIG_IN_CP ) )
|
||||
// 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
|
||||
|
||||
#define USE_CONFIGURABLE_DNS true
|
||||
|
||||
IPAddress dns1IP = gatewayIP;
|
||||
IPAddress dns2IP = IPAddress(8, 8, 8, 8);
|
||||
|
||||
#include <ESP_WiFiManager.h> //https://github.com/khoih-prog/ESP_WiFiManager
|
||||
|
||||
// Function Prototypes
|
||||
uint8_t connectMultiWiFi(void);
|
||||
|
||||
void heartBeatPrint(void)
|
||||
{
|
||||
static int num = 1;
|
||||
|
||||
if (WiFi.status() == WL_CONNECTED)
|
||||
Serial.print("H"); // H means connected to WiFi
|
||||
else
|
||||
Serial.print("F"); // F means not connected to WiFi
|
||||
|
||||
if (num == 80)
|
||||
{
|
||||
Serial.println();
|
||||
num = 1;
|
||||
}
|
||||
else if (num++ % 10 == 0)
|
||||
{
|
||||
Serial.print(" ");
|
||||
}
|
||||
}
|
||||
|
||||
void check_WiFi(void)
|
||||
{
|
||||
if ( (WiFi.status() != WL_CONNECTED) )
|
||||
{
|
||||
Serial.println("\nWiFi lost. Call connectMultiWiFi in loop");
|
||||
connectMultiWiFi();
|
||||
}
|
||||
}
|
||||
|
||||
void check_status(void)
|
||||
{
|
||||
static ulong checkstatus_timeout = 0;
|
||||
static ulong checkwifi_timeout = 0;
|
||||
|
||||
static ulong current_millis;
|
||||
|
||||
#define WIFICHECK_INTERVAL 1000L
|
||||
#define HEARTBEAT_INTERVAL 10000L
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// Print hearbeat every HEARTBEAT_INTERVAL (10) seconds.
|
||||
if ((current_millis > checkstatus_timeout) || (checkstatus_timeout == 0))
|
||||
{
|
||||
heartBeatPrint();
|
||||
checkstatus_timeout = current_millis + HEARTBEAT_INTERVAL;
|
||||
}
|
||||
}
|
||||
|
||||
void configModeCallback (ESP_WiFiManager *myESP_WiFiManager)
|
||||
{
|
||||
Serial.print("Entered config mode with ");
|
||||
Serial.println("AP_SSID : " + myESP_WiFiManager->getConfigPortalSSID() + " and AP_PASS = " + myESP_WiFiManager->getConfigPortalPW());
|
||||
}
|
||||
|
||||
void loadConfigData(void)
|
||||
{
|
||||
File file = FileFS.open(CONFIG_FILENAME, "r");
|
||||
LOGERROR(F("LoadWiFiCfgFile "));
|
||||
|
||||
if (file)
|
||||
{
|
||||
file.readBytes((char *) &WM_config, sizeof(WM_config));
|
||||
file.close();
|
||||
LOGERROR(F("OK"));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGERROR(F("failed"));
|
||||
}
|
||||
}
|
||||
|
||||
void saveConfigData(void)
|
||||
{
|
||||
File file = FileFS.open(CONFIG_FILENAME, "w");
|
||||
LOGERROR(F("SaveWiFiCfgFile "));
|
||||
|
||||
if (file)
|
||||
{
|
||||
file.write((uint8_t*) &WM_config, sizeof(WM_config));
|
||||
file.close();
|
||||
LOGERROR(F("OK"));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGERROR(F("failed"));
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t connectMultiWiFi(void)
|
||||
{
|
||||
#if ESP32
|
||||
// For ESP32, this better be 0 to shorten the connect time
|
||||
#define WIFI_MULTI_1ST_CONNECT_WAITING_MS 0
|
||||
#else
|
||||
// For ESP8266, this better be 2200 to enable connect the 1st time
|
||||
#define WIFI_MULTI_1ST_CONNECT_WAITING_MS 2200L
|
||||
#endif
|
||||
|
||||
#define WIFI_MULTI_CONNECT_WAITING_MS 100L
|
||||
|
||||
uint8_t status;
|
||||
|
||||
LOGERROR(F("ConnectMultiWiFi with :"));
|
||||
|
||||
if ( (Router_SSID != "") && (Router_Pass != "") )
|
||||
{
|
||||
LOGERROR3(F("* Flash-stored Router_SSID = "), Router_SSID, F(", Router_Pass = "), Router_Pass );
|
||||
}
|
||||
|
||||
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
|
||||
#if USE_CONFIGURABLE_DNS
|
||||
// Set static IP, Gateway, Subnetmask, DNS1 and DNS2. New in v1.0.5
|
||||
WiFi.config(stationIP, gatewayIP, netMask, dns1IP, dns2IP);
|
||||
#else
|
||||
// Set static IP, Gateway, Subnetmask, Use auto DNS1 and DNS2.
|
||||
WiFi.config(stationIP, gatewayIP, netMask);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
int i = 0;
|
||||
status = wifiMulti.run();
|
||||
delay(WIFI_MULTI_1ST_CONNECT_WAITING_MS);
|
||||
|
||||
while ( ( i++ < 10 ) && ( status != WL_CONNECTED ) )
|
||||
{
|
||||
status = wifiMulti.run();
|
||||
|
||||
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"));
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
// put your setup code here, to run once:
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
|
||||
Serial.print("\nStarting AutoConnectWithFeedBack using " + String(FS_Name));
|
||||
Serial.println(" on " + String(ARDUINO_BOARD));
|
||||
|
||||
if (FORMAT_FILESYSTEM)
|
||||
FileFS.format();
|
||||
|
||||
// Format FileFS if not yet
|
||||
#ifdef ESP32
|
||||
if (!FileFS.begin(true))
|
||||
#else
|
||||
if (!FileFS.begin())
|
||||
#endif
|
||||
{
|
||||
Serial.print(FS_Name);
|
||||
Serial.println(F(" failed! AutoFormatting."));
|
||||
|
||||
#ifdef ESP8266
|
||||
FileFS.format();
|
||||
#endif
|
||||
}
|
||||
|
||||
unsigned long startedAt = millis();
|
||||
|
||||
// Use this to default DHCP hostname to ESP8266-XXXXXX or ESP32-XXXXXX
|
||||
//ESP_WiFiManager ESP_wifiManager;
|
||||
// Use this to personalize DHCP hostname (RFC952 conformed)
|
||||
ESP_WiFiManager ESP_wifiManager("AutoConnectWithFeedBack");
|
||||
|
||||
//reset settings - for testing
|
||||
//ESP_wifiManager.resetSettings();
|
||||
|
||||
//set callback that gets called when connecting to previous WiFi fails, and enters Access Point mode
|
||||
ESP_wifiManager.setAPCallback(configModeCallback);
|
||||
|
||||
ESP_wifiManager.setDebugOutput(true);
|
||||
|
||||
//set custom ip for portal
|
||||
ESP_wifiManager.setAPStaticIPConfig(IPAddress(192, 168, 100, 1), IPAddress(192, 168, 100, 1), IPAddress(255, 255, 255, 0));
|
||||
|
||||
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_DHCP_IP
|
||||
#if USE_CONFIGURABLE_DNS
|
||||
// Set static IP, Gateway, Subnetmask, DNS1 and DNS2. New in v1.0.5
|
||||
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
|
||||
|
||||
// New from v1.1.1
|
||||
#if USING_CORS_FEATURE
|
||||
ESP_wifiManager.setCORSHeader("Your Access-Control-Allow-Origin");
|
||||
#endif
|
||||
|
||||
// We can't use WiFi.SSID() in ESP32 as it's only valid after connected.
|
||||
// SSID and Password stored in ESP32 wifi_ap_record_t and wifi_config_t are also cleared in reboot
|
||||
// Have to create a new function to store in EEPROM/SPIFFS for this purpose
|
||||
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("Stored: SSID = " + Router_SSID + ", Pass = " + Router_Pass);
|
||||
|
||||
if (Router_SSID != "")
|
||||
{
|
||||
ESP_wifiManager.setConfigPortalTimeout(120); //If no access point name has been previously entered disable timeout.
|
||||
Serial.println("Got stored Credentials. Timeout 120s");
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println("No stored Credentials. No timeout");
|
||||
}
|
||||
|
||||
String chipID = String(ESP_getChipId(), HEX);
|
||||
chipID.toUpperCase();
|
||||
|
||||
// SSID and PW for Config Portal
|
||||
AP_SSID = "ESP_" + chipID + "_AutoConnectAP";
|
||||
AP_PASS = "MyESP_" + chipID;
|
||||
|
||||
// From v1.1.0, Don't permit NULL password
|
||||
if ( (Router_SSID == "") || (Router_Pass == "") )
|
||||
{
|
||||
Serial.println("We haven't got any access point credentials, so get them now");
|
||||
|
||||
initialConfig = true;
|
||||
|
||||
// Starts an access point
|
||||
//if (!ESP_wifiManager.startConfigPortal((const char *) ssid.c_str(), password))
|
||||
if ( !ESP_wifiManager.startConfigPortal(AP_SSID.c_str(), AP_PASS.c_str()) )
|
||||
Serial.println("Not connected to WiFi but continuing anyway.");
|
||||
else
|
||||
Serial.println("WiFi connected...yeey :)");
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
saveConfigData();
|
||||
}
|
||||
else
|
||||
{
|
||||
wifiMulti.addAP(Router_SSID.c_str(), Router_Pass.c_str());
|
||||
}
|
||||
|
||||
startedAt = millis();
|
||||
|
||||
if (!initialConfig)
|
||||
{
|
||||
// Load stored data, the addAP ready for MultiWiFi reconnection
|
||||
loadConfigData();
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
if ( WiFi.status() != WL_CONNECTED )
|
||||
{
|
||||
Serial.println("ConnectMultiWiFi in setup");
|
||||
|
||||
connectMultiWiFi();
|
||||
}
|
||||
}
|
||||
|
||||
Serial.print("After waiting ");
|
||||
Serial.print((float) (millis() - startedAt) / 1000L);
|
||||
Serial.print(" secs more in setup(), connection result is ");
|
||||
|
||||
if (WiFi.status() == WL_CONNECTED)
|
||||
{
|
||||
Serial.print("connected. Local IP: ");
|
||||
Serial.println(WiFi.localIP());
|
||||
}
|
||||
else
|
||||
Serial.println(ESP_wifiManager.getStatus(WiFi.status()));
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// put your main code here, to run repeatedly:
|
||||
check_status();
|
||||
}
|
||||
@@ -0,0 +1,599 @@
|
||||
/****************************************************************************************************************************
|
||||
AutoConnectWithFeedBackLED.ino
|
||||
For ESP8266 / ESP32 boards
|
||||
|
||||
ESP_WiFiManager is a library for the ESP8266/ESP32 platform (https://github.com/esp8266/Arduino) to enable easy
|
||||
configuration and reconfiguration of WiFi credentials using a Captive Portal.
|
||||
|
||||
Modified from Tzapu https://github.com/tzapu/WiFiManager
|
||||
and from Ken Taylor https://github.com/kentaylor
|
||||
|
||||
Built by Khoi Hoang https://github.com/khoih-prog/ESP_WiFiManager
|
||||
Licensed under MIT license
|
||||
Version: 1.2.0
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 07/10/2019 Initial coding
|
||||
1.0.1 K Hoang 13/12/2019 Fix bug. Add features. Add support for ESP32
|
||||
1.0.2 K Hoang 19/12/2019 Fix bug thatkeeps ConfigPortal in endless loop if Portal/Router SSID or Password is NULL.
|
||||
1.0.3 K Hoang 05/01/2020 Option not displaying AvailablePages in Info page. Enhance README.md. Modify examples
|
||||
1.0.4 K Hoang 07/01/2020 Add RFC952 setHostname feature.
|
||||
1.0.5 K Hoang 15/01/2020 Add configurable DNS feature. Thanks to @Amorphous of https://community.blynk.cc
|
||||
1.0.6 K Hoang 03/02/2020 Add support for ArduinoJson version 6.0.0+ ( tested with v6.14.1 )
|
||||
1.0.7 K Hoang 13/04/2020 Reduce start time, fix SPIFFS bug in examples, update README.md
|
||||
1.0.8 K Hoang 10/06/2020 Fix STAstaticIP issue. Restructure code. Add LittleFS support for ESP8266 core 2.7.1+
|
||||
1.0.9 K Hoang 29/07/2020 Fix ESP32 STAstaticIP bug. Permit changing from DHCP <-> static IP using Config Portal.
|
||||
Add, enhance examples (fix MDNS for ESP32)
|
||||
1.0.10 K Hoang 08/08/2020 Add more features to Config Portal. Use random WiFi AP channel to avoid conflict.
|
||||
1.0.11 K Hoang 17/08/2020 Add CORS feature. Fix bug in softAP, autoConnect, resetSettings.
|
||||
1.1.0 K Hoang 28/08/2020 Add MultiWiFi feature to autoconnect to best WiFi at runtime
|
||||
1.1.1 K Hoang 30/08/2020 Add setCORSHeader function to allow flexible CORS. Fix typo and minor improvement.
|
||||
1.1.2 K Hoang 17/08/2020 Fix bug. Add example.
|
||||
1.2.0 K Hoang 09/10/2020 Restore cpp code besides Impl.h code to use if linker error. Fix bug.
|
||||
*****************************************************************************************************************************/
|
||||
#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
|
||||
|
||||
// Use from 0 to 4. Higher number, more debugging messages and memory usage.
|
||||
#define _WIFIMGR_LOGLEVEL_ 3
|
||||
|
||||
#include <FS.h>
|
||||
|
||||
//Ported to ESP32
|
||||
#ifdef ESP32
|
||||
#include <esp_wifi.h>
|
||||
#include <WiFi.h>
|
||||
#include <WiFiClient.h>
|
||||
|
||||
// From v1.1.0
|
||||
#include <WiFiMulti.h>
|
||||
WiFiMulti wifiMulti;
|
||||
|
||||
#define USE_SPIFFS true
|
||||
|
||||
#if USE_SPIFFS
|
||||
#include <SPIFFS.h>
|
||||
FS* filesystem = &SPIFFS;
|
||||
#define FileFS SPIFFS
|
||||
#define FS_Name "SPIFFS"
|
||||
#else
|
||||
// Use FFat
|
||||
#include <FFat.h>
|
||||
FS* filesystem = &FFat;
|
||||
#define FileFS FFat
|
||||
#define FS_Name "FFat"
|
||||
#endif
|
||||
//////
|
||||
|
||||
#define ESP_getChipId() ((uint32_t)ESP.getEfuseMac())
|
||||
|
||||
#define LED_BUILTIN 2
|
||||
#define LED_ON HIGH
|
||||
#define LED_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;
|
||||
|
||||
#define USE_LITTLEFS true
|
||||
|
||||
#if USE_LITTLEFS
|
||||
#include <LittleFS.h>
|
||||
FS* filesystem = &LittleFS;
|
||||
#define FileFS LittleFS
|
||||
#define FS_Name "LittleFS"
|
||||
#else
|
||||
FS* filesystem = &SPIFFS;
|
||||
#define FileFS SPIFFS
|
||||
#define FS_Name "SPIFFS"
|
||||
#endif
|
||||
//////
|
||||
|
||||
#define ESP_getChipId() (ESP.getChipId())
|
||||
|
||||
#define LED_ON LOW
|
||||
#define LED_OFF HIGH
|
||||
#endif
|
||||
|
||||
// Pin D2 mapped to pin GPIO2/ADC12 of ESP32, or GPIO2/TXD1 of NodeMCU control on-board LED
|
||||
#define PIN_LED LED_BUILTIN
|
||||
|
||||
// You only need to format the filesystem once
|
||||
//#define FORMAT_FILESYSTEM true
|
||||
#define FORMAT_FILESYSTEM false
|
||||
|
||||
// SSID and PW for your Router
|
||||
String Router_SSID;
|
||||
String Router_Pass;
|
||||
|
||||
// From v1.1.0
|
||||
#define MIN_AP_PASSWORD_SIZE 8
|
||||
|
||||
#define SSID_MAX_LEN 32
|
||||
//From v1.0.10, WPA2 passwords can be up to 63 characters long.
|
||||
#define PASS_MAX_LEN 64
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char wifi_ssid[SSID_MAX_LEN];
|
||||
char wifi_pw [PASS_MAX_LEN];
|
||||
} WiFi_Credentials;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
String wifi_ssid;
|
||||
String wifi_pw;
|
||||
} WiFi_Credentials_String;
|
||||
|
||||
#define NUM_WIFI_CREDENTIALS 2
|
||||
|
||||
typedef struct
|
||||
{
|
||||
WiFi_Credentials WiFi_Creds [NUM_WIFI_CREDENTIALS];
|
||||
} WM_Config;
|
||||
|
||||
WM_Config WM_config;
|
||||
|
||||
#define CONFIG_FILENAME F("/wifi_cred.dat")
|
||||
|
||||
// Indicates whether ESP has WiFi credentials saved from previous session, or double reset detected
|
||||
bool initialConfig = false;
|
||||
//////
|
||||
|
||||
// SSID and PW for Config Portal
|
||||
String AP_SSID;
|
||||
String AP_PASS;
|
||||
|
||||
// Use false if you don't like to display Available Pages in Information Page of Config Portal
|
||||
// Comment out or use true to display Available Pages in Information Page of Config Portal
|
||||
// Must be placed before #include <ESP_WiFiManager.h>
|
||||
#define USE_AVAILABLE_PAGES false
|
||||
|
||||
// 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)
|
||||
#define USE_ESP_WIFIMANAGER_NTP false
|
||||
|
||||
// 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)
|
||||
#define USE_CLOUDFLARE_NTP false
|
||||
|
||||
// New in v1.0.11
|
||||
#define USING_CORS_FEATURE true
|
||||
//////
|
||||
|
||||
// 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
|
||||
#define USE_DHCP_IP true
|
||||
#else
|
||||
// You can select DHCP or Static IP here
|
||||
//#define USE_DHCP_IP true
|
||||
#define USE_DHCP_IP false
|
||||
#endif
|
||||
|
||||
#if ( USE_DHCP_IP || ( defined(USE_STATIC_IP_CONFIG_IN_CP) && !USE_STATIC_IP_CONFIG_IN_CP ) )
|
||||
// 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
|
||||
|
||||
#define USE_CONFIGURABLE_DNS true
|
||||
|
||||
IPAddress dns1IP = gatewayIP;
|
||||
IPAddress dns2IP = IPAddress(8, 8, 8, 8);
|
||||
|
||||
#include <ESP_WiFiManager.h> //https://github.com/khoih-prog/ESP_WiFiManager
|
||||
|
||||
//for LED status
|
||||
#include <Ticker.h>
|
||||
Ticker ticker;
|
||||
|
||||
// Function Prototypes
|
||||
uint8_t connectMultiWiFi(void);
|
||||
|
||||
void toggleLED()
|
||||
{
|
||||
//toggle state
|
||||
digitalWrite(PIN_LED, !digitalRead(PIN_LED));
|
||||
}
|
||||
|
||||
//gets called when WiFiManager enters configuration mode
|
||||
void configModeCallback (ESP_WiFiManager *myESP_WiFiManager)
|
||||
{
|
||||
Serial.print("Entered config mode with ");
|
||||
Serial.println("AP_SSID : " + myESP_WiFiManager->getConfigPortalSSID() + " and AP_PASS = " + myESP_WiFiManager->getConfigPortalPW());
|
||||
//entered config mode, make led toggle faster at 0.2s
|
||||
ticker.attach(0.2, toggleLED);
|
||||
}
|
||||
|
||||
void heartBeatPrint(void)
|
||||
{
|
||||
static int num = 1;
|
||||
|
||||
if (WiFi.status() == WL_CONNECTED)
|
||||
Serial.print("H"); // H means connected to WiFi
|
||||
else
|
||||
Serial.print("F"); // F means not connected to WiFi
|
||||
|
||||
if (num == 80)
|
||||
{
|
||||
Serial.println();
|
||||
num = 1;
|
||||
}
|
||||
else if (num++ % 10 == 0)
|
||||
{
|
||||
Serial.print(" ");
|
||||
}
|
||||
}
|
||||
|
||||
void check_WiFi(void)
|
||||
{
|
||||
if ( (WiFi.status() != WL_CONNECTED) )
|
||||
{
|
||||
Serial.println("\nWiFi lost. Call connectMultiWiFi in loop");
|
||||
connectMultiWiFi();
|
||||
}
|
||||
}
|
||||
|
||||
void check_status()
|
||||
{
|
||||
static ulong checkstatus_timeout = 0;
|
||||
static ulong LEDstatus_timeout = 0;
|
||||
static ulong checkwifi_timeout = 0;
|
||||
|
||||
static ulong currentMillis;
|
||||
|
||||
#define HEARTBEAT_INTERVAL 10000L
|
||||
#define LED_INTERVAL 2000L
|
||||
#define WIFICHECK_INTERVAL 1000L
|
||||
|
||||
currentMillis = millis();
|
||||
|
||||
// Check WiFi every WIFICHECK_INTERVAL (1) seconds.
|
||||
if ((currentMillis > checkwifi_timeout) || (checkwifi_timeout == 0))
|
||||
{
|
||||
check_WiFi();
|
||||
checkwifi_timeout = currentMillis + WIFICHECK_INTERVAL;
|
||||
}
|
||||
|
||||
if ((currentMillis > LEDstatus_timeout) || (LEDstatus_timeout == 0))
|
||||
{
|
||||
// Toggle LED at LED_INTERVAL = 2s
|
||||
toggleLED();
|
||||
LEDstatus_timeout = currentMillis + LED_INTERVAL;
|
||||
}
|
||||
|
||||
// Print hearbeat every HEARTBEAT_INTERVAL (10) seconds.
|
||||
if ((currentMillis > checkstatus_timeout) || (checkstatus_timeout == 0))
|
||||
{
|
||||
heartBeatPrint();
|
||||
checkstatus_timeout = currentMillis + HEARTBEAT_INTERVAL;
|
||||
}
|
||||
}
|
||||
|
||||
void loadConfigData(void)
|
||||
{
|
||||
File file = FileFS.open(CONFIG_FILENAME, "r");
|
||||
LOGERROR(F("LoadWiFiCfgFile "));
|
||||
|
||||
if (file)
|
||||
{
|
||||
file.readBytes((char *) &WM_config, sizeof(WM_config));
|
||||
file.close();
|
||||
LOGERROR(F("OK"));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGERROR(F("failed"));
|
||||
}
|
||||
}
|
||||
|
||||
void saveConfigData(void)
|
||||
{
|
||||
File file = FileFS.open(CONFIG_FILENAME, "w");
|
||||
LOGERROR(F("SaveWiFiCfgFile "));
|
||||
|
||||
if (file)
|
||||
{
|
||||
file.write((uint8_t*) &WM_config, sizeof(WM_config));
|
||||
file.close();
|
||||
LOGERROR(F("OK"));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGERROR(F("failed"));
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t connectMultiWiFi(void)
|
||||
{
|
||||
#if ESP32
|
||||
// For ESP32, this better be 0 to shorten the connect time
|
||||
#define WIFI_MULTI_1ST_CONNECT_WAITING_MS 0
|
||||
#else
|
||||
// For ESP8266, this better be 2200 to enable connect the 1st time
|
||||
#define WIFI_MULTI_1ST_CONNECT_WAITING_MS 2200L
|
||||
#endif
|
||||
|
||||
#define WIFI_MULTI_CONNECT_WAITING_MS 100L
|
||||
|
||||
uint8_t status;
|
||||
|
||||
LOGERROR(F("ConnectMultiWiFi with :"));
|
||||
|
||||
if ( (Router_SSID != "") && (Router_Pass != "") )
|
||||
{
|
||||
LOGERROR3(F("* Flash-stored Router_SSID = "), Router_SSID, F(", Router_Pass = "), Router_Pass );
|
||||
}
|
||||
|
||||
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
|
||||
#if USE_CONFIGURABLE_DNS
|
||||
// Set static IP, Gateway, Subnetmask, DNS1 and DNS2. New in v1.0.5
|
||||
WiFi.config(stationIP, gatewayIP, netMask, dns1IP, dns2IP);
|
||||
#else
|
||||
// Set static IP, Gateway, Subnetmask, Use auto DNS1 and DNS2.
|
||||
WiFi.config(stationIP, gatewayIP, netMask);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
int i = 0;
|
||||
status = wifiMulti.run();
|
||||
delay(WIFI_MULTI_1ST_CONNECT_WAITING_MS);
|
||||
|
||||
while ( ( i++ < 10 ) && ( status != WL_CONNECTED ) )
|
||||
{
|
||||
status = wifiMulti.run();
|
||||
|
||||
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"));
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
//set led pin as output
|
||||
pinMode(PIN_LED, OUTPUT);
|
||||
|
||||
// put your setup code here, to run once:
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
|
||||
Serial.print("\nStarting AutoConnectWithFeedBackLED using " + String(FS_Name));
|
||||
Serial.println(" on " + String(ARDUINO_BOARD));
|
||||
|
||||
if (FORMAT_FILESYSTEM)
|
||||
FileFS.format();
|
||||
|
||||
// Format FileFS if not yet
|
||||
#ifdef ESP32
|
||||
if (!FileFS.begin(true))
|
||||
#else
|
||||
if (!FileFS.begin())
|
||||
#endif
|
||||
{
|
||||
Serial.print(FS_Name);
|
||||
Serial.println(F(" failed! AutoFormatting."));
|
||||
|
||||
#ifdef ESP8266
|
||||
FileFS.format();
|
||||
#endif
|
||||
}
|
||||
|
||||
unsigned long startedAt = millis();
|
||||
|
||||
// start ticker with 0.5s because we start in AP mode and try to connect
|
||||
ticker.attach(0.5, toggleLED);
|
||||
|
||||
// Use this to default DHCP hostname to ESP8266-XXXXXX or ESP32-XXXXXX
|
||||
//ESP_WiFiManager ESP_wifiManager;
|
||||
// Use this to personalize DHCP hostname (RFC952 conformed)
|
||||
ESP_WiFiManager ESP_wifiManager("AutoConnectFeedBackLED");
|
||||
|
||||
//reset settings - for testing
|
||||
//ESP_wifiManager.resetSettings();
|
||||
|
||||
//set callback that gets called when connecting to previous WiFi fails, and enters Access Point mode
|
||||
ESP_wifiManager.setAPCallback(configModeCallback);
|
||||
|
||||
ESP_wifiManager.setDebugOutput(true);
|
||||
|
||||
//set custom ip for portal
|
||||
ESP_wifiManager.setAPStaticIPConfig(IPAddress(192, 168, 100, 1), IPAddress(192, 168, 100, 1), IPAddress(255, 255, 255, 0));
|
||||
|
||||
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_DHCP_IP
|
||||
#if USE_CONFIGURABLE_DNS
|
||||
// Set static IP, Gateway, Subnetmask, DNS1 and DNS2. New in v1.0.5
|
||||
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
|
||||
|
||||
// New from v1.1.1
|
||||
#if USING_CORS_FEATURE
|
||||
ESP_wifiManager.setCORSHeader("Your Access-Control-Allow-Origin");
|
||||
#endif
|
||||
|
||||
// We can't use WiFi.SSID() in ESP32 as it's only valid after connected.
|
||||
// SSID and Password stored in ESP32 wifi_ap_record_t and wifi_config_t are also cleared in reboot
|
||||
// Have to create a new function to store in EEPROM/SPIFFS for this purpose
|
||||
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("Stored: SSID = " + Router_SSID + ", Pass = " + Router_Pass);
|
||||
|
||||
if (Router_SSID != "")
|
||||
{
|
||||
ESP_wifiManager.setConfigPortalTimeout(120); //If no access point name has been previously entered disable timeout.
|
||||
Serial.println("Got stored Credentials. Timeout 120s");
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println("No stored Credentials. No timeout");
|
||||
}
|
||||
|
||||
String chipID = String(ESP_getChipId(), HEX);
|
||||
chipID.toUpperCase();
|
||||
|
||||
// SSID and PW for Config Portal
|
||||
AP_SSID = "ESP_" + chipID + "_AutoConnectAP";
|
||||
AP_PASS = "MyESP_" + chipID;
|
||||
|
||||
// From v1.1.0, Don't permit NULL password
|
||||
if ( (Router_SSID == "") || (Router_Pass == "") )
|
||||
{
|
||||
Serial.println("We haven't got any access point credentials, so get them now");
|
||||
|
||||
initialConfig = true;
|
||||
|
||||
// Starts an access point
|
||||
//if (!ESP_wifiManager.startConfigPortal((const char *) ssid.c_str(), password))
|
||||
if ( !ESP_wifiManager.startConfigPortal(AP_SSID.c_str(), AP_PASS.c_str()) )
|
||||
Serial.println("Not connected to WiFi but continuing anyway.");
|
||||
else
|
||||
Serial.println("WiFi connected...yeey :)");
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
saveConfigData();
|
||||
}
|
||||
else
|
||||
{
|
||||
wifiMulti.addAP(Router_SSID.c_str(), Router_Pass.c_str());
|
||||
}
|
||||
|
||||
startedAt = millis();
|
||||
|
||||
if (!initialConfig)
|
||||
{
|
||||
// Load stored data, the addAP ready for MultiWiFi reconnection
|
||||
loadConfigData();
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
if ( WiFi.status() != WL_CONNECTED )
|
||||
{
|
||||
Serial.println("ConnectMultiWiFi in setup");
|
||||
|
||||
connectMultiWiFi();
|
||||
}
|
||||
}
|
||||
|
||||
Serial.print("After waiting ");
|
||||
Serial.print((float) (millis() - startedAt) / 1000L);
|
||||
Serial.print(" secs more in setup(), connection result is ");
|
||||
|
||||
if (WiFi.status() == WL_CONNECTED)
|
||||
{
|
||||
Serial.print("connected. Local IP: ");
|
||||
Serial.println(WiFi.localIP());
|
||||
}
|
||||
else
|
||||
Serial.println(ESP_wifiManager.getStatus(WiFi.status()));
|
||||
|
||||
ticker.detach();
|
||||
//keep LED on
|
||||
digitalWrite(PIN_LED, LED_ON);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
check_status();
|
||||
}
|
||||
@@ -0,0 +1,658 @@
|
||||
/****************************************************************************************************************************
|
||||
ConfigOnDoubleReset.ino
|
||||
For ESP8266 / ESP32 boards
|
||||
|
||||
ESP_WiFiManager is a library for the ESP8266/ESP32 platform (https://github.com/esp8266/Arduino) to enable easy
|
||||
configuration and reconfiguration of WiFi credentials using a Captive Portal. Inspired by:
|
||||
http://www.esp8266.com/viewtopic.php?f=29&t=2520
|
||||
https://github.com/chriscook8/esp-arduino-apboot
|
||||
https://github.com/esp8266/Arduino/blob/master/libraries/DNSServer/examples/CaptivePortalAdvanced/
|
||||
|
||||
Modified from Tzapu https://github.com/tzapu/WiFiManager
|
||||
and from Ken Taylor https://github.com/kentaylor
|
||||
|
||||
Built by Khoi Hoang https://github.com/khoih-prog/ESP_WiFiManager
|
||||
Licensed under MIT license
|
||||
Version: 1.2.0
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 07/10/2019 Initial coding
|
||||
1.0.1 K Hoang 13/12/2019 Fix bug. Add features. Add support for ESP32
|
||||
1.0.2 K Hoang 19/12/2019 Fix bug thatkeeps ConfigPortal in endless loop if Portal/Router SSID or Password is NULL.
|
||||
1.0.3 K Hoang 05/01/2020 Option not displaying AvailablePages in Info page. Enhance README.md. Modify examples
|
||||
1.0.4 K Hoang 07/01/2020 Add RFC952 setHostname feature.
|
||||
1.0.5 K Hoang 15/01/2020 Add configurable DNS feature. Thanks to @Amorphous of https://community.blynk.cc
|
||||
1.0.6 K Hoang 03/02/2020 Add support for ArduinoJson version 6.0.0+ ( tested with v6.14.1 )
|
||||
1.0.7 K Hoang 13/04/2020 Reduce start time, fix SPIFFS bug in examples, update README.md
|
||||
1.0.8 K Hoang 10/06/2020 Fix STAstaticIP issue. Restructure code. Add LittleFS support for ESP8266 core 2.7.1+
|
||||
1.0.9 K Hoang 29/07/2020 Fix ESP32 STAstaticIP bug. Permit changing from DHCP <-> static IP using Config Portal.
|
||||
Add, enhance examples (fix MDNS for ESP32)
|
||||
1.0.10 K Hoang 08/08/2020 Add more features to Config Portal. Use random WiFi AP channel to avoid conflict.
|
||||
1.0.11 K Hoang 17/08/2020 Add CORS feature. Fix bug in softAP, autoConnect, resetSettings.
|
||||
1.1.0 K Hoang 28/08/2020 Add MultiWiFi feature to autoconnect to best WiFi at runtime
|
||||
1.1.1 K Hoang 30/08/2020 Add setCORSHeader function to allow flexible CORS. Fix typo and minor improvement.
|
||||
1.1.2 K Hoang 17/08/2020 Fix bug. Add example.
|
||||
1.2.0 K Hoang 09/10/2020 Restore cpp code besides Impl.h code to use if linker error. Fix bug.
|
||||
*****************************************************************************************************************************/
|
||||
/****************************************************************************************************************************
|
||||
This example will open a configuration portal when the reset button is pressed twice.
|
||||
This method works well on Wemos boards which have a single reset button on board. It avoids using a pin for launching the configuration portal.
|
||||
|
||||
How It Works
|
||||
1) ESP8266
|
||||
Save data in RTC memory
|
||||
2) ESP32
|
||||
Save data in EEPROM from address 256, size 512 bytes (both configurable)
|
||||
|
||||
So when the device starts up it checks this region of ram for a flag to see if it has been recently reset.
|
||||
If so it launches a configuration portal, if not it sets the reset flag. After running for a while this flag is cleared so that
|
||||
it will only launch the configuration portal in response to closely spaced resets.
|
||||
|
||||
Settings
|
||||
There are two values to be set in the sketch.
|
||||
|
||||
DRD_TIMEOUT - Number of seconds to wait for the second reset. Set to 10 in the example.
|
||||
DRD_ADDRESS - The address in ESP8266 RTC RAM to store the flag. This memory must not be used for other purposes in the same sketch. Set to 0 in the example.
|
||||
|
||||
This example, originally relied on the Double Reset Detector library from https://github.com/datacute/DoubleResetDetector
|
||||
To support ESP32, use ESP_DoubleResetDetector library from //https://github.com/khoih-prog/ESP_DoubleResetDetector
|
||||
*****************************************************************************************************************************/
|
||||
#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
|
||||
|
||||
// Use from 0 to 4. Higher number, more debugging messages and memory usage.
|
||||
#define _WIFIMGR_LOGLEVEL_ 3
|
||||
|
||||
#include <FS.h>
|
||||
|
||||
//Ported to ESP32
|
||||
#ifdef ESP32
|
||||
#include <esp_wifi.h>
|
||||
#include <WiFi.h>
|
||||
#include <WiFiClient.h>
|
||||
|
||||
// From v1.1.0
|
||||
#include <WiFiMulti.h>
|
||||
WiFiMulti wifiMulti;
|
||||
|
||||
#define USE_SPIFFS true
|
||||
|
||||
#if USE_SPIFFS
|
||||
#include <SPIFFS.h>
|
||||
FS* filesystem = &SPIFFS;
|
||||
#define FileFS SPIFFS
|
||||
#define FS_Name "SPIFFS"
|
||||
#else
|
||||
// Use FFat
|
||||
#include <FFat.h>
|
||||
FS* filesystem = &FFat;
|
||||
#define FileFS FFat
|
||||
#define FS_Name "FFat"
|
||||
#endif
|
||||
//////
|
||||
|
||||
#define ESP_getChipId() ((uint32_t)ESP.getEfuseMac())
|
||||
|
||||
#define LED_BUILTIN 2
|
||||
#define LED_ON HIGH
|
||||
#define LED_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;
|
||||
|
||||
#define USE_LITTLEFS true
|
||||
|
||||
#if USE_LITTLEFS
|
||||
#include <LittleFS.h>
|
||||
FS* filesystem = &LittleFS;
|
||||
#define FileFS LittleFS
|
||||
#define FS_Name "LittleFS"
|
||||
#else
|
||||
FS* filesystem = &SPIFFS;
|
||||
#define FileFS SPIFFS
|
||||
#define FS_Name "SPIFFS"
|
||||
#endif
|
||||
//////
|
||||
|
||||
#define ESP_getChipId() (ESP.getChipId())
|
||||
|
||||
#define LED_ON LOW
|
||||
#define LED_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_SPIFFS
|
||||
#define ESP_DRD_USE_SPIFFS true
|
||||
#define ESP_DRD_USE_EEPROM false
|
||||
#else
|
||||
#define ESP_DRD_USE_SPIFFS false
|
||||
#define ESP_DRD_USE_EEPROM true
|
||||
#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
|
||||
#define ESP_DRD_USE_LITTLEFS true
|
||||
#define ESP_DRD_USE_SPIFFS false
|
||||
#else
|
||||
#define ESP_DRD_USE_LITTLEFS false
|
||||
#define ESP_DRD_USE_SPIFFS true
|
||||
#endif
|
||||
|
||||
#define ESP_DRD_USE_EEPROM false
|
||||
#define ESP8266_DRD_USE_RTC false
|
||||
#endif
|
||||
|
||||
#define DOUBLERESETDETECTOR_DEBUG true //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.
|
||||
#define DRD_TIMEOUT 10
|
||||
|
||||
// RTC Memory Address for the DoubleResetDetector to use
|
||||
#define DRD_ADDRESS 0
|
||||
|
||||
//DoubleResetDetector drd(DRD_TIMEOUT, DRD_ADDRESS);
|
||||
DoubleResetDetector* drd;//////
|
||||
|
||||
// Onboard LED I/O pin on NodeMCU board
|
||||
const int PIN_LED = 2; // D4 on NodeMCU and WeMos. GPIO2/ADC12 of ESP32. Controls the onboard LED.
|
||||
|
||||
// SSID and PW for Config Portal
|
||||
String ssid = "ESP_" + String(ESP_getChipId(), HEX);
|
||||
const char* password = "your_password";
|
||||
|
||||
// SSID and PW for your Router
|
||||
String Router_SSID;
|
||||
String Router_Pass;
|
||||
|
||||
// From v1.1.0
|
||||
// You only need to format the filesystem once
|
||||
//#define FORMAT_FILESYSTEM true
|
||||
#define FORMAT_FILESYSTEM false
|
||||
|
||||
#define MIN_AP_PASSWORD_SIZE 8
|
||||
|
||||
#define SSID_MAX_LEN 32
|
||||
//From v1.0.10, WPA2 passwords can be up to 63 characters long.
|
||||
#define PASS_MAX_LEN 64
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char wifi_ssid[SSID_MAX_LEN];
|
||||
char wifi_pw [PASS_MAX_LEN];
|
||||
} WiFi_Credentials;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
String wifi_ssid;
|
||||
String wifi_pw;
|
||||
} WiFi_Credentials_String;
|
||||
|
||||
#define NUM_WIFI_CREDENTIALS 2
|
||||
|
||||
typedef struct
|
||||
{
|
||||
WiFi_Credentials WiFi_Creds [NUM_WIFI_CREDENTIALS];
|
||||
} WM_Config;
|
||||
|
||||
WM_Config WM_config;
|
||||
|
||||
#define CONFIG_FILENAME F("/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 <ESP_WiFiManager.h>
|
||||
#define USE_AVAILABLE_PAGES false
|
||||
|
||||
// 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)
|
||||
#define USE_ESP_WIFIMANAGER_NTP false
|
||||
|
||||
// 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)
|
||||
#define USE_CLOUDFLARE_NTP false
|
||||
|
||||
// New in v1.0.11
|
||||
#define USING_CORS_FEATURE true
|
||||
//////
|
||||
|
||||
// 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
|
||||
#define USE_DHCP_IP true
|
||||
#else
|
||||
// You can select DHCP or Static IP here
|
||||
//#define USE_DHCP_IP true
|
||||
#define USE_DHCP_IP false
|
||||
#endif
|
||||
|
||||
#if ( USE_DHCP_IP || ( defined(USE_STATIC_IP_CONFIG_IN_CP) && !USE_STATIC_IP_CONFIG_IN_CP ) )
|
||||
// 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
|
||||
|
||||
#define USE_CONFIGURABLE_DNS true
|
||||
|
||||
IPAddress dns1IP = gatewayIP;
|
||||
IPAddress dns2IP = IPAddress(8, 8, 8, 8);
|
||||
|
||||
#include <ESP_WiFiManager.h> //https://github.com/khoih-prog/ESP_WiFiManager
|
||||
|
||||
// Function Prototypes
|
||||
uint8_t connectMultiWiFi(void);
|
||||
|
||||
void heartBeatPrint(void)
|
||||
{
|
||||
static int num = 1;
|
||||
|
||||
if (WiFi.status() == WL_CONNECTED)
|
||||
Serial.print("H"); // H means connected to WiFi
|
||||
else
|
||||
Serial.print("F"); // F means not connected to WiFi
|
||||
|
||||
if (num == 80)
|
||||
{
|
||||
Serial.println();
|
||||
num = 1;
|
||||
}
|
||||
else if (num++ % 10 == 0)
|
||||
{
|
||||
Serial.print(" ");
|
||||
}
|
||||
}
|
||||
|
||||
void check_WiFi(void)
|
||||
{
|
||||
if ( (WiFi.status() != WL_CONNECTED) )
|
||||
{
|
||||
Serial.println("\nWiFi lost. Call connectMultiWiFi in loop");
|
||||
connectMultiWiFi();
|
||||
}
|
||||
}
|
||||
|
||||
void check_status(void)
|
||||
{
|
||||
static ulong checkstatus_timeout = 0;
|
||||
static ulong checkwifi_timeout = 0;
|
||||
|
||||
static ulong current_millis;
|
||||
|
||||
#define WIFICHECK_INTERVAL 1000L
|
||||
#define HEARTBEAT_INTERVAL 10000L
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// Print hearbeat every HEARTBEAT_INTERVAL (10) seconds.
|
||||
if ((current_millis > checkstatus_timeout) || (checkstatus_timeout == 0))
|
||||
{
|
||||
heartBeatPrint();
|
||||
checkstatus_timeout = current_millis + HEARTBEAT_INTERVAL;
|
||||
}
|
||||
}
|
||||
|
||||
void loadConfigData(void)
|
||||
{
|
||||
File file = FileFS.open(CONFIG_FILENAME, "r");
|
||||
LOGERROR(F("LoadWiFiCfgFile "));
|
||||
|
||||
if (file)
|
||||
{
|
||||
file.readBytes((char *) &WM_config, sizeof(WM_config));
|
||||
file.close();
|
||||
LOGERROR(F("OK"));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGERROR(F("failed"));
|
||||
}
|
||||
}
|
||||
|
||||
void saveConfigData(void)
|
||||
{
|
||||
File file = FileFS.open(CONFIG_FILENAME, "w");
|
||||
LOGERROR(F("SaveWiFiCfgFile "));
|
||||
|
||||
if (file)
|
||||
{
|
||||
file.write((uint8_t*) &WM_config, sizeof(WM_config));
|
||||
file.close();
|
||||
LOGERROR(F("OK"));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGERROR(F("failed"));
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t connectMultiWiFi(void)
|
||||
{
|
||||
#if ESP32
|
||||
// For ESP32, this better be 0 to shorten the connect time
|
||||
#define WIFI_MULTI_1ST_CONNECT_WAITING_MS 0
|
||||
#else
|
||||
// For ESP8266, this better be 2200 to enable connect the 1st time
|
||||
#define WIFI_MULTI_1ST_CONNECT_WAITING_MS 2200L
|
||||
#endif
|
||||
|
||||
#define WIFI_MULTI_CONNECT_WAITING_MS 100L
|
||||
|
||||
uint8_t status;
|
||||
|
||||
LOGERROR(F("ConnectMultiWiFi with :"));
|
||||
|
||||
if ( (Router_SSID != "") && (Router_Pass != "") )
|
||||
{
|
||||
LOGERROR3(F("* Flash-stored Router_SSID = "), Router_SSID, F(", Router_Pass = "), Router_Pass );
|
||||
}
|
||||
|
||||
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
|
||||
#if USE_CONFIGURABLE_DNS
|
||||
// Set static IP, Gateway, Subnetmask, DNS1 and DNS2. New in v1.0.5
|
||||
WiFi.config(stationIP, gatewayIP, netMask, dns1IP, dns2IP);
|
||||
#else
|
||||
// Set static IP, Gateway, Subnetmask, Use auto DNS1 and DNS2.
|
||||
WiFi.config(stationIP, gatewayIP, netMask);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
int i = 0;
|
||||
status = wifiMulti.run();
|
||||
delay(WIFI_MULTI_1ST_CONNECT_WAITING_MS);
|
||||
|
||||
while ( ( i++ < 10 ) && ( status != WL_CONNECTED ) )
|
||||
{
|
||||
status = wifiMulti.run();
|
||||
|
||||
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"));
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
// put your setup code here, to run once:
|
||||
// initialize the LED digital pin as an output.
|
||||
pinMode(PIN_LED, OUTPUT);
|
||||
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
|
||||
Serial.print("\nStarting ConfigOnDoubleReset with DoubleResetDetect using " + String(FS_Name));
|
||||
Serial.println(" on " + String(ARDUINO_BOARD));
|
||||
|
||||
Serial.setDebugOutput(false);
|
||||
|
||||
if (FORMAT_FILESYSTEM)
|
||||
FileFS.format();
|
||||
|
||||
// Format FileFS if not yet
|
||||
#ifdef ESP32
|
||||
if (!FileFS.begin(true))
|
||||
#else
|
||||
if (!FileFS.begin())
|
||||
#endif
|
||||
{
|
||||
Serial.print(FS_Name);
|
||||
Serial.println(F(" failed! AutoFormatting."));
|
||||
|
||||
#ifdef ESP8266
|
||||
FileFS.format();
|
||||
#endif
|
||||
}
|
||||
|
||||
drd = new DoubleResetDetector(DRD_TIMEOUT, DRD_ADDRESS);
|
||||
|
||||
unsigned long startedAt = millis();
|
||||
|
||||
//Local intialization. Once its business is done, there is no need to keep it around
|
||||
// Use this to default DHCP hostname to ESP8266-XXXXXX or ESP32-XXXXXX
|
||||
//ESP_WiFiManager ESP_wifiManager;
|
||||
// Use this to personalize DHCP hostname (RFC952 conformed)
|
||||
ESP_WiFiManager ESP_wifiManager("ConfigOnDoubleReset");
|
||||
|
||||
//set custom ip for portal
|
||||
//ESP_wifiManager.setAPStaticIPConfig(IPAddress(192, 168, 100, 1), IPAddress(192, 168, 100, 1), IPAddress(255, 255, 255, 0));
|
||||
|
||||
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_DHCP_IP
|
||||
#if USE_CONFIGURABLE_DNS
|
||||
// Set static IP, Gateway, Subnetmask, DNS1 and DNS2. New in v1.0.5
|
||||
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
|
||||
|
||||
// New from v1.1.1
|
||||
#if USING_CORS_FEATURE
|
||||
ESP_wifiManager.setCORSHeader("Your Access-Control-Allow-Origin");
|
||||
#endif
|
||||
|
||||
// We can't use WiFi.SSID() in ESP32 as it's only valid after connected.
|
||||
// SSID and Password stored in ESP32 wifi_ap_record_t and wifi_config_t are also cleared in reboot
|
||||
// Have to create a new function to store in EEPROM/SPIFFS for this purpose
|
||||
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("Stored: SSID = " + Router_SSID + ", Pass = " + Router_Pass);
|
||||
|
||||
// SSID to uppercase
|
||||
ssid.toUpperCase();
|
||||
|
||||
// From v1.1.0, Don't permit NULL password
|
||||
if ( (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("Got stored Credentials. Timeout 120s for Config Portal");
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println("Open Config Portal without Timeout: No stored Credentials.");
|
||||
initialConfig = true;
|
||||
}
|
||||
|
||||
if (drd->detectDoubleReset())
|
||||
{
|
||||
// DRD, disable timeout.
|
||||
ESP_wifiManager.setConfigPortalTimeout(0);
|
||||
|
||||
Serial.println("Open Config Portal without Timeout: Double Reset Detected");
|
||||
initialConfig = true;
|
||||
}
|
||||
|
||||
if (initialConfig)
|
||||
{
|
||||
Serial.println("Starting configuration portal.");
|
||||
digitalWrite(PIN_LED, LED_ON); // turn the LED on by making the voltage LOW to tell us we are in configuration mode.
|
||||
|
||||
//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(600);
|
||||
|
||||
// Starts an access point
|
||||
if (!ESP_wifiManager.startConfigPortal((const char *) ssid.c_str(), password))
|
||||
Serial.println("Not connected to WiFi but continuing anyway.");
|
||||
else
|
||||
{
|
||||
Serial.println("WiFi connected...yeey :)");
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
saveConfigData();
|
||||
}
|
||||
|
||||
digitalWrite(PIN_LED, LED_OFF); // Turn led off as we are not in configuration mode.
|
||||
|
||||
startedAt = millis();
|
||||
|
||||
if (!initialConfig)
|
||||
{
|
||||
// Load stored data, the addAP ready for MultiWiFi reconnection
|
||||
loadConfigData();
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
if ( WiFi.status() != WL_CONNECTED )
|
||||
{
|
||||
Serial.println("ConnectMultiWiFi in setup");
|
||||
|
||||
connectMultiWiFi();
|
||||
}
|
||||
}
|
||||
|
||||
Serial.print("After waiting ");
|
||||
Serial.print((float) (millis() - startedAt) / 1000L);
|
||||
Serial.print(" secs more in setup(), connection result is ");
|
||||
|
||||
if (WiFi.status() == WL_CONNECTED)
|
||||
{
|
||||
Serial.print("connected. Local IP: ");
|
||||
Serial.println(WiFi.localIP());
|
||||
}
|
||||
else
|
||||
Serial.println(ESP_wifiManager.getStatus(WiFi.status()));
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// 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.
|
||||
drd->loop();
|
||||
|
||||
// put your main code here, to run repeatedly
|
||||
check_status();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,598 @@
|
||||
/****************************************************************************************************************************
|
||||
ConfigOnStartup.ino
|
||||
For ESP8266 / ESP32 boards
|
||||
|
||||
ESP_WiFiManager is a library for the ESP8266/ESP32 platform (https://github.com/esp8266/Arduino) to enable easy
|
||||
configuration and reconfiguration of WiFi credentials using a Captive Portal. Inspired by:
|
||||
http://www.esp8266.com/viewtopic.php?f=29&t=2520
|
||||
https://github.com/chriscook8/esp-arduino-apboot
|
||||
https://github.com/esp8266/Arduino/blob/master/libraries/DNSServer/examples/CaptivePortalAdvanced/
|
||||
|
||||
Modified from Tzapu https://github.com/tzapu/WiFiManager
|
||||
and from Ken Taylor https://github.com/kentaylor
|
||||
|
||||
Built by Khoi Hoang https://github.com/khoih-prog/ESP_WiFiManager
|
||||
Licensed under MIT license
|
||||
Version: 1.2.0
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 07/10/2019 Initial coding
|
||||
1.0.1 K Hoang 13/12/2019 Fix bug. Add features. Add support for ESP32
|
||||
1.0.2 K Hoang 19/12/2019 Fix bug thatkeeps ConfigPortal in endless loop if Portal/Router SSID or Password is NULL.
|
||||
1.0.3 K Hoang 05/01/2020 Option not displaying AvailablePages in Info page. Enhance README.md. Modify examples
|
||||
1.0.4 K Hoang 07/01/2020 Add RFC952 setHostname feature.
|
||||
1.0.5 K Hoang 15/01/2020 Add configurable DNS feature. Thanks to @Amorphous of https://community.blynk.cc
|
||||
1.0.6 K Hoang 03/02/2020 Add support for ArduinoJson version 6.0.0+ ( tested with v6.14.1 )
|
||||
1.0.7 K Hoang 13/04/2020 Reduce start time, fix SPIFFS bug in examples, update README.md
|
||||
1.0.8 K Hoang 10/06/2020 Fix STAstaticIP issue. Restructure code. Add LittleFS support for ESP8266 core 2.7.1+
|
||||
1.0.9 K Hoang 29/07/2020 Fix ESP32 STAstaticIP bug. Permit changing from DHCP <-> static IP using Config Portal.
|
||||
Add, enhance examples (fix MDNS for ESP32)
|
||||
1.0.10 K Hoang 08/08/2020 Add more features to Config Portal. Use random WiFi AP channel to avoid conflict.
|
||||
1.0.11 K Hoang 17/08/2020 Add CORS feature. Fix bug in softAP, autoConnect, resetSettings.
|
||||
1.1.0 K Hoang 28/08/2020 Add MultiWiFi feature to autoconnect to best WiFi at runtime
|
||||
1.1.1 K Hoang 30/08/2020 Add setCORSHeader function to allow flexible CORS. Fix typo and minor improvement.
|
||||
1.1.2 K Hoang 17/08/2020 Fix bug. Add example.
|
||||
1.2.0 K Hoang 09/10/2020 Restore cpp code besides Impl.h code to use if linker error. Fix bug.
|
||||
*****************************************************************************************************************************/
|
||||
/****************************************************************************************************************************
|
||||
This example will open a configuration portal for 60 seconds when first powered up if the boards has stored WiFi Credentials.
|
||||
Otherwise, it'll stay indefinitely in ConfigPortal until getting WiFi Credentials and connecting to WiFi
|
||||
|
||||
ConfigOnSwitch is a a bettter example for most situations but this has the advantage
|
||||
that no pins or buttons are required on the ESP32/ESP8266 device at the cost of delaying
|
||||
the user sketch for the period that the configuration portal is open.
|
||||
|
||||
Also in this example a password is required to connect to the configuration portal
|
||||
network. This is inconvenient but means that only those who know the password or those
|
||||
already connected to the target WiFi network can access the configuration portal and
|
||||
the WiFi network credentials will be sent from the browser over an encrypted connection and
|
||||
can not be read by observers.
|
||||
*****************************************************************************************************************************/
|
||||
|
||||
#if !( defined(ESP8266) || defined(ESP32) )
|
||||
#error This code is intended to run only on the ESP8266 and ESP32 boards ! Please check your Tools->Board setting.
|
||||
#endif
|
||||
|
||||
// Use from 0 to 4. Higher number, more debugging messages and memory usage.
|
||||
#define _WIFIMGR_LOGLEVEL_ 3
|
||||
|
||||
//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;
|
||||
|
||||
#define USE_SPIFFS true
|
||||
|
||||
#if USE_SPIFFS
|
||||
#include <SPIFFS.h>
|
||||
FS* filesystem = &SPIFFS;
|
||||
#define FileFS SPIFFS
|
||||
#define FS_Name "SPIFFS"
|
||||
#else
|
||||
// Use FFat
|
||||
#include <FFat.h>
|
||||
FS* filesystem = &FFat;
|
||||
#define FileFS FFat
|
||||
#define FS_Name "FFat"
|
||||
#endif
|
||||
//////
|
||||
|
||||
#define ESP_getChipId() ((uint32_t)ESP.getEfuseMac())
|
||||
|
||||
#define LED_BUILTIN 2
|
||||
#define LED_ON HIGH
|
||||
#define LED_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;
|
||||
|
||||
#define USE_LITTLEFS true
|
||||
|
||||
#if USE_LITTLEFS
|
||||
#include <LittleFS.h>
|
||||
FS* filesystem = &LittleFS;
|
||||
#define FileFS LittleFS
|
||||
#define FS_Name "LittleFS"
|
||||
#else
|
||||
FS* filesystem = &SPIFFS;
|
||||
#define FileFS SPIFFS
|
||||
#define FS_Name "SPIFFS"
|
||||
#endif
|
||||
//////
|
||||
|
||||
#define ESP_getChipId() (ESP.getChipId())
|
||||
|
||||
#define LED_ON LOW
|
||||
#define LED_OFF HIGH
|
||||
#endif
|
||||
|
||||
// SSID and PW for Config Portal
|
||||
String ssid = "ESP_" + String(ESP_getChipId(), HEX);
|
||||
const char* password = "your_password";
|
||||
|
||||
// SSID and PW for your Router
|
||||
String Router_SSID;
|
||||
String Router_Pass;
|
||||
|
||||
// From v1.1.0
|
||||
// You only need to format the filesystem once
|
||||
//#define FORMAT_FILESYSTEM true
|
||||
#define FORMAT_FILESYSTEM false
|
||||
|
||||
#define MIN_AP_PASSWORD_SIZE 8
|
||||
|
||||
#define SSID_MAX_LEN 32
|
||||
//From v1.0.10, WPA2 passwords can be up to 63 characters long.
|
||||
#define PASS_MAX_LEN 64
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char wifi_ssid[SSID_MAX_LEN];
|
||||
char wifi_pw [PASS_MAX_LEN];
|
||||
} WiFi_Credentials;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
String wifi_ssid;
|
||||
String wifi_pw;
|
||||
} WiFi_Credentials_String;
|
||||
|
||||
#define NUM_WIFI_CREDENTIALS 2
|
||||
|
||||
typedef struct
|
||||
{
|
||||
WiFi_Credentials WiFi_Creds [NUM_WIFI_CREDENTIALS];
|
||||
} WM_Config;
|
||||
|
||||
WM_Config WM_config;
|
||||
|
||||
#define CONFIG_FILENAME F("/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 <ESP_WiFiManager.h>
|
||||
#define USE_AVAILABLE_PAGES false
|
||||
|
||||
// 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)
|
||||
#define USE_ESP_WIFIMANAGER_NTP false
|
||||
|
||||
// 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)
|
||||
#define USE_CLOUDFLARE_NTP false
|
||||
|
||||
// New in v1.0.11
|
||||
#define USING_CORS_FEATURE true
|
||||
//////
|
||||
|
||||
// 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
|
||||
#define USE_DHCP_IP true
|
||||
#else
|
||||
// You can select DHCP or Static IP here
|
||||
//#define USE_DHCP_IP true
|
||||
#define USE_DHCP_IP false
|
||||
#endif
|
||||
|
||||
// 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
|
||||
#define USE_DHCP_IP true
|
||||
#else
|
||||
// You can select DHCP or Static IP here
|
||||
//#define USE_DHCP_IP true
|
||||
#define USE_DHCP_IP false
|
||||
#endif
|
||||
|
||||
#if ( USE_DHCP_IP || ( defined(USE_STATIC_IP_CONFIG_IN_CP) && !USE_STATIC_IP_CONFIG_IN_CP ) )
|
||||
// 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
|
||||
|
||||
#define USE_CONFIGURABLE_DNS true
|
||||
|
||||
IPAddress dns1IP = gatewayIP;
|
||||
IPAddress dns2IP = IPAddress(8, 8, 8, 8);
|
||||
|
||||
#include <ESP_WiFiManager.h> //https://github.com/khoih-prog/ESP_WiFiManager
|
||||
|
||||
// Onboard LED I/O pin on NodeMCU board
|
||||
const int PIN_LED = 2; // D4 on NodeMCU and WeMos. GPIO2/ADC12 of ESP32. Controls the onboard LED.
|
||||
|
||||
// Function Prototypes
|
||||
uint8_t connectMultiWiFi(void);
|
||||
|
||||
void heartBeatPrint(void)
|
||||
{
|
||||
static int num = 1;
|
||||
|
||||
if (WiFi.status() == WL_CONNECTED)
|
||||
Serial.print("H"); // H means connected to WiFi
|
||||
else
|
||||
Serial.print("F"); // F means not connected to WiFi
|
||||
|
||||
if (num == 80)
|
||||
{
|
||||
Serial.println();
|
||||
num = 1;
|
||||
}
|
||||
else if (num++ % 10 == 0)
|
||||
{
|
||||
Serial.print(" ");
|
||||
}
|
||||
}
|
||||
|
||||
void check_WiFi(void)
|
||||
{
|
||||
if ( (WiFi.status() != WL_CONNECTED) )
|
||||
{
|
||||
Serial.println("\nWiFi lost. Call connectMultiWiFi in loop");
|
||||
connectMultiWiFi();
|
||||
}
|
||||
}
|
||||
|
||||
void check_status(void)
|
||||
{
|
||||
static ulong checkstatus_timeout = 0;
|
||||
static ulong checkwifi_timeout = 0;
|
||||
|
||||
static ulong current_millis;
|
||||
|
||||
#define WIFICHECK_INTERVAL 1000L
|
||||
#define HEARTBEAT_INTERVAL 10000L
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// Print hearbeat every HEARTBEAT_INTERVAL (10) seconds.
|
||||
if ((current_millis > checkstatus_timeout) || (checkstatus_timeout == 0))
|
||||
{
|
||||
heartBeatPrint();
|
||||
checkstatus_timeout = current_millis + HEARTBEAT_INTERVAL;
|
||||
}
|
||||
}
|
||||
|
||||
void loadConfigData(void)
|
||||
{
|
||||
File file = FileFS.open(CONFIG_FILENAME, "r");
|
||||
LOGERROR(F("LoadWiFiCfgFile "));
|
||||
|
||||
if (file)
|
||||
{
|
||||
file.readBytes((char *) &WM_config, sizeof(WM_config));
|
||||
file.close();
|
||||
LOGERROR(F("OK"));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGERROR(F("failed"));
|
||||
}
|
||||
}
|
||||
|
||||
void saveConfigData(void)
|
||||
{
|
||||
File file = FileFS.open(CONFIG_FILENAME, "w");
|
||||
LOGERROR(F("SaveWiFiCfgFile "));
|
||||
|
||||
if (file)
|
||||
{
|
||||
file.write((uint8_t*) &WM_config, sizeof(WM_config));
|
||||
file.close();
|
||||
LOGERROR(F("OK"));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGERROR(F("failed"));
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t connectMultiWiFi(void)
|
||||
{
|
||||
#if ESP32
|
||||
// For ESP32, this better be 0 to shorten the connect time
|
||||
#define WIFI_MULTI_1ST_CONNECT_WAITING_MS 0
|
||||
#else
|
||||
// For ESP8266, this better be 2200 to enable connect the 1st time
|
||||
#define WIFI_MULTI_1ST_CONNECT_WAITING_MS 2200L
|
||||
#endif
|
||||
|
||||
#define WIFI_MULTI_CONNECT_WAITING_MS 100L
|
||||
|
||||
uint8_t status;
|
||||
|
||||
LOGERROR(F("ConnectMultiWiFi with :"));
|
||||
|
||||
if ( (Router_SSID != "") && (Router_Pass != "") )
|
||||
{
|
||||
LOGERROR3(F("* Flash-stored Router_SSID = "), Router_SSID, F(", Router_Pass = "), Router_Pass );
|
||||
}
|
||||
|
||||
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
|
||||
#if USE_CONFIGURABLE_DNS
|
||||
// Set static IP, Gateway, Subnetmask, DNS1 and DNS2. New in v1.0.5
|
||||
WiFi.config(stationIP, gatewayIP, netMask, dns1IP, dns2IP);
|
||||
#else
|
||||
// Set static IP, Gateway, Subnetmask, Use auto DNS1 and DNS2.
|
||||
WiFi.config(stationIP, gatewayIP, netMask);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
int i = 0;
|
||||
status = wifiMulti.run();
|
||||
delay(WIFI_MULTI_1ST_CONNECT_WAITING_MS);
|
||||
|
||||
while ( ( i++ < 10 ) && ( status != WL_CONNECTED ) )
|
||||
{
|
||||
status = wifiMulti.run();
|
||||
|
||||
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"));
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
// put your setup code here, to run once:
|
||||
// initialize the LED digital pin as an output.
|
||||
pinMode(PIN_LED, OUTPUT);
|
||||
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
|
||||
Serial.print("\nStarting ConfigOnStartup with DoubleResetDetect using " + String(FS_Name));
|
||||
Serial.println(" on " + String(ARDUINO_BOARD));
|
||||
|
||||
Serial.setDebugOutput(false);
|
||||
|
||||
if (FORMAT_FILESYSTEM)
|
||||
FileFS.format();
|
||||
|
||||
// Format FileFS if not yet
|
||||
#ifdef ESP32
|
||||
if (!FileFS.begin(true))
|
||||
#else
|
||||
if (!FileFS.begin())
|
||||
#endif
|
||||
{
|
||||
Serial.print(FS_Name);
|
||||
Serial.println(F(" failed! AutoFormatting."));
|
||||
|
||||
#ifdef ESP8266
|
||||
FileFS.format();
|
||||
#endif
|
||||
}
|
||||
|
||||
digitalWrite(PIN_LED, LED_ON); // turn the LED on by making the voltage LOW to tell us we are in configuration mode.
|
||||
|
||||
unsigned long startedAt = millis();
|
||||
|
||||
//Local intialization. Once its business is done, there is no need to keep it around
|
||||
// Use this to default DHCP hostname to ESP8266-XXXXXX or ESP32-XXXXXX
|
||||
ESP_WiFiManager ESP_wifiManager;
|
||||
// Use this to personalize DHCP hostname (RFC952 conformed)
|
||||
//ESP_WiFiManager ESP_wifiManager("ConfigOnStartup");
|
||||
|
||||
//set custom ip for portal
|
||||
//ESP_wifiManager.setAPStaticIPConfig(IPAddress(192, 168, 100, 1), IPAddress(192, 168, 100, 1), IPAddress(255, 255, 255, 0));
|
||||
|
||||
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_DHCP_IP
|
||||
#if USE_CONFIGURABLE_DNS
|
||||
// Set static IP, Gateway, Subnetmask, DNS1 and DNS2. New in v1.0.5
|
||||
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
|
||||
|
||||
// New from v1.1.1
|
||||
#if USING_CORS_FEATURE
|
||||
ESP_wifiManager.setCORSHeader("Your Access-Control-Allow-Origin");
|
||||
#endif
|
||||
|
||||
// We can't use WiFi.SSID() in ESP32 as it's only valid after connected.
|
||||
// SSID and Password stored in ESP32 wifi_ap_record_t and wifi_config_t are also cleared in reboot
|
||||
// Have to create a new function to store in EEPROM/SPIFFS for this purpose
|
||||
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("Stored: SSID = " + Router_SSID + ", Pass = " + Router_Pass);
|
||||
|
||||
//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("Opening configuration portal.");
|
||||
|
||||
// From v1.1.0, Don't permit NULL password
|
||||
if ( (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("Got stored Credentials. Timeout 120s for Config Portal");
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println("Open Config Portal without Timeout: No stored Credentials.");
|
||||
initialConfig = true;
|
||||
}
|
||||
|
||||
// SSID to uppercase
|
||||
ssid.toUpperCase();
|
||||
|
||||
Serial.println("Starting configuration portal.");
|
||||
digitalWrite(PIN_LED, LED_ON); // turn the LED on by making the voltage LOW to tell us we are in configuration mode.
|
||||
|
||||
// Starts an access point
|
||||
if (!ESP_wifiManager.startConfigPortal((const char *) ssid.c_str(), password))
|
||||
Serial.println("Not connected to WiFi but continuing anyway.");
|
||||
else
|
||||
{
|
||||
Serial.println("WiFi connected...yeey :)");
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
saveConfigData();
|
||||
|
||||
initialConfig = true;
|
||||
}
|
||||
|
||||
digitalWrite(PIN_LED, LED_OFF); // Turn led off as we are not in configuration mode.
|
||||
|
||||
startedAt = millis();
|
||||
|
||||
if (!initialConfig)
|
||||
{
|
||||
// Load stored data, the addAP ready for MultiWiFi reconnection
|
||||
loadConfigData();
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
if ( WiFi.status() != WL_CONNECTED )
|
||||
{
|
||||
Serial.println("ConnectMultiWiFi in setup");
|
||||
|
||||
connectMultiWiFi();
|
||||
}
|
||||
}
|
||||
|
||||
Serial.print("After waiting ");
|
||||
Serial.print((float) (millis() - startedAt) / 1000L);
|
||||
Serial.print(" secs more in setup(), connection result is ");
|
||||
|
||||
if (WiFi.status() == WL_CONNECTED)
|
||||
{
|
||||
Serial.print("connected. Local IP: ");
|
||||
Serial.println(WiFi.localIP());
|
||||
}
|
||||
else
|
||||
Serial.println(ESP_wifiManager.getStatus(WiFi.status()));
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// put your main code here, to run repeatedly
|
||||
check_status();
|
||||
}
|
||||
@@ -0,0 +1,799 @@
|
||||
/****************************************************************************************************************************
|
||||
ConfigOnSwitch.ino
|
||||
For ESP8266 / ESP32 boards
|
||||
|
||||
ESP_WiFiManager is a library for the ESP8266/ESP32 platform (https://github.com/esp8266/Arduino) to enable easy
|
||||
configuration and reconfiguration of WiFi credentials using a Captive Portal. Inspired by:
|
||||
http://www.esp8266.com/viewtopic.php?f=29&t=2520
|
||||
https://github.com/chriscook8/esp-arduino-apboot
|
||||
https://github.com/esp8266/Arduino/blob/master/libraries/DNSServer/examples/CaptivePortalAdvanced/
|
||||
|
||||
Modified from Tzapu https://github.com/tzapu/WiFiManager
|
||||
and from Ken Taylor https://github.com/kentaylor
|
||||
|
||||
Built by Khoi Hoang https://github.com/khoih-prog/ESP_WiFiManager
|
||||
Licensed under MIT license
|
||||
Version: 1.2.0
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 07/10/2019 Initial coding
|
||||
1.0.1 K Hoang 13/12/2019 Fix bug. Add features. Add support for ESP32
|
||||
1.0.2 K Hoang 19/12/2019 Fix bug thatkeeps ConfigPortal in endless loop if Portal/Router SSID or Password is NULL.
|
||||
1.0.3 K Hoang 05/01/2020 Option not displaying AvailablePages in Info page. Enhance README.md. Modify examples
|
||||
1.0.4 K Hoang 07/01/2020 Add RFC952 setHostname feature.
|
||||
1.0.5 K Hoang 15/01/2020 Add configurable DNS feature. Thanks to @Amorphous of https://community.blynk.cc
|
||||
1.0.6 K Hoang 03/02/2020 Add support for ArduinoJson version 6.0.0+ ( tested with v6.14.1 )
|
||||
1.0.7 K Hoang 13/04/2020 Reduce start time, fix SPIFFS bug in examples, update README.md
|
||||
1.0.8 K Hoang 10/06/2020 Fix STAstaticIP issue. Restructure code. Add LittleFS support for ESP8266 core 2.7.1+
|
||||
1.0.9 K Hoang 29/07/2020 Fix ESP32 STAstaticIP bug. Permit changing from DHCP <-> static IP using Config Portal.
|
||||
Add, enhance examples (fix MDNS for ESP32)
|
||||
1.0.10 K Hoang 08/08/2020 Add more features to Config Portal. Use random WiFi AP channel to avoid conflict.
|
||||
1.0.11 K Hoang 17/08/2020 Add CORS feature. Fix bug in softAP, autoConnect, resetSettings.
|
||||
1.1.0 K Hoang 28/08/2020 Add MultiWiFi feature to autoconnect to best WiFi at runtime
|
||||
1.1.1 K Hoang 30/08/2020 Add setCORSHeader function to allow flexible CORS. Fix typo and minor improvement.
|
||||
1.1.2 K Hoang 17/08/2020 Fix bug. Add example.
|
||||
1.2.0 K Hoang 09/10/2020 Restore cpp code besides Impl.h code to use if linker error. Fix bug.
|
||||
*****************************************************************************************************************************/
|
||||
/****************************************************************************************************************************
|
||||
This example will open a configuration portal when no WiFi configuration has been previously entered or when a button is pushed.
|
||||
It is the easiest scenario for configuration but requires a pin and a button on the ESP8266 device.
|
||||
The Flash button is convenient for this on NodeMCU devices.
|
||||
|
||||
Also in this example a password is required to connect to the configuration portal
|
||||
network. This is inconvenient but means that only those who know the password or those
|
||||
already connected to the target WiFi network can access the configuration portal and
|
||||
the WiFi network credentials will be sent from the browser over an encrypted connection and
|
||||
can not be read by observers.
|
||||
*****************************************************************************************************************************/
|
||||
|
||||
#if !( defined(ESP8266) || defined(ESP32) )
|
||||
#error This code is intended to run only on the ESP8266 and ESP32 boards ! Please check your Tools->Board setting.
|
||||
#endif
|
||||
|
||||
// Use from 0 to 4. Higher number, more debugging messages and memory usage.
|
||||
#define _WIFIMGR_LOGLEVEL_ 3
|
||||
|
||||
//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;
|
||||
|
||||
#define USE_SPIFFS true
|
||||
|
||||
#if USE_SPIFFS
|
||||
#include <SPIFFS.h>
|
||||
FS* filesystem = &SPIFFS;
|
||||
#define FileFS SPIFFS
|
||||
#define FS_Name "SPIFFS"
|
||||
#else
|
||||
// Use FFat
|
||||
#include <FFat.h>
|
||||
FS* filesystem = &FFat;
|
||||
#define FileFS FFat
|
||||
#define FS_Name "FFat"
|
||||
#endif
|
||||
//////
|
||||
|
||||
#define ESP_getChipId() ((uint32_t)ESP.getEfuseMac())
|
||||
|
||||
#define LED_BUILTIN 2
|
||||
#define LED_ON HIGH
|
||||
#define LED_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;
|
||||
|
||||
#define USE_LITTLEFS true
|
||||
|
||||
#if USE_LITTLEFS
|
||||
#include <LittleFS.h>
|
||||
FS* filesystem = &LittleFS;
|
||||
#define FileFS LittleFS
|
||||
#define FS_Name "LittleFS"
|
||||
#else
|
||||
FS* filesystem = &SPIFFS;
|
||||
#define FileFS SPIFFS
|
||||
#define FS_Name "SPIFFS"
|
||||
#endif
|
||||
//////
|
||||
|
||||
#define ESP_getChipId() (ESP.getChipId())
|
||||
|
||||
#define LED_ON LOW
|
||||
#define LED_OFF HIGH
|
||||
#endif
|
||||
|
||||
#ifdef ESP32
|
||||
|
||||
//See file .../hardware/espressif/esp32/variants/(esp32|doitESP32devkitV1)/pins_arduino.h
|
||||
#define LED_BUILTIN 2 // Pin D2 mapped to pin GPIO2/ADC12 of ESP32, control on-board LED
|
||||
#define PIN_LED 2 // Pin D2 mapped to pin GPIO2/ADC12 of ESP32, control on-board LED
|
||||
|
||||
#define PIN_D0 0 // Pin D0 mapped to pin GPIO0/BOOT/ADC11/TOUCH1 of ESP32
|
||||
#define PIN_D1 1 // Pin D1 mapped to pin GPIO1/TX0 of ESP32
|
||||
#define PIN_D2 2 // Pin D2 mapped to pin GPIO2/ADC12/TOUCH2 of ESP32
|
||||
#define PIN_D3 3 // Pin D3 mapped to pin GPIO3/RX0 of ESP32
|
||||
#define PIN_D4 4 // Pin D4 mapped to pin GPIO4/ADC10/TOUCH0 of ESP32
|
||||
#define PIN_D5 5 // Pin D5 mapped to pin GPIO5/SPISS/VSPI_SS of ESP32
|
||||
#define PIN_D6 6 // Pin D6 mapped to pin GPIO6/FLASH_SCK of ESP32
|
||||
#define PIN_D7 7 // Pin D7 mapped to pin GPIO7/FLASH_D0 of ESP32
|
||||
#define PIN_D8 8 // Pin D8 mapped to pin GPIO8/FLASH_D1 of ESP32
|
||||
#define PIN_D9 9 // Pin D9 mapped to pin GPIO9/FLASH_D2 of ESP32
|
||||
|
||||
#define PIN_D10 10 // Pin D10 mapped to pin GPIO10/FLASH_D3 of ESP32
|
||||
#define PIN_D11 11 // Pin D11 mapped to pin GPIO11/FLASH_CMD of ESP32
|
||||
#define PIN_D12 12 // Pin D12 mapped to pin GPIO12/HSPI_MISO/ADC15/TOUCH5/TDI of ESP32
|
||||
#define PIN_D13 13 // Pin D13 mapped to pin GPIO13/HSPI_MOSI/ADC14/TOUCH4/TCK of ESP32
|
||||
#define PIN_D14 14 // Pin D14 mapped to pin GPIO14/HSPI_SCK/ADC16/TOUCH6/TMS of ESP32
|
||||
#define PIN_D15 15 // Pin D15 mapped to pin GPIO15/HSPI_SS/ADC13/TOUCH3/TDO of ESP32
|
||||
#define PIN_D16 16 // Pin D16 mapped to pin GPIO16/TX2 of ESP32
|
||||
#define PIN_D17 17 // Pin D17 mapped to pin GPIO17/RX2 of ESP32
|
||||
#define PIN_D18 18 // Pin D18 mapped to pin GPIO18/VSPI_SCK of ESP32
|
||||
#define PIN_D19 19 // Pin D19 mapped to pin GPIO19/VSPI_MISO of ESP32
|
||||
|
||||
#define PIN_D21 21 // Pin D21 mapped to pin GPIO21/SDA of ESP32
|
||||
#define PIN_D22 22 // Pin D22 mapped to pin GPIO22/SCL of ESP32
|
||||
#define PIN_D23 23 // Pin D23 mapped to pin GPIO23/VSPI_MOSI of ESP32
|
||||
#define PIN_D24 24 // Pin D24 mapped to pin GPIO24 of ESP32
|
||||
#define PIN_D25 25 // Pin D25 mapped to pin GPIO25/ADC18/DAC1 of ESP32
|
||||
#define PIN_D26 26 // Pin D26 mapped to pin GPIO26/ADC19/DAC2 of ESP32
|
||||
#define PIN_D27 27 // Pin D27 mapped to pin GPIO27/ADC17/TOUCH7 of ESP32
|
||||
|
||||
#define PIN_D32 32 // Pin D32 mapped to pin GPIO32/ADC4/TOUCH9 of ESP32
|
||||
#define PIN_D33 33 // Pin D33 mapped to pin GPIO33/ADC5/TOUCH8 of ESP32
|
||||
#define PIN_D34 34 // Pin D34 mapped to pin GPIO34/ADC6 of ESP32
|
||||
|
||||
//Only GPIO pin < 34 can be used as output. Pins >= 34 can be only inputs
|
||||
//See .../cores/esp32/esp32-hal-gpio.h/c
|
||||
//#define digitalPinIsValid(pin) ((pin) < 40 && esp32_gpioMux[(pin)].reg)
|
||||
//#define digitalPinCanOutput(pin) ((pin) < 34 && esp32_gpioMux[(pin)].reg)
|
||||
//#define digitalPinToRtcPin(pin) (((pin) < 40)?esp32_gpioMux[(pin)].rtc:-1)
|
||||
//#define digitalPinToAnalogChannel(pin) (((pin) < 40)?esp32_gpioMux[(pin)].adc:-1)
|
||||
//#define digitalPinToTouchChannel(pin) (((pin) < 40)?esp32_gpioMux[(pin)].touch:-1)
|
||||
//#define digitalPinToDacChannel(pin) (((pin) == 25)?0:((pin) == 26)?1:-1)
|
||||
|
||||
#define PIN_D35 35 // Pin D35 mapped to pin GPIO35/ADC7 of ESP32
|
||||
#define PIN_D36 36 // Pin D36 mapped to pin GPIO36/ADC0/SVP of ESP32
|
||||
#define PIN_D39 39 // Pin D39 mapped to pin GPIO39/ADC3/SVN of ESP32
|
||||
|
||||
#define PIN_RX0 3 // Pin RX0 mapped to pin GPIO3/RX0 of ESP32
|
||||
#define PIN_TX0 1 // Pin TX0 mapped to pin GPIO1/TX0 of ESP32
|
||||
|
||||
#define PIN_SCL 22 // Pin SCL mapped to pin GPIO22/SCL of ESP32
|
||||
#define PIN_SDA 21 // Pin SDA mapped to pin GPIO21/SDA of ESP32
|
||||
#else
|
||||
//PIN_D0 can't be used for PWM/I2C
|
||||
#define PIN_D0 16 // Pin D0 mapped to pin GPIO16/USER/WAKE of ESP8266. This pin is also used for Onboard-Blue LED. PIN_D0 = 0 => LED ON
|
||||
#define PIN_D1 5 // Pin D1 mapped to pin GPIO5 of ESP8266
|
||||
#define PIN_D2 4 // Pin D2 mapped to pin GPIO4 of ESP8266
|
||||
#define PIN_D3 0 // Pin D3 mapped to pin GPIO0/FLASH of ESP8266
|
||||
#define PIN_D4 2 // Pin D4 mapped to pin GPIO2/TXD1 of ESP8266
|
||||
#define PIN_LED 2 // Pin D4 mapped to pin GPIO2/TXD1 of ESP8266, NodeMCU and WeMoS, control on-board LED
|
||||
#define PIN_D5 14 // Pin D5 mapped to pin GPIO14/HSCLK of ESP8266
|
||||
#define PIN_D6 12 // Pin D6 mapped to pin GPIO12/HMISO of ESP8266
|
||||
#define PIN_D7 13 // Pin D7 mapped to pin GPIO13/RXD2/HMOSI of ESP8266
|
||||
#define PIN_D8 15 // Pin D8 mapped to pin GPIO15/TXD2/HCS of ESP8266
|
||||
|
||||
//Don't use pins GPIO6 to GPIO11 as already connected to flash, etc. Use them can crash the program
|
||||
//GPIO9(D11/SD2) and GPIO11 can be used only if flash in DIO mode ( not the default QIO mode)
|
||||
#define PIN_D11 9 // Pin D11/SD2 mapped to pin GPIO9/SDD2 of ESP8266
|
||||
#define PIN_D12 10 // Pin D12/SD3 mapped to pin GPIO10/SDD3 of ESP8266
|
||||
#define PIN_SD2 9 // Pin SD2 mapped to pin GPIO9/SDD2 of ESP8266
|
||||
#define PIN_SD3 10 // Pin SD3 mapped to pin GPIO10/SDD3 of ESP8266
|
||||
|
||||
#define PIN_D9 3 // Pin D9 /RX mapped to pin GPIO3/RXD0 of ESP8266
|
||||
#define PIN_D10 1 // Pin D10/TX mapped to pin GPIO1/TXD0 of ESP8266
|
||||
#define PIN_RX 3 // Pin RX mapped to pin GPIO3/RXD0 of ESP8266
|
||||
#define PIN_TX 1 // Pin RX mapped to pin GPIO1/TXD0 of ESP8266
|
||||
|
||||
#define LED_PIN 16 // Pin D0 mapped to pin GPIO16 of ESP8266. This pin is also used for Onboard-Blue LED. PIN_D0 = 0 => LED ON
|
||||
|
||||
#endif //USE_ESP32
|
||||
|
||||
#ifdef ESP32
|
||||
/* Trigger for inititating config mode is Pin D3 and also flash button on NodeMCU
|
||||
Flash button is convenient to use but if it is pressed it will stuff up the serial port device driver
|
||||
until the computer is rebooted on windows machines.
|
||||
*/
|
||||
const int TRIGGER_PIN = PIN_D0; // Pin D0 mapped to pin GPIO0/BOOT/ADC11/TOUCH1 of ESP32
|
||||
/*
|
||||
Alternative trigger pin. Needs to be connected to a button to use this pin. It must be a momentary connection
|
||||
not connected permanently to ground. Either trigger pin will work.
|
||||
*/
|
||||
const int TRIGGER_PIN2 = PIN_D25; // Pin D25 mapped to pin GPIO25/ADC18/DAC1 of ESP32
|
||||
#else
|
||||
/* Trigger for inititating config mode is Pin D3 and also flash button on NodeMCU
|
||||
Flash button is convenient to use but if it is pressed it will stuff up the serial port device driver
|
||||
until the computer is rebooted on windows machines.
|
||||
*/
|
||||
const int TRIGGER_PIN = PIN_D3; // D3 on NodeMCU and WeMos.
|
||||
/*
|
||||
Alternative trigger pin. Needs to be connected to a button to use this pin. It must be a momentary connection
|
||||
not connected permanently to ground. Either trigger pin will work.
|
||||
*/
|
||||
const int TRIGGER_PIN2 = PIN_D7; // D7 on NodeMCU and WeMos.
|
||||
|
||||
#endif
|
||||
|
||||
// SSID and PW for Config Portal
|
||||
String ssid = "ESP_" + String(ESP_getChipId(), HEX);
|
||||
const char* password = "your_password";
|
||||
|
||||
// SSID and PW for your Router
|
||||
String Router_SSID;
|
||||
String Router_Pass;
|
||||
|
||||
// From v1.1.0
|
||||
// You only need to format the filesystem once
|
||||
//#define FORMAT_FILESYSTEM true
|
||||
#define FORMAT_FILESYSTEM false
|
||||
|
||||
#define MIN_AP_PASSWORD_SIZE 8
|
||||
|
||||
#define SSID_MAX_LEN 32
|
||||
//From v1.0.10, WPA2 passwords can be up to 63 characters long.
|
||||
#define PASS_MAX_LEN 64
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char wifi_ssid[SSID_MAX_LEN];
|
||||
char wifi_pw [PASS_MAX_LEN];
|
||||
} WiFi_Credentials;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
String wifi_ssid;
|
||||
String wifi_pw;
|
||||
} WiFi_Credentials_String;
|
||||
|
||||
#define NUM_WIFI_CREDENTIALS 2
|
||||
|
||||
typedef struct
|
||||
{
|
||||
WiFi_Credentials WiFi_Creds [NUM_WIFI_CREDENTIALS];
|
||||
} WM_Config;
|
||||
|
||||
WM_Config WM_config;
|
||||
|
||||
#define CONFIG_FILENAME F("/wifi_cred.dat")
|
||||
//////
|
||||
|
||||
// Indicates whether ESP has WiFi credentials saved from previous session
|
||||
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 <ESP_WiFiManager.h>
|
||||
#define USE_AVAILABLE_PAGES false
|
||||
|
||||
// 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)
|
||||
#define USE_ESP_WIFIMANAGER_NTP false
|
||||
|
||||
// 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)
|
||||
#define USE_CLOUDFLARE_NTP false
|
||||
|
||||
// New in v1.0.11
|
||||
#define USING_CORS_FEATURE true
|
||||
//////
|
||||
|
||||
// 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
|
||||
#define USE_DHCP_IP true
|
||||
#else
|
||||
// You can select DHCP or Static IP here
|
||||
//#define USE_DHCP_IP true
|
||||
#define USE_DHCP_IP false
|
||||
#endif
|
||||
|
||||
#if ( USE_DHCP_IP || ( defined(USE_STATIC_IP_CONFIG_IN_CP) && !USE_STATIC_IP_CONFIG_IN_CP ) )
|
||||
// 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
|
||||
|
||||
#define USE_CONFIGURABLE_DNS true
|
||||
|
||||
IPAddress dns1IP = gatewayIP;
|
||||
IPAddress dns2IP = IPAddress(8, 8, 8, 8);
|
||||
|
||||
#include <ESP_WiFiManager.h> //https://github.com/khoih-prog/ESP_WiFiManager
|
||||
|
||||
// Function Prototypes
|
||||
uint8_t connectMultiWiFi(void);
|
||||
|
||||
void heartBeatPrint(void)
|
||||
{
|
||||
static int num = 1;
|
||||
|
||||
if (WiFi.status() == WL_CONNECTED)
|
||||
Serial.print("H"); // H means connected to WiFi
|
||||
else
|
||||
Serial.print("F"); // F means not connected to WiFi
|
||||
|
||||
if (num == 80)
|
||||
{
|
||||
Serial.println();
|
||||
num = 1;
|
||||
}
|
||||
else if (num++ % 10 == 0)
|
||||
{
|
||||
Serial.print(" ");
|
||||
}
|
||||
}
|
||||
|
||||
void check_WiFi(void)
|
||||
{
|
||||
if ( (WiFi.status() != WL_CONNECTED) )
|
||||
{
|
||||
Serial.println("\nWiFi lost. Call connectMultiWiFi in loop");
|
||||
connectMultiWiFi();
|
||||
}
|
||||
}
|
||||
|
||||
void check_status(void)
|
||||
{
|
||||
static ulong checkstatus_timeout = 0;
|
||||
static ulong checkwifi_timeout = 0;
|
||||
|
||||
static ulong current_millis;
|
||||
|
||||
#define WIFICHECK_INTERVAL 1000L
|
||||
#define HEARTBEAT_INTERVAL 10000L
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// Print hearbeat every HEARTBEAT_INTERVAL (10) seconds.
|
||||
if ((current_millis > checkstatus_timeout) || (checkstatus_timeout == 0))
|
||||
{
|
||||
heartBeatPrint();
|
||||
checkstatus_timeout = current_millis + HEARTBEAT_INTERVAL;
|
||||
}
|
||||
}
|
||||
|
||||
void loadConfigData(void)
|
||||
{
|
||||
File file = FileFS.open(CONFIG_FILENAME, "r");
|
||||
LOGERROR(F("LoadWiFiCfgFile "));
|
||||
|
||||
if (file)
|
||||
{
|
||||
file.readBytes((char *) &WM_config, sizeof(WM_config));
|
||||
file.close();
|
||||
LOGERROR(F("OK"));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGERROR(F("failed"));
|
||||
}
|
||||
}
|
||||
|
||||
void saveConfigData(void)
|
||||
{
|
||||
File file = FileFS.open(CONFIG_FILENAME, "w");
|
||||
LOGERROR(F("SaveWiFiCfgFile "));
|
||||
|
||||
if (file)
|
||||
{
|
||||
file.write((uint8_t*) &WM_config, sizeof(WM_config));
|
||||
file.close();
|
||||
LOGERROR(F("OK"));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGERROR(F("failed"));
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t connectMultiWiFi(void)
|
||||
{
|
||||
#if ESP32
|
||||
// For ESP32, this better be 0 to shorten the connect time
|
||||
#define WIFI_MULTI_1ST_CONNECT_WAITING_MS 0
|
||||
#else
|
||||
// For ESP8266, this better be 2200 to enable connect the 1st time
|
||||
#define WIFI_MULTI_1ST_CONNECT_WAITING_MS 2200L
|
||||
#endif
|
||||
|
||||
#define WIFI_MULTI_CONNECT_WAITING_MS 100L
|
||||
|
||||
uint8_t status;
|
||||
|
||||
LOGERROR(F("ConnectMultiWiFi with :"));
|
||||
|
||||
if ( (Router_SSID != "") && (Router_Pass != "") )
|
||||
{
|
||||
LOGERROR3(F("* Flash-stored Router_SSID = "), Router_SSID, F(", Router_Pass = "), Router_Pass );
|
||||
}
|
||||
|
||||
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
|
||||
#if USE_CONFIGURABLE_DNS
|
||||
// Set static IP, Gateway, Subnetmask, DNS1 and DNS2. New in v1.0.5
|
||||
WiFi.config(stationIP, gatewayIP, netMask, dns1IP, dns2IP);
|
||||
#else
|
||||
// Set static IP, Gateway, Subnetmask, Use auto DNS1 and DNS2.
|
||||
WiFi.config(stationIP, gatewayIP, netMask);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
int i = 0;
|
||||
status = wifiMulti.run();
|
||||
delay(WIFI_MULTI_1ST_CONNECT_WAITING_MS);
|
||||
|
||||
while ( ( i++ < 10 ) && ( status != WL_CONNECTED ) )
|
||||
{
|
||||
status = wifiMulti.run();
|
||||
|
||||
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"));
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
// put your setup code here, to run once:
|
||||
// initialize the LED digital pin as an output.
|
||||
pinMode(PIN_LED, OUTPUT);
|
||||
pinMode(TRIGGER_PIN, INPUT_PULLUP);
|
||||
pinMode(TRIGGER_PIN2, INPUT_PULLUP);
|
||||
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
|
||||
Serial.print("\nStarting ConfigOnSwitch using " + String(FS_Name));
|
||||
Serial.println(" on " + String(ARDUINO_BOARD));
|
||||
|
||||
Serial.setDebugOutput(false);
|
||||
|
||||
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
|
||||
{
|
||||
Serial.print(FS_Name);
|
||||
Serial.println(F(" failed! AutoFormatting."));
|
||||
|
||||
#ifdef ESP8266
|
||||
FileFS.format();
|
||||
#endif
|
||||
}
|
||||
|
||||
unsigned long startedAt = millis();
|
||||
|
||||
//Local intialization. Once its business is done, there is no need to keep it around
|
||||
// Use this to default DHCP hostname to ESP8266-XXXXXX or ESP32-XXXXXX
|
||||
//ESP_WiFiManager ESP_wifiManager;
|
||||
// Use this to personalize DHCP hostname (RFC952 conformed)
|
||||
ESP_WiFiManager ESP_wifiManager("ConfigOnSwitch");
|
||||
|
||||
ESP_wifiManager.setDebugOutput(true);
|
||||
|
||||
// Use only to erase stored WiFi Credentials
|
||||
//resetSettings();
|
||||
//ESP_wifiManager.resetSettings();
|
||||
|
||||
//set custom ip for portal
|
||||
//ESP_wifiManager.setAPStaticIPConfig(IPAddress(192, 168, 100, 1), IPAddress(192, 168, 100, 1), IPAddress(255, 255, 255, 0));
|
||||
|
||||
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_DHCP_IP
|
||||
#if USE_CONFIGURABLE_DNS
|
||||
// Set static IP, Gateway, Subnetmask, DNS1 and DNS2. New in v1.0.5
|
||||
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
|
||||
|
||||
// New from v1.1.1
|
||||
#if USING_CORS_FEATURE
|
||||
ESP_wifiManager.setCORSHeader("Your Access-Control-Allow-Origin");
|
||||
#endif
|
||||
|
||||
// We can't use WiFi.SSID() in ESP32as it's only valid after connected.
|
||||
// SSID and Password stored in ESP32 wifi_ap_record_t and wifi_config_t are also cleared in reboot
|
||||
// Have to create a new function to store in EEPROM/SPIFFS for this purpose
|
||||
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("Stored: SSID = " + Router_SSID + ", Pass = " + Router_Pass);
|
||||
|
||||
// SSID to uppercase
|
||||
ssid.toUpperCase();
|
||||
|
||||
// From v1.1.0, Don't permit NULL password
|
||||
if ( (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("Got stored Credentials. Timeout 120s for Config Portal");
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println("Open Config Portal without Timeout: No stored Credentials.");
|
||||
digitalWrite(PIN_LED, LED_ON); // Turn led on as we are in configuration mode.
|
||||
|
||||
initialConfig = true;
|
||||
}
|
||||
|
||||
if (initialConfig)
|
||||
{
|
||||
Serial.println("Starting configuration portal.");
|
||||
digitalWrite(PIN_LED, LED_ON); // turn the LED on by making the voltage LOW to tell us we are in configuration mode.
|
||||
|
||||
//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(600);
|
||||
|
||||
// Starts an access point
|
||||
if (!ESP_wifiManager.startConfigPortal((const char *) ssid.c_str(), password))
|
||||
Serial.println("Not connected to WiFi but continuing anyway.");
|
||||
else
|
||||
{
|
||||
Serial.println("WiFi connected...yeey :)");
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
saveConfigData();
|
||||
}
|
||||
|
||||
digitalWrite(PIN_LED, LED_OFF); // Turn led off as we are not in configuration mode.
|
||||
|
||||
startedAt = millis();
|
||||
|
||||
if (!initialConfig)
|
||||
{
|
||||
// Load stored data, the addAP ready for MultiWiFi reconnection
|
||||
loadConfigData();
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
if ( WiFi.status() != WL_CONNECTED )
|
||||
{
|
||||
Serial.println("ConnectMultiWiFi in setup");
|
||||
|
||||
connectMultiWiFi();
|
||||
}
|
||||
}
|
||||
|
||||
Serial.print("After waiting ");
|
||||
Serial.print((float) (millis() - startedAt) / 1000L);
|
||||
Serial.print(" secs more in setup(), connection result is ");
|
||||
|
||||
if (WiFi.status() == WL_CONNECTED)
|
||||
{
|
||||
Serial.print("connected. Local IP: ");
|
||||
Serial.println(WiFi.localIP());
|
||||
}
|
||||
else
|
||||
Serial.println(ESP_wifiManager.getStatus(WiFi.status()));
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// 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 intialization. Once its business is done, there is no need to keep it around
|
||||
ESP_WiFiManager ESP_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. New in v1.0.5
|
||||
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
|
||||
|
||||
// New from v1.1.1
|
||||
#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.print("Opening configuration portal. ");
|
||||
Router_SSID = ESP_wifiManager.WiFi_SSID();
|
||||
Router_Pass = ESP_wifiManager.WiFi_Pass();
|
||||
|
||||
// From v1.1.0, Don't permit NULL password
|
||||
if ( (Router_SSID != "") && (Router_Pass != "") )
|
||||
{
|
||||
ESP_wifiManager.setConfigPortalTimeout(120); //If no access point name has been previously entered disable timeout.
|
||||
Serial.println("Got stored Credentials. Timeout 120s");
|
||||
}
|
||||
else
|
||||
Serial.println("No stored Credentials. No timeout");
|
||||
|
||||
//Starts an access point
|
||||
//and goes into a blocking loop awaiting configuration
|
||||
if (!ESP_wifiManager.startConfigPortal((const char *) ssid.c_str(), password))
|
||||
{
|
||||
Serial.println("Not connected to WiFi but continuing anyway.");
|
||||
}
|
||||
else
|
||||
{
|
||||
//if you get here you have connected to the WiFi
|
||||
Serial.println("connected...yeey :)");
|
||||
Serial.print("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);
|
||||
}
|
||||
}
|
||||
|
||||
saveConfigData();
|
||||
}
|
||||
|
||||
digitalWrite(PIN_LED, LED_OFF); // Turn led off as we are not in configuration mode.
|
||||
}
|
||||
|
||||
// put your main code here, to run repeatedly
|
||||
check_status();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
# The Config On Switch Example
|
||||
In this example we initiate the configuration portal to connect an ESP8266 to WiFi by pushing a button. The example requires this version of WiFi Manager. It will not work with the tzapu version.
|
||||
|
||||
## Why Have A Button To Initiate Configuration?
|
||||
Once the ESP device contains network credentials it will always try to connect to that network in the background and succeed whenever that network becomes visible. The application continues to function and because WiFi networks tend to be flaky only a human has the knowledge of whether a new network is required or it is better to wait for the network to become visible again. Therefore, providing a configuration portal must be human initiated and requiring a button push is a good way to get human input.
|
||||
|
||||
The alternative of automatically going into configuration mode every time a WiFi network becomes invisible will cause the application to stop and the device will sit in configuration mode forever. This is undesirable when a network is temporarily unavailable.
|
||||
|
||||
## Issues With Automatically Going Into Configuration Mode
|
||||
Providing a timeout on configuration mode is one way to get the application running again when a network becomes temporarily unavailable and no one is around to reboot. However, the application will still not function while waiting for the timeout and the device is vulnerable to sabotage when in config mode. With a push button it will also be vulnerable to sabotage whenever the saboteur has physical access but then it is vulnerable in other ways as well. An assumption that saboteurs will not have physical access to the device is sufficient for most applications.
|
||||
|
||||
|
||||
@@ -0,0 +1,971 @@
|
||||
/****************************************************************************************************************************
|
||||
ConfigPortalParamsOnSwitch.ino
|
||||
For ESP8266 / ESP32 boards
|
||||
|
||||
ESP_WiFiManager is a library for the ESP8266/ESP32 platform (https://github.com/esp8266/Arduino) to enable easy
|
||||
configuration and reconfiguration of WiFi credentials using a Captive Portal. Inspired by:
|
||||
http://www.esp8266.com/viewtopic.php?f=29&t=2520
|
||||
https://github.com/chriscook8/esp-arduino-apboot
|
||||
https://github.com/esp8266/Arduino/blob/master/libraries/DNSServer/examples/CaptivePortalAdvanced/
|
||||
|
||||
Modified from Tzapu https://github.com/tzapu/WiFiManager
|
||||
and from Ken Taylor https://github.com/kentaylor
|
||||
|
||||
Built by Khoi Hoang https://github.com/khoih-prog/ESP_WiFiManager
|
||||
Licensed under MIT license
|
||||
Version: 1.2.0
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 07/10/2019 Initial coding
|
||||
1.0.1 K Hoang 13/12/2019 Fix bug. Add features. Add support for ESP32
|
||||
1.0.2 K Hoang 19/12/2019 Fix bug thatkeeps ConfigPortal in endless loop if Portal/Router SSID or Password is NULL.
|
||||
1.0.3 K Hoang 05/01/2020 Option not displaying AvailablePages in Info page. Enhance README.md. Modify examples
|
||||
1.0.4 K Hoang 07/01/2020 Add RFC952 setHostname feature.
|
||||
1.0.5 K Hoang 15/01/2020 Add configurable DNS feature. Thanks to @Amorphous of https://community.blynk.cc
|
||||
1.0.6 K Hoang 03/02/2020 Add support for ArduinoJson version 6.0.0+ ( tested with v6.14.1 )
|
||||
1.0.7 K Hoang 13/04/2020 Reduce start time, fix SPIFFS bug in examples, update README.md
|
||||
1.0.8 K Hoang 10/06/2020 Fix STAstaticIP issue. Restructure code. Add LittleFS support for ESP8266 core 2.7.1+
|
||||
1.0.9 K Hoang 29/07/2020 Fix ESP32 STAstaticIP bug. Permit changing from DHCP <-> static IP using Config Portal.
|
||||
Add, enhance examples (fix MDNS for ESP32)
|
||||
1.0.10 K Hoang 08/08/2020 Add more features to Config Portal. Use random WiFi AP channel to avoid conflict.
|
||||
1.0.11 K Hoang 17/08/2020 Add CORS feature. Fix bug in softAP, autoConnect, resetSettings.
|
||||
1.1.0 K Hoang 28/08/2020 Add MultiWiFi feature to autoconnect to best WiFi at runtime
|
||||
1.1.1 K Hoang 30/08/2020 Add setCORSHeader function to allow flexible CORS. Fix typo and minor improvement.
|
||||
1.1.2 K Hoang 17/08/2020 Fix bug. Add example.
|
||||
1.2.0 K Hoang 09/10/2020 Restore cpp code besides Impl.h code to use if linker error. Fix bug.
|
||||
*****************************************************************************************************************************/
|
||||
/****************************************************************************************************************************
|
||||
This example will open a configuration portal when a predetermined button is pressed
|
||||
The Flash button is convenient for this on NodeMCU devices.
|
||||
|
||||
You then can modify ConfigPortal Parameters. such as Portal SSID and Password
|
||||
This example will open a configuration portal when no WiFi configuration has been previously entered or when a button is pushed.
|
||||
|
||||
Also in this example, a configurable password is required to connect to the configuration portal
|
||||
network. This is inconvenient but means that only those who know the password or those
|
||||
already connected to the target WiFi network can access the configuration portal and
|
||||
the WiFi network credentials will be sent from the browser over an encrypted connection and
|
||||
can not be read by observers.
|
||||
*****************************************************************************************************************************/
|
||||
|
||||
#if !( defined(ESP8266) || defined(ESP32) )
|
||||
#error This code is intended to run on the ESP8266 or ESP32 platform! Please check your Tools->Board setting.
|
||||
#endif
|
||||
|
||||
// Use from 0 to 4. Higher number, more debugging messages and memory usage.
|
||||
#define _WIFIMGR_LOGLEVEL_ 3
|
||||
|
||||
#include <FS.h>
|
||||
// Now support ArduinoJson 6.0.0+ ( tested with v6.14.1 )
|
||||
#include <ArduinoJson.h> // get it from https://arduinojson.org/ or install via Arduino library manager
|
||||
|
||||
//Ported to ESP32
|
||||
//For ESP32, To use ESP32 Dev Module, QIO, Flash 4MB/80MHz, Upload 921600
|
||||
//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;
|
||||
|
||||
#define USE_SPIFFS true
|
||||
|
||||
#if USE_SPIFFS
|
||||
#include <SPIFFS.h>
|
||||
FS* filesystem = &SPIFFS;
|
||||
#define FileFS SPIFFS
|
||||
#define FS_Name "SPIFFS"
|
||||
#else
|
||||
// Use FFat
|
||||
#include <FFat.h>
|
||||
FS* filesystem = &FFat;
|
||||
#define FileFS FFat
|
||||
#define FS_Name "FFat"
|
||||
#endif
|
||||
//////
|
||||
|
||||
#define ESP_getChipId() ((uint32_t)ESP.getEfuseMac())
|
||||
|
||||
#define LED_BUILTIN 2
|
||||
#define LED_ON HIGH
|
||||
#define LED_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;
|
||||
|
||||
#define USE_LITTLEFS true
|
||||
|
||||
#if USE_LITTLEFS
|
||||
#include <LittleFS.h>
|
||||
FS* filesystem = &LittleFS;
|
||||
#define FileFS LittleFS
|
||||
#define FS_Name "LittleFS"
|
||||
#else
|
||||
FS* filesystem = &SPIFFS;
|
||||
#define FileFS SPIFFS
|
||||
#define FS_Name "SPIFFS"
|
||||
#endif
|
||||
//////
|
||||
|
||||
#define ESP_getChipId() (ESP.getChipId())
|
||||
|
||||
#define LED_ON LOW
|
||||
#define LED_OFF HIGH
|
||||
#endif
|
||||
|
||||
#ifdef ESP32
|
||||
|
||||
//See file .../hardware/espressif/esp32/variants/(esp32|doitESP32devkitV1)/pins_arduino.h
|
||||
#define LED_BUILTIN 2 // Pin D2 mapped to pin GPIO2/ADC12 of ESP32, control on-board LED
|
||||
#define PIN_LED 2 // Pin D2 mapped to pin GPIO2/ADC12 of ESP32, control on-board LED
|
||||
|
||||
#define PIN_D0 0 // Pin D0 mapped to pin GPIO0/BOOT/ADC11/TOUCH1 of ESP32
|
||||
#define PIN_D1 1 // Pin D1 mapped to pin GPIO1/TX0 of ESP32
|
||||
#define PIN_D2 2 // Pin D2 mapped to pin GPIO2/ADC12/TOUCH2 of ESP32
|
||||
#define PIN_D3 3 // Pin D3 mapped to pin GPIO3/RX0 of ESP32
|
||||
#define PIN_D4 4 // Pin D4 mapped to pin GPIO4/ADC10/TOUCH0 of ESP32
|
||||
#define PIN_D5 5 // Pin D5 mapped to pin GPIO5/SPISS/VSPI_SS of ESP32
|
||||
#define PIN_D6 6 // Pin D6 mapped to pin GPIO6/FLASH_SCK of ESP32
|
||||
#define PIN_D7 7 // Pin D7 mapped to pin GPIO7/FLASH_D0 of ESP32
|
||||
#define PIN_D8 8 // Pin D8 mapped to pin GPIO8/FLASH_D1 of ESP32
|
||||
#define PIN_D9 9 // Pin D9 mapped to pin GPIO9/FLASH_D2 of ESP32
|
||||
|
||||
#define PIN_D10 10 // Pin D10 mapped to pin GPIO10/FLASH_D3 of ESP32
|
||||
#define PIN_D11 11 // Pin D11 mapped to pin GPIO11/FLASH_CMD of ESP32
|
||||
#define PIN_D12 12 // Pin D12 mapped to pin GPIO12/HSPI_MISO/ADC15/TOUCH5/TDI of ESP32
|
||||
#define PIN_D13 13 // Pin D13 mapped to pin GPIO13/HSPI_MOSI/ADC14/TOUCH4/TCK of ESP32
|
||||
#define PIN_D14 14 // Pin D14 mapped to pin GPIO14/HSPI_SCK/ADC16/TOUCH6/TMS of ESP32
|
||||
#define PIN_D15 15 // Pin D15 mapped to pin GPIO15/HSPI_SS/ADC13/TOUCH3/TDO of ESP32
|
||||
#define PIN_D16 16 // Pin D16 mapped to pin GPIO16/TX2 of ESP32
|
||||
#define PIN_D17 17 // Pin D17 mapped to pin GPIO17/RX2 of ESP32
|
||||
#define PIN_D18 18 // Pin D18 mapped to pin GPIO18/VSPI_SCK of ESP32
|
||||
#define PIN_D19 19 // Pin D19 mapped to pin GPIO19/VSPI_MISO of ESP32
|
||||
|
||||
#define PIN_D21 21 // Pin D21 mapped to pin GPIO21/SDA of ESP32
|
||||
#define PIN_D22 22 // Pin D22 mapped to pin GPIO22/SCL of ESP32
|
||||
#define PIN_D23 23 // Pin D23 mapped to pin GPIO23/VSPI_MOSI of ESP32
|
||||
#define PIN_D24 24 // Pin D24 mapped to pin GPIO24 of ESP32
|
||||
#define PIN_D25 25 // Pin D25 mapped to pin GPIO25/ADC18/DAC1 of ESP32
|
||||
#define PIN_D26 26 // Pin D26 mapped to pin GPIO26/ADC19/DAC2 of ESP32
|
||||
#define PIN_D27 27 // Pin D27 mapped to pin GPIO27/ADC17/TOUCH7 of ESP32
|
||||
|
||||
#define PIN_D32 32 // Pin D32 mapped to pin GPIO32/ADC4/TOUCH9 of ESP32
|
||||
#define PIN_D33 33 // Pin D33 mapped to pin GPIO33/ADC5/TOUCH8 of ESP32
|
||||
#define PIN_D34 34 // Pin D34 mapped to pin GPIO34/ADC6 of ESP32
|
||||
|
||||
//Only GPIO pin < 34 can be used as output. Pins >= 34 can be only inputs
|
||||
//See .../cores/esp32/esp32-hal-gpio.h/c
|
||||
//#define digitalPinIsValid(pin) ((pin) < 40 && esp32_gpioMux[(pin)].reg)
|
||||
//#define digitalPinCanOutput(pin) ((pin) < 34 && esp32_gpioMux[(pin)].reg)
|
||||
//#define digitalPinToRtcPin(pin) (((pin) < 40)?esp32_gpioMux[(pin)].rtc:-1)
|
||||
//#define digitalPinToAnalogChannel(pin) (((pin) < 40)?esp32_gpioMux[(pin)].adc:-1)
|
||||
//#define digitalPinToTouchChannel(pin) (((pin) < 40)?esp32_gpioMux[(pin)].touch:-1)
|
||||
//#define digitalPinToDacChannel(pin) (((pin) == 25)?0:((pin) == 26)?1:-1)
|
||||
|
||||
#define PIN_D35 35 // Pin D35 mapped to pin GPIO35/ADC7 of ESP32
|
||||
#define PIN_D36 36 // Pin D36 mapped to pin GPIO36/ADC0/SVP of ESP32
|
||||
#define PIN_D39 39 // Pin D39 mapped to pin GPIO39/ADC3/SVN of ESP32
|
||||
|
||||
#define PIN_RX0 3 // Pin RX0 mapped to pin GPIO3/RX0 of ESP32
|
||||
#define PIN_TX0 1 // Pin TX0 mapped to pin GPIO1/TX0 of ESP32
|
||||
|
||||
#define PIN_SCL 22 // Pin SCL mapped to pin GPIO22/SCL of ESP32
|
||||
#define PIN_SDA 21 // Pin SDA mapped to pin GPIO21/SDA of ESP32
|
||||
#else
|
||||
//PIN_D0 can't be used for PWM/I2C
|
||||
#define PIN_D0 16 // Pin D0 mapped to pin GPIO16/USER/WAKE of ESP8266. This pin is also used for Onboard-Blue LED. PIN_D0 = 0 => LED ON
|
||||
#define PIN_D1 5 // Pin D1 mapped to pin GPIO5 of ESP8266
|
||||
#define PIN_D2 4 // Pin D2 mapped to pin GPIO4 of ESP8266
|
||||
#define PIN_D3 0 // Pin D3 mapped to pin GPIO0/FLASH of ESP8266
|
||||
#define PIN_D4 2 // Pin D4 mapped to pin GPIO2/TXD1 of ESP8266
|
||||
#define PIN_LED 2 // Pin D4 mapped to pin GPIO2/TXD1 of ESP8266, NodeMCU and WeMoS, control on-board LED
|
||||
#define PIN_D5 14 // Pin D5 mapped to pin GPIO14/HSCLK of ESP8266
|
||||
#define PIN_D6 12 // Pin D6 mapped to pin GPIO12/HMISO of ESP8266
|
||||
#define PIN_D7 13 // Pin D7 mapped to pin GPIO13/RXD2/HMOSI of ESP8266
|
||||
#define PIN_D8 15 // Pin D8 mapped to pin GPIO15/TXD2/HCS of ESP8266
|
||||
|
||||
//Don't use pins GPIO6 to GPIO11 as already connected to flash, etc. Use them can crash the program
|
||||
//GPIO9(D11/SD2) and GPIO11 can be used only if flash in DIO mode ( not the default QIO mode)
|
||||
#define PIN_D11 9 // Pin D11/SD2 mapped to pin GPIO9/SDD2 of ESP8266
|
||||
#define PIN_D12 10 // Pin D12/SD3 mapped to pin GPIO10/SDD3 of ESP8266
|
||||
#define PIN_SD2 9 // Pin SD2 mapped to pin GPIO9/SDD2 of ESP8266
|
||||
#define PIN_SD3 10 // Pin SD3 mapped to pin GPIO10/SDD3 of ESP8266
|
||||
|
||||
#define PIN_D9 3 // Pin D9 /RX mapped to pin GPIO3/RXD0 of ESP8266
|
||||
#define PIN_D10 1 // Pin D10/TX mapped to pin GPIO1/TXD0 of ESP8266
|
||||
#define PIN_RX 3 // Pin RX mapped to pin GPIO3/RXD0 of ESP8266
|
||||
#define PIN_TX 1 // Pin RX mapped to pin GPIO1/TXD0 of ESP8266
|
||||
|
||||
#define LED_PIN 16 // Pin D0 mapped to pin GPIO16 of ESP8266. This pin is also used for Onboard-Blue LED. PIN_D0 = 0 => LED ON
|
||||
|
||||
#endif //USE_ESP32
|
||||
|
||||
#ifdef ESP32
|
||||
/* Trigger for inititating config mode is Pin D3 and also flash button on NodeMCU
|
||||
Flash button is convenient to use but if it is pressed it will stuff up the serial port device driver
|
||||
until the computer is rebooted on windows machines.
|
||||
*/
|
||||
const int TRIGGER_PIN = PIN_D0; // Pin D0 mapped to pin GPIO0/BOOT/ADC11/TOUCH1 of ESP32
|
||||
/*
|
||||
Alternative trigger pin. Needs to be connected to a button to use this pin. It must be a momentary connection
|
||||
not connected permanently to ground. Either trigger pin will work.
|
||||
*/
|
||||
const int TRIGGER_PIN2 = PIN_D25; // Pin D25 mapped to pin GPIO25/ADC18/DAC1 of ESP32
|
||||
#else
|
||||
/* Trigger for inititating config mode is Pin D3 and also flash button on NodeMCU
|
||||
Flash button is convenient to use but if it is pressed it will stuff up the serial port device driver
|
||||
until the computer is rebooted on windows machines.
|
||||
*/
|
||||
const int TRIGGER_PIN = PIN_D3; // D3 on NodeMCU and WeMos.
|
||||
/*
|
||||
Alternative trigger pin. Needs to be connected to a button to use this pin. It must be a momentary connection
|
||||
not connected permanently to ground. Either trigger pin will work.
|
||||
*/
|
||||
const int TRIGGER_PIN2 = PIN_D7; // D7 on NodeMCU and WeMos.
|
||||
#endif
|
||||
|
||||
const char* CONFIG_FILE = "/ConfigSW.json";
|
||||
|
||||
// Variables
|
||||
|
||||
#define SSID_MAX_LENGTH 32
|
||||
#define PASSWORD_MAX_LENGTH 32
|
||||
|
||||
// Default Config Portal SID and Password
|
||||
// SSID and PW for Config Portal
|
||||
|
||||
String DefaultPortalSSID = "ESP_" + String(ESP_getChipId(), HEX);
|
||||
char PortalSSID[SSID_MAX_LENGTH + 1] = "your_ssid";
|
||||
|
||||
// Use in case PortalSSID or PortalPassword is invalid (NULL)
|
||||
String DefaultPortalPassword = "My" + DefaultPortalSSID;
|
||||
char PortalPassword[PASSWORD_MAX_LENGTH + 1] = "your_password";
|
||||
|
||||
#define PortalSSID_Label "PortalSSID"
|
||||
#define PortalPassword_Label "PortalPassword"
|
||||
|
||||
// SSID and PW for your Router
|
||||
String Router_SSID;
|
||||
String Router_Pass;
|
||||
|
||||
// From v1.1.0
|
||||
// You only need to format the filesystem once
|
||||
//#define FORMAT_FILESYSTEM true
|
||||
#define FORMAT_FILESYSTEM false
|
||||
|
||||
#define MIN_AP_PASSWORD_SIZE 8
|
||||
|
||||
#define SSID_MAX_LEN 32
|
||||
//From v1.0.10, WPA2 passwords can be up to 63 characters long.
|
||||
#define PASS_MAX_LEN 64
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char wifi_ssid[SSID_MAX_LEN];
|
||||
char wifi_pw [PASS_MAX_LEN];
|
||||
} WiFi_Credentials;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
String wifi_ssid;
|
||||
String wifi_pw;
|
||||
} WiFi_Credentials_String;
|
||||
|
||||
#define NUM_WIFI_CREDENTIALS 2
|
||||
|
||||
typedef struct
|
||||
{
|
||||
WiFi_Credentials WiFi_Creds [NUM_WIFI_CREDENTIALS];
|
||||
} WM_Config;
|
||||
|
||||
WM_Config WM_config;
|
||||
|
||||
#define CONFIG_FILENAME F("/wifi_cred.dat")
|
||||
//////
|
||||
|
||||
// Indicates whether ESP has WiFi credentials saved from previous session
|
||||
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 <ESP_WiFiManager.h>
|
||||
#define USE_AVAILABLE_PAGES false
|
||||
|
||||
// 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)
|
||||
#define USE_ESP_WIFIMANAGER_NTP false
|
||||
|
||||
// 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)
|
||||
#define USE_CLOUDFLARE_NTP false
|
||||
|
||||
// New in v1.0.11
|
||||
#define USING_CORS_FEATURE true
|
||||
//////
|
||||
|
||||
// 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
|
||||
#define USE_DHCP_IP true
|
||||
#else
|
||||
// You can select DHCP or Static IP here
|
||||
//#define USE_DHCP_IP true
|
||||
#define USE_DHCP_IP false
|
||||
#endif
|
||||
|
||||
#if ( USE_DHCP_IP || ( defined(USE_STATIC_IP_CONFIG_IN_CP) && !USE_STATIC_IP_CONFIG_IN_CP ) )
|
||||
// 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
|
||||
|
||||
#define USE_CONFIGURABLE_DNS true
|
||||
|
||||
IPAddress dns1IP = gatewayIP;
|
||||
IPAddress dns2IP = IPAddress(8, 8, 8, 8);
|
||||
|
||||
#include <ESP_WiFiManager.h> //https://github.com/khoih-prog/ESP_WiFiManager
|
||||
|
||||
// Function Prototypes
|
||||
uint8_t connectMultiWiFi(void);
|
||||
bool readConfigFile(void);
|
||||
bool writeConfigFile(void);
|
||||
|
||||
void heartBeatPrint(void)
|
||||
{
|
||||
static int num = 1;
|
||||
|
||||
if (WiFi.status() == WL_CONNECTED)
|
||||
Serial.print("H"); // H means connected to WiFi
|
||||
else
|
||||
Serial.print("F"); // F means not connected to WiFi
|
||||
|
||||
if (num == 80)
|
||||
{
|
||||
Serial.println();
|
||||
num = 1;
|
||||
}
|
||||
else if (num++ % 10 == 0)
|
||||
{
|
||||
Serial.print(" ");
|
||||
}
|
||||
}
|
||||
|
||||
void check_WiFi(void)
|
||||
{
|
||||
if ( (WiFi.status() != WL_CONNECTED) )
|
||||
{
|
||||
Serial.println("\nWiFi lost. Call connectMultiWiFi in loop");
|
||||
connectMultiWiFi();
|
||||
}
|
||||
}
|
||||
|
||||
void check_status(void)
|
||||
{
|
||||
static ulong checkstatus_timeout = 0;
|
||||
static ulong checkwifi_timeout = 0;
|
||||
|
||||
static ulong current_millis;
|
||||
|
||||
#define WIFICHECK_INTERVAL 1000L
|
||||
#define HEARTBEAT_INTERVAL 10000L
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// Print hearbeat every HEARTBEAT_INTERVAL (10) seconds.
|
||||
if ((current_millis > checkstatus_timeout) || (checkstatus_timeout == 0))
|
||||
{
|
||||
heartBeatPrint();
|
||||
checkstatus_timeout = current_millis + HEARTBEAT_INTERVAL;
|
||||
}
|
||||
}
|
||||
|
||||
void loadConfigData(void)
|
||||
{
|
||||
File file = FileFS.open(CONFIG_FILENAME, "r");
|
||||
LOGERROR(F("LoadWiFiCfgFile "));
|
||||
|
||||
if (file)
|
||||
{
|
||||
file.readBytes((char *) &WM_config, sizeof(WM_config));
|
||||
file.close();
|
||||
LOGERROR(F("OK"));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGERROR(F("failed"));
|
||||
}
|
||||
}
|
||||
|
||||
void saveConfigData(void)
|
||||
{
|
||||
File file = FileFS.open(CONFIG_FILENAME, "w");
|
||||
LOGERROR(F("SaveWiFiCfgFile "));
|
||||
|
||||
if (file)
|
||||
{
|
||||
file.write((uint8_t*) &WM_config, sizeof(WM_config));
|
||||
file.close();
|
||||
LOGERROR(F("OK"));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGERROR(F("failed"));
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t connectMultiWiFi(void)
|
||||
{
|
||||
#if ESP32
|
||||
// For ESP32, this better be 0 to shorten the connect time
|
||||
#define WIFI_MULTI_1ST_CONNECT_WAITING_MS 0
|
||||
#else
|
||||
// For ESP8266, this better be 2200 to enable connect the 1st time
|
||||
#define WIFI_MULTI_1ST_CONNECT_WAITING_MS 2200L
|
||||
#endif
|
||||
|
||||
#define WIFI_MULTI_CONNECT_WAITING_MS 100L
|
||||
|
||||
uint8_t status;
|
||||
|
||||
LOGERROR(F("ConnectMultiWiFi with :"));
|
||||
|
||||
if ( (Router_SSID != "") && (Router_Pass != "") )
|
||||
{
|
||||
LOGERROR3(F("* Flash-stored Router_SSID = "), Router_SSID, F(", Router_Pass = "), Router_Pass );
|
||||
}
|
||||
|
||||
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
|
||||
#if USE_CONFIGURABLE_DNS
|
||||
// Set static IP, Gateway, Subnetmask, DNS1 and DNS2. New in v1.0.5
|
||||
WiFi.config(stationIP, gatewayIP, netMask, dns1IP, dns2IP);
|
||||
#else
|
||||
// Set static IP, Gateway, Subnetmask, Use auto DNS1 and DNS2.
|
||||
WiFi.config(stationIP, gatewayIP, netMask);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
int i = 0;
|
||||
status = wifiMulti.run();
|
||||
delay(WIFI_MULTI_1ST_CONNECT_WAITING_MS);
|
||||
|
||||
while ( ( i++ < 10 ) && ( status != WL_CONNECTED ) )
|
||||
{
|
||||
status = wifiMulti.run();
|
||||
|
||||
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"));
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
bool readConfigFile()
|
||||
{
|
||||
// this opens the config file in read-mode
|
||||
File f = FileFS.open(CONFIG_FILE, "r");
|
||||
|
||||
if (!f)
|
||||
{
|
||||
Serial.println("Configuration file not found");
|
||||
return false;
|
||||
}
|
||||
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(new char[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)
|
||||
DynamicJsonDocument json(1024);
|
||||
auto deserializeError = deserializeJson(json, buf.get());
|
||||
if ( deserializeError )
|
||||
{
|
||||
Serial.println("JSON parseObject() failed");
|
||||
return false;
|
||||
}
|
||||
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");
|
||||
return false;
|
||||
}
|
||||
json.printTo(Serial);
|
||||
#endif
|
||||
|
||||
// Parse all config file parameters, override
|
||||
// local config variables with parsed values
|
||||
if (json.containsKey(PortalSSID_Label))
|
||||
{
|
||||
strcpy(PortalSSID, json[PortalSSID_Label]);
|
||||
}
|
||||
|
||||
if (json.containsKey(PortalPassword_Label))
|
||||
{
|
||||
strcpy(PortalPassword, json[PortalPassword_Label]);
|
||||
}
|
||||
}
|
||||
Serial.println("\nConfig file was successfully parsed");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool writeConfigFile()
|
||||
{
|
||||
Serial.println("Saving config file");
|
||||
|
||||
#if (ARDUINOJSON_VERSION_MAJOR >= 6)
|
||||
DynamicJsonDocument json(1024);
|
||||
#else
|
||||
DynamicJsonBuffer jsonBuffer;
|
||||
JsonObject& json = jsonBuffer.createObject();
|
||||
#endif
|
||||
|
||||
|
||||
// JSONify local configuration parameters
|
||||
json[PortalSSID_Label] = PortalSSID;
|
||||
json[PortalPassword_Label] = PortalPassword;
|
||||
|
||||
// Open file for writing
|
||||
File f = FileFS.open(CONFIG_FILE, "w");
|
||||
|
||||
if (!f)
|
||||
{
|
||||
Serial.println("Failed to open config file for writing");
|
||||
return false;
|
||||
}
|
||||
|
||||
#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("\nConfig file was successfully saved");
|
||||
return true;
|
||||
}
|
||||
|
||||
// Setup function
|
||||
void setup()
|
||||
{
|
||||
// Put your setup code here, to run once
|
||||
Serial.begin(115200);
|
||||
while (!Serial);
|
||||
|
||||
Serial.print("\nStarting ConfigPortalParamsOnSwitch using " + String(FS_Name));
|
||||
Serial.println(" on " + String(ARDUINO_BOARD));
|
||||
|
||||
// Initialize the LED digital pin as an output.
|
||||
pinMode(PIN_LED, OUTPUT);
|
||||
// Initialize trigger pins
|
||||
pinMode(TRIGGER_PIN, INPUT_PULLUP);
|
||||
pinMode(TRIGGER_PIN2, INPUT_PULLUP);
|
||||
|
||||
// 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
|
||||
{
|
||||
Serial.print(FS_Name);
|
||||
Serial.println(F(" failed! AutoFormatting."));
|
||||
|
||||
#ifdef ESP8266
|
||||
FileFS.format();
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!readConfigFile())
|
||||
{
|
||||
Serial.println("Failed to read configuration file, using default values");
|
||||
}
|
||||
|
||||
unsigned long startedAt = millis();
|
||||
|
||||
//Local intialization. Once its business is done, there is no need to keep it around
|
||||
// Use this to default DHCP hostname to ESP8266-XXXXXX or ESP32-XXXXXX
|
||||
//ESP_WiFiManager ESP_wifiManager;
|
||||
// Use this to personalize DHCP hostname (RFC952 conformed)
|
||||
ESP_WiFiManager ESP_wifiManager("ConfigPortalParamsOnSW");
|
||||
|
||||
ESP_wifiManager.setDebugOutput(true);
|
||||
|
||||
// Use only to erase stored WiFi Credentials
|
||||
//resetSettings();
|
||||
//ESP_wifiManager.resetSettings();
|
||||
|
||||
//set custom ip for portal
|
||||
//ESP_wifiManager.setAPStaticIPConfig(IPAddress(192, 168, 100, 1), IPAddress(192, 168, 100, 1), IPAddress(255, 255, 255, 0));
|
||||
|
||||
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_DHCP_IP
|
||||
#if USE_CONFIGURABLE_DNS
|
||||
// Set static IP, Gateway, Subnetmask, DNS1 and DNS2. New in v1.0.5
|
||||
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
|
||||
|
||||
// New from v1.1.1
|
||||
#if USING_CORS_FEATURE
|
||||
ESP_wifiManager.setCORSHeader("Your Access-Control-Allow-Origin");
|
||||
#endif
|
||||
|
||||
// We can't use WiFi.SSID() in ESP32 as it's only valid after connected.
|
||||
// SSID and Password stored in ESP32 wifi_ap_record_t and wifi_config_t are also cleared in reboot
|
||||
// Have to create a new function to store in EEPROM/SPIFFS for this purpose
|
||||
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("Stored: SSID = " + Router_SSID + ", Pass = " + Router_Pass);
|
||||
|
||||
// From v1.1.0, Don't permit NULL password
|
||||
if ( (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("Got stored Credentials. Timeout 120s for Config Portal");
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println("Open Config Portal without Timeout: No stored Credentials.");
|
||||
|
||||
initialConfig = true;
|
||||
}
|
||||
|
||||
// From v1.1.0, Don't permit NULL password
|
||||
if (initialConfig)
|
||||
{
|
||||
Serial.println("We haven't got any access point credentials, so get them now");
|
||||
|
||||
digitalWrite(PIN_LED, LED_ON); // Turn led on as we are in configuration mode.
|
||||
|
||||
//it starts an access point
|
||||
//and goes into a blocking loop awaiting configuration
|
||||
// If Invalid PortalSSID or PortalPassword => use default
|
||||
|
||||
bool resultConfigPortal;
|
||||
|
||||
if ( (PortalSSID[0] == 0) || (PortalPassword[0] == 0) )
|
||||
{
|
||||
resultConfigPortal = ESP_wifiManager.startConfigPortal((const char *) DefaultPortalSSID.c_str(), DefaultPortalPassword.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
resultConfigPortal = ESP_wifiManager.startConfigPortal((const char *) PortalSSID, PortalPassword);
|
||||
}
|
||||
|
||||
if (resultConfigPortal)
|
||||
Serial.println("WiFi connected...yeey :)");
|
||||
else
|
||||
Serial.println("Not connected to WiFi but continuing anyway.");
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
saveConfigData();
|
||||
}
|
||||
|
||||
digitalWrite(PIN_LED, LED_OFF); // Turn led off as we are not in configuration mode.
|
||||
|
||||
startedAt = millis();
|
||||
|
||||
if (!initialConfig)
|
||||
{
|
||||
// Load stored data, the addAP ready for MultiWiFi reconnection
|
||||
loadConfigData();
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
if ( WiFi.status() != WL_CONNECTED )
|
||||
{
|
||||
Serial.println("ConnectMultiWiFi in setup");
|
||||
|
||||
connectMultiWiFi();
|
||||
}
|
||||
}
|
||||
|
||||
Serial.print("After waiting ");
|
||||
Serial.print((float) (millis() - startedAt) / 1000L);
|
||||
Serial.print(" secs more in setup(), connection result is ");
|
||||
|
||||
if (WiFi.status() == WL_CONNECTED)
|
||||
{
|
||||
Serial.print("connected. Local IP: ");
|
||||
Serial.println(WiFi.localIP());
|
||||
}
|
||||
else
|
||||
Serial.println(ESP_wifiManager.getStatus(WiFi.status()));
|
||||
}
|
||||
|
||||
// Loop function
|
||||
|
||||
void loop()
|
||||
{
|
||||
// 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 intialization. Once its business is done, there is no need to keep it around
|
||||
ESP_WiFiManager ESP_wifiManager("ConfigPortalParamsOnSW");
|
||||
|
||||
//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. ");
|
||||
|
||||
Router_SSID = ESP_wifiManager.WiFi_SSID();
|
||||
Router_Pass = ESP_wifiManager.WiFi_Pass();
|
||||
|
||||
// From v1.1.0, Don't permit NULL password
|
||||
if ( (Router_SSID != "") && (Router_Pass != "") )
|
||||
{
|
||||
ESP_wifiManager.setConfigPortalTimeout(120); //If no access point name has been previously entered disable timeout.
|
||||
Serial.println("Got stored Credentials. Timeout 120s");
|
||||
}
|
||||
else
|
||||
Serial.println("No stored Credentials. No timeout");
|
||||
|
||||
// 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>
|
||||
|
||||
// Config Portal SSID - this is a straight forward string parameter
|
||||
ESP_WMParameter p_PortalSSID(PortalSSID_Label, "Portal_SSID", PortalSSID, SSID_MAX_LENGTH + 1);
|
||||
|
||||
// Config Portal SSID - this is a straight forward string parameter
|
||||
ESP_WMParameter p_PortalPassword(PortalPassword_Label, "Portal_Password", PortalPassword, PASSWORD_MAX_LENGTH + 1);
|
||||
|
||||
//add all parameters here
|
||||
ESP_wifiManager.addParameter(&p_PortalSSID);
|
||||
ESP_wifiManager.addParameter(&p_PortalPassword);
|
||||
|
||||
// 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);
|
||||
//////
|
||||
|
||||
//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. New in v1.0.5
|
||||
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
|
||||
|
||||
// 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
|
||||
|
||||
static bool resultConfigPortal;
|
||||
if ( (PortalSSID[0] == 0) || (PortalPassword[0] == 0) )
|
||||
{
|
||||
resultConfigPortal = ESP_wifiManager.startConfigPortal((const char *) DefaultPortalSSID.c_str(), DefaultPortalPassword.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
resultConfigPortal = ESP_wifiManager.startConfigPortal((const char *) PortalSSID, PortalPassword);
|
||||
}
|
||||
|
||||
if (resultConfigPortal)
|
||||
{
|
||||
Serial.println("WiFi connected...yeey :)");
|
||||
Serial.print("Local IP: ");
|
||||
Serial.println(WiFi.localIP());
|
||||
}
|
||||
else
|
||||
Serial.println("Not connected to WiFi but continuing anyway.");
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
saveConfigData();
|
||||
}
|
||||
|
||||
// Getting posted form values and overriding local variables parameters
|
||||
// Config file is written regardless the connection state
|
||||
strcpy(PortalSSID, p_PortalSSID.getValue());
|
||||
strcpy(PortalPassword, p_PortalPassword.getValue());
|
||||
|
||||
// Writing JSON config file to flash for next boot
|
||||
writeConfigFile();
|
||||
|
||||
digitalWrite(PIN_LED, LED_OFF); // Turn LED off as we are not in configuration mode.
|
||||
}
|
||||
|
||||
// Configuration portal not requested, so run normal loop
|
||||
// Put your main code here, to run repeatedly...
|
||||
check_status();
|
||||
}
|
||||
@@ -0,0 +1,860 @@
|
||||
/****************************************************************************************************************************
|
||||
ESP32_FSWebServer - Example WebServer with SPIFFS backend for esp8266
|
||||
For ESP32 boards
|
||||
|
||||
ESP_WiFiManager is a library for the ESP8266/ESP32 platform (https://github.com/esp8266/Arduino) to enable easy
|
||||
configuration and reconfiguration of WiFi credentials using a Captive Portal.
|
||||
|
||||
Modified from Tzapu https://github.com/tzapu/WiFiManager
|
||||
and from Ken Taylor https://github.com/kentaylor
|
||||
|
||||
Built by Khoi Hoang https://github.com/khoih-prog/ESP_WiFiManager
|
||||
Licensed under MIT license
|
||||
|
||||
Example modified from https://github.com/esp8266/Arduino/blob/master/libraries/ESP8266WebServer/examples/FSBrowser/FSBrowser.ino
|
||||
|
||||
Copyright (c) 2015 Hristo Gochkov. All rights reserved.
|
||||
This file is part of the ESP8266WebServer library for Arduino environment.
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Version: 1.2.0
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 07/10/2019 Initial coding
|
||||
1.0.1 K Hoang 13/12/2019 Fix bug. Add features. Add support for ESP32
|
||||
1.0.2 K Hoang 19/12/2019 Fix bug thatkeeps ConfigPortal in endless loop if Portal/Router SSID or Password is NULL.
|
||||
1.0.3 K Hoang 05/01/2020 Option not displaying AvailablePages in Info page. Enhance README.md. Modify examples
|
||||
1.0.4 K Hoang 07/01/2020 Add RFC952 setHostname feature.
|
||||
1.0.5 K Hoang 15/01/2020 Add configurable DNS feature. Thanks to @Amorphous of https://community.blynk.cc
|
||||
1.0.6 K Hoang 03/02/2020 Add support for ArduinoJson version 6.0.0+ ( tested with v6.14.1 )
|
||||
1.0.7 K Hoang 13/04/2020 Reduce start time, fix SPIFFS bug in examples, update README.md
|
||||
1.0.8 K Hoang 10/06/2020 Fix STAstaticIP issue. Restructure code. Add LittleFS support for ESP8266 core 2.7.1+
|
||||
1.0.9 K Hoang 29/07/2020 Fix ESP32 STAstaticIP bug. Permit changing from DHCP <-> static IP using Config Portal.
|
||||
Add, enhance examples (fix MDNS for ESP32)
|
||||
1.0.10 K Hoang 08/08/2020 Add more features to Config Portal. Use random WiFi AP channel to avoid conflict.
|
||||
1.0.11 K Hoang 17/08/2020 Add CORS feature. Fix bug in softAP, autoConnect, resetSettings.
|
||||
1.1.0 K Hoang 28/08/2020 Add MultiWiFi feature to autoconnect to best WiFi at runtime
|
||||
1.1.1 K Hoang 30/08/2020 Add setCORSHeader function to allow flexible CORS. Fix typo and minor improvement.
|
||||
1.1.2 K Hoang 17/08/2020 Fix bug. Add example.
|
||||
1.2.0 K Hoang 09/10/2020 Restore cpp code besides Impl.h code to use if linker error. Fix bug.
|
||||
*****************************************************************************************************************************/
|
||||
/*****************************************************************************************************************************
|
||||
How To Use:
|
||||
1) Upload the contents of the data folder with MkSPIFFS Tool ("ESP32 Sketch Data Upload" in Tools menu in Arduino IDE)
|
||||
2) or you can upload the contents of a folder if you CD in that folder and run the following command:
|
||||
for file in `\ls -A1`; do curl -F "file=@$PWD/$file" esp32-fs-browser.local/edit; done
|
||||
3) access the sample web page at http://esp32-fs-browser.local
|
||||
4) edit the page by going to http://esp32-fs-browser.local/edit
|
||||
*****************************************************************************************************************************/
|
||||
#if !defined(ESP32)
|
||||
#error This code is intended to run on the ESP32 platform! Please check your Tools->Board setting.
|
||||
#endif
|
||||
|
||||
// Use from 0 to 4. Higher number, more debugging messages and memory usage.
|
||||
#define _WIFIMGR_LOGLEVEL_ 3
|
||||
|
||||
#include <WiFi.h>
|
||||
#include <WiFiClient.h>
|
||||
#include <WebServer.h>
|
||||
#include <ESPmDNS.h>
|
||||
|
||||
// From v1.1.0
|
||||
#include <WiFiMulti.h>
|
||||
WiFiMulti wifiMulti;
|
||||
//////
|
||||
|
||||
// You only need to format the filesystem once
|
||||
//#define FORMAT_FILESYSTEM true
|
||||
#define FORMAT_FILESYSTEM false
|
||||
|
||||
#define USE_SPIFFS true
|
||||
|
||||
#if USE_SPIFFS
|
||||
#include <SPIFFS.h>
|
||||
FS* filesystem = &SPIFFS;
|
||||
#define FileFS SPIFFS
|
||||
#define FS_Name "SPIFFS"
|
||||
#else
|
||||
// Use FFat
|
||||
#include <FFat.h>
|
||||
FS* filesystem = &FFat;
|
||||
#define FileFS FFat
|
||||
#define FS_Name "FFat"
|
||||
#endif
|
||||
|
||||
#define DBG_OUTPUT_PORT Serial
|
||||
|
||||
// SSID and PW for Config Portal
|
||||
String ssid = "ESP_" + String((uint32_t)ESP.getEfuseMac(), HEX);
|
||||
const char* password = "your_password";
|
||||
|
||||
// SSID and PW for your Router
|
||||
String Router_SSID;
|
||||
String Router_Pass;
|
||||
|
||||
// From v1.1.0
|
||||
#define MIN_AP_PASSWORD_SIZE 8
|
||||
|
||||
#define SSID_MAX_LEN 32
|
||||
//From v1.0.10, WPA2 passwords can be up to 63 characters long.
|
||||
#define PASS_MAX_LEN 64
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char wifi_ssid[SSID_MAX_LEN];
|
||||
char wifi_pw [PASS_MAX_LEN];
|
||||
} WiFi_Credentials;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
String wifi_ssid;
|
||||
String wifi_pw;
|
||||
} WiFi_Credentials_String;
|
||||
|
||||
#define NUM_WIFI_CREDENTIALS 2
|
||||
|
||||
typedef struct
|
||||
{
|
||||
WiFi_Credentials WiFi_Creds [NUM_WIFI_CREDENTIALS];
|
||||
} WM_Config;
|
||||
|
||||
WM_Config WM_config;
|
||||
|
||||
#define CONFIG_FILENAME F("/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 <ESP_WiFiManager.h>
|
||||
#define USE_AVAILABLE_PAGES false
|
||||
|
||||
// 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)
|
||||
#define USE_ESP_WIFIMANAGER_NTP false
|
||||
|
||||
// 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)
|
||||
#define USE_CLOUDFLARE_NTP false
|
||||
|
||||
// New in v1.0.11
|
||||
#define USING_CORS_FEATURE true
|
||||
//////
|
||||
|
||||
// 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
|
||||
#define USE_DHCP_IP true
|
||||
#else
|
||||
// You can select DHCP or Static IP here
|
||||
//#define USE_DHCP_IP true
|
||||
#define USE_DHCP_IP false
|
||||
#endif
|
||||
|
||||
// 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
|
||||
#define USE_DHCP_IP true
|
||||
#else
|
||||
// You can select DHCP or Static IP here
|
||||
//#define USE_DHCP_IP true
|
||||
#define USE_DHCP_IP false
|
||||
#endif
|
||||
|
||||
#if ( USE_DHCP_IP || ( defined(USE_STATIC_IP_CONFIG_IN_CP) && !USE_STATIC_IP_CONFIG_IN_CP ) )
|
||||
// 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
|
||||
|
||||
#define USE_CONFIGURABLE_DNS true
|
||||
|
||||
IPAddress dns1IP = gatewayIP;
|
||||
IPAddress dns2IP = IPAddress(8, 8, 8, 8);
|
||||
|
||||
#include <ESP_WiFiManager.h> //https://github.com/khoih-prog/ESP_WiFiManager
|
||||
|
||||
const char* host = "esp32-fs-browser";
|
||||
|
||||
#define HTTP_PORT 80
|
||||
|
||||
WebServer server(HTTP_PORT);
|
||||
|
||||
//holds the current upload
|
||||
File fsUploadFile;
|
||||
|
||||
// Function Prototypes
|
||||
uint8_t connectMultiWiFi(void);
|
||||
|
||||
void heartBeatPrint(void)
|
||||
{
|
||||
static int num = 1;
|
||||
|
||||
if (WiFi.status() == WL_CONNECTED)
|
||||
Serial.print("H"); // H means connected to WiFi
|
||||
else
|
||||
Serial.print("F"); // F means not connected to WiFi
|
||||
|
||||
if (num == 80)
|
||||
{
|
||||
Serial.println();
|
||||
num = 1;
|
||||
}
|
||||
else if (num++ % 10 == 0)
|
||||
{
|
||||
Serial.print(" ");
|
||||
}
|
||||
}
|
||||
|
||||
void check_WiFi(void)
|
||||
{
|
||||
if ( (WiFi.status() != WL_CONNECTED) )
|
||||
{
|
||||
Serial.println("\nWiFi lost. Call connectMultiWiFi in loop");
|
||||
connectMultiWiFi();
|
||||
}
|
||||
}
|
||||
|
||||
void check_status(void)
|
||||
{
|
||||
static ulong checkstatus_timeout = 0;
|
||||
static ulong checkwifi_timeout = 0;
|
||||
|
||||
static ulong current_millis;
|
||||
|
||||
#define WIFICHECK_INTERVAL 1000L
|
||||
#define HEARTBEAT_INTERVAL 10000L
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// Print hearbeat every HEARTBEAT_INTERVAL (10) seconds.
|
||||
if ((current_millis > checkstatus_timeout) || (checkstatus_timeout == 0))
|
||||
{
|
||||
heartBeatPrint();
|
||||
checkstatus_timeout = current_millis + HEARTBEAT_INTERVAL;
|
||||
}
|
||||
}
|
||||
|
||||
//format bytes
|
||||
String formatBytes(size_t bytes)
|
||||
{
|
||||
if (bytes < 1024)
|
||||
{
|
||||
return String(bytes) + "B";
|
||||
}
|
||||
else if (bytes < (1024 * 1024))
|
||||
{
|
||||
return String(bytes / 1024.0) + "KB";
|
||||
}
|
||||
else if (bytes < (1024 * 1024 * 1024))
|
||||
{
|
||||
return String(bytes / 1024.0 / 1024.0) + "MB";
|
||||
}
|
||||
else
|
||||
{
|
||||
return String(bytes / 1024.0 / 1024.0 / 1024.0) + "GB";
|
||||
}
|
||||
}
|
||||
|
||||
String getContentType(String filename)
|
||||
{
|
||||
if (server.hasArg("download"))
|
||||
{
|
||||
return "application/octet-stream";
|
||||
}
|
||||
else if (filename.endsWith(".htm"))
|
||||
{
|
||||
return "text/html";
|
||||
}
|
||||
else if (filename.endsWith(".html"))
|
||||
{
|
||||
return "text/html";
|
||||
}
|
||||
else if (filename.endsWith(".css"))
|
||||
{
|
||||
return "text/css";
|
||||
}
|
||||
else if (filename.endsWith(".js"))
|
||||
{
|
||||
return "application/javascript";
|
||||
}
|
||||
else if (filename.endsWith(".png"))
|
||||
{
|
||||
return "image/png";
|
||||
}
|
||||
else if (filename.endsWith(".gif"))
|
||||
{
|
||||
return "image/gif";
|
||||
}
|
||||
else if (filename.endsWith(".jpg"))
|
||||
{
|
||||
return "image/jpeg";
|
||||
}
|
||||
else if (filename.endsWith(".ico"))
|
||||
{
|
||||
return "image/x-icon";
|
||||
}
|
||||
else if (filename.endsWith(".xml"))
|
||||
{
|
||||
return "text/xml";
|
||||
}
|
||||
else if (filename.endsWith(".pdf"))
|
||||
{
|
||||
return "application/x-pdf";
|
||||
}
|
||||
else if (filename.endsWith(".zip"))
|
||||
{
|
||||
return "application/x-zip";
|
||||
}
|
||||
else if (filename.endsWith(".gz"))
|
||||
{
|
||||
return "application/x-gzip";
|
||||
}
|
||||
return "text/plain";
|
||||
}
|
||||
|
||||
bool handleFileRead(String path)
|
||||
{
|
||||
DBG_OUTPUT_PORT.println("handleFileRead: " + path);
|
||||
|
||||
if (path.endsWith("/"))
|
||||
{
|
||||
path += "index.htm";
|
||||
}
|
||||
|
||||
String contentType = getContentType(path);
|
||||
String pathWithGz = path + ".gz";
|
||||
|
||||
if (filesystem->exists(pathWithGz) || filesystem->exists(path))
|
||||
{
|
||||
if (filesystem->exists(pathWithGz))
|
||||
{
|
||||
path += ".gz";
|
||||
}
|
||||
|
||||
File file = filesystem->open(path, "r");
|
||||
server.streamFile(file, contentType);
|
||||
file.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void handleFileUpload()
|
||||
{
|
||||
if (server.uri() != "/edit")
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
HTTPUpload& upload = server.upload();
|
||||
|
||||
if (upload.status == UPLOAD_FILE_START)
|
||||
{
|
||||
String filename = upload.filename;
|
||||
if (!filename.startsWith("/"))
|
||||
{
|
||||
filename = "/" + filename;
|
||||
}
|
||||
|
||||
DBG_OUTPUT_PORT.print("handleFileUpload Name: "); DBG_OUTPUT_PORT.println(filename);
|
||||
fsUploadFile = filesystem->open(filename, "w");
|
||||
filename.clear();
|
||||
}
|
||||
else if (upload.status == UPLOAD_FILE_WRITE)
|
||||
{
|
||||
//DBG_OUTPUT_PORT.print("handleFileUpload Data: "); DBG_OUTPUT_PORT.println(upload.currentSize);
|
||||
if (fsUploadFile)
|
||||
{
|
||||
fsUploadFile.write(upload.buf, upload.currentSize);
|
||||
}
|
||||
}
|
||||
else if (upload.status == UPLOAD_FILE_END)
|
||||
{
|
||||
if (fsUploadFile)
|
||||
{
|
||||
fsUploadFile.close();
|
||||
}
|
||||
DBG_OUTPUT_PORT.print("handleFileUpload Size: "); DBG_OUTPUT_PORT.println(upload.totalSize);
|
||||
}
|
||||
}
|
||||
|
||||
void handleFileDelete()
|
||||
{
|
||||
if (server.args() == 0)
|
||||
{
|
||||
return server.send(500, "text/plain", "BAD ARGS");
|
||||
}
|
||||
String path = server.arg(0);
|
||||
DBG_OUTPUT_PORT.println("handleFileDelete: " + path);
|
||||
|
||||
if (path == "/")
|
||||
{
|
||||
return server.send(500, "text/plain", "BAD PATH");
|
||||
}
|
||||
|
||||
if (!filesystem->exists(path))
|
||||
{
|
||||
return server.send(404, "text/plain", "FileNotFound");
|
||||
}
|
||||
|
||||
filesystem->remove(path);
|
||||
server.send(200, "text/plain", "");
|
||||
path.clear();
|
||||
}
|
||||
|
||||
void handleFileCreate()
|
||||
{
|
||||
if (server.args() == 0)
|
||||
{
|
||||
return server.send(500, "text/plain", "BAD ARGS");
|
||||
}
|
||||
|
||||
String path = server.arg(0);
|
||||
DBG_OUTPUT_PORT.println("handleFileCreate: " + path);
|
||||
|
||||
if (path == "/")
|
||||
{
|
||||
return server.send(500, "text/plain", "BAD PATH");
|
||||
}
|
||||
|
||||
if (filesystem->exists(path))
|
||||
{
|
||||
return server.send(500, "text/plain", "FILE EXISTS");
|
||||
}
|
||||
|
||||
File file = filesystem->open(path, "w");
|
||||
|
||||
if (file)
|
||||
{
|
||||
file.close();
|
||||
}
|
||||
else
|
||||
{
|
||||
return server.send(500, "text/plain", "CREATE FAILED");
|
||||
}
|
||||
server.send(200, "text/plain", "");
|
||||
path.clear();
|
||||
}
|
||||
|
||||
void handleFileList()
|
||||
{
|
||||
if (!server.hasArg("dir"))
|
||||
{
|
||||
server.send(500, "text/plain", "BAD ARGS");
|
||||
return;
|
||||
}
|
||||
|
||||
String path = server.arg("dir");
|
||||
DBG_OUTPUT_PORT.println("handleFileList: " + path);
|
||||
|
||||
File root = FileFS.open(path);
|
||||
path = String();
|
||||
|
||||
String output = "[";
|
||||
|
||||
if (root.isDirectory())
|
||||
{
|
||||
File file = root.openNextFile();
|
||||
|
||||
while (file)
|
||||
{
|
||||
if (output != "[")
|
||||
{
|
||||
output += ',';
|
||||
}
|
||||
|
||||
output += "{\"type\":\"";
|
||||
output += (file.isDirectory()) ? "dir" : "file";
|
||||
output += "\",\"name\":\"";
|
||||
output += String(file.name()).substring(1);
|
||||
output += "\"}";
|
||||
file = root.openNextFile();
|
||||
}
|
||||
}
|
||||
|
||||
output += "]";
|
||||
|
||||
DBG_OUTPUT_PORT.println("handleFileList: " + output);
|
||||
|
||||
server.send(200, "text/json", output);
|
||||
}
|
||||
|
||||
void loadConfigData(void)
|
||||
{
|
||||
File file = FileFS.open(CONFIG_FILENAME, "r");
|
||||
LOGERROR(F("LoadWiFiCfgFile "));
|
||||
|
||||
if (file)
|
||||
{
|
||||
file.readBytes((char *) &WM_config, sizeof(WM_config));
|
||||
file.close();
|
||||
LOGERROR(F("OK"));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGERROR(F("failed"));
|
||||
}
|
||||
}
|
||||
|
||||
void saveConfigData(void)
|
||||
{
|
||||
File file = FileFS.open(CONFIG_FILENAME, "w");
|
||||
LOGERROR(F("SaveWiFiCfgFile "));
|
||||
|
||||
if (file)
|
||||
{
|
||||
file.write((uint8_t*) &WM_config, sizeof(WM_config));
|
||||
file.close();
|
||||
LOGERROR(F("OK"));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGERROR(F("failed"));
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t connectMultiWiFi(void)
|
||||
{
|
||||
#if ESP32
|
||||
// For ESP32, this better be 0 to shorten the connect time
|
||||
#define WIFI_MULTI_1ST_CONNECT_WAITING_MS 0
|
||||
#else
|
||||
// For ESP8266, this better be 2200 to enable connect the 1st time
|
||||
#define WIFI_MULTI_1ST_CONNECT_WAITING_MS 2200L
|
||||
#endif
|
||||
|
||||
#define WIFI_MULTI_CONNECT_WAITING_MS 100L
|
||||
|
||||
uint8_t status;
|
||||
|
||||
LOGERROR(F("ConnectMultiWiFi with :"));
|
||||
|
||||
if ( (Router_SSID != "") && (Router_Pass != "") )
|
||||
{
|
||||
LOGERROR3(F("* Flash-stored Router_SSID = "), Router_SSID, F(", Router_Pass = "), Router_Pass );
|
||||
}
|
||||
|
||||
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
|
||||
#if USE_CONFIGURABLE_DNS
|
||||
// Set static IP, Gateway, Subnetmask, DNS1 and DNS2. New in v1.0.5
|
||||
WiFi.config(stationIP, gatewayIP, netMask, dns1IP, dns2IP);
|
||||
#else
|
||||
// Set static IP, Gateway, Subnetmask, Use auto DNS1 and DNS2.
|
||||
WiFi.config(stationIP, gatewayIP, netMask);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
int i = 0;
|
||||
status = wifiMulti.run();
|
||||
delay(WIFI_MULTI_1ST_CONNECT_WAITING_MS);
|
||||
|
||||
while ( ( i++ < 10 ) && ( status != WL_CONNECTED ) )
|
||||
{
|
||||
status = wifiMulti.run();
|
||||
|
||||
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"));
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void setup(void)
|
||||
{
|
||||
DBG_OUTPUT_PORT.begin(115200);
|
||||
while (!DBG_OUTPUT_PORT);
|
||||
|
||||
DBG_OUTPUT_PORT.print("\nStarting ESP32_FSWebServer with DoubleResetDetect using " + String(FS_Name));
|
||||
DBG_OUTPUT_PORT.println(" on " + String(ARDUINO_BOARD));
|
||||
|
||||
DBG_OUTPUT_PORT.setDebugOutput(false);
|
||||
|
||||
if (FORMAT_FILESYSTEM)
|
||||
FileFS.format();
|
||||
|
||||
// Format SPIFFS if not yet
|
||||
if (!FileFS.begin(true))
|
||||
{
|
||||
DBG_OUTPUT_PORT.print(FS_Name);
|
||||
DBG_OUTPUT_PORT.println(F(" failed! AutoFormatting."));
|
||||
}
|
||||
|
||||
File root = FileFS.open("/");
|
||||
File file = root.openNextFile();
|
||||
while (file)
|
||||
{
|
||||
String fileName = file.name();
|
||||
size_t fileSize = file.size();
|
||||
DBG_OUTPUT_PORT.printf("FS File: %s, size: %s\n", fileName.c_str(), formatBytes(fileSize).c_str());
|
||||
file = root.openNextFile();
|
||||
}
|
||||
|
||||
DBG_OUTPUT_PORT.println();
|
||||
|
||||
unsigned long startedAt = millis();
|
||||
|
||||
//Local intialization. Once its business is done, there is no need to keep it around
|
||||
// Use this to default DHCP hostname to ESP8266-XXXXXX or ESP32-XXXXXX
|
||||
//ESP_WiFiManager ESP_wifiManager;
|
||||
// Use this to personalize DHCP hostname (RFC952 conformed)
|
||||
ESP_WiFiManager ESP_wifiManager("ESP32-FSWebServer");
|
||||
|
||||
//set custom ip for portal
|
||||
ESP_wifiManager.setAPStaticIPConfig(IPAddress(192, 168, 100, 1), IPAddress(192, 168, 100, 1), IPAddress(255, 255, 255, 0));
|
||||
|
||||
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_DHCP_IP
|
||||
#if USE_CONFIGURABLE_DNS
|
||||
// Set static IP, Gateway, Subnetmask, DNS1 and DNS2. New in v1.0.5
|
||||
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
|
||||
|
||||
// New from v1.1.1
|
||||
#if USING_CORS_FEATURE
|
||||
ESP_wifiManager.setCORSHeader("Your Access-Control-Allow-Origin");
|
||||
#endif
|
||||
|
||||
// We can't use WiFi.SSID() in ESP32as it's only valid after connected.
|
||||
// SSID and Password stored in ESP32 wifi_ap_record_t and wifi_config_t are also cleared in reboot
|
||||
// Have to create a new function to store in EEPROM/SPIFFS for this purpose
|
||||
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
|
||||
DBG_OUTPUT_PORT.println("Stored: SSID = " + Router_SSID + ", Pass = " + Router_Pass);
|
||||
|
||||
// SSID to uppercase
|
||||
ssid.toUpperCase();
|
||||
|
||||
// From v1.1.0, Don't permit NULL password
|
||||
if ( (Router_SSID == "") || (Router_Pass == "") )
|
||||
{
|
||||
DBG_OUTPUT_PORT.println("We haven't got any access point credentials, so get them now");
|
||||
|
||||
initialConfig = true;
|
||||
|
||||
// Starts an access point
|
||||
if (!ESP_wifiManager.startConfigPortal((const char *) ssid.c_str(), password))
|
||||
DBG_OUTPUT_PORT.println("Not connected to WiFi but continuing anyway.");
|
||||
else
|
||||
DBG_OUTPUT_PORT.println("WiFi connected...yeey :)");
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
saveConfigData();
|
||||
}
|
||||
else
|
||||
{
|
||||
wifiMulti.addAP(Router_SSID.c_str(), Router_Pass.c_str());
|
||||
}
|
||||
|
||||
startedAt = millis();
|
||||
|
||||
if (!initialConfig)
|
||||
{
|
||||
// Load stored data, the addAP ready for MultiWiFi reconnection
|
||||
loadConfigData();
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
if ( WiFi.status() != WL_CONNECTED )
|
||||
{
|
||||
DBG_OUTPUT_PORT.println("ConnectMultiWiFi in setup");
|
||||
|
||||
connectMultiWiFi();
|
||||
}
|
||||
}
|
||||
|
||||
DBG_OUTPUT_PORT.print("After waiting ");
|
||||
DBG_OUTPUT_PORT.print((float) (millis() - startedAt) / 1000L);
|
||||
DBG_OUTPUT_PORT.print(" secs more in setup(), connection result is ");
|
||||
|
||||
if (WiFi.status() == WL_CONNECTED)
|
||||
{
|
||||
DBG_OUTPUT_PORT.print("connected. Local IP: ");
|
||||
DBG_OUTPUT_PORT.println(WiFi.localIP());
|
||||
}
|
||||
else
|
||||
DBG_OUTPUT_PORT.println(ESP_wifiManager.getStatus(WiFi.status()));
|
||||
|
||||
//SERVER INIT
|
||||
//list directory
|
||||
server.on("/list", HTTP_GET, handleFileList);
|
||||
|
||||
//load editor
|
||||
server.on("/edit", HTTP_GET, []()
|
||||
{
|
||||
if (!handleFileRead("/edit.htm"))
|
||||
{
|
||||
server.send(404, "text/plain", "FileNotFound");
|
||||
}
|
||||
});
|
||||
|
||||
//create file
|
||||
server.on("/edit", HTTP_PUT, handleFileCreate);
|
||||
|
||||
//delete file
|
||||
server.on("/edit", HTTP_DELETE, handleFileDelete);
|
||||
|
||||
//first callback is called after the request has ended with all parsed arguments
|
||||
//second callback handles file uploads at that location
|
||||
server.on("/edit", HTTP_POST, []()
|
||||
{
|
||||
server.send(200, "text/plain", "");
|
||||
}, handleFileUpload);
|
||||
|
||||
//called when the url is not defined here
|
||||
//use it to load content from SPIFFS
|
||||
server.onNotFound([]()
|
||||
{
|
||||
if (!handleFileRead(server.uri()))
|
||||
{
|
||||
server.send(404, "text/plain", "FileNotFound");
|
||||
}
|
||||
});
|
||||
|
||||
//get heap status, analog input value and all GPIO statuses in one json call
|
||||
server.on("/all", HTTP_GET, []()
|
||||
{
|
||||
String json = "{";
|
||||
json += "\"heap\":" + String(ESP.getFreeHeap());
|
||||
json += ", \"analog\":" + String(analogRead(A0));
|
||||
json += ", \"gpio\":" + String((uint32_t)(0));
|
||||
json += "}";
|
||||
server.send(200, "text/json", json);
|
||||
json = String();
|
||||
});
|
||||
|
||||
server.begin();
|
||||
|
||||
DBG_OUTPUT_PORT.print("HTTP server started @ ");
|
||||
DBG_OUTPUT_PORT.println(WiFi.localIP());
|
||||
|
||||
MDNS.begin(host);
|
||||
// Add service to MDNS-SD
|
||||
MDNS.addService("http", "tcp", HTTP_PORT);
|
||||
|
||||
DBG_OUTPUT_PORT.print("Open http://");
|
||||
DBG_OUTPUT_PORT.print(host);
|
||||
DBG_OUTPUT_PORT.println(".local/edit to see the file browser");
|
||||
}
|
||||
|
||||
void loop(void)
|
||||
{
|
||||
server.handleClient();
|
||||
|
||||
// this is just for checking if we are alive and connected to WiFi
|
||||
check_status();
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
# ESP_FSWebServer Example
|
||||
|
||||
## First, how Config Portal works?
|
||||
In `Configuration Portal Mode`, it starts an access point called `ESP_xxxxxx`. Connect to it using the configurable password you can define in the code. For example, `your_password` (see examples):
|
||||
|
||||
```cpp
|
||||
// SSID and PW for Config Portal
|
||||
String ssid = "ESP_" + String(ESP_getChipId(), HEX);
|
||||
const char* password = "your_password";
|
||||
```
|
||||
After you connected, please, go to http://192.168.4.1, you'll see this `Main` page:
|
||||
|
||||
<p align="center">
|
||||
<img src="https://github.com/khoih-prog/ESP_WiFiManager/blob/master/Images/Main.png">
|
||||
</p>
|
||||
|
||||
Select `Information` to enter the Info page where the board info will be shown (long page)
|
||||
|
||||
<p align="center">
|
||||
<img src="https://github.com/khoih-prog/ESP_WiFiManager/blob/master/Images/Info.png">
|
||||
</p>
|
||||
|
||||
or short page (default)
|
||||
|
||||
<p align="center">
|
||||
<img src="https://github.com/khoih-prog/ESP_WiFiManager/blob/master/Images/Info_Short.png">
|
||||
</p>
|
||||
|
||||
Select `Configuration` to enter this page where you can select an AP and specify its WiFi Credentials
|
||||
|
||||
<p align="center">
|
||||
<img src="https://github.com/khoih-prog/ESP_WiFiManager/blob/master/Images/Configuration.png">
|
||||
</p>
|
||||
|
||||
Enter your credentials, then click `Save`. 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 select `Exit Portal` from the `Main` page to reboot the board and connect to the previously-stored AP. The WiFi Credentials are still intact.
|
||||
|
||||
|
||||
## How to use this ESP_FSWebServer example?
|
||||
|
||||
This shows you how to use this example in Ubuntu (but you can use similar commands in other OSes)
|
||||
|
||||
1. For example, you already downloaded from (https://github.com/khoih-prog/ESP_WiFiManager/tree/master/examples/ESP_FSWebServer/data) to a local folder, e.g.,
|
||||
|
||||
~/Arduino/libraries/ESP_WiFiManager-master/examples/ESP_FSWebServer/data
|
||||
|
||||
1. Upload the contents of that `data folder` with MkSPIFFS Tool ("ESP8266 Sketch Data Upload" in Tools menu in Arduino IDE)
|
||||
2. or upload the contents of a folder by running the following commands:
|
||||
- Ubuntu$ cd ~/Arduino/libraries/ESP_WiFiManager-master/examples/ESP_FSWebServer/data
|
||||
- Ubuntu$ for file in \`\ls -A1\`; do curl -F "file=@$PWD/$file" esp8266fs.local/edit; done
|
||||
3. Access the sample web page at http://esp8266fs.local
|
||||
|
||||
<p align="center">
|
||||
<img src="https://github.com/khoih-prog/ESP_WiFiManager/blob/master/examples/ESP_FSWebServer/pics/esp8266fs.local.png">
|
||||
</p>
|
||||
|
||||
4. Edit / Delete / Download any file in the the folder by going to http://esp8266fs.local/edit
|
||||
|
||||
<p align="center">
|
||||
<img src="https://github.com/khoih-prog/ESP_WiFiManager/blob/master/examples/ESP_FSWebServer/pics/esp8266fs.local_edit.png">
|
||||
</p>
|
||||
|
||||
|
||||
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 8.1 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,97 @@
|
||||
<!--
|
||||
FSWebServer - Example Index Page
|
||||
Copyright (c) 2015 Hristo Gochkov. All rights reserved.
|
||||
This file is part of the WebServer library for Arduino environment.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
-->
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
|
||||
<title>ESP Monitor</title>
|
||||
<script type="text/javascript" src="graphs.js"></script>
|
||||
<script type="text/javascript">
|
||||
var heap,temp,digi;
|
||||
var reloadPeriod = 1000;
|
||||
var running = false;
|
||||
|
||||
function loadValues(){
|
||||
if(!running) return;
|
||||
var xh = new XMLHttpRequest();
|
||||
xh.onreadystatechange = function(){
|
||||
if (xh.readyState == 4){
|
||||
if(xh.status == 200) {
|
||||
var res = JSON.parse(xh.responseText);
|
||||
heap.add(res.heap);
|
||||
temp.add(res.analog);
|
||||
digi.add(res.gpio);
|
||||
if(running) setTimeout(loadValues, reloadPeriod);
|
||||
} else running = false;
|
||||
}
|
||||
};
|
||||
xh.open("GET", "/all", true);
|
||||
xh.send(null);
|
||||
};
|
||||
|
||||
function run(){
|
||||
if(!running){
|
||||
running = true;
|
||||
loadValues();
|
||||
}
|
||||
}
|
||||
|
||||
function onBodyLoad(){
|
||||
var refreshInput = document.getElementById("refresh-rate");
|
||||
refreshInput.value = reloadPeriod;
|
||||
refreshInput.onchange = function(e){
|
||||
var value = parseInt(e.target.value);
|
||||
reloadPeriod = (value > 0)?value:0;
|
||||
e.target.value = reloadPeriod;
|
||||
}
|
||||
var stopButton = document.getElementById("stop-button");
|
||||
stopButton.onclick = function(e){
|
||||
running = false;
|
||||
}
|
||||
var startButton = document.getElementById("start-button");
|
||||
startButton.onclick = function(e){
|
||||
run();
|
||||
}
|
||||
|
||||
// Example with 10K thermistor
|
||||
//function calcThermistor(v) {
|
||||
// var t = Math.log(((10230000 / v) - 10000));
|
||||
// t = (1/(0.001129148+(0.000234125*t)+(0.0000000876741*t*t*t)))-273.15;
|
||||
// return (t>120)?0:Math.round(t*10)/10;
|
||||
//}
|
||||
//temp = createGraph(document.getElementById("analog"), "Temperature", 100, 128, 10, 40, false, "cyan", calcThermistor);
|
||||
|
||||
temp = createGraph(document.getElementById("analog"), "Analog Input", 100, 128, 0, 1023, false, "cyan");
|
||||
heap = createGraph(document.getElementById("heap"), "Current Heap", 100, 125, 0, 30000, true, "orange");
|
||||
digi = createDigiGraph(document.getElementById("digital"), "GPIO", 100, 146, [0, 4, 5, 16], "gold");
|
||||
run();
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body id="index" style="margin:0; padding:0;" onload="onBodyLoad()">
|
||||
<div id="controls" style="display: block; border: 1px solid rgb(68, 68, 68); padding: 5px; margin: 5px; width: 362px; background-color: rgb(238, 238, 238);">
|
||||
<label>Period (ms):</label>
|
||||
<input type="number" id="refresh-rate"/>
|
||||
<input type="button" id="start-button" value="Start"/>
|
||||
<input type="button" id="stop-button" value="Stop"/>
|
||||
</div>
|
||||
<div id="heap"></div>
|
||||
<div id="analog"></div>
|
||||
<div id="digital"></div>
|
||||
</body>
|
||||
</html>
|
||||
|
After Width: | Height: | Size: 45 KiB |
|
After Width: | Height: | Size: 77 KiB |
@@ -0,0 +1,913 @@
|
||||
/****************************************************************************************************************************
|
||||
ESP32_FSWebServer_DRD - Example WebServer with SPIFFS backend for esp32 with DoubleResetDetect feature
|
||||
For ESP32 boards
|
||||
|
||||
ESP_WiFiManager is a library for the ESP8266/ESP32 platform (https://github.com/esp8266/Arduino) to enable easy
|
||||
configuration and reconfiguration of WiFi credentials using a Captive Portal.
|
||||
|
||||
Modified from Tzapu https://github.com/tzapu/WiFiManager
|
||||
and from Ken Taylor https://github.com/kentaylor
|
||||
|
||||
Built by Khoi Hoang https://github.com/khoih-prog/ESP_WiFiManager
|
||||
Licensed under MIT license
|
||||
|
||||
Example modified from https://github.com/esp8266/Arduino/blob/master/libraries/ESP8266WebServer/examples/FSBrowser/FSBrowser.ino
|
||||
|
||||
Copyright (c) 2015 Hristo Gochkov. All rights reserved.
|
||||
This file is part of the ESP8266WebServer library for Arduino environment.
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Version: 1.2.0
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 07/10/2019 Initial coding
|
||||
1.0.1 K Hoang 13/12/2019 Fix bug. Add features. Add support for ESP32
|
||||
1.0.2 K Hoang 19/12/2019 Fix bug thatkeeps ConfigPortal in endless loop if Portal/Router SSID or Password is NULL.
|
||||
1.0.3 K Hoang 05/01/2020 Option not displaying AvailablePages in Info page. Enhance README.md. Modify examples
|
||||
1.0.4 K Hoang 07/01/2020 Add RFC952 setHostname feature.
|
||||
1.0.5 K Hoang 15/01/2020 Add configurable DNS feature. Thanks to @Amorphous of https://community.blynk.cc
|
||||
1.0.6 K Hoang 03/02/2020 Add support for ArduinoJson version 6.0.0+ ( tested with v6.14.1 )
|
||||
1.0.7 K Hoang 13/04/2020 Reduce start time, fix SPIFFS bug in examples, update README.md
|
||||
1.0.8 K Hoang 10/06/2020 Fix STAstaticIP issue. Restructure code. Add LittleFS support for ESP8266 core 2.7.1+
|
||||
1.0.9 K Hoang 29/07/2020 Fix ESP32 STAstaticIP bug. Permit changing from DHCP <-> static IP using Config Portal.
|
||||
Add, enhance examples (fix MDNS for ESP32)
|
||||
1.0.10 K Hoang 08/08/2020 Add more features to Config Portal. Use random WiFi AP channel to avoid conflict.
|
||||
1.0.11 K Hoang 17/08/2020 Add CORS feature. Fix bug in softAP, autoConnect, resetSettings.
|
||||
1.1.0 K Hoang 28/08/2020 Add MultiWiFi feature to autoconnect to best WiFi at runtime
|
||||
1.1.1 K Hoang 30/08/2020 Add setCORSHeader function to allow flexible CORS. Fix typo and minor improvement.
|
||||
1.1.2 K Hoang 17/08/2020 Fix bug. Add example.
|
||||
1.2.0 K Hoang 09/10/2020 Restore cpp code besides Impl.h code to use if linker error. Fix bug.
|
||||
*****************************************************************************************************************************/
|
||||
/*****************************************************************************************************************************
|
||||
How To Use:
|
||||
1) Upload the contents of the data folder with MkSPIFFS Tool ("ESP32 Sketch Data Upload" in Tools menu in Arduino IDE)
|
||||
2) or you can upload the contents of a folder if you CD in that folder and run the following command:
|
||||
for file in `\ls -A1`; do curl -F "file=@$PWD/$file" esp32-fs-browser.local/edit; done
|
||||
3) access the sample web page at http://esp32-fs-browser.local
|
||||
4) edit the page by going to http://esp32-fs-browser.local/edit
|
||||
*****************************************************************************************************************************/
|
||||
#if !defined(ESP32)
|
||||
#error This code is intended to run on the ESP32 platform! Please check your Tools->Board setting.
|
||||
#endif
|
||||
|
||||
// Use from 0 to 4. Higher number, more debugging messages and memory usage.
|
||||
#define _WIFIMGR_LOGLEVEL_ 3
|
||||
|
||||
#include <WiFi.h>
|
||||
#include <WiFiClient.h>
|
||||
#include <WebServer.h>
|
||||
#include <ESPmDNS.h>
|
||||
|
||||
// From v1.1.0
|
||||
#include <WiFiMulti.h>
|
||||
WiFiMulti wifiMulti;
|
||||
//////
|
||||
|
||||
#define USE_SPIFFS true
|
||||
|
||||
// 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_SPIFFS
|
||||
#define ESP_DRD_USE_SPIFFS true
|
||||
#define ESP_DRD_USE_EEPROM false
|
||||
#else
|
||||
#define ESP_DRD_USE_SPIFFS false
|
||||
#define ESP_DRD_USE_EEPROM true
|
||||
#endif
|
||||
|
||||
#define DOUBLERESETDETECTOR_DEBUG true //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.
|
||||
#define DRD_TIMEOUT 10
|
||||
|
||||
// RTC Memory Address for the DoubleResetDetector to use
|
||||
#define DRD_ADDRESS 0
|
||||
|
||||
//DoubleResetDetector drd(DRD_TIMEOUT, DRD_ADDRESS);
|
||||
DoubleResetDetector* drd;
|
||||
//////
|
||||
|
||||
// You only need to format the filesystem once
|
||||
//#define FORMAT_FILESYSTEM true
|
||||
#define FORMAT_FILESYSTEM false
|
||||
|
||||
#if USE_SPIFFS
|
||||
#include <SPIFFS.h>
|
||||
FS* filesystem = &SPIFFS;
|
||||
#define FileFS SPIFFS
|
||||
#define FS_Name "SPIFFS"
|
||||
#else
|
||||
// Use FFat
|
||||
#include <FFat.h>
|
||||
FS* filesystem = &FFat;
|
||||
#define FileFS FFat
|
||||
#define FS_Name "FFat"
|
||||
#endif
|
||||
|
||||
#define DBG_OUTPUT_PORT Serial
|
||||
|
||||
// SSID and PW for Config Portal
|
||||
String ssid = "ESP_" + String((uint32_t)ESP.getEfuseMac(), HEX);
|
||||
const char* password = "your_password";
|
||||
|
||||
// SSID and PW for your Router
|
||||
String Router_SSID;
|
||||
String Router_Pass;
|
||||
|
||||
// From v1.1.0
|
||||
#define MIN_AP_PASSWORD_SIZE 8
|
||||
|
||||
#define SSID_MAX_LEN 32
|
||||
//From v1.0.10, WPA2 passwords can be up to 63 characters long.
|
||||
#define PASS_MAX_LEN 64
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char wifi_ssid[SSID_MAX_LEN];
|
||||
char wifi_pw [PASS_MAX_LEN];
|
||||
} WiFi_Credentials;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
String wifi_ssid;
|
||||
String wifi_pw;
|
||||
} WiFi_Credentials_String;
|
||||
|
||||
#define NUM_WIFI_CREDENTIALS 2
|
||||
|
||||
typedef struct
|
||||
{
|
||||
WiFi_Credentials WiFi_Creds [NUM_WIFI_CREDENTIALS];
|
||||
} WM_Config;
|
||||
|
||||
WM_Config WM_config;
|
||||
|
||||
#define CONFIG_FILENAME F("/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 <ESP_WiFiManager.h>
|
||||
#define USE_AVAILABLE_PAGES false
|
||||
|
||||
// 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)
|
||||
#define USE_ESP_WIFIMANAGER_NTP false
|
||||
|
||||
// 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)
|
||||
#define USE_CLOUDFLARE_NTP false
|
||||
|
||||
// New in v1.0.11
|
||||
#define USING_CORS_FEATURE true
|
||||
//////
|
||||
|
||||
// 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
|
||||
#define USE_DHCP_IP true
|
||||
#else
|
||||
// You can select DHCP or Static IP here
|
||||
//#define USE_DHCP_IP true
|
||||
#define USE_DHCP_IP false
|
||||
#endif
|
||||
|
||||
// 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
|
||||
#define USE_DHCP_IP true
|
||||
#else
|
||||
// You can select DHCP or Static IP here
|
||||
//#define USE_DHCP_IP true
|
||||
#define USE_DHCP_IP false
|
||||
#endif
|
||||
|
||||
#if ( USE_DHCP_IP || ( defined(USE_STATIC_IP_CONFIG_IN_CP) && !USE_STATIC_IP_CONFIG_IN_CP ) )
|
||||
// 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
|
||||
|
||||
#define USE_CONFIGURABLE_DNS true
|
||||
|
||||
IPAddress dns1IP = gatewayIP;
|
||||
IPAddress dns2IP = IPAddress(8, 8, 8, 8);
|
||||
|
||||
#include <ESP_WiFiManager.h> //https://github.com/khoih-prog/ESP_WiFiManager
|
||||
|
||||
const char* host = "esp32-fs-browser";
|
||||
|
||||
#define HTTP_PORT 80
|
||||
|
||||
WebServer server(HTTP_PORT);
|
||||
|
||||
//holds the current upload
|
||||
File fsUploadFile;
|
||||
|
||||
// Function Prototypes
|
||||
uint8_t connectMultiWiFi(void);
|
||||
|
||||
void heartBeatPrint(void)
|
||||
{
|
||||
static int num = 1;
|
||||
|
||||
if (WiFi.status() == WL_CONNECTED)
|
||||
Serial.print("H"); // H means connected to WiFi
|
||||
else
|
||||
Serial.print("F"); // F means not connected to WiFi
|
||||
|
||||
if (num == 80)
|
||||
{
|
||||
Serial.println();
|
||||
num = 1;
|
||||
}
|
||||
else if (num++ % 10 == 0)
|
||||
{
|
||||
Serial.print(" ");
|
||||
}
|
||||
}
|
||||
|
||||
void check_WiFi(void)
|
||||
{
|
||||
if ( (WiFi.status() != WL_CONNECTED) )
|
||||
{
|
||||
Serial.println("\nWiFi lost. Call connectMultiWiFi in loop");
|
||||
connectMultiWiFi();
|
||||
}
|
||||
}
|
||||
|
||||
void check_status(void)
|
||||
{
|
||||
static ulong checkstatus_timeout = 0;
|
||||
static ulong checkwifi_timeout = 0;
|
||||
|
||||
static ulong current_millis;
|
||||
|
||||
#define WIFICHECK_INTERVAL 1000L
|
||||
#define HEARTBEAT_INTERVAL 10000L
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// Print hearbeat every HEARTBEAT_INTERVAL (10) seconds.
|
||||
if ((current_millis > checkstatus_timeout) || (checkstatus_timeout == 0))
|
||||
{
|
||||
heartBeatPrint();
|
||||
checkstatus_timeout = current_millis + HEARTBEAT_INTERVAL;
|
||||
}
|
||||
}
|
||||
|
||||
//format bytes
|
||||
String formatBytes(size_t bytes)
|
||||
{
|
||||
if (bytes < 1024)
|
||||
{
|
||||
return String(bytes) + "B";
|
||||
}
|
||||
else if (bytes < (1024 * 1024))
|
||||
{
|
||||
return String(bytes / 1024.0) + "KB";
|
||||
}
|
||||
else if (bytes < (1024 * 1024 * 1024))
|
||||
{
|
||||
return String(bytes / 1024.0 / 1024.0) + "MB";
|
||||
}
|
||||
else
|
||||
{
|
||||
return String(bytes / 1024.0 / 1024.0 / 1024.0) + "GB";
|
||||
}
|
||||
}
|
||||
|
||||
String getContentType(String filename)
|
||||
{
|
||||
if (server.hasArg("download"))
|
||||
{
|
||||
return "application/octet-stream";
|
||||
}
|
||||
else if (filename.endsWith(".htm"))
|
||||
{
|
||||
return "text/html";
|
||||
}
|
||||
else if (filename.endsWith(".html"))
|
||||
{
|
||||
return "text/html";
|
||||
}
|
||||
else if (filename.endsWith(".css"))
|
||||
{
|
||||
return "text/css";
|
||||
}
|
||||
else if (filename.endsWith(".js"))
|
||||
{
|
||||
return "application/javascript";
|
||||
}
|
||||
else if (filename.endsWith(".png"))
|
||||
{
|
||||
return "image/png";
|
||||
}
|
||||
else if (filename.endsWith(".gif"))
|
||||
{
|
||||
return "image/gif";
|
||||
}
|
||||
else if (filename.endsWith(".jpg"))
|
||||
{
|
||||
return "image/jpeg";
|
||||
}
|
||||
else if (filename.endsWith(".ico"))
|
||||
{
|
||||
return "image/x-icon";
|
||||
}
|
||||
else if (filename.endsWith(".xml"))
|
||||
{
|
||||
return "text/xml";
|
||||
}
|
||||
else if (filename.endsWith(".pdf"))
|
||||
{
|
||||
return "application/x-pdf";
|
||||
}
|
||||
else if (filename.endsWith(".zip"))
|
||||
{
|
||||
return "application/x-zip";
|
||||
}
|
||||
else if (filename.endsWith(".gz"))
|
||||
{
|
||||
return "application/x-gzip";
|
||||
}
|
||||
return "text/plain";
|
||||
}
|
||||
|
||||
bool handleFileRead(String path)
|
||||
{
|
||||
DBG_OUTPUT_PORT.println("handleFileRead: " + path);
|
||||
|
||||
if (path.endsWith("/"))
|
||||
{
|
||||
path += "index.htm";
|
||||
}
|
||||
|
||||
String contentType = getContentType(path);
|
||||
String pathWithGz = path + ".gz";
|
||||
|
||||
if (filesystem->exists(pathWithGz) || filesystem->exists(path))
|
||||
{
|
||||
if (filesystem->exists(pathWithGz))
|
||||
{
|
||||
path += ".gz";
|
||||
}
|
||||
|
||||
File file = filesystem->open(path, "r");
|
||||
server.streamFile(file, contentType);
|
||||
file.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void handleFileUpload()
|
||||
{
|
||||
if (server.uri() != "/edit")
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
HTTPUpload& upload = server.upload();
|
||||
|
||||
if (upload.status == UPLOAD_FILE_START)
|
||||
{
|
||||
String filename = upload.filename;
|
||||
if (!filename.startsWith("/"))
|
||||
{
|
||||
filename = "/" + filename;
|
||||
}
|
||||
|
||||
DBG_OUTPUT_PORT.print("handleFileUpload Name: "); DBG_OUTPUT_PORT.println(filename);
|
||||
fsUploadFile = filesystem->open(filename, "w");
|
||||
filename.clear();
|
||||
}
|
||||
else if (upload.status == UPLOAD_FILE_WRITE)
|
||||
{
|
||||
//DBG_OUTPUT_PORT.print("handleFileUpload Data: "); DBG_OUTPUT_PORT.println(upload.currentSize);
|
||||
if (fsUploadFile)
|
||||
{
|
||||
fsUploadFile.write(upload.buf, upload.currentSize);
|
||||
}
|
||||
}
|
||||
else if (upload.status == UPLOAD_FILE_END)
|
||||
{
|
||||
if (fsUploadFile)
|
||||
{
|
||||
fsUploadFile.close();
|
||||
}
|
||||
DBG_OUTPUT_PORT.print("handleFileUpload Size: "); DBG_OUTPUT_PORT.println(upload.totalSize);
|
||||
}
|
||||
}
|
||||
|
||||
void handleFileDelete()
|
||||
{
|
||||
if (server.args() == 0)
|
||||
{
|
||||
return server.send(500, "text/plain", "BAD ARGS");
|
||||
}
|
||||
String path = server.arg(0);
|
||||
DBG_OUTPUT_PORT.println("handleFileDelete: " + path);
|
||||
|
||||
if (path == "/")
|
||||
{
|
||||
return server.send(500, "text/plain", "BAD PATH");
|
||||
}
|
||||
|
||||
if (!filesystem->exists(path))
|
||||
{
|
||||
return server.send(404, "text/plain", "FileNotFound");
|
||||
}
|
||||
|
||||
filesystem->remove(path);
|
||||
server.send(200, "text/plain", "");
|
||||
path.clear();
|
||||
}
|
||||
|
||||
void handleFileCreate()
|
||||
{
|
||||
if (server.args() == 0)
|
||||
{
|
||||
return server.send(500, "text/plain", "BAD ARGS");
|
||||
}
|
||||
|
||||
String path = server.arg(0);
|
||||
DBG_OUTPUT_PORT.println("handleFileCreate: " + path);
|
||||
|
||||
if (path == "/")
|
||||
{
|
||||
return server.send(500, "text/plain", "BAD PATH");
|
||||
}
|
||||
|
||||
if (filesystem->exists(path))
|
||||
{
|
||||
return server.send(500, "text/plain", "FILE EXISTS");
|
||||
}
|
||||
|
||||
File file = filesystem->open(path, "w");
|
||||
|
||||
if (file)
|
||||
{
|
||||
file.close();
|
||||
}
|
||||
else
|
||||
{
|
||||
return server.send(500, "text/plain", "CREATE FAILED");
|
||||
}
|
||||
server.send(200, "text/plain", "");
|
||||
path.clear();
|
||||
}
|
||||
|
||||
void handleFileList()
|
||||
{
|
||||
if (!server.hasArg("dir"))
|
||||
{
|
||||
server.send(500, "text/plain", "BAD ARGS");
|
||||
return;
|
||||
}
|
||||
|
||||
String path = server.arg("dir");
|
||||
DBG_OUTPUT_PORT.println("handleFileList: " + path);
|
||||
|
||||
File root = filesystem->open(path);
|
||||
path = String();
|
||||
|
||||
String output = "[";
|
||||
|
||||
if (root.isDirectory())
|
||||
{
|
||||
File file = root.openNextFile();
|
||||
|
||||
while (file)
|
||||
{
|
||||
if (output != "[")
|
||||
{
|
||||
output += ',';
|
||||
}
|
||||
|
||||
output += "{\"type\":\"";
|
||||
output += (file.isDirectory()) ? "dir" : "file";
|
||||
output += "\",\"name\":\"";
|
||||
output += String(file.name()).substring(1);
|
||||
output += "\"}";
|
||||
file = root.openNextFile();
|
||||
}
|
||||
}
|
||||
|
||||
output += "]";
|
||||
|
||||
DBG_OUTPUT_PORT.println("handleFileList: " + output);
|
||||
|
||||
server.send(200, "text/json", output);
|
||||
}
|
||||
|
||||
void loadConfigData(void)
|
||||
{
|
||||
File file = FileFS.open(CONFIG_FILENAME, "r");
|
||||
LOGERROR(F("LoadWiFiCfgFile "));
|
||||
|
||||
if (file)
|
||||
{
|
||||
file.readBytes((char *) &WM_config, sizeof(WM_config));
|
||||
file.close();
|
||||
LOGERROR(F("OK"));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGERROR(F("failed"));
|
||||
}
|
||||
}
|
||||
|
||||
void saveConfigData(void)
|
||||
{
|
||||
File file = FileFS.open(CONFIG_FILENAME, "w");
|
||||
LOGERROR(F("SaveWiFiCfgFile "));
|
||||
|
||||
if (file)
|
||||
{
|
||||
file.write((uint8_t*) &WM_config, sizeof(WM_config));
|
||||
file.close();
|
||||
LOGERROR(F("OK"));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGERROR(F("failed"));
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t connectMultiWiFi(void)
|
||||
{
|
||||
#if ESP32
|
||||
// For ESP32, this better be 0 to shorten the connect time
|
||||
#define WIFI_MULTI_1ST_CONNECT_WAITING_MS 0
|
||||
#else
|
||||
// For ESP8266, this better be 2200 to enable connect the 1st time
|
||||
#define WIFI_MULTI_1ST_CONNECT_WAITING_MS 2200L
|
||||
#endif
|
||||
|
||||
#define WIFI_MULTI_CONNECT_WAITING_MS 100L
|
||||
|
||||
uint8_t status;
|
||||
|
||||
LOGERROR(F("ConnectMultiWiFi with :"));
|
||||
|
||||
if ( (Router_SSID != "") && (Router_Pass != "") )
|
||||
{
|
||||
LOGERROR3(F("* Flash-stored Router_SSID = "), Router_SSID, F(", Router_Pass = "), Router_Pass );
|
||||
}
|
||||
|
||||
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
|
||||
#if USE_CONFIGURABLE_DNS
|
||||
// Set static IP, Gateway, Subnetmask, DNS1 and DNS2. New in v1.0.5
|
||||
WiFi.config(stationIP, gatewayIP, netMask, dns1IP, dns2IP);
|
||||
#else
|
||||
// Set static IP, Gateway, Subnetmask, Use auto DNS1 and DNS2.
|
||||
WiFi.config(stationIP, gatewayIP, netMask);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
int i = 0;
|
||||
status = wifiMulti.run();
|
||||
delay(WIFI_MULTI_1ST_CONNECT_WAITING_MS);
|
||||
|
||||
while ( ( i++ < 10 ) && ( status != WL_CONNECTED ) )
|
||||
{
|
||||
status = wifiMulti.run();
|
||||
|
||||
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"));
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void setup(void)
|
||||
{
|
||||
DBG_OUTPUT_PORT.begin(115200);
|
||||
while (!DBG_OUTPUT_PORT);
|
||||
|
||||
DBG_OUTPUT_PORT.print("\nStarting ESP32_FSWebServer_DRD with DoubleResetDetect using " + String(FS_Name));
|
||||
DBG_OUTPUT_PORT.println(" on " + String(ARDUINO_BOARD));
|
||||
|
||||
DBG_OUTPUT_PORT.setDebugOutput(false);
|
||||
|
||||
drd = new DoubleResetDetector(DRD_TIMEOUT, DRD_ADDRESS);
|
||||
|
||||
if (FORMAT_FILESYSTEM)
|
||||
FileFS.format();
|
||||
|
||||
// Format SPIFFS if not yet
|
||||
if (!FileFS.begin(true))
|
||||
{
|
||||
DBG_OUTPUT_PORT.print(FS_Name);
|
||||
DBG_OUTPUT_PORT.println(F(" failed! AutoFormatting."));
|
||||
}
|
||||
|
||||
File root = filesystem->open("/");
|
||||
File file = root.openNextFile();
|
||||
|
||||
while (file)
|
||||
{
|
||||
String fileName = file.name();
|
||||
size_t fileSize = file.size();
|
||||
DBG_OUTPUT_PORT.printf("FS File: %s, size: %s\n", fileName.c_str(), formatBytes(fileSize).c_str());
|
||||
file = root.openNextFile();
|
||||
}
|
||||
|
||||
DBG_OUTPUT_PORT.println();
|
||||
|
||||
unsigned long startedAt = millis();
|
||||
|
||||
//Local intialization. Once its business is done, there is no need to keep it around
|
||||
// Use this to default DHCP hostname to ESP8266-XXXXXX or ESP32-XXXXXX
|
||||
//ESP_WiFiManager ESP_wifiManager;
|
||||
// Use this to personalize DHCP hostname (RFC952 conformed)
|
||||
ESP_WiFiManager ESP_wifiManager("ESP32-FSWebServer_DRD");
|
||||
|
||||
//set custom ip for portal
|
||||
ESP_wifiManager.setAPStaticIPConfig(IPAddress(192, 168, 232, 1), IPAddress(192, 168, 232, 1), IPAddress(255, 255, 255, 0));
|
||||
|
||||
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_DHCP_IP
|
||||
#if USE_CONFIGURABLE_DNS
|
||||
// Set static IP, Gateway, Subnetmask, DNS1 and DNS2. New in v1.0.5
|
||||
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
|
||||
|
||||
// New from v1.1.1
|
||||
#if USING_CORS_FEATURE
|
||||
ESP_wifiManager.setCORSHeader("Your Access-Control-Allow-Origin");
|
||||
#endif
|
||||
|
||||
// We can't use WiFi.SSID() in ESP32as it's only valid after connected.
|
||||
// SSID and Password stored in ESP32 wifi_ap_record_t and wifi_config_t are also cleared in reboot
|
||||
// Have to create a new function to store in EEPROM/SPIFFS for this purpose
|
||||
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
|
||||
DBG_OUTPUT_PORT.println("Stored: SSID = " + Router_SSID + ", Pass = " + Router_Pass);
|
||||
|
||||
// SSID to uppercase
|
||||
ssid.toUpperCase();
|
||||
|
||||
// From v1.1.0, Don't permit NULL password
|
||||
if ( (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("Got stored Credentials. Timeout 120s for Config Portal");
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println("Open Config Portal without Timeout: No stored Credentials.");
|
||||
initialConfig = true;
|
||||
}
|
||||
|
||||
if (drd->detectDoubleReset())
|
||||
{
|
||||
// DRD, disable timeout.
|
||||
ESP_wifiManager.setConfigPortalTimeout(0);
|
||||
|
||||
DBG_OUTPUT_PORT.println("Open Config Portal without Timeout: Double Reset Detected");
|
||||
initialConfig = true;
|
||||
}
|
||||
|
||||
if (initialConfig)
|
||||
{
|
||||
// Starts an access point
|
||||
if (!ESP_wifiManager.startConfigPortal((const char *) ssid.c_str(), password))
|
||||
DBG_OUTPUT_PORT.println("Not connected to WiFi but continuing anyway.");
|
||||
else
|
||||
{
|
||||
DBG_OUTPUT_PORT.println("WiFi connected...yeey :)");
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
saveConfigData();
|
||||
}
|
||||
|
||||
startedAt = millis();
|
||||
|
||||
if (!initialConfig)
|
||||
{
|
||||
// Load stored data, the addAP ready for MultiWiFi reconnection
|
||||
loadConfigData();
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
if ( WiFi.status() != WL_CONNECTED )
|
||||
{
|
||||
DBG_OUTPUT_PORT.println("ConnectMultiWiFi in setup");
|
||||
|
||||
connectMultiWiFi();
|
||||
}
|
||||
}
|
||||
|
||||
DBG_OUTPUT_PORT.print("After waiting ");
|
||||
DBG_OUTPUT_PORT.print((float) (millis() - startedAt) / 1000L);
|
||||
DBG_OUTPUT_PORT.print(" secs more in setup(), connection result is ");
|
||||
|
||||
if (WiFi.status() == WL_CONNECTED)
|
||||
{
|
||||
DBG_OUTPUT_PORT.print("connected. Local IP: ");
|
||||
DBG_OUTPUT_PORT.println(WiFi.localIP());
|
||||
}
|
||||
else
|
||||
DBG_OUTPUT_PORT.println(ESP_wifiManager.getStatus(WiFi.status()));
|
||||
|
||||
//SERVER INIT
|
||||
//list directory
|
||||
server.on("/list", HTTP_GET, handleFileList);
|
||||
|
||||
//load editor
|
||||
server.on("/edit", HTTP_GET, []()
|
||||
{
|
||||
if (!handleFileRead("/edit.htm"))
|
||||
{
|
||||
server.send(404, "text/plain", "FileNotFound");
|
||||
}
|
||||
});
|
||||
|
||||
//create file
|
||||
server.on("/edit", HTTP_PUT, handleFileCreate);
|
||||
|
||||
//delete file
|
||||
server.on("/edit", HTTP_DELETE, handleFileDelete);
|
||||
|
||||
//first callback is called after the request has ended with all parsed arguments
|
||||
//second callback handles file uploads at that location
|
||||
server.on("/edit", HTTP_POST, []()
|
||||
{
|
||||
server.send(200, "text/plain", "");
|
||||
}, handleFileUpload);
|
||||
|
||||
//called when the url is not defined here
|
||||
//use it to load content from SPIFFS
|
||||
server.onNotFound([]()
|
||||
{
|
||||
if (!handleFileRead(server.uri()))
|
||||
{
|
||||
server.send(404, "text/plain", "FileNotFound");
|
||||
}
|
||||
});
|
||||
|
||||
//get heap status, analog input value and all GPIO statuses in one json call
|
||||
server.on("/all", HTTP_GET, []()
|
||||
{
|
||||
String json = "{";
|
||||
json += "\"heap\":" + String(ESP.getFreeHeap());
|
||||
json += ", \"analog\":" + String(analogRead(A0));
|
||||
json += ", \"gpio\":" + String((uint32_t)(0));
|
||||
json += "}";
|
||||
server.send(200, "text/json", json);
|
||||
json = String();
|
||||
});
|
||||
|
||||
server.begin();
|
||||
|
||||
DBG_OUTPUT_PORT.print("HTTP server started @ ");
|
||||
DBG_OUTPUT_PORT.println(WiFi.localIP());
|
||||
|
||||
MDNS.begin(host);
|
||||
// Add service to MDNS-SD
|
||||
MDNS.addService("http", "tcp", HTTP_PORT);
|
||||
|
||||
DBG_OUTPUT_PORT.print("Open http://");
|
||||
DBG_OUTPUT_PORT.print(host);
|
||||
DBG_OUTPUT_PORT.println(".local/edit to see the file browser");
|
||||
}
|
||||
|
||||
void loop(void)
|
||||
{
|
||||
// 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.
|
||||
drd->loop();
|
||||
|
||||
// this is just for checking if we are alive and connected to WiFi
|
||||
check_status();
|
||||
|
||||
server.handleClient();
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
# ESP_FSWebServer Example
|
||||
|
||||
## First, how Config Portal works?
|
||||
In `Configuration Portal Mode`, it starts an access point called `ESP_xxxxxx`. Connect to it using the configurable password you can define in the code. For example, `your_password` (see examples):
|
||||
|
||||
```cpp
|
||||
// SSID and PW for Config Portal
|
||||
String ssid = "ESP_" + String(ESP_getChipId(), HEX);
|
||||
const char* password = "your_password";
|
||||
```
|
||||
After you connected, please, go to http://192.168.4.1, you'll see this `Main` page:
|
||||
|
||||
<p align="center">
|
||||
<img src="https://github.com/khoih-prog/ESP_WiFiManager/blob/master/Images/Main.png">
|
||||
</p>
|
||||
|
||||
Select `Information` to enter the Info page where the board info will be shown (long page)
|
||||
|
||||
<p align="center">
|
||||
<img src="https://github.com/khoih-prog/ESP_WiFiManager/blob/master/Images/Info.png">
|
||||
</p>
|
||||
|
||||
or short page (default)
|
||||
|
||||
<p align="center">
|
||||
<img src="https://github.com/khoih-prog/ESP_WiFiManager/blob/master/Images/Info_Short.png">
|
||||
</p>
|
||||
|
||||
Select `Configuration` to enter this page where you can select an AP and specify its WiFi Credentials
|
||||
|
||||
<p align="center">
|
||||
<img src="https://github.com/khoih-prog/ESP_WiFiManager/blob/master/Images/Configuration.png">
|
||||
</p>
|
||||
|
||||
Enter your credentials, then click `Save`. 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 select `Exit Portal` from the `Main` page to reboot the board and connect to the previously-stored AP. The WiFi Credentials are still intact.
|
||||
|
||||
|
||||
## How to use this ESP_FSWebServer example?
|
||||
|
||||
This shows you how to use this example in Ubuntu (but you can use similar commands in other OSes)
|
||||
|
||||
1. For example, you already downloaded from (https://github.com/khoih-prog/ESP_WiFiManager/tree/master/examples/ESP_FSWebServer/data) to a local folder, e.g.,
|
||||
|
||||
~/Arduino/libraries/ESP_WiFiManager-master/examples/ESP_FSWebServer/data
|
||||
|
||||
1. Upload the contents of that `data folder` with MkSPIFFS Tool ("ESP8266 Sketch Data Upload" in Tools menu in Arduino IDE)
|
||||
2. or upload the contents of a folder by running the following commands:
|
||||
- Ubuntu$ cd ~/Arduino/libraries/ESP_WiFiManager-master/examples/ESP_FSWebServer/data
|
||||
- Ubuntu$ for file in \`\ls -A1\`; do curl -F "file=@$PWD/$file" esp8266fs.local/edit; done
|
||||
3. Access the sample web page at http://esp8266fs.local
|
||||
|
||||
<p align="center">
|
||||
<img src="https://github.com/khoih-prog/ESP_WiFiManager/blob/master/examples/ESP_FSWebServer/pics/esp8266fs.local.png">
|
||||
</p>
|
||||
|
||||
4. Edit / Delete / Download any file in the the folder by going to http://esp8266fs.local/edit
|
||||
|
||||
<p align="center">
|
||||
<img src="https://github.com/khoih-prog/ESP_WiFiManager/blob/master/examples/ESP_FSWebServer/pics/esp8266fs.local_edit.png">
|
||||
</p>
|
||||
|
||||
|
||||
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 8.1 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,97 @@
|
||||
<!--
|
||||
FSWebServer - Example Index Page
|
||||
Copyright (c) 2015 Hristo Gochkov. All rights reserved.
|
||||
This file is part of the WebServer library for Arduino environment.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
-->
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
|
||||
<title>ESP Monitor</title>
|
||||
<script type="text/javascript" src="graphs.js"></script>
|
||||
<script type="text/javascript">
|
||||
var heap,temp,digi;
|
||||
var reloadPeriod = 1000;
|
||||
var running = false;
|
||||
|
||||
function loadValues(){
|
||||
if(!running) return;
|
||||
var xh = new XMLHttpRequest();
|
||||
xh.onreadystatechange = function(){
|
||||
if (xh.readyState == 4){
|
||||
if(xh.status == 200) {
|
||||
var res = JSON.parse(xh.responseText);
|
||||
heap.add(res.heap);
|
||||
temp.add(res.analog);
|
||||
digi.add(res.gpio);
|
||||
if(running) setTimeout(loadValues, reloadPeriod);
|
||||
} else running = false;
|
||||
}
|
||||
};
|
||||
xh.open("GET", "/all", true);
|
||||
xh.send(null);
|
||||
};
|
||||
|
||||
function run(){
|
||||
if(!running){
|
||||
running = true;
|
||||
loadValues();
|
||||
}
|
||||
}
|
||||
|
||||
function onBodyLoad(){
|
||||
var refreshInput = document.getElementById("refresh-rate");
|
||||
refreshInput.value = reloadPeriod;
|
||||
refreshInput.onchange = function(e){
|
||||
var value = parseInt(e.target.value);
|
||||
reloadPeriod = (value > 0)?value:0;
|
||||
e.target.value = reloadPeriod;
|
||||
}
|
||||
var stopButton = document.getElementById("stop-button");
|
||||
stopButton.onclick = function(e){
|
||||
running = false;
|
||||
}
|
||||
var startButton = document.getElementById("start-button");
|
||||
startButton.onclick = function(e){
|
||||
run();
|
||||
}
|
||||
|
||||
// Example with 10K thermistor
|
||||
//function calcThermistor(v) {
|
||||
// var t = Math.log(((10230000 / v) - 10000));
|
||||
// t = (1/(0.001129148+(0.000234125*t)+(0.0000000876741*t*t*t)))-273.15;
|
||||
// return (t>120)?0:Math.round(t*10)/10;
|
||||
//}
|
||||
//temp = createGraph(document.getElementById("analog"), "Temperature", 100, 128, 10, 40, false, "cyan", calcThermistor);
|
||||
|
||||
temp = createGraph(document.getElementById("analog"), "Analog Input", 100, 128, 0, 1023, false, "cyan");
|
||||
heap = createGraph(document.getElementById("heap"), "Current Heap", 100, 125, 0, 30000, true, "orange");
|
||||
digi = createDigiGraph(document.getElementById("digital"), "GPIO", 100, 146, [0, 4, 5, 16], "gold");
|
||||
run();
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body id="index" style="margin:0; padding:0;" onload="onBodyLoad()">
|
||||
<div id="controls" style="display: block; border: 1px solid rgb(68, 68, 68); padding: 5px; margin: 5px; width: 362px; background-color: rgb(238, 238, 238);">
|
||||
<label>Period (ms):</label>
|
||||
<input type="number" id="refresh-rate"/>
|
||||
<input type="button" id="start-button" value="Start"/>
|
||||
<input type="button" id="stop-button" value="Stop"/>
|
||||
</div>
|
||||
<div id="heap"></div>
|
||||
<div id="analog"></div>
|
||||
<div id="digital"></div>
|
||||
</body>
|
||||
</html>
|
||||
|
After Width: | Height: | Size: 45 KiB |
|
After Width: | Height: | Size: 77 KiB |
@@ -0,0 +1,860 @@
|
||||
/****************************************************************************************************************************
|
||||
ESP_FSWebServer - Example WebServer with SPIFFS backend for esp8266
|
||||
For ESP8266 boards
|
||||
|
||||
ESP_WiFiManager is a library for the ESP8266/ESP32 platform (https://github.com/esp8266/Arduino) to enable easy
|
||||
configuration and reconfiguration of WiFi credentials using a Captive Portal.
|
||||
|
||||
Modified from Tzapu https://github.com/tzapu/WiFiManager
|
||||
and from Ken Taylor https://github.com/kentaylor
|
||||
|
||||
Built by Khoi Hoang https://github.com/khoih-prog/ESP_WiFiManager
|
||||
Licensed under MIT license
|
||||
|
||||
Example modified from https://github.com/esp8266/Arduino/blob/master/libraries/ESP8266WebServer/examples/FSBrowser/FSBrowser.ino
|
||||
|
||||
Copyright (c) 2015 Hristo Gochkov. All rights reserved.
|
||||
This file is part of the ESP8266WebServer library for Arduino environment.
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Version: 1.2.0
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 07/10/2019 Initial coding
|
||||
1.0.1 K Hoang 13/12/2019 Fix bug. Add features. Add support for ESP32
|
||||
1.0.2 K Hoang 19/12/2019 Fix bug thatkeeps ConfigPortal in endless loop if Portal/Router SSID or Password is NULL.
|
||||
1.0.3 K Hoang 05/01/2020 Option not displaying AvailablePages in Info page. Enhance README.md. Modify examples
|
||||
1.0.4 K Hoang 07/01/2020 Add RFC952 setHostname feature.
|
||||
1.0.5 K Hoang 15/01/2020 Add configurable DNS feature. Thanks to @Amorphous of https://community.blynk.cc
|
||||
1.0.6 K Hoang 03/02/2020 Add support for ArduinoJson version 6.0.0+ ( tested with v6.14.1 )
|
||||
1.0.7 K Hoang 13/04/2020 Reduce start time, fix SPIFFS bug in examples, update README.md
|
||||
1.0.8 K Hoang 10/06/2020 Fix STAstaticIP issue. Restructure code. Add LittleFS support for ESP8266 core 2.7.1+
|
||||
1.0.9 K Hoang 29/07/2020 Fix ESP32 STAstaticIP bug. Permit changing from DHCP <-> static IP using Config Portal.
|
||||
Add, enhance examples (fix MDNS for ESP32)
|
||||
1.0.10 K Hoang 08/08/2020 Add more features to Config Portal. Use random WiFi AP channel to avoid conflict.
|
||||
1.0.11 K Hoang 17/08/2020 Add CORS feature. Fix bug in softAP, autoConnect, resetSettings.
|
||||
1.1.0 K Hoang 28/08/2020 Add MultiWiFi feature to autoconnect to best WiFi at runtime
|
||||
1.1.1 K Hoang 30/08/2020 Add setCORSHeader function to allow flexible CORS. Fix typo and minor improvement.
|
||||
1.1.2 K Hoang 17/08/2020 Fix bug. Add example.
|
||||
1.2.0 K Hoang 09/10/2020 Restore cpp code besides Impl.h code to use if linker error. Fix bug.
|
||||
*****************************************************************************************************************************/
|
||||
/*****************************************************************************************************************************
|
||||
How To Use:
|
||||
1) Upload the contents of the data folder with MkSPIFFS Tool ("ESP8266 Sketch Data Upload" in Tools menu in Arduino IDE)
|
||||
2) or you can upload the contents of a folder if you CD in that folder and run the following command:
|
||||
for file in `\ls -A1`; do curl -F "file=@$PWD/$file" esp8266fs.local/edit; done
|
||||
3) access the sample web page at http://esp8266fs.local
|
||||
4) edit the page by going to http://esp8266fs.local/edit
|
||||
*****************************************************************************************************************************/
|
||||
#if !defined(ESP8266)
|
||||
#error This code is intended to run on the ESP8266 platform! Please check your Tools->Board setting.
|
||||
#endif
|
||||
|
||||
// Use from 0 to 4. Higher number, more debugging messages and memory usage.
|
||||
#define _WIFIMGR_LOGLEVEL_ 3
|
||||
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <WiFiClient.h>
|
||||
#include <DNSServer.h>
|
||||
#include <ESP8266WebServer.h>
|
||||
#include <ESP8266mDNS.h>
|
||||
|
||||
// From v1.1.0
|
||||
#include <ESP8266WiFiMulti.h>
|
||||
ESP8266WiFiMulti wifiMulti;
|
||||
//////
|
||||
|
||||
#include <FS.h>
|
||||
|
||||
#define USE_LITTLEFS true
|
||||
|
||||
#if USE_LITTLEFS
|
||||
#include <LittleFS.h>
|
||||
FS* filesystem = &LittleFS;
|
||||
#define FileFS LittleFS
|
||||
#define FS_Name "LittleFS"
|
||||
#else
|
||||
FS* filesystem = &SPIFFS;
|
||||
#define FileFS SPIFFS
|
||||
#define FS_Name "SPIFFS"
|
||||
#endif
|
||||
|
||||
#define DBG_OUTPUT_PORT Serial
|
||||
|
||||
#define ESP_getChipId() (ESP.getChipId())
|
||||
|
||||
// SSID and PW for Config Portal
|
||||
String ssid = "ESP_" + String(ESP_getChipId(), HEX);
|
||||
const char* password = "your_password";
|
||||
|
||||
// SSID and PW for your Router
|
||||
String Router_SSID;
|
||||
String Router_Pass;
|
||||
|
||||
// From v1.1.0
|
||||
#define MIN_AP_PASSWORD_SIZE 8
|
||||
|
||||
#define SSID_MAX_LEN 32
|
||||
//From v1.0.10, WPA2 passwords can be up to 63 characters long.
|
||||
#define PASS_MAX_LEN 64
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char wifi_ssid[SSID_MAX_LEN];
|
||||
char wifi_pw [PASS_MAX_LEN];
|
||||
} WiFi_Credentials;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
String wifi_ssid;
|
||||
String wifi_pw;
|
||||
} WiFi_Credentials_String;
|
||||
|
||||
#define NUM_WIFI_CREDENTIALS 2
|
||||
|
||||
typedef struct
|
||||
{
|
||||
WiFi_Credentials WiFi_Creds [NUM_WIFI_CREDENTIALS];
|
||||
} WM_Config;
|
||||
|
||||
WM_Config WM_config;
|
||||
|
||||
#define CONFIG_FILENAME F("/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 <ESP_WiFiManager.h>
|
||||
#define USE_AVAILABLE_PAGES false
|
||||
|
||||
// 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)
|
||||
#define USE_ESP_WIFIMANAGER_NTP false
|
||||
|
||||
// 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)
|
||||
#define USE_CLOUDFLARE_NTP false
|
||||
|
||||
// New in v1.0.11
|
||||
#define USING_CORS_FEATURE true
|
||||
//////
|
||||
|
||||
// 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
|
||||
#define USE_DHCP_IP true
|
||||
#else
|
||||
// You can select DHCP or Static IP here
|
||||
//#define USE_DHCP_IP true
|
||||
#define USE_DHCP_IP false
|
||||
#endif
|
||||
|
||||
// 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
|
||||
#define USE_DHCP_IP true
|
||||
#else
|
||||
// You can select DHCP or Static IP here
|
||||
//#define USE_DHCP_IP true
|
||||
#define USE_DHCP_IP false
|
||||
#endif
|
||||
|
||||
#if ( USE_DHCP_IP || ( defined(USE_STATIC_IP_CONFIG_IN_CP) && !USE_STATIC_IP_CONFIG_IN_CP ) )
|
||||
// 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
|
||||
|
||||
#define USE_CONFIGURABLE_DNS true
|
||||
|
||||
IPAddress dns1IP = gatewayIP;
|
||||
IPAddress dns2IP = IPAddress(8, 8, 8, 8);
|
||||
|
||||
#include <ESP_WiFiManager.h> //https://github.com/khoih-prog/ESP_WiFiManager
|
||||
|
||||
const char* host = "esp8266fs";
|
||||
|
||||
ESP8266WebServer server(80);
|
||||
|
||||
//holds the current upload
|
||||
File fsUploadFile;
|
||||
|
||||
// Function Prototypes
|
||||
uint8_t connectMultiWiFi(void);
|
||||
|
||||
void heartBeatPrint(void)
|
||||
{
|
||||
static int num = 1;
|
||||
|
||||
if (WiFi.status() == WL_CONNECTED)
|
||||
Serial.print("H"); // H means connected to WiFi
|
||||
else
|
||||
Serial.print("F"); // F means not connected to WiFi
|
||||
|
||||
if (num == 80)
|
||||
{
|
||||
Serial.println();
|
||||
num = 1;
|
||||
}
|
||||
else if (num++ % 10 == 0)
|
||||
{
|
||||
Serial.print(" ");
|
||||
}
|
||||
}
|
||||
|
||||
void check_WiFi(void)
|
||||
{
|
||||
if ( (WiFi.status() != WL_CONNECTED) )
|
||||
{
|
||||
Serial.println("\nWiFi lost. Call connectMultiWiFi in loop");
|
||||
connectMultiWiFi();
|
||||
}
|
||||
}
|
||||
|
||||
void check_status(void)
|
||||
{
|
||||
static ulong checkstatus_timeout = 0;
|
||||
static ulong checkwifi_timeout = 0;
|
||||
|
||||
static ulong current_millis;
|
||||
|
||||
#define WIFICHECK_INTERVAL 1000L
|
||||
#define HEARTBEAT_INTERVAL 10000L
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// Print hearbeat every HEARTBEAT_INTERVAL (10) seconds.
|
||||
if ((current_millis > checkstatus_timeout) || (checkstatus_timeout == 0))
|
||||
{
|
||||
heartBeatPrint();
|
||||
checkstatus_timeout = current_millis + HEARTBEAT_INTERVAL;
|
||||
}
|
||||
}
|
||||
|
||||
//format bytes
|
||||
String formatBytes(size_t bytes)
|
||||
{
|
||||
if (bytes < 1024)
|
||||
{
|
||||
return String(bytes) + "B";
|
||||
}
|
||||
else if (bytes < (1024 * 1024))
|
||||
{
|
||||
return String(bytes / 1024.0) + "KB";
|
||||
}
|
||||
else if (bytes < (1024 * 1024 * 1024))
|
||||
{
|
||||
return String(bytes / 1024.0 / 1024.0) + "MB";
|
||||
}
|
||||
else
|
||||
{
|
||||
return String(bytes / 1024.0 / 1024.0 / 1024.0) + "GB";
|
||||
}
|
||||
}
|
||||
|
||||
String getContentType(String filename)
|
||||
{
|
||||
if (server.hasArg("download"))
|
||||
{
|
||||
return "application/octet-stream";
|
||||
}
|
||||
else if (filename.endsWith(".htm"))
|
||||
{
|
||||
return "text/html";
|
||||
}
|
||||
else if (filename.endsWith(".html"))
|
||||
{
|
||||
return "text/html";
|
||||
}
|
||||
else if (filename.endsWith(".css"))
|
||||
{
|
||||
return "text/css";
|
||||
}
|
||||
else if (filename.endsWith(".js"))
|
||||
{
|
||||
return "application/javascript";
|
||||
}
|
||||
else if (filename.endsWith(".png"))
|
||||
{
|
||||
return "image/png";
|
||||
}
|
||||
else if (filename.endsWith(".gif"))
|
||||
{
|
||||
return "image/gif";
|
||||
}
|
||||
else if (filename.endsWith(".jpg"))
|
||||
{
|
||||
return "image/jpeg";
|
||||
}
|
||||
else if (filename.endsWith(".ico"))
|
||||
{
|
||||
return "image/x-icon";
|
||||
}
|
||||
else if (filename.endsWith(".xml"))
|
||||
{
|
||||
return "text/xml";
|
||||
}
|
||||
else if (filename.endsWith(".pdf"))
|
||||
{
|
||||
return "application/x-pdf";
|
||||
}
|
||||
else if (filename.endsWith(".zip"))
|
||||
{
|
||||
return "application/x-zip";
|
||||
}
|
||||
else if (filename.endsWith(".gz"))
|
||||
{
|
||||
return "application/x-gzip";
|
||||
}
|
||||
return "text/plain";
|
||||
}
|
||||
|
||||
bool handleFileRead(String path)
|
||||
{
|
||||
DBG_OUTPUT_PORT.println("handleFileRead: " + path);
|
||||
if (path.endsWith("/"))
|
||||
{
|
||||
path += "index.htm";
|
||||
}
|
||||
|
||||
String contentType = getContentType(path);
|
||||
String pathWithGz = path + ".gz";
|
||||
|
||||
if (filesystem->exists(pathWithGz) || filesystem->exists(path))
|
||||
{
|
||||
if (filesystem->exists(pathWithGz))
|
||||
{
|
||||
path += ".gz";
|
||||
}
|
||||
|
||||
File file = filesystem->open(path, "r");
|
||||
server.streamFile(file, contentType);
|
||||
file.close();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void handleFileUpload()
|
||||
{
|
||||
if (server.uri() != "/edit")
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
HTTPUpload& upload = server.upload();
|
||||
|
||||
if (upload.status == UPLOAD_FILE_START)
|
||||
{
|
||||
String filename = upload.filename;
|
||||
|
||||
if (!filename.startsWith("/"))
|
||||
{
|
||||
filename = "/" + filename;
|
||||
}
|
||||
|
||||
DBG_OUTPUT_PORT.print("handleFileUpload Name: "); DBG_OUTPUT_PORT.println(filename);
|
||||
fsUploadFile = filesystem->open(filename, "w");
|
||||
filename.clear();
|
||||
}
|
||||
else if (upload.status == UPLOAD_FILE_WRITE)
|
||||
{
|
||||
//DBG_OUTPUT_PORT.print("handleFileUpload Data: "); DBG_OUTPUT_PORT.println(upload.currentSize);
|
||||
|
||||
if (fsUploadFile)
|
||||
{
|
||||
fsUploadFile.write(upload.buf, upload.currentSize);
|
||||
}
|
||||
}
|
||||
else if (upload.status == UPLOAD_FILE_END)
|
||||
{
|
||||
if (fsUploadFile)
|
||||
{
|
||||
fsUploadFile.close();
|
||||
}
|
||||
|
||||
DBG_OUTPUT_PORT.print("handleFileUpload Size: "); DBG_OUTPUT_PORT.println(upload.totalSize);
|
||||
}
|
||||
}
|
||||
|
||||
void handleFileDelete()
|
||||
{
|
||||
if (server.args() == 0)
|
||||
{
|
||||
return server.send(500, "text/plain", "BAD ARGS");
|
||||
}
|
||||
String path = server.arg(0);
|
||||
DBG_OUTPUT_PORT.println("handleFileDelete: " + path);
|
||||
|
||||
if (path == "/")
|
||||
{
|
||||
return server.send(500, "text/plain", "BAD PATH");
|
||||
}
|
||||
|
||||
if (!filesystem->exists(path))
|
||||
{
|
||||
return server.send(404, "text/plain", "FileNotFound");
|
||||
}
|
||||
|
||||
filesystem->remove(path);
|
||||
server.send(200, "text/plain", "");
|
||||
path.clear();
|
||||
}
|
||||
|
||||
void handleFileCreate()
|
||||
{
|
||||
if (server.args() == 0)
|
||||
{
|
||||
return server.send(500, "text/plain", "BAD ARGS");
|
||||
}
|
||||
|
||||
String path = server.arg(0);
|
||||
DBG_OUTPUT_PORT.println("handleFileCreate: " + path);
|
||||
|
||||
if (path == "/")
|
||||
{
|
||||
return server.send(500, "text/plain", "BAD PATH");
|
||||
}
|
||||
|
||||
if (filesystem->exists(path))
|
||||
{
|
||||
return server.send(500, "text/plain", "FILE EXISTS");
|
||||
}
|
||||
|
||||
File file = filesystem->open(path, "w");
|
||||
|
||||
if (file)
|
||||
{
|
||||
file.close();
|
||||
}
|
||||
else
|
||||
{
|
||||
return server.send(500, "text/plain", "CREATE FAILED");
|
||||
}
|
||||
|
||||
server.send(200, "text/plain", "");
|
||||
path.clear();
|
||||
}
|
||||
|
||||
void handleFileList()
|
||||
{
|
||||
if (!server.hasArg("dir"))
|
||||
{
|
||||
server.send(500, "text/plain", "BAD ARGS");
|
||||
return;
|
||||
}
|
||||
|
||||
String path = server.arg("dir");
|
||||
DBG_OUTPUT_PORT.println("handleFileList: " + path);
|
||||
Dir dir = filesystem->openDir(path);
|
||||
path.clear();
|
||||
|
||||
String output = "[";
|
||||
|
||||
while (dir.next())
|
||||
{
|
||||
File entry = dir.openFile("r");
|
||||
|
||||
if (output != "[")
|
||||
{
|
||||
output += ',';
|
||||
}
|
||||
|
||||
bool isDir = false;
|
||||
output += "{\"type\":\"";
|
||||
output += (isDir) ? "dir" : "file";
|
||||
output += "\",\"name\":\"";
|
||||
|
||||
if (entry.name()[0] == '/')
|
||||
{
|
||||
output += &(entry.name()[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
output += entry.name();
|
||||
}
|
||||
|
||||
output += "\"}";
|
||||
entry.close();
|
||||
}
|
||||
|
||||
output += "]";
|
||||
server.send(200, "text/json", output);
|
||||
}
|
||||
|
||||
void loadConfigData(void)
|
||||
{
|
||||
File file = FileFS.open(CONFIG_FILENAME, "r");
|
||||
LOGERROR(F("LoadWiFiCfgFile "));
|
||||
|
||||
if (file)
|
||||
{
|
||||
file.readBytes((char *) &WM_config, sizeof(WM_config));
|
||||
file.close();
|
||||
LOGERROR(F("OK"));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGERROR(F("failed"));
|
||||
}
|
||||
}
|
||||
|
||||
void saveConfigData(void)
|
||||
{
|
||||
File file = FileFS.open(CONFIG_FILENAME, "w");
|
||||
LOGERROR(F("SaveWiFiCfgFile "));
|
||||
|
||||
if (file)
|
||||
{
|
||||
file.write((uint8_t*) &WM_config, sizeof(WM_config));
|
||||
file.close();
|
||||
LOGERROR(F("OK"));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGERROR(F("failed"));
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t connectMultiWiFi(void)
|
||||
{
|
||||
#if ESP32
|
||||
// For ESP32, this better be 0 to shorten the connect time
|
||||
#define WIFI_MULTI_1ST_CONNECT_WAITING_MS 0
|
||||
#else
|
||||
// For ESP8266, this better be 2200 to enable connect the 1st time
|
||||
#define WIFI_MULTI_1ST_CONNECT_WAITING_MS 2200L
|
||||
#endif
|
||||
|
||||
#define WIFI_MULTI_CONNECT_WAITING_MS 100L
|
||||
|
||||
uint8_t status;
|
||||
|
||||
LOGERROR(F("ConnectMultiWiFi with :"));
|
||||
|
||||
if ( (Router_SSID != "") && (Router_Pass != "") )
|
||||
{
|
||||
LOGERROR3(F("* Flash-stored Router_SSID = "), Router_SSID, F(", Router_Pass = "), Router_Pass );
|
||||
}
|
||||
|
||||
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
|
||||
#if USE_CONFIGURABLE_DNS
|
||||
// Set static IP, Gateway, Subnetmask, DNS1 and DNS2. New in v1.0.5
|
||||
WiFi.config(stationIP, gatewayIP, netMask, dns1IP, dns2IP);
|
||||
#else
|
||||
// Set static IP, Gateway, Subnetmask, Use auto DNS1 and DNS2.
|
||||
WiFi.config(stationIP, gatewayIP, netMask);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
int i = 0;
|
||||
status = wifiMulti.run();
|
||||
delay(WIFI_MULTI_1ST_CONNECT_WAITING_MS);
|
||||
|
||||
while ( ( i++ < 10 ) && ( status != WL_CONNECTED ) )
|
||||
{
|
||||
status = wifiMulti.run();
|
||||
|
||||
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"));
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void setup(void)
|
||||
{
|
||||
DBG_OUTPUT_PORT.begin(115200);
|
||||
while (!DBG_OUTPUT_PORT);
|
||||
|
||||
DBG_OUTPUT_PORT.print("\nStarting ESP_FSWebServer using " + String(FS_Name));
|
||||
DBG_OUTPUT_PORT.println(" on " + String(ARDUINO_BOARD));
|
||||
|
||||
DBG_OUTPUT_PORT.setDebugOutput(false);
|
||||
|
||||
if (!filesystem->begin())
|
||||
{
|
||||
DBG_OUTPUT_PORT.print(FS_Name);
|
||||
DBG_OUTPUT_PORT.println(F(" failed! AutoFormatting."));
|
||||
|
||||
filesystem->format();
|
||||
}
|
||||
|
||||
// Uncomment to format FS. Remember to uncomment after done
|
||||
//filesystem->format();
|
||||
Dir dir = filesystem->openDir("/");
|
||||
DBG_OUTPUT_PORT.println("Opening / directory");
|
||||
|
||||
while (dir.next())
|
||||
{
|
||||
String fileName = dir.fileName();
|
||||
size_t fileSize = dir.fileSize();
|
||||
DBG_OUTPUT_PORT.printf("FS File: %s, size: %s\n", fileName.c_str(), formatBytes(fileSize).c_str());
|
||||
}
|
||||
|
||||
DBG_OUTPUT_PORT.println();
|
||||
|
||||
unsigned long startedAt = millis();
|
||||
|
||||
//Local intialization. Once its business is done, there is no need to keep it around
|
||||
// Use this to default DHCP hostname to ESP8266-XXXXXX or ESP32-XXXXXX
|
||||
//ESP_WiFiManager ESP_wifiManager;
|
||||
// Use this to personalize DHCP hostname (RFC952 conformed)
|
||||
ESP_WiFiManager ESP_wifiManager("ESP-FSWebServer");
|
||||
|
||||
//set custom ip for portal
|
||||
ESP_wifiManager.setAPStaticIPConfig(IPAddress(192, 168, 186, 1), IPAddress(192, 168, 186, 1), IPAddress(255, 255, 255, 0));
|
||||
|
||||
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_DHCP_IP
|
||||
#if USE_CONFIGURABLE_DNS
|
||||
// Set static IP, Gateway, Subnetmask, DNS1 and DNS2. New in v1.0.5
|
||||
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
|
||||
|
||||
// New from v1.1.1
|
||||
#if USING_CORS_FEATURE
|
||||
ESP_wifiManager.setCORSHeader("Your Access-Control-Allow-Origin");
|
||||
#endif
|
||||
|
||||
// We can't use WiFi.SSID() in ESP32 as it's only valid after connected.
|
||||
// SSID and Password stored in ESP32 wifi_ap_record_t and wifi_config_t are also cleared in reboot
|
||||
// Have to create a new function to store in EEPROM/SPIFFS for this purpose
|
||||
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
|
||||
DBG_OUTPUT_PORT.println("Stored: SSID = " + Router_SSID + ", Pass = " + Router_Pass);
|
||||
|
||||
// SSID to uppercase
|
||||
ssid.toUpperCase();
|
||||
|
||||
// From v1.1.0, Don't permit NULL password
|
||||
if ( (Router_SSID == "") || (Router_Pass == "") )
|
||||
{
|
||||
DBG_OUTPUT_PORT.println("We haven't got any access point credentials, so get them now");
|
||||
|
||||
initialConfig = true;
|
||||
|
||||
// Starts an access point
|
||||
if (!ESP_wifiManager.startConfigPortal((const char *) ssid.c_str(), password))
|
||||
DBG_OUTPUT_PORT.println("Not connected to WiFi but continuing anyway.");
|
||||
else
|
||||
DBG_OUTPUT_PORT.println("WiFi connected...yeey :)");
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
saveConfigData();
|
||||
}
|
||||
else
|
||||
{
|
||||
wifiMulti.addAP(Router_SSID.c_str(), Router_Pass.c_str());
|
||||
}
|
||||
|
||||
startedAt = millis();
|
||||
|
||||
if (!initialConfig)
|
||||
{
|
||||
// Load stored data, the addAP ready for MultiWiFi reconnection
|
||||
loadConfigData();
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
if ( WiFi.status() != WL_CONNECTED )
|
||||
{
|
||||
DBG_OUTPUT_PORT.println("ConnectMultiWiFi in setup");
|
||||
|
||||
connectMultiWiFi();
|
||||
}
|
||||
}
|
||||
|
||||
DBG_OUTPUT_PORT.print("After waiting ");
|
||||
DBG_OUTPUT_PORT.print((float) (millis() - startedAt) / 1000L);
|
||||
DBG_OUTPUT_PORT.print(" secs more in setup(), connection result is ");
|
||||
|
||||
if (WiFi.status() == WL_CONNECTED)
|
||||
{
|
||||
DBG_OUTPUT_PORT.print("connected. Local IP: ");
|
||||
DBG_OUTPUT_PORT.println(WiFi.localIP());
|
||||
}
|
||||
else
|
||||
DBG_OUTPUT_PORT.println(ESP_wifiManager.getStatus(WiFi.status()));
|
||||
|
||||
//SERVER INIT
|
||||
//list directory
|
||||
server.on("/list", HTTP_GET, handleFileList);
|
||||
|
||||
//load editor
|
||||
server.on("/edit", HTTP_GET, []()
|
||||
{
|
||||
if (!handleFileRead("/edit.htm"))
|
||||
{
|
||||
server.send(404, "text/plain", "FileNotFound");
|
||||
}
|
||||
});
|
||||
|
||||
//create file
|
||||
server.on("/edit", HTTP_PUT, handleFileCreate);
|
||||
|
||||
//delete file
|
||||
server.on("/edit", HTTP_DELETE, handleFileDelete);
|
||||
|
||||
//first callback is called after the request has ended with all parsed arguments
|
||||
//second callback handles file uploads at that location
|
||||
server.on("/edit", HTTP_POST, []()
|
||||
{
|
||||
server.send(200, "text/plain", "");
|
||||
}, handleFileUpload);
|
||||
|
||||
//called when the url is not defined here
|
||||
//use it to load content from SPIFFS
|
||||
server.onNotFound([]()
|
||||
{
|
||||
if (!handleFileRead(server.uri()))
|
||||
{
|
||||
server.send(404, "text/plain", "FileNotFound");
|
||||
}
|
||||
});
|
||||
|
||||
//get heap status, analog input value and all GPIO statuses in one json call
|
||||
server.on("/all", HTTP_GET, []()
|
||||
{
|
||||
String json('{');
|
||||
json += "\"heap\":" + String(ESP.getFreeHeap());
|
||||
json += ", \"analog\":" + String(analogRead(A0));
|
||||
json += ", \"gpio\":" + String((uint32_t)(((GPI | GPO) & 0xFFFF) | ((GP16I & 0x01) << 16)));
|
||||
json += "}";
|
||||
server.send(200, "text/json", json);
|
||||
json.clear();
|
||||
});
|
||||
|
||||
server.begin();
|
||||
|
||||
DBG_OUTPUT_PORT.print("HTTP server started @ ");
|
||||
DBG_OUTPUT_PORT.println(WiFi.localIP());
|
||||
|
||||
MDNS.begin(host);
|
||||
DBG_OUTPUT_PORT.print("Open http://");
|
||||
DBG_OUTPUT_PORT.print(host);
|
||||
DBG_OUTPUT_PORT.println(".local/edit to see the file browser");
|
||||
}
|
||||
|
||||
void loop(void)
|
||||
{
|
||||
// this is just for checking if we are alive and connected to WiFi
|
||||
check_status();
|
||||
|
||||
server.handleClient();
|
||||
MDNS.update();
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
# ESP_FSWebServer Example
|
||||
|
||||
## First, how Config Portal works?
|
||||
In `Configuration Portal Mode`, it starts an access point called `ESP_xxxxxx`. Connect to it using the configurable password you can define in the code. For example, `your_password` (see examples):
|
||||
|
||||
```cpp
|
||||
// SSID and PW for Config Portal
|
||||
String ssid = "ESP_" + String(ESP_getChipId(), HEX);
|
||||
const char* password = "your_password";
|
||||
```
|
||||
After you connected, please, go to http://192.168.4.1, you'll see this `Main` page:
|
||||
|
||||
<p align="center">
|
||||
<img src="https://github.com/khoih-prog/ESP_WiFiManager/blob/master/Images/Main.png">
|
||||
</p>
|
||||
|
||||
Select `Information` to enter the Info page where the board info will be shown (long page)
|
||||
|
||||
<p align="center">
|
||||
<img src="https://github.com/khoih-prog/ESP_WiFiManager/blob/master/Images/Info.png">
|
||||
</p>
|
||||
|
||||
or short page (default)
|
||||
|
||||
<p align="center">
|
||||
<img src="https://github.com/khoih-prog/ESP_WiFiManager/blob/master/Images/Info_Short.png">
|
||||
</p>
|
||||
|
||||
Select `Configuration` to enter this page where you can select an AP and specify its WiFi Credentials
|
||||
|
||||
<p align="center">
|
||||
<img src="https://github.com/khoih-prog/ESP_WiFiManager/blob/master/Images/Configuration.png">
|
||||
</p>
|
||||
|
||||
Enter your credentials, then click `Save`. 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 select `Exit Portal` from the `Main` page to reboot the board and connect to the previously-stored AP. The WiFi Credentials are still intact.
|
||||
|
||||
|
||||
## How to use this ESP_FSWebServer example?
|
||||
|
||||
This shows you how to use this example in Ubuntu (but you can use similar commands in other OSes)
|
||||
|
||||
1. For example, you already downloaded from (https://github.com/khoih-prog/ESP_WiFiManager/tree/master/examples/ESP_FSWebServer/data) to a local folder, e.g.,
|
||||
|
||||
~/Arduino/libraries/ESP_WiFiManager-master/examples/ESP_FSWebServer/data
|
||||
|
||||
1. Upload the contents of that `data folder` with MkSPIFFS Tool ("ESP8266 Sketch Data Upload" in Tools menu in Arduino IDE)
|
||||
2. or upload the contents of a folder by running the following commands:
|
||||
- Ubuntu$ cd ~/Arduino/libraries/ESP_WiFiManager-master/examples/ESP_FSWebServer/data
|
||||
- Ubuntu$ for file in \`\ls -A1\`; do curl -F "file=@$PWD/$file" esp8266fs.local/edit; done
|
||||
3. Access the sample web page at http://esp8266fs.local
|
||||
|
||||
<p align="center">
|
||||
<img src="https://github.com/khoih-prog/ESP_WiFiManager/blob/master/examples/ESP_FSWebServer/pics/esp8266fs.local.png">
|
||||
</p>
|
||||
|
||||
4. Edit / Delete / Download any file in the the folder by going to http://esp8266fs.local/edit
|
||||
|
||||
<p align="center">
|
||||
<img src="https://github.com/khoih-prog/ESP_WiFiManager/blob/master/examples/ESP_FSWebServer/pics/esp8266fs.local_edit.png">
|
||||
</p>
|
||||
|
||||
|
||||
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 8.1 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,97 @@
|
||||
<!--
|
||||
FSWebServer - Example Index Page
|
||||
Copyright (c) 2015 Hristo Gochkov. All rights reserved.
|
||||
This file is part of the ESP8266WebServer library for Arduino environment.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
-->
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
|
||||
<title>ESP Monitor</title>
|
||||
<script type="text/javascript" src="graphs.js"></script>
|
||||
<script type="text/javascript">
|
||||
var heap,temp,digi;
|
||||
var reloadPeriod = 1000;
|
||||
var running = false;
|
||||
|
||||
function loadValues(){
|
||||
if(!running) return;
|
||||
var xh = new XMLHttpRequest();
|
||||
xh.onreadystatechange = function(){
|
||||
if (xh.readyState == 4){
|
||||
if(xh.status == 200) {
|
||||
var res = JSON.parse(xh.responseText);
|
||||
heap.add(res.heap);
|
||||
temp.add(res.analog);
|
||||
digi.add(res.gpio);
|
||||
if(running) setTimeout(loadValues, reloadPeriod);
|
||||
} else running = false;
|
||||
}
|
||||
};
|
||||
xh.open("GET", "/all", true);
|
||||
xh.send(null);
|
||||
};
|
||||
|
||||
function run(){
|
||||
if(!running){
|
||||
running = true;
|
||||
loadValues();
|
||||
}
|
||||
}
|
||||
|
||||
function onBodyLoad(){
|
||||
var refreshInput = document.getElementById("refresh-rate");
|
||||
refreshInput.value = reloadPeriod;
|
||||
refreshInput.onchange = function(e){
|
||||
var value = parseInt(e.target.value);
|
||||
reloadPeriod = (value > 0)?value:0;
|
||||
e.target.value = reloadPeriod;
|
||||
}
|
||||
var stopButton = document.getElementById("stop-button");
|
||||
stopButton.onclick = function(e){
|
||||
running = false;
|
||||
}
|
||||
var startButton = document.getElementById("start-button");
|
||||
startButton.onclick = function(e){
|
||||
run();
|
||||
}
|
||||
|
||||
// Example with 10K thermistor
|
||||
//function calcThermistor(v) {
|
||||
// var t = Math.log(((10230000 / v) - 10000));
|
||||
// t = (1/(0.001129148+(0.000234125*t)+(0.0000000876741*t*t*t)))-273.15;
|
||||
// return (t>120)?0:Math.round(t*10)/10;
|
||||
//}
|
||||
//temp = createGraph(document.getElementById("analog"), "Temperature", 100, 128, 10, 40, false, "cyan", calcThermistor);
|
||||
|
||||
temp = createGraph(document.getElementById("analog"), "Analog Input", 100, 128, 0, 1023, false, "cyan");
|
||||
heap = createGraph(document.getElementById("heap"), "Current Heap", 100, 125, 0, 30000, true, "orange");
|
||||
digi = createDigiGraph(document.getElementById("digital"), "GPIO", 100, 146, [0, 4, 5, 16], "gold");
|
||||
run();
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body id="index" style="margin:0; padding:0;" onload="onBodyLoad()">
|
||||
<div id="controls" style="display: block; border: 1px solid rgb(68, 68, 68); padding: 5px; margin: 5px; width: 362px; background-color: rgb(238, 238, 238);">
|
||||
<label>Period (ms):</label>
|
||||
<input type="number" id="refresh-rate"/>
|
||||
<input type="button" id="start-button" value="Start"/>
|
||||
<input type="button" id="stop-button" value="Stop"/>
|
||||
</div>
|
||||
<div id="heap"></div>
|
||||
<div id="analog"></div>
|
||||
<div id="digital"></div>
|
||||
</body>
|
||||
</html>
|
||||
|
After Width: | Height: | Size: 45 KiB |
|
After Width: | Height: | Size: 77 KiB |
@@ -0,0 +1,919 @@
|
||||
/****************************************************************************************************************************
|
||||
ESP_FSWebServer_DRD - Example WebServer with SPIFFS backend for esp8266 with DoubleResetDetect feature
|
||||
For ESP8266 boards
|
||||
|
||||
ESP_WiFiManager is a library for the ESP8266/ESP32 platform (https://github.com/esp8266/Arduino) to enable easy
|
||||
configuration and reconfiguration of WiFi credentials using a Captive Portal.
|
||||
|
||||
Modified from Tzapu https://github.com/tzapu/WiFiManager
|
||||
and from Ken Taylor https://github.com/kentaylor
|
||||
|
||||
Built by Khoi Hoang https://github.com/khoih-prog/ESP_WiFiManager
|
||||
Licensed under MIT license
|
||||
|
||||
Example modified from https://github.com/esp8266/Arduino/blob/master/libraries/ESP8266WebServer/examples/FSBrowser/FSBrowser.ino
|
||||
|
||||
Copyright (c) 2015 Hristo Gochkov. All rights reserved.
|
||||
This file is part of the ESP8266WebServer library for Arduino environment.
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Version: 1.2.0
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 07/10/2019 Initial coding
|
||||
1.0.1 K Hoang 13/12/2019 Fix bug. Add features. Add support for ESP32
|
||||
1.0.2 K Hoang 19/12/2019 Fix bug thatkeeps ConfigPortal in endless loop if Portal/Router SSID or Password is NULL.
|
||||
1.0.3 K Hoang 05/01/2020 Option not displaying AvailablePages in Info page. Enhance README.md. Modify examples
|
||||
1.0.4 K Hoang 07/01/2020 Add RFC952 setHostname feature.
|
||||
1.0.5 K Hoang 15/01/2020 Add configurable DNS feature. Thanks to @Amorphous of https://community.blynk.cc
|
||||
1.0.6 K Hoang 03/02/2020 Add support for ArduinoJson version 6.0.0+ ( tested with v6.14.1 )
|
||||
1.0.7 K Hoang 13/04/2020 Reduce start time, fix SPIFFS bug in examples, update README.md
|
||||
1.0.8 K Hoang 10/06/2020 Fix STAstaticIP issue. Restructure code. Add LittleFS support for ESP8266 core 2.7.1+
|
||||
1.0.9 K Hoang 29/07/2020 Fix ESP32 STAstaticIP bug. Permit changing from DHCP <-> static IP using Config Portal.
|
||||
Add, enhance examples (fix MDNS for ESP32)
|
||||
1.0.10 K Hoang 08/08/2020 Add more features to Config Portal. Use random WiFi AP channel to avoid conflict.
|
||||
1.0.11 K Hoang 17/08/2020 Add CORS feature. Fix bug in softAP, autoConnect, resetSettings.
|
||||
1.1.0 K Hoang 28/08/2020 Add MultiWiFi feature to autoconnect to best WiFi at runtime
|
||||
1.1.1 K Hoang 30/08/2020 Add setCORSHeader function to allow flexible CORS. Fix typo and minor improvement.
|
||||
1.1.2 K Hoang 17/08/2020 Fix bug. Add example.
|
||||
1.2.0 K Hoang 09/10/2020 Restore cpp code besides Impl.h code to use if linker error. Fix bug.
|
||||
*****************************************************************************************************************************/
|
||||
/*****************************************************************************************************************************
|
||||
How To Use:
|
||||
1) Upload the contents of the data folder with MkSPIFFS Tool ("ESP8266 Sketch Data Upload" in Tools menu in Arduino IDE)
|
||||
2) or you can upload the contents of a folder if you CD in that folder and run the following command:
|
||||
for file in `\ls -A1`; do curl -F "file=@$PWD/$file" esp8266fs.local/edit; done
|
||||
3) access the sample web page at http://esp8266fs.local
|
||||
4) edit the page by going to http://esp8266fs.local/edit
|
||||
*****************************************************************************************************************************/
|
||||
#if !defined(ESP8266)
|
||||
#error This code is intended to run on the ESP8266 platform! Please check your Tools->Board setting.
|
||||
#endif
|
||||
|
||||
// Use from 0 to 4. Higher number, more debugging messages and memory usage.
|
||||
#define _WIFIMGR_LOGLEVEL_ 3
|
||||
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <WiFiClient.h>
|
||||
#include <DNSServer.h>
|
||||
#include <ESP8266WebServer.h>
|
||||
#include <ESP8266mDNS.h>
|
||||
|
||||
// From v1.1.0
|
||||
#include <ESP8266WiFiMulti.h>
|
||||
ESP8266WiFiMulti wifiMulti;
|
||||
//////
|
||||
|
||||
#include <FS.h>
|
||||
|
||||
#define USE_LITTLEFS true
|
||||
|
||||
// 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
|
||||
#define ESP_DRD_USE_LITTLEFS true
|
||||
#define ESP_DRD_USE_SPIFFS false
|
||||
#else
|
||||
#define ESP_DRD_USE_LITTLEFS false
|
||||
#define ESP_DRD_USE_SPIFFS true
|
||||
#endif
|
||||
|
||||
#define ESP_DRD_USE_EEPROM false
|
||||
#define ESP8266_DRD_USE_RTC false
|
||||
|
||||
#define DOUBLERESETDETECTOR_DEBUG true //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.
|
||||
#define DRD_TIMEOUT 10
|
||||
|
||||
// RTC Memory Address for the DoubleResetDetector to use
|
||||
#define DRD_ADDRESS 0
|
||||
|
||||
//DoubleResetDetector drd(DRD_TIMEOUT, DRD_ADDRESS);
|
||||
DoubleResetDetector* drd;
|
||||
|
||||
#if USE_LITTLEFS
|
||||
#include <LittleFS.h>
|
||||
FS* filesystem = &LittleFS;
|
||||
#define FileFS LittleFS
|
||||
#define FS_Name "LittleFS"
|
||||
#else
|
||||
FS* filesystem = &SPIFFS;
|
||||
#define FileFS SPIFFS
|
||||
#define FS_Name "SPIFFS"
|
||||
#endif
|
||||
|
||||
#define DBG_OUTPUT_PORT Serial
|
||||
|
||||
#define ESP_getChipId() (ESP.getChipId())
|
||||
|
||||
// SSID and PW for Config Portal
|
||||
String ssid = "ESP_" + String(ESP_getChipId(), HEX);
|
||||
//String ssid = "your_ssid";
|
||||
const char* password = "your_password";
|
||||
|
||||
// SSID and PW for your Router
|
||||
String Router_SSID;
|
||||
String Router_Pass;
|
||||
|
||||
// From v1.1.0
|
||||
#define MIN_AP_PASSWORD_SIZE 8
|
||||
|
||||
#define SSID_MAX_LEN 32
|
||||
//From v1.0.10, WPA2 passwords can be up to 63 characters long.
|
||||
#define PASS_MAX_LEN 64
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char wifi_ssid[SSID_MAX_LEN];
|
||||
char wifi_pw [PASS_MAX_LEN];
|
||||
} WiFi_Credentials;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
String wifi_ssid;
|
||||
String wifi_pw;
|
||||
} WiFi_Credentials_String;
|
||||
|
||||
#define NUM_WIFI_CREDENTIALS 2
|
||||
|
||||
typedef struct
|
||||
{
|
||||
WiFi_Credentials WiFi_Creds [NUM_WIFI_CREDENTIALS];
|
||||
} WM_Config;
|
||||
|
||||
WM_Config WM_config;
|
||||
|
||||
#define CONFIG_FILENAME F("/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 <ESP_WiFiManager.h>
|
||||
#define USE_AVAILABLE_PAGES false
|
||||
|
||||
// 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)
|
||||
#define USE_ESP_WIFIMANAGER_NTP false
|
||||
|
||||
// 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)
|
||||
#define USE_CLOUDFLARE_NTP false
|
||||
|
||||
// New in v1.0.11
|
||||
#define USING_CORS_FEATURE true
|
||||
//////
|
||||
|
||||
// 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
|
||||
#define USE_DHCP_IP true
|
||||
#else
|
||||
// You can select DHCP or Static IP here
|
||||
//#define USE_DHCP_IP true
|
||||
#define USE_DHCP_IP false
|
||||
#endif
|
||||
|
||||
// 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
|
||||
#define USE_DHCP_IP true
|
||||
#else
|
||||
// You can select DHCP or Static IP here
|
||||
//#define USE_DHCP_IP true
|
||||
#define USE_DHCP_IP false
|
||||
#endif
|
||||
|
||||
#if ( USE_DHCP_IP || ( defined(USE_STATIC_IP_CONFIG_IN_CP) && !USE_STATIC_IP_CONFIG_IN_CP ) )
|
||||
// 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
|
||||
|
||||
#define USE_CONFIGURABLE_DNS true
|
||||
|
||||
IPAddress dns1IP = gatewayIP;
|
||||
IPAddress dns2IP = IPAddress(8, 8, 8, 8);
|
||||
|
||||
#include <ESP_WiFiManager.h> //https://github.com/khoih-prog/ESP_WiFiManager
|
||||
|
||||
const char* host = "esp8266fs";
|
||||
|
||||
ESP8266WebServer server(80);
|
||||
|
||||
//holds the current upload
|
||||
File fsUploadFile;
|
||||
|
||||
// Function Prototypes
|
||||
uint8_t connectMultiWiFi(void);
|
||||
|
||||
void heartBeatPrint(void)
|
||||
{
|
||||
static int num = 1;
|
||||
|
||||
if (WiFi.status() == WL_CONNECTED)
|
||||
Serial.print("H"); // H means connected to WiFi
|
||||
else
|
||||
Serial.print("F"); // F means not connected to WiFi
|
||||
|
||||
if (num == 80)
|
||||
{
|
||||
Serial.println();
|
||||
num = 1;
|
||||
}
|
||||
else if (num++ % 10 == 0)
|
||||
{
|
||||
Serial.print(" ");
|
||||
}
|
||||
}
|
||||
|
||||
void check_WiFi(void)
|
||||
{
|
||||
if ( (WiFi.status() != WL_CONNECTED) )
|
||||
{
|
||||
Serial.println("\nWiFi lost. Call connectMultiWiFi in loop");
|
||||
connectMultiWiFi();
|
||||
}
|
||||
}
|
||||
|
||||
void check_status(void)
|
||||
{
|
||||
static ulong checkstatus_timeout = 0;
|
||||
static ulong checkwifi_timeout = 0;
|
||||
|
||||
static ulong current_millis;
|
||||
|
||||
#define WIFICHECK_INTERVAL 3000L
|
||||
#define HEARTBEAT_INTERVAL 10000L
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// Print hearbeat every HEARTBEAT_INTERVAL (10) seconds.
|
||||
if ((current_millis > checkstatus_timeout) || (checkstatus_timeout == 0))
|
||||
{
|
||||
heartBeatPrint();
|
||||
checkstatus_timeout = current_millis + HEARTBEAT_INTERVAL;
|
||||
}
|
||||
}
|
||||
|
||||
//format bytes
|
||||
String formatBytes(size_t bytes)
|
||||
{
|
||||
if (bytes < 1024)
|
||||
{
|
||||
return String(bytes) + "B";
|
||||
}
|
||||
else if (bytes < (1024 * 1024))
|
||||
{
|
||||
return String(bytes / 1024.0) + "KB";
|
||||
}
|
||||
else if (bytes < (1024 * 1024 * 1024))
|
||||
{
|
||||
return String(bytes / 1024.0 / 1024.0) + "MB";
|
||||
}
|
||||
else
|
||||
{
|
||||
return String(bytes / 1024.0 / 1024.0 / 1024.0) + "GB";
|
||||
}
|
||||
}
|
||||
|
||||
String getContentType(String filename)
|
||||
{
|
||||
if (server.hasArg("download"))
|
||||
{
|
||||
return "application/octet-stream";
|
||||
}
|
||||
else if (filename.endsWith(".htm"))
|
||||
{
|
||||
return "text/html";
|
||||
}
|
||||
else if (filename.endsWith(".html"))
|
||||
{
|
||||
return "text/html";
|
||||
}
|
||||
else if (filename.endsWith(".css"))
|
||||
{
|
||||
return "text/css";
|
||||
}
|
||||
else if (filename.endsWith(".js"))
|
||||
{
|
||||
return "application/javascript";
|
||||
}
|
||||
else if (filename.endsWith(".png"))
|
||||
{
|
||||
return "image/png";
|
||||
}
|
||||
else if (filename.endsWith(".gif"))
|
||||
{
|
||||
return "image/gif";
|
||||
}
|
||||
else if (filename.endsWith(".jpg"))
|
||||
{
|
||||
return "image/jpeg";
|
||||
}
|
||||
else if (filename.endsWith(".ico"))
|
||||
{
|
||||
return "image/x-icon";
|
||||
}
|
||||
else if (filename.endsWith(".xml"))
|
||||
{
|
||||
return "text/xml";
|
||||
}
|
||||
else if (filename.endsWith(".pdf"))
|
||||
{
|
||||
return "application/x-pdf";
|
||||
}
|
||||
else if (filename.endsWith(".zip"))
|
||||
{
|
||||
return "application/x-zip";
|
||||
}
|
||||
else if (filename.endsWith(".gz"))
|
||||
{
|
||||
return "application/x-gzip";
|
||||
}
|
||||
return "text/plain";
|
||||
}
|
||||
|
||||
bool handleFileRead(String path)
|
||||
{
|
||||
DBG_OUTPUT_PORT.println("handleFileRead: " + path);
|
||||
|
||||
if (path.endsWith("/"))
|
||||
{
|
||||
path += "index.htm";
|
||||
}
|
||||
|
||||
String contentType = getContentType(path);
|
||||
String pathWithGz = path + ".gz";
|
||||
|
||||
if (filesystem->exists(pathWithGz) || filesystem->exists(path))
|
||||
{
|
||||
if (filesystem->exists(pathWithGz))
|
||||
{
|
||||
path += ".gz";
|
||||
}
|
||||
|
||||
File file = filesystem->open(path, "r");
|
||||
server.streamFile(file, contentType);
|
||||
file.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void handleFileUpload()
|
||||
{
|
||||
if (server.uri() != "/edit")
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
HTTPUpload& upload = server.upload();
|
||||
|
||||
if (upload.status == UPLOAD_FILE_START)
|
||||
{
|
||||
String filename = upload.filename;
|
||||
|
||||
if (!filename.startsWith("/"))
|
||||
{
|
||||
filename = "/" + filename;
|
||||
}
|
||||
|
||||
DBG_OUTPUT_PORT.print("handleFileUpload Name: "); DBG_OUTPUT_PORT.println(filename);
|
||||
fsUploadFile = filesystem->open(filename, "w");
|
||||
filename.clear();
|
||||
}
|
||||
else if (upload.status == UPLOAD_FILE_WRITE)
|
||||
{
|
||||
//DBG_OUTPUT_PORT.print("handleFileUpload Data: "); DBG_OUTPUT_PORT.println(upload.currentSize);
|
||||
|
||||
if (fsUploadFile)
|
||||
{
|
||||
fsUploadFile.write(upload.buf, upload.currentSize);
|
||||
}
|
||||
}
|
||||
else if (upload.status == UPLOAD_FILE_END)
|
||||
{
|
||||
if (fsUploadFile)
|
||||
{
|
||||
fsUploadFile.close();
|
||||
}
|
||||
|
||||
DBG_OUTPUT_PORT.print("handleFileUpload Size: "); DBG_OUTPUT_PORT.println(upload.totalSize);
|
||||
}
|
||||
}
|
||||
|
||||
void handleFileDelete()
|
||||
{
|
||||
if (server.args() == 0)
|
||||
{
|
||||
return server.send(500, "text/plain", "BAD ARGS");
|
||||
}
|
||||
String path = server.arg(0);
|
||||
DBG_OUTPUT_PORT.println("handleFileDelete: " + path);
|
||||
|
||||
if (path == "/")
|
||||
{
|
||||
return server.send(500, "text/plain", "BAD PATH");
|
||||
}
|
||||
|
||||
if (!filesystem->exists(path))
|
||||
{
|
||||
return server.send(404, "text/plain", "FileNotFound");
|
||||
}
|
||||
|
||||
filesystem->remove(path);
|
||||
server.send(200, "text/plain", "");
|
||||
path.clear();
|
||||
}
|
||||
|
||||
void handleFileCreate()
|
||||
{
|
||||
if (server.args() == 0)
|
||||
{
|
||||
return server.send(500, "text/plain", "BAD ARGS");
|
||||
}
|
||||
|
||||
String path = server.arg(0);
|
||||
DBG_OUTPUT_PORT.println("handleFileCreate: " + path);
|
||||
|
||||
if (path == "/")
|
||||
{
|
||||
return server.send(500, "text/plain", "BAD PATH");
|
||||
}
|
||||
|
||||
if (filesystem->exists(path))
|
||||
{
|
||||
return server.send(500, "text/plain", "FILE EXISTS");
|
||||
}
|
||||
|
||||
File file = filesystem->open(path, "w");
|
||||
|
||||
if (file)
|
||||
{
|
||||
file.close();
|
||||
}
|
||||
else
|
||||
{
|
||||
return server.send(500, "text/plain", "CREATE FAILED");
|
||||
}
|
||||
|
||||
server.send(200, "text/plain", "");
|
||||
path.clear();
|
||||
}
|
||||
|
||||
void handleFileList()
|
||||
{
|
||||
if (!server.hasArg("dir"))
|
||||
{
|
||||
server.send(500, "text/plain", "BAD ARGS");
|
||||
return;
|
||||
}
|
||||
|
||||
String path = server.arg("dir");
|
||||
DBG_OUTPUT_PORT.println("handleFileList: " + path);
|
||||
Dir dir = filesystem->openDir(path);
|
||||
path.clear();
|
||||
|
||||
String output = "[";
|
||||
|
||||
while (dir.next())
|
||||
{
|
||||
File entry = dir.openFile("r");
|
||||
|
||||
if (output != "[")
|
||||
{
|
||||
output += ',';
|
||||
}
|
||||
|
||||
bool isDir = false;
|
||||
output += "{\"type\":\"";
|
||||
output += (isDir) ? "dir" : "file";
|
||||
output += "\",\"name\":\"";
|
||||
|
||||
if (entry.name()[0] == '/')
|
||||
{
|
||||
output += &(entry.name()[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
output += entry.name();
|
||||
}
|
||||
|
||||
output += "\"}";
|
||||
entry.close();
|
||||
}
|
||||
|
||||
output += "]";
|
||||
server.send(200, "text/json", output);
|
||||
}
|
||||
|
||||
void loadConfigData(void)
|
||||
{
|
||||
File file = FileFS.open(CONFIG_FILENAME, "r");
|
||||
LOGERROR(F("LoadWiFiCfgFile "));
|
||||
|
||||
if (file)
|
||||
{
|
||||
file.readBytes((char *) &WM_config, sizeof(WM_config));
|
||||
file.close();
|
||||
LOGERROR(F("OK"));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGERROR(F("failed"));
|
||||
}
|
||||
}
|
||||
|
||||
void saveConfigData(void)
|
||||
{
|
||||
File file = FileFS.open(CONFIG_FILENAME, "w");
|
||||
LOGERROR(F("SaveWiFiCfgFile "));
|
||||
|
||||
if (file)
|
||||
{
|
||||
file.write((uint8_t*) &WM_config, sizeof(WM_config));
|
||||
file.close();
|
||||
LOGERROR(F("OK"));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGERROR(F("failed"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint8_t connectMultiWiFi(void)
|
||||
{
|
||||
#if ESP32
|
||||
// For ESP32, this better be 0 to shorten the connect time
|
||||
#define WIFI_MULTI_1ST_CONNECT_WAITING_MS 0
|
||||
#else
|
||||
// For ESP8266, this better be 2200 to enable connect the 1st time
|
||||
#define WIFI_MULTI_1ST_CONNECT_WAITING_MS 2200L
|
||||
#endif
|
||||
|
||||
#define WIFI_MULTI_CONNECT_WAITING_MS 100L
|
||||
|
||||
uint8_t status;
|
||||
|
||||
LOGERROR(F("ConnectMultiWiFi with :"));
|
||||
|
||||
if ( (Router_SSID != "") && (Router_Pass != "") )
|
||||
{
|
||||
LOGERROR3(F("* Flash-stored Router_SSID = "), Router_SSID, F(", Router_Pass = "), Router_Pass );
|
||||
}
|
||||
|
||||
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
|
||||
#if USE_CONFIGURABLE_DNS
|
||||
// Set static IP, Gateway, Subnetmask, DNS1 and DNS2. New in v1.0.5
|
||||
WiFi.config(stationIP, gatewayIP, netMask, dns1IP, dns2IP);
|
||||
#else
|
||||
// Set static IP, Gateway, Subnetmask, Use auto DNS1 and DNS2.
|
||||
WiFi.config(stationIP, gatewayIP, netMask);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
int i = 0;
|
||||
status = wifiMulti.run();
|
||||
delay(WIFI_MULTI_1ST_CONNECT_WAITING_MS);
|
||||
|
||||
while ( ( i++ < 10 ) && ( status != WL_CONNECTED ) )
|
||||
{
|
||||
status = wifiMulti.run();
|
||||
|
||||
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"));
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void setup(void)
|
||||
{
|
||||
DBG_OUTPUT_PORT.begin(115200);
|
||||
while (!DBG_OUTPUT_PORT);
|
||||
|
||||
DBG_OUTPUT_PORT.print("\nStarting ESP_FSWebServer_DRD with DoubleResetDetect using " + String(FS_Name));
|
||||
DBG_OUTPUT_PORT.println(" on " + String(ARDUINO_BOARD));
|
||||
|
||||
DBG_OUTPUT_PORT.setDebugOutput(false);
|
||||
|
||||
drd = new DoubleResetDetector(DRD_TIMEOUT, DRD_ADDRESS);
|
||||
|
||||
if (!filesystem->begin())
|
||||
{
|
||||
DBG_OUTPUT_PORT.print(FS_Name);
|
||||
DBG_OUTPUT_PORT.println(F(" failed! AutoFormatting."));
|
||||
|
||||
filesystem->format();
|
||||
}
|
||||
|
||||
// Uncomment to format FS. Remember to uncomment after done
|
||||
//filesystem->format();
|
||||
Dir dir = filesystem->openDir("/");
|
||||
DBG_OUTPUT_PORT.println("Opening / directory");
|
||||
|
||||
while (dir.next())
|
||||
{
|
||||
String fileName = dir.fileName();
|
||||
size_t fileSize = dir.fileSize();
|
||||
DBG_OUTPUT_PORT.printf("FS File: %s, size: %s\n", fileName.c_str(), formatBytes(fileSize).c_str());
|
||||
}
|
||||
|
||||
DBG_OUTPUT_PORT.println();
|
||||
|
||||
unsigned long startedAt = millis();
|
||||
|
||||
//Local intialization. Once its business is done, there is no need to keep it around
|
||||
// Use this to default DHCP hostname to ESP8266-XXXXXX or ESP32-XXXXXX
|
||||
//ESP_WiFiManager ESP_wifiManager;
|
||||
// Use this to personalize DHCP hostname (RFC952 conformed)
|
||||
ESP_WiFiManager ESP_wifiManager("ESP-FSWebServer_DRD");
|
||||
|
||||
//set custom ip for portal
|
||||
ESP_wifiManager.setAPStaticIPConfig(IPAddress(192, 168, 186, 1), IPAddress(192, 168, 186, 1), IPAddress(255, 255, 255, 0));
|
||||
|
||||
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_DHCP_IP
|
||||
#if USE_CONFIGURABLE_DNS
|
||||
// Set static IP, Gateway, Subnetmask, DNS1 and DNS2. New in v1.0.5
|
||||
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
|
||||
|
||||
// New from v1.1.0+
|
||||
#if USING_CORS_FEATURE
|
||||
ESP_wifiManager.setCORSHeader("Your Access-Control-Allow-Origin");
|
||||
#endif
|
||||
|
||||
// We can't use WiFi.SSID() in ESP32as it's only valid after connected.
|
||||
// SSID and Password stored in ESP32 wifi_ap_record_t and wifi_config_t are also cleared in reboot
|
||||
// Have to create a new function to store in EEPROM/SPIFFS for this purpose
|
||||
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
|
||||
DBG_OUTPUT_PORT.println("Stored: SSID = " + Router_SSID + ", Pass = " + Router_Pass);
|
||||
|
||||
// SSID to uppercase
|
||||
ssid.toUpperCase();
|
||||
|
||||
// From v1.1.0, Don't permit NULL password
|
||||
if ( (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("Got stored Credentials. Timeout 120s for Config Portal");
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println("Open Config Portal without Timeout: No stored Credentials.");
|
||||
initialConfig = true;
|
||||
}
|
||||
|
||||
if (drd->detectDoubleReset())
|
||||
{
|
||||
// DRD, disable timeout.
|
||||
ESP_wifiManager.setConfigPortalTimeout(0);
|
||||
|
||||
DBG_OUTPUT_PORT.println("Open Config Portal without Timeout: Double Reset Detected");
|
||||
initialConfig = true;
|
||||
}
|
||||
|
||||
if (initialConfig)
|
||||
{
|
||||
// Starts an access point
|
||||
if (!ESP_wifiManager.startConfigPortal((const char *) ssid.c_str(), password))
|
||||
DBG_OUTPUT_PORT.println("Not connected to WiFi but continuing anyway.");
|
||||
else
|
||||
{
|
||||
DBG_OUTPUT_PORT.println("WiFi connected...yeey :)");
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
saveConfigData();
|
||||
}
|
||||
|
||||
startedAt = millis();
|
||||
|
||||
if (!initialConfig)
|
||||
{
|
||||
// Load stored data, the addAP ready for MultiWiFi reconnection
|
||||
loadConfigData();
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
if ( WiFi.status() != WL_CONNECTED )
|
||||
{
|
||||
DBG_OUTPUT_PORT.println("ConnectMultiWiFi in setup");
|
||||
|
||||
connectMultiWiFi();
|
||||
}
|
||||
}
|
||||
|
||||
DBG_OUTPUT_PORT.print("After waiting ");
|
||||
DBG_OUTPUT_PORT.print((float) (millis() - startedAt) / 1000L);
|
||||
DBG_OUTPUT_PORT.print(" secs more in setup(), connection result is ");
|
||||
|
||||
if (WiFi.status() == WL_CONNECTED)
|
||||
{
|
||||
DBG_OUTPUT_PORT.print("connected. Local IP: ");
|
||||
DBG_OUTPUT_PORT.println(WiFi.localIP());
|
||||
}
|
||||
else
|
||||
DBG_OUTPUT_PORT.println(ESP_wifiManager.getStatus(WiFi.status()));
|
||||
|
||||
//SERVER INIT
|
||||
//list directory
|
||||
server.on("/list", HTTP_GET, handleFileList);
|
||||
|
||||
//load editor
|
||||
server.on("/edit", HTTP_GET, []()
|
||||
{
|
||||
if (!handleFileRead("/edit.htm"))
|
||||
{
|
||||
server.send(404, "text/plain", "FileNotFound");
|
||||
}
|
||||
});
|
||||
|
||||
//create file
|
||||
server.on("/edit", HTTP_PUT, handleFileCreate);
|
||||
|
||||
//delete file
|
||||
server.on("/edit", HTTP_DELETE, handleFileDelete);
|
||||
|
||||
//first callback is called after the request has ended with all parsed arguments
|
||||
//second callback handles file uploads at that location
|
||||
server.on("/edit", HTTP_POST, []()
|
||||
{
|
||||
server.send(200, "text/plain", "");
|
||||
}, handleFileUpload);
|
||||
|
||||
//called when the url is not defined here
|
||||
//use it to load content from SPIFFS
|
||||
server.onNotFound([]()
|
||||
{
|
||||
if (!handleFileRead(server.uri()))
|
||||
{
|
||||
server.send(404, "text/plain", "FileNotFound");
|
||||
}
|
||||
});
|
||||
|
||||
//get heap status, analog input value and all GPIO statuses in one json call
|
||||
server.on("/all", HTTP_GET, []()
|
||||
{
|
||||
String json('{');
|
||||
json += "\"heap\":" + String(ESP.getFreeHeap());
|
||||
json += ", \"analog\":" + String(analogRead(A0));
|
||||
json += ", \"gpio\":" + String((uint32_t)(((GPI | GPO) & 0xFFFF) | ((GP16I & 0x01) << 16)));
|
||||
json += "}";
|
||||
server.send(200, "text/json", json);
|
||||
json.clear();
|
||||
});
|
||||
|
||||
server.begin();
|
||||
|
||||
DBG_OUTPUT_PORT.print("HTTP server started @ ");
|
||||
DBG_OUTPUT_PORT.println(WiFi.localIP());
|
||||
|
||||
MDNS.begin(host);
|
||||
DBG_OUTPUT_PORT.print("Open http://");
|
||||
DBG_OUTPUT_PORT.print(host);
|
||||
DBG_OUTPUT_PORT.println(".local/edit to see the file browser");
|
||||
}
|
||||
|
||||
void loop(void)
|
||||
{
|
||||
// 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.
|
||||
drd->loop();
|
||||
|
||||
// this is just for checking if we are alive and connected to WiFi
|
||||
check_status();
|
||||
|
||||
server.handleClient();
|
||||
MDNS.update();
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
# ESP_FSWebServer Example
|
||||
|
||||
## First, how Config Portal works?
|
||||
In `Configuration Portal Mode`, it starts an access point called `ESP_xxxxxx`. Connect to it using the configurable password you can define in the code. For example, `your_password` (see examples):
|
||||
|
||||
```cpp
|
||||
// SSID and PW for Config Portal
|
||||
String ssid = "ESP_" + String(ESP_getChipId(), HEX);
|
||||
const char* password = "your_password";
|
||||
```
|
||||
After you connected, please, go to http://192.168.4.1, you'll see this `Main` page:
|
||||
|
||||
<p align="center">
|
||||
<img src="https://github.com/khoih-prog/ESP_WiFiManager/blob/master/Images/Main.png">
|
||||
</p>
|
||||
|
||||
Select `Information` to enter the Info page where the board info will be shown (long page)
|
||||
|
||||
<p align="center">
|
||||
<img src="https://github.com/khoih-prog/ESP_WiFiManager/blob/master/Images/Info.png">
|
||||
</p>
|
||||
|
||||
or short page (default)
|
||||
|
||||
<p align="center">
|
||||
<img src="https://github.com/khoih-prog/ESP_WiFiManager/blob/master/Images/Info_Short.png">
|
||||
</p>
|
||||
|
||||
Select `Configuration` to enter this page where you can select an AP and specify its WiFi Credentials
|
||||
|
||||
<p align="center">
|
||||
<img src="https://github.com/khoih-prog/ESP_WiFiManager/blob/master/Images/Configuration.png">
|
||||
</p>
|
||||
|
||||
Enter your credentials, then click `Save`. 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 select `Exit Portal` from the `Main` page to reboot the board and connect to the previously-stored AP. The WiFi Credentials are still intact.
|
||||
|
||||
|
||||
## How to use this ESP_FSWebServer example?
|
||||
|
||||
This shows you how to use this example in Ubuntu (but you can use similar commands in other OSes)
|
||||
|
||||
1. For example, you already downloaded from (https://github.com/khoih-prog/ESP_WiFiManager/tree/master/examples/ESP_FSWebServer/data) to a local folder, e.g.,
|
||||
|
||||
~/Arduino/libraries/ESP_WiFiManager-master/examples/ESP_FSWebServer/data
|
||||
|
||||
1. Upload the contents of that `data folder` with MkSPIFFS Tool ("ESP8266 Sketch Data Upload" in Tools menu in Arduino IDE)
|
||||
2. or upload the contents of a folder by running the following commands:
|
||||
- Ubuntu$ cd ~/Arduino/libraries/ESP_WiFiManager-master/examples/ESP_FSWebServer/data
|
||||
- Ubuntu$ for file in \`\ls -A1\`; do curl -F "file=@$PWD/$file" esp8266fs.local/edit; done
|
||||
3. Access the sample web page at http://esp8266fs.local
|
||||
|
||||
<p align="center">
|
||||
<img src="https://github.com/khoih-prog/ESP_WiFiManager/blob/master/examples/ESP_FSWebServer/pics/esp8266fs.local.png">
|
||||
</p>
|
||||
|
||||
4. Edit / Delete / Download any file in the the folder by going to http://esp8266fs.local/edit
|
||||
|
||||
<p align="center">
|
||||
<img src="https://github.com/khoih-prog/ESP_WiFiManager/blob/master/examples/ESP_FSWebServer/pics/esp8266fs.local_edit.png">
|
||||
</p>
|
||||
|
||||
|
||||
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 8.1 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,97 @@
|
||||
<!--
|
||||
FSWebServer - Example Index Page
|
||||
Copyright (c) 2015 Hristo Gochkov. All rights reserved.
|
||||
This file is part of the ESP8266WebServer library for Arduino environment.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
-->
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
|
||||
<title>ESP Monitor</title>
|
||||
<script type="text/javascript" src="graphs.js"></script>
|
||||
<script type="text/javascript">
|
||||
var heap,temp,digi;
|
||||
var reloadPeriod = 1000;
|
||||
var running = false;
|
||||
|
||||
function loadValues(){
|
||||
if(!running) return;
|
||||
var xh = new XMLHttpRequest();
|
||||
xh.onreadystatechange = function(){
|
||||
if (xh.readyState == 4){
|
||||
if(xh.status == 200) {
|
||||
var res = JSON.parse(xh.responseText);
|
||||
heap.add(res.heap);
|
||||
temp.add(res.analog);
|
||||
digi.add(res.gpio);
|
||||
if(running) setTimeout(loadValues, reloadPeriod);
|
||||
} else running = false;
|
||||
}
|
||||
};
|
||||
xh.open("GET", "/all", true);
|
||||
xh.send(null);
|
||||
};
|
||||
|
||||
function run(){
|
||||
if(!running){
|
||||
running = true;
|
||||
loadValues();
|
||||
}
|
||||
}
|
||||
|
||||
function onBodyLoad(){
|
||||
var refreshInput = document.getElementById("refresh-rate");
|
||||
refreshInput.value = reloadPeriod;
|
||||
refreshInput.onchange = function(e){
|
||||
var value = parseInt(e.target.value);
|
||||
reloadPeriod = (value > 0)?value:0;
|
||||
e.target.value = reloadPeriod;
|
||||
}
|
||||
var stopButton = document.getElementById("stop-button");
|
||||
stopButton.onclick = function(e){
|
||||
running = false;
|
||||
}
|
||||
var startButton = document.getElementById("start-button");
|
||||
startButton.onclick = function(e){
|
||||
run();
|
||||
}
|
||||
|
||||
// Example with 10K thermistor
|
||||
//function calcThermistor(v) {
|
||||
// var t = Math.log(((10230000 / v) - 10000));
|
||||
// t = (1/(0.001129148+(0.000234125*t)+(0.0000000876741*t*t*t)))-273.15;
|
||||
// return (t>120)?0:Math.round(t*10)/10;
|
||||
//}
|
||||
//temp = createGraph(document.getElementById("analog"), "Temperature", 100, 128, 10, 40, false, "cyan", calcThermistor);
|
||||
|
||||
temp = createGraph(document.getElementById("analog"), "Analog Input", 100, 128, 0, 1023, false, "cyan");
|
||||
heap = createGraph(document.getElementById("heap"), "Current Heap", 100, 125, 0, 30000, true, "orange");
|
||||
digi = createDigiGraph(document.getElementById("digital"), "GPIO", 100, 146, [0, 4, 5, 16], "gold");
|
||||
run();
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body id="index" style="margin:0; padding:0;" onload="onBodyLoad()">
|
||||
<div id="controls" style="display: block; border: 1px solid rgb(68, 68, 68); padding: 5px; margin: 5px; width: 362px; background-color: rgb(238, 238, 238);">
|
||||
<label>Period (ms):</label>
|
||||
<input type="number" id="refresh-rate"/>
|
||||
<input type="button" id="start-button" value="Start"/>
|
||||
<input type="button" id="stop-button" value="Stop"/>
|
||||
</div>
|
||||
<div id="heap"></div>
|
||||
<div id="analog"></div>
|
||||
<div id="digital"></div>
|
||||
</body>
|
||||
</html>
|
||||
|
After Width: | Height: | Size: 45 KiB |
|
After Width: | Height: | Size: 77 KiB |
90
arduino-cli/libraries/ESP_WiFiManager/keywords.txt
Normal file
@@ -0,0 +1,90 @@
|
||||
##########################################
|
||||
# Syntax Coloring Map For ESP_WifiManager
|
||||
##########################################
|
||||
|
||||
#######################################
|
||||
# Datatypes (KEYWORD1)
|
||||
#######################################
|
||||
|
||||
ESP_WiFiManager KEYWORD1
|
||||
ESP_WMParameter KEYWORD1
|
||||
|
||||
|
||||
#######################################
|
||||
# Methods and Functions (KEYWORD2)
|
||||
#######################################
|
||||
getID KEYWORD2
|
||||
getValue KEYWORD2
|
||||
getPlaceholder KEYWORD2
|
||||
getValueLength KEYWORD2
|
||||
getLabelPlacement KEYWORD2
|
||||
getCustomHTML KEYWORD2
|
||||
autoConnect KEYWORD2
|
||||
startConfigPortal KEYWORD2
|
||||
getConfigPortalSSID KEYWORD2
|
||||
getConfigPortalPW KEYWORD2
|
||||
resetSettings KEYWORD2
|
||||
setConfigPortalTimeout KEYWORD2
|
||||
setTimeout KEYWORD2
|
||||
setConnectTimeout KEYWORD2
|
||||
setDebugOutput KEYWORD2
|
||||
setMinimumSignalQuality KEYWORD2
|
||||
setConfigPortalChannel KEYWORD2
|
||||
setAPStaticIPConfig KEYWORD2
|
||||
setSTAStaticIPConfig KEYWORD2
|
||||
setAPCallback KEYWORD2
|
||||
setSaveConfigCallback KEYWORD2
|
||||
addParameter KEYWORD2
|
||||
setBreakAfterConfig KEYWORD2
|
||||
setCustomHeadElement KEYWORD2
|
||||
setRemoveDuplicateAPs KEYWORD2
|
||||
scanWifiNetworks KEYWORD2
|
||||
getSSID KEYWORD2
|
||||
getPW KEYWORD2
|
||||
getSSID1 KEYWORD2
|
||||
getPW1 KEYWORD2
|
||||
setCORSHeader KEYWORD2
|
||||
getCORSHeader KEYWORD2
|
||||
getParameters KEYWORD2
|
||||
getParametersCount KEYWORD2
|
||||
getStatus KEYWORD2
|
||||
getStoredWiFiSSID KEYWORD2
|
||||
getStoredWiFiPass KEYWORD2
|
||||
WiFi_SSID KEYWORD2
|
||||
WiFi_Pass KEYWORD2
|
||||
setHostname KEYWORD2
|
||||
|
||||
#######################################
|
||||
# Constants (LITERAL1)
|
||||
#######################################
|
||||
|
||||
# LITERAL1
|
||||
|
||||
WM_HTTP_200 LITERAL1
|
||||
WM_HTTP_HEAD_START LITERAL1
|
||||
WM_HTTP_STYLE LITERAL1
|
||||
WM_HTTP_SCRIPT LITERAL1
|
||||
WM_HTTP_SCRIPT_NTP_MSG LITERAL1
|
||||
WM_HTTP_SCRIPT_NTP LITERAL1
|
||||
WM_HTTP_HEAD_END LITERAL1
|
||||
WM_FLDSET_START LITERAL1
|
||||
WM_FLDSET_END LITERAL1
|
||||
WM_HTTP_PORTAL_OPTIONS LITERAL1
|
||||
WM_HTTP_ITEM LITERAL1
|
||||
JSON_ITEM LITERAL1
|
||||
WM_HTTP_FORM_LABEL_BEFORE LITERAL1
|
||||
WM_HTTP_FORM_LABEL_AFTER LITERAL1
|
||||
WM_HTTP_FORM_LABEL LITERAL1
|
||||
WM_HTTP_FORM_PARAM LITERAL1
|
||||
WM_HTTP_FORM_END LITERAL1
|
||||
WM_HTTP_SAVED LITERAL1
|
||||
WM_HTTP_END LITERAL1
|
||||
WM_HTTP_HEAD_CL LITERAL1
|
||||
WM_HTTP_HEAD_CT LITERAL1
|
||||
WM_HTTP_HEAD_CT2 LITERAL1
|
||||
WM_HTTP_CACHE_CONTROL LITERAL1
|
||||
WM_HTTP_PRAGMA LITERAL1
|
||||
WM_HTTP_NO_CACHE LITERAL1
|
||||
WM_HTTP_EXPIRES LITERAL1
|
||||
WM_HTTP_CORS LITERAL1
|
||||
WM_HTTP_CORS_ALLOW_ALL LITERAL1
|
||||
28
arduino-cli/libraries/ESP_WiFiManager/library.json
Normal file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"name": "ESP_WifiManager",
|
||||
"version": "1.2.0",
|
||||
"keywords": "wifi, WiFiManager, esp8266, esp32",
|
||||
"description": "ESP32, ESP8266 MultiWiFi Connection Manager with enhanced GUI and fallback web ConfigPortal. This Library is used for configuring ESP32, ESP8266 modules MultiWiFi Credentials at runtime. You can also specify static DNS servers, personalized HostName, fixed or random AP channel. Now with MultiWiFi auto(Re)connect feature and configurable CORS Header.",
|
||||
"authors":
|
||||
{
|
||||
"name": "Khoi Hoang",
|
||||
"url": "https://github.com/khoih-prog",
|
||||
"maintainer": true
|
||||
},
|
||||
"repository":
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://github.com/khoih-prog/ESP_WiFiManager"
|
||||
},
|
||||
"homepage": "https://github.com/khoih-prog/ESP_WiFiManager",
|
||||
"export": {
|
||||
"exclude": [
|
||||
"linux",
|
||||
"extras",
|
||||
"tests"
|
||||
]
|
||||
},
|
||||
"frameworks": "*",
|
||||
"platforms": "espressif",
|
||||
"examples": "examples/*/*/*.ino"
|
||||
}
|
||||
11
arduino-cli/libraries/ESP_WiFiManager/library.properties
Normal file
@@ -0,0 +1,11 @@
|
||||
name=ESP_WiFiManager
|
||||
version=1.2.0
|
||||
author=Khoi Hoang
|
||||
maintainer=Khoi Hoang <khoih.prog@gmail.com>
|
||||
license=MIT
|
||||
sentence=ESP32, ESP8266 MuiltiWiFi Connection Manager with enhanced GUI and fallback web ConfigPortal
|
||||
paragraph=Library for configuring ESP32, ESP8266 modules MultiWiFi credentials at runtime. You can also specify static DNS servers, personalized HostName, fixed or random AP channel. Now with MultiWiFi auto(Re)connect feature and configurable CORS Header.
|
||||
category=Communication
|
||||
url=https://github.com/khoih-prog/ESP_WiFiManager
|
||||
architectures=esp8266,esp32
|
||||
depends=ESP_DoubleResetDetector
|
||||
126
arduino-cli/libraries/ESP_WiFiManager/platformio/platformio.ini
Normal file
@@ -0,0 +1,126 @@
|
||||
;PlatformIO Project Configuration File
|
||||
;
|
||||
; Build options: build flags, source filter
|
||||
; Upload options: custom upload port, speed and extra flags
|
||||
; Library options: dependencies, extra library storages
|
||||
; Advanced options: extra scripting
|
||||
;
|
||||
; Please visit documentation for the other options and examples
|
||||
; https://docs.platformio.org/page/projectconf.html
|
||||
|
||||
[platformio]
|
||||
; ============================================================
|
||||
; chose environment:
|
||||
; ESP8266
|
||||
; ESP32
|
||||
; ============================================================
|
||||
default_envs = ESP8266
|
||||
;default_envs = ESP32
|
||||
|
||||
[env]
|
||||
; ============================================================
|
||||
; Serial configuration
|
||||
; choose upload speed, serial-monitor speed
|
||||
; ============================================================
|
||||
upload_speed = 921600
|
||||
;upload_port = COM11
|
||||
;monitor_speed = 9600
|
||||
;monitor_port = COM11
|
||||
|
||||
lib_deps =
|
||||
; PlatformIO 4.x
|
||||
ESP_DoubleResetDetector@~1.0.3
|
||||
; PlatformIO 5.x
|
||||
; khoih-prog/ESP_DoubleResetDetector@~1.0.3
|
||||
|
||||
build_flags =
|
||||
; set your debug output (default=Serial)
|
||||
-D DEBUG_ESP_PORT=Serial
|
||||
; comment the folowing line to enable WiFi debugging
|
||||
-D NDEBUG
|
||||
|
||||
[env:ESP8266]
|
||||
platform = espressif8266
|
||||
framework = arduino
|
||||
; ============================================================
|
||||
; Board configuration
|
||||
; choose your board by uncommenting one of the following lines
|
||||
; ============================================================
|
||||
;board = gen4iod
|
||||
;board = huzzah
|
||||
;board = oak
|
||||
;board = esp_wroom_02
|
||||
;board = espduino
|
||||
;board = espectro
|
||||
;board = espino
|
||||
;board = espresso_lite_v1
|
||||
;board = espresso_lite_v2
|
||||
;board = esp12e
|
||||
;board = esp01_1m
|
||||
;board = esp01
|
||||
;board = esp07
|
||||
;board = esp8285
|
||||
;board = heltec_wifi_kit_8
|
||||
;board = inventone
|
||||
;board = nodemcu
|
||||
board = nodemcuv2
|
||||
;board = modwifi
|
||||
;board = phoenix_v1
|
||||
;board = phoenix_v2
|
||||
;board = sparkfunBlynk
|
||||
;board = thing
|
||||
;board = thingdev
|
||||
;board = esp210
|
||||
;board = espinotee
|
||||
;board = d1
|
||||
;board = d1_mini
|
||||
;board = d1_mini_lite
|
||||
;board = d1_mini_pro
|
||||
;board = wifi_slot
|
||||
;board = wifiduino
|
||||
;board = wifinfo
|
||||
;board = wio_link
|
||||
;board = wio_node
|
||||
;board = xinabox_cw01
|
||||
;board = esp32doit-devkit-v1
|
||||
|
||||
[env:ESP32]
|
||||
platform = espressif32
|
||||
framework = arduino, espidf
|
||||
; ============================================================
|
||||
; Board configuration
|
||||
; choose your board by uncommenting one of the following lines
|
||||
; ============================================================
|
||||
;board = esp32cam
|
||||
;board = alksesp32
|
||||
;board = featheresp32
|
||||
;board = espea32
|
||||
;board = bpi-bit
|
||||
;board = d-duino-32
|
||||
board = esp32doit-devkit-v1
|
||||
;board = pocket_32
|
||||
;board = fm-devkit
|
||||
;board = pico32
|
||||
;board = esp32-evb
|
||||
;board = esp32-gateway
|
||||
;board = esp32-pro
|
||||
;board = esp32-poe
|
||||
;board = oroca_edubot
|
||||
;board = onehorse32dev
|
||||
;board = lopy
|
||||
;board = lopy4
|
||||
;board = wesp32
|
||||
;board = esp32thing
|
||||
;board = sparkfun_lora_gateway_1-channel
|
||||
;board = ttgo-lora32-v1
|
||||
;board = ttgo-t-beam
|
||||
;board = turta_iot_node
|
||||
;board = lolin_d32
|
||||
;board = lolin_d32_pro
|
||||
;board = lolin32
|
||||
;board = wemosbat
|
||||
;board = widora-air
|
||||
;board = xinabox_cw02
|
||||
;board = iotbusio
|
||||
;board = iotbusproteus
|
||||
;board = nina_w10
|
||||
2022
arduino-cli/libraries/ESP_WiFiManager/src/ESP_WiFiManager.cpp
Normal file
543
arduino-cli/libraries/ESP_WiFiManager/src/ESP_WiFiManager.h
Normal file
@@ -0,0 +1,83 @@
|
||||
/****************************************************************************************************************************
|
||||
ESP_WiFiManager_Debug.h
|
||||
For ESP8266 / ESP32 boards
|
||||
|
||||
ESP_WiFiManager is a library for the ESP8266/Arduino platform
|
||||
(https://github.com/esp8266/Arduino) to enable easy
|
||||
configuration and reconfiguration of WiFi credentials using a Captive Portal
|
||||
inspired by:
|
||||
http://www.esp8266.com/viewtopic.php?f=29&t=2520
|
||||
https://github.com/chriscook8/esp-arduino-apboot
|
||||
https://github.com/esp8266/Arduino/blob/master/libraries/DNSServer/examples/CaptivePortalAdvanced/
|
||||
|
||||
Modified from Tzapu https://github.com/tzapu/WiFiManager
|
||||
and from Ken Taylor https://github.com/kentaylor
|
||||
|
||||
Built by Khoi Hoang https://github.com/khoih-prog/ESP_WiFiManager
|
||||
Licensed under MIT license
|
||||
Version: 1.2.0
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 07/10/2019 Initial coding
|
||||
1.0.1 K Hoang 13/12/2019 Fix bug. Add features. Add support for ESP32
|
||||
1.0.2 K Hoang 19/12/2019 Fix bug thatkeeps ConfigPortal in endless loop if Portal/Router SSID or Password is NULL.
|
||||
1.0.3 K Hoang 05/01/2020 Option not displaying AvailablePages in Info page. Enhance README.md. Modify examples
|
||||
1.0.4 K Hoang 07/01/2020 Add RFC952 setHostname feature.
|
||||
1.0.5 K Hoang 15/01/2020 Add configurable DNS feature. Thanks to @Amorphous of https://community.blynk.cc
|
||||
1.0.6 K Hoang 03/02/2020 Add support for ArduinoJson version 6.0.0+ ( tested with v6.14.1 )
|
||||
1.0.7 K Hoang 13/04/2020 Reduce start time, fix SPIFFS bug in examples, update README.md
|
||||
1.0.8 K Hoang 10/06/2020 Fix STAstaticIP issue. Restructure code. Add LittleFS support for ESP8266 core 2.7.1+
|
||||
1.0.9 K Hoang 29/07/2020 Fix ESP32 STAstaticIP bug. Permit changing from DHCP <-> static IP using Config Portal.
|
||||
Add, enhance examples (fix MDNS for ESP32)
|
||||
1.0.10 K Hoang 08/08/2020 Add more features to Config Portal. Use random WiFi AP channel to avoid conflict.
|
||||
1.0.11 K Hoang 17/08/2020 Add CORS feature. Fix bug in softAP, autoConnect, resetSettings.
|
||||
1.1.0 K Hoang 28/08/2020 Add MultiWiFi feature to autoconnect to best WiFi at runtime
|
||||
1.1.1 K Hoang 30/08/2020 Add setCORSHeader function to allow flexible CORS. Fix typo and minor improvement.
|
||||
1.1.2 K Hoang 17/08/2020 Fix bug. Add example.
|
||||
1.2.0 K Hoang 09/10/2020 Restore cpp code besides Impl.h code to use if linker error. Fix bug.
|
||||
*****************************************************************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef WIFIMGR_DEBUG_PORT
|
||||
#define DBG_PORT WIFIMGR_DEBUG_PORT
|
||||
#else
|
||||
#define DBG_PORT Serial
|
||||
#endif
|
||||
|
||||
// Change _WIFIMGR_LOGLEVEL_ to set tracing and logging verbosity
|
||||
// 0: DISABLED: no logging
|
||||
// 1: ERROR: errors
|
||||
// 2: WARN: errors and warnings
|
||||
// 3: INFO: errors, warnings and informational (default)
|
||||
// 4: DEBUG: errors, warnings, informational and debug
|
||||
|
||||
#ifndef _WIFIMGR_LOGLEVEL_
|
||||
#define _WIFIMGR_LOGLEVEL_ 0
|
||||
#endif
|
||||
|
||||
#define LOGERROR(x) if(_WIFIMGR_LOGLEVEL_>0) { DBG_PORT.print("[WM] "); DBG_PORT.println(x); }
|
||||
#define LOGERROR0(x) if(_WIFIMGR_LOGLEVEL_>0) { DBG_PORT.print(x); }
|
||||
#define LOGERROR1(x,y) if(_WIFIMGR_LOGLEVEL_>0) { DBG_PORT.print("[WM] "); DBG_PORT.print(x); DBG_PORT.print(" "); DBG_PORT.println(y); }
|
||||
#define LOGERROR2(x,y,z) if(_WIFIMGR_LOGLEVEL_>0) { DBG_PORT.print("[WM] "); DBG_PORT.print(x); DBG_PORT.print(" "); DBG_PORT.print(y); DBG_PORT.print(" "); DBG_PORT.println(z); }
|
||||
#define LOGERROR3(x,y,z,w) if(_WIFIMGR_LOGLEVEL_>0) { DBG_PORT.print("[WM] "); DBG_PORT.print(x); DBG_PORT.print(" "); DBG_PORT.print(y); DBG_PORT.print(" "); DBG_PORT.print(z); DBG_PORT.print(" "); DBG_PORT.println(w); }
|
||||
|
||||
#define LOGWARN(x) if(_WIFIMGR_LOGLEVEL_>1) { DBG_PORT.print("[WM] "); DBG_PORT.println(x); }
|
||||
#define LOGWARN0(x) if(_WIFIMGR_LOGLEVEL_>1) { DBG_PORT.print(x); }
|
||||
#define LOGWARN1(x,y) if(_WIFIMGR_LOGLEVEL_>1) { DBG_PORT.print("[WM] "); DBG_PORT.print(x); DBG_PORT.print(" "); DBG_PORT.println(y); }
|
||||
#define LOGWARN2(x,y,z) if(_WIFIMGR_LOGLEVEL_>1) { DBG_PORT.print("[WM] "); DBG_PORT.print(x); DBG_PORT.print(" "); DBG_PORT.print(y); DBG_PORT.print(" "); DBG_PORT.println(z); }
|
||||
#define LOGWARN3(x,y,z,w) if(_WIFIMGR_LOGLEVEL_>1) { DBG_PORT.print("[WM] "); DBG_PORT.print(x); DBG_PORT.print(" "); DBG_PORT.print(y); DBG_PORT.print(" "); DBG_PORT.print(z); DBG_PORT.print(" "); DBG_PORT.println(w); }
|
||||
|
||||
#define LOGINFO(x) if(_WIFIMGR_LOGLEVEL_>2) { DBG_PORT.print("[WM] "); DBG_PORT.println(x); }
|
||||
#define LOGINFO0(x) if(_WIFIMGR_LOGLEVEL_>2) { DBG_PORT.print(x); }
|
||||
#define LOGINFO1(x,y) if(_WIFIMGR_LOGLEVEL_>2) { DBG_PORT.print("[WM] "); DBG_PORT.print(x); DBG_PORT.print(" "); DBG_PORT.println(y); }
|
||||
#define LOGINFO2(x,y,z) if(_WIFIMGR_LOGLEVEL_>2) { DBG_PORT.print("[WM] "); DBG_PORT.print(x); DBG_PORT.print(" "); DBG_PORT.print(y); DBG_PORT.print(" "); DBG_PORT.println(z); }
|
||||
#define LOGINFO3(x,y,z,w) if(_WIFIMGR_LOGLEVEL_>2) { DBG_PORT.print("[WM] "); DBG_PORT.print(x); DBG_PORT.print(" "); DBG_PORT.print(y); DBG_PORT.print(" "); DBG_PORT.print(z); DBG_PORT.print(" "); DBG_PORT.println(w); }
|
||||
|
||||
#define LOGDEBUG(x) if(_WIFIMGR_LOGLEVEL_>3) { DBG_PORT.print("[WM] "); DBG_PORT.println(x); }
|
||||
#define LOGDEBUG0(x) if(_WIFIMGR_LOGLEVEL_>3) { DBG_PORT.print(x); }
|
||||
#define LOGDEBUG1(x,y) if(_WIFIMGR_LOGLEVEL_>3) { DBG_PORT.print("[WM] "); DBG_PORT.print(x); DBG_PORT.print(" "); DBG_PORT.println(y); }
|
||||
#define LOGDEBUG2(x,y,z) if(_WIFIMGR_LOGLEVEL_>3) { DBG_PORT.print("[WM] "); DBG_PORT.print(x); DBG_PORT.print(" "); DBG_PORT.print(y); DBG_PORT.print(" "); DBG_PORT.println(z); }
|
||||
#define LOGDEBUG3(x,y,z,w) if(_WIFIMGR_LOGLEVEL_>3) { DBG_PORT.print("[WM] "); DBG_PORT.print(x); DBG_PORT.print(" "); DBG_PORT.print(y); DBG_PORT.print(" "); DBG_PORT.print(z); DBG_PORT.print(" "); DBG_PORT.println(w); }
|
||||
|
||||
2029
arduino-cli/libraries/ESP_WiFiManager/src_h/ESP_WiFiManager-Impl.h
Normal file
546
arduino-cli/libraries/ESP_WiFiManager/src_h/ESP_WiFiManager.h
Normal file
@@ -0,0 +1,87 @@
|
||||
/****************************************************************************************************************************
|
||||
ESP_WiFiManager_Debug.h
|
||||
For ESP8266 / ESP32 boards
|
||||
|
||||
ESP_WiFiManager is a library for the ESP8266/Arduino platform
|
||||
(https://github.com/esp8266/Arduino) to enable easy
|
||||
configuration and reconfiguration of WiFi credentials using a Captive Portal
|
||||
inspired by:
|
||||
http://www.esp8266.com/viewtopic.php?f=29&t=2520
|
||||
https://github.com/chriscook8/esp-arduino-apboot
|
||||
https://github.com/esp8266/Arduino/blob/master/libraries/DNSServer/examples/CaptivePortalAdvanced/
|
||||
|
||||
Modified from Tzapu https://github.com/tzapu/WiFiManager
|
||||
and from Ken Taylor https://github.com/kentaylor
|
||||
|
||||
Built by Khoi Hoang https://github.com/khoih-prog/ESP_WiFiManager
|
||||
Licensed under MIT license
|
||||
Version: 1.2.0
|
||||
|
||||
Version Modified By Date Comments
|
||||
------- ----------- ---------- -----------
|
||||
1.0.0 K Hoang 07/10/2019 Initial coding
|
||||
1.0.1 K Hoang 13/12/2019 Fix bug. Add features. Add support for ESP32
|
||||
1.0.2 K Hoang 19/12/2019 Fix bug thatkeeps ConfigPortal in endless loop if Portal/Router SSID or Password is NULL.
|
||||
1.0.3 K Hoang 05/01/2020 Option not displaying AvailablePages in Info page. Enhance README.md. Modify examples
|
||||
1.0.4 K Hoang 07/01/2020 Add RFC952 setHostname feature.
|
||||
1.0.5 K Hoang 15/01/2020 Add configurable DNS feature. Thanks to @Amorphous of https://community.blynk.cc
|
||||
1.0.6 K Hoang 03/02/2020 Add support for ArduinoJson version 6.0.0+ ( tested with v6.14.1 )
|
||||
1.0.7 K Hoang 13/04/2020 Reduce start time, fix SPIFFS bug in examples, update README.md
|
||||
1.0.8 K Hoang 10/06/2020 Fix STAstaticIP issue. Restructure code. Add LittleFS support for ESP8266 core 2.7.1+
|
||||
1.0.9 K Hoang 29/07/2020 Fix ESP32 STAstaticIP bug. Permit changing from DHCP <-> static IP using Config Portal.
|
||||
Add, enhance examples (fix MDNS for ESP32)
|
||||
1.0.10 K Hoang 08/08/2020 Add more features to Config Portal. Use random WiFi AP channel to avoid conflict.
|
||||
1.0.11 K Hoang 17/08/2020 Add CORS feature. Fix bug in softAP, autoConnect, resetSettings.
|
||||
1.1.0 K Hoang 28/08/2020 Add MultiWiFi feature to autoconnect to best WiFi at runtime
|
||||
1.1.1 K Hoang 30/08/2020 Add setCORSHeader function to allow flexible CORS. Fix typo and minor improvement.
|
||||
1.1.2 K Hoang 17/08/2020 Fix bug. Add example.
|
||||
1.2.0 K Hoang 09/10/2020 Restore cpp code besides Impl.h code to use if linker error. Fix bug.
|
||||
*****************************************************************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
//#ifndef ESP_WiFiManager_Debug_H
|
||||
//#define ESP_WiFiManager_Debug_H
|
||||
|
||||
#ifdef WIFIMGR_DEBUG_PORT
|
||||
#define DBG_PORT WIFIMGR_DEBUG_PORT
|
||||
#else
|
||||
#define DBG_PORT Serial
|
||||
#endif
|
||||
|
||||
// Change _WIFIMGR_LOGLEVEL_ to set tracing and logging verbosity
|
||||
// 0: DISABLED: no logging
|
||||
// 1: ERROR: errors
|
||||
// 2: WARN: errors and warnings
|
||||
// 3: INFO: errors, warnings and informational (default)
|
||||
// 4: DEBUG: errors, warnings, informational and debug
|
||||
|
||||
#ifndef _WIFIMGR_LOGLEVEL_
|
||||
#define _WIFIMGR_LOGLEVEL_ 0
|
||||
#endif
|
||||
|
||||
#define LOGERROR(x) if(_WIFIMGR_LOGLEVEL_>0) { DBG_PORT.print("[WM] "); DBG_PORT.println(x); }
|
||||
#define LOGERROR0(x) if(_WIFIMGR_LOGLEVEL_>0) { DBG_PORT.print(x); }
|
||||
#define LOGERROR1(x,y) if(_WIFIMGR_LOGLEVEL_>0) { DBG_PORT.print("[WM] "); DBG_PORT.print(x); DBG_PORT.print(" "); DBG_PORT.println(y); }
|
||||
#define LOGERROR2(x,y,z) if(_WIFIMGR_LOGLEVEL_>0) { DBG_PORT.print("[WM] "); DBG_PORT.print(x); DBG_PORT.print(" "); DBG_PORT.print(y); DBG_PORT.print(" "); DBG_PORT.println(z); }
|
||||
#define LOGERROR3(x,y,z,w) if(_WIFIMGR_LOGLEVEL_>0) { DBG_PORT.print("[WM] "); DBG_PORT.print(x); DBG_PORT.print(" "); DBG_PORT.print(y); DBG_PORT.print(" "); DBG_PORT.print(z); DBG_PORT.print(" "); DBG_PORT.println(w); }
|
||||
|
||||
#define LOGWARN(x) if(_WIFIMGR_LOGLEVEL_>1) { DBG_PORT.print("[WM] "); DBG_PORT.println(x); }
|
||||
#define LOGWARN0(x) if(_WIFIMGR_LOGLEVEL_>1) { DBG_PORT.print(x); }
|
||||
#define LOGWARN1(x,y) if(_WIFIMGR_LOGLEVEL_>1) { DBG_PORT.print("[WM] "); DBG_PORT.print(x); DBG_PORT.print(" "); DBG_PORT.println(y); }
|
||||
#define LOGWARN2(x,y,z) if(_WIFIMGR_LOGLEVEL_>1) { DBG_PORT.print("[WM] "); DBG_PORT.print(x); DBG_PORT.print(" "); DBG_PORT.print(y); DBG_PORT.print(" "); DBG_PORT.println(z); }
|
||||
#define LOGWARN3(x,y,z,w) if(_WIFIMGR_LOGLEVEL_>1) { DBG_PORT.print("[WM] "); DBG_PORT.print(x); DBG_PORT.print(" "); DBG_PORT.print(y); DBG_PORT.print(" "); DBG_PORT.print(z); DBG_PORT.print(" "); DBG_PORT.println(w); }
|
||||
|
||||
#define LOGINFO(x) if(_WIFIMGR_LOGLEVEL_>2) { DBG_PORT.print("[WM] "); DBG_PORT.println(x); }
|
||||
#define LOGINFO0(x) if(_WIFIMGR_LOGLEVEL_>2) { DBG_PORT.print(x); }
|
||||
#define LOGINFO1(x,y) if(_WIFIMGR_LOGLEVEL_>2) { DBG_PORT.print("[WM] "); DBG_PORT.print(x); DBG_PORT.print(" "); DBG_PORT.println(y); }
|
||||
#define LOGINFO2(x,y,z) if(_WIFIMGR_LOGLEVEL_>2) { DBG_PORT.print("[WM] "); DBG_PORT.print(x); DBG_PORT.print(" "); DBG_PORT.print(y); DBG_PORT.print(" "); DBG_PORT.println(z); }
|
||||
#define LOGINFO3(x,y,z,w) if(_WIFIMGR_LOGLEVEL_>2) { DBG_PORT.print("[WM] "); DBG_PORT.print(x); DBG_PORT.print(" "); DBG_PORT.print(y); DBG_PORT.print(" "); DBG_PORT.print(z); DBG_PORT.print(" "); DBG_PORT.println(w); }
|
||||
|
||||
#define LOGDEBUG(x) if(_WIFIMGR_LOGLEVEL_>3) { DBG_PORT.print("[WM] "); DBG_PORT.println(x); }
|
||||
#define LOGDEBUG0(x) if(_WIFIMGR_LOGLEVEL_>3) { DBG_PORT.print(x); }
|
||||
#define LOGDEBUG1(x,y) if(_WIFIMGR_LOGLEVEL_>3) { DBG_PORT.print("[WM] "); DBG_PORT.print(x); DBG_PORT.print(" "); DBG_PORT.println(y); }
|
||||
#define LOGDEBUG2(x,y,z) if(_WIFIMGR_LOGLEVEL_>3) { DBG_PORT.print("[WM] "); DBG_PORT.print(x); DBG_PORT.print(" "); DBG_PORT.print(y); DBG_PORT.print(" "); DBG_PORT.println(z); }
|
||||
#define LOGDEBUG3(x,y,z,w) if(_WIFIMGR_LOGLEVEL_>3) { DBG_PORT.print("[WM] "); DBG_PORT.print(x); DBG_PORT.print(" "); DBG_PORT.print(y); DBG_PORT.print(" "); DBG_PORT.print(z); DBG_PORT.print(" "); DBG_PORT.println(w); }
|
||||
|
||||
//#endif //ESP_WiFiManager_Debug_H
|
||||
51
arduino-cli/libraries/ESP_WiFiManager/travis/common.sh
Normal file
@@ -0,0 +1,51 @@
|
||||
#!/bin/bash
|
||||
|
||||
function build_examples()
|
||||
{
|
||||
# track the exit code for this platform
|
||||
local exit_code=0
|
||||
# loop through results and add them to the array
|
||||
examples=($(find $PWD/examples/ -name "*.pde" -o -name "*.ino"))
|
||||
|
||||
# get the last example in the array
|
||||
local last="${examples[@]:(-1)}"
|
||||
|
||||
# loop through example sketches
|
||||
for example in "${examples[@]}"; do
|
||||
|
||||
# store the full path to the example's sketch directory
|
||||
local example_dir=$(dirname $example)
|
||||
|
||||
# store the filename for the example without the path
|
||||
local example_file=$(basename $example)
|
||||
|
||||
echo "$example_file: "
|
||||
local sketch="$example_dir/$example_file"
|
||||
echo "$sketch"
|
||||
#arduino -v --verbose-build --verify $sketch
|
||||
|
||||
# verify the example, and save stdout & stderr to a variable
|
||||
# we have to avoid reading the exit code of local:
|
||||
# "when declaring a local variable in a function, the local acts as a command in its own right"
|
||||
local build_stdout
|
||||
build_stdout=$(arduino --verify $sketch 2>&1)
|
||||
|
||||
# echo output if the build failed
|
||||
if [ $? -ne 0 ]; then
|
||||
# heavy X
|
||||
echo -e "\xe2\x9c\x96"
|
||||
echo -e "----------------------------- DEBUG OUTPUT -----------------------------\n"
|
||||
echo "$build_stdout"
|
||||
echo -e "\n------------------------------------------------------------------------\n"
|
||||
|
||||
# mark as fail
|
||||
exit_code=1
|
||||
|
||||
else
|
||||
# heavy checkmark
|
||||
echo -e "\xe2\x9c\x93"
|
||||
fi
|
||||
done
|
||||
|
||||
return $exit_code
|
||||
}
|
||||