This repository was archived by the owner on Feb 4, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 98
/
Copy pathConfigOnDoubleReset_Multi.ino
387 lines (307 loc) · 13.5 KB
/
ConfigOnDoubleReset_Multi.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
/****************************************************************************************************************************
ConfigOnDoubleReset_Multi.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
*****************************************************************************************************************************/
/****************************************************************************************************************************
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
#define ESP_WIFIMANAGER_VERSION_MIN_TARGET "ESP_WiFiManager v1.12.0"
#define ESP_WIFIMANAGER_VERSION_MIN 1012000
// Use from 0 to 4. Higher number, more debugging messages and memory usage.
#define _WIFIMGR_LOGLEVEL_ 1
// To not display stored SSIDs and PWDs on Config Portal, select false. Default is true
// Even the stored Credentials are not display, just leave them all blank to reconnect and reuse the stored Credentials
//#define DISPLAY_STORED_CREDENTIALS_IN_CP false
// These definitions must be placed before #include <ESPAsync_WiFiManager.h>
#include "ConfigOnDoubleReset_Multi.h"
#include <ESP_WiFiManager.h> //https://github.com/khoih-prog/ESP_WiFiManager
// Redundant, for v1.8.0 only
//#include <ESP_WiFiManager-Impl.h> //https://github.com/khoih-prog/ESP_WiFiManager
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);
delay(200);
Serial.print(F("\nStarting ConfigOnDoubleReset_Multi with DoubleResetDetect using ")); Serial.print(FS_Name);
Serial.print(F(" on ")); Serial.println(ARDUINO_BOARD);
Serial.println(ESP_WIFIMANAGER_VERSION);
Serial.println(ESP_DOUBLE_RESET_DETECTOR_VERSION);
#if defined(ESP_WIFIMANAGER_VERSION_MIN)
if (ESP_WIFIMANAGER_VERSION_INT < ESP_WIFIMANAGER_VERSION_MIN)
{
Serial.print("Warning. Must use this example on Version equal or later than : ");
Serial.println(ESP_WIFIMANAGER_VERSION_MIN_TARGET);
}
#endif
Serial.setDebugOutput(false);
if (FORMAT_FILESYSTEM)
FileFS.format();
// Format FileFS if not yet
#ifdef ESP32
if (!FileFS.begin(true))
#else
if (!FileFS.begin())
#endif
{
#ifdef ESP8266
FileFS.format();
#endif
Serial.println(F("SPIFFS/LittleFS failed! Already tried formatting."));
if (!FileFS.begin())
{
// prevents debug info from the library to hide err message.
delay(100);
#if USE_LITTLEFS
Serial.println(F("LittleFS failed!. Please use SPIFFS or EEPROM. Stay forever"));
#else
Serial.println(F("SPIFFS failed!. Please use LittleFS or EEPROM. Stay forever"));
#endif
while (true)
{
delay(1);
}
}
}
drd = new DoubleResetDetector(DRD_TIMEOUT, DRD_ADDRESS);
unsigned long startedAt = millis();
// New in v1.4.0
initAPIPConfigStruct(WM_AP_IPconfig);
initSTAIPConfigStruct(WM_STA_IPconfig);
//////
//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");
#if USE_CUSTOM_AP_IP
//set custom ip for portal
// New in v1.4.0
ESP_wifiManager.setAPStaticIPConfig(WM_AP_IPconfig);
//////
#endif
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
// Set (static IP, Gateway, Subnetmask, DNS1 and DNS2) or (IP, Gateway, Subnetmask). New in v1.0.5
// New in v1.4.0
ESP_wifiManager.setSTAStaticIPConfig(WM_STA_IPconfig);
//////
#endif
// New from v1.1.1
#if USING_CORS_FEATURE
ESP_wifiManager.setCORSHeader("Your Access-Control-Allow-Origin");
#endif
// 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("ESP Self-Stored: SSID = " + Router_SSID + ", Pass = " + Router_Pass);
// SSID/PWD to uppercase
ssid.toUpperCase();
password = "My" + ssid;
bool configDataLoaded = false;
// 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(F("Got ESP Self-Stored Credentials. Timeout 120s for Config Portal"));
}
if (loadConfigData())
{
configDataLoaded = true;
ESP_wifiManager.setConfigPortalTimeout(120); //If no access point name has been previously entered disable timeout.
Serial.println(F("Got stored Credentials. Timeout 120s for Config Portal"));
#if USE_ESP_WIFIMANAGER_NTP
if ( strlen(WM_config.TZ_Name) > 0 )
{
LOGERROR3(F("Current TZ_Name ="), WM_config.TZ_Name, F(", TZ = "), WM_config.TZ);
#if ESP8266
configTime(WM_config.TZ, "pool.ntp.org");
#else
//configTzTime(WM_config.TZ, "pool.ntp.org" );
configTzTime(WM_config.TZ, "time.nist.gov", "0.pool.ntp.org", "1.pool.ntp.org");
#endif
}
else
{
Serial.println(F("Current Timezone is not set. Enter Config Portal to set."));
}
#endif
}
else
{
// Enter CP only if no stored SSID on flash and file
Serial.println(F("Open Config Portal without Timeout: No stored Credentials."));
initialConfig = true;
}
if (drd->detectDoubleReset())
{
// DRD, disable timeout.
ESP_wifiManager.setConfigPortalTimeout(0);
Serial.println(F("Open Config Portal without Timeout: Double Reset Detected"));
initialConfig = true;
}
if (initialConfig)
{
Serial.print(F("Starting configuration portal @ "));
#if USE_CUSTOM_AP_IP
Serial.print(APStaticIP);
#else
Serial.print(F("192.168.4.1"));
#endif
#if defined(HTTP_PORT_TO_USE)
Serial.print(F(":")); Serial.print(HTTP_PORT_TO_USE);
#endif
Serial.print(F(", SSID = "));
Serial.print(ssid);
Serial.print(F(", PWD = "));
Serial.println(password);
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);
#if DISPLAY_STORED_CREDENTIALS_IN_CP
// New. Update Credentials, got from loadConfigData(), to display on CP
ESP_wifiManager.setCredentials(WM_config.WiFi_Creds[0].wifi_ssid, WM_config.WiFi_Creds[0].wifi_pw,
WM_config.WiFi_Creds[1].wifi_ssid, WM_config.WiFi_Creds[1].wifi_pw);
#endif
// Starts an access point
if (!ESP_wifiManager.startConfigPortal((const char *) ssid.c_str(), (const char *) password.c_str()))
Serial.println(F("Not connected to WiFi but continuing anyway."));
else
{
Serial.println(F("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);
}
}
#if USE_ESP_WIFIMANAGER_NTP
String tempTZ = ESP_wifiManager.getTimezoneName();
if (strlen(tempTZ.c_str()) < sizeof(WM_config.TZ_Name) - 1)
strcpy(WM_config.TZ_Name, tempTZ.c_str());
else
strncpy(WM_config.TZ_Name, tempTZ.c_str(), sizeof(WM_config.TZ_Name) - 1);
const char * TZ_Result = ESP_wifiManager.getTZ(WM_config.TZ_Name);
if (strlen(TZ_Result) < sizeof(WM_config.TZ) - 1)
strcpy(WM_config.TZ, TZ_Result);
else
strncpy(WM_config.TZ, TZ_Result, sizeof(WM_config.TZ_Name) - 1);
if ( strlen(WM_config.TZ_Name) > 0 )
{
LOGERROR3(F("Saving current TZ_Name ="), WM_config.TZ_Name, F(", TZ = "), WM_config.TZ);
#if ESP8266
configTime(WM_config.TZ, "pool.ntp.org");
#else
//configTzTime(WM_config.TZ, "pool.ntp.org" );
configTzTime(WM_config.TZ, "time.nist.gov", "0.pool.ntp.org", "1.pool.ntp.org");
#endif
}
else
{
LOGERROR(F("Current Timezone Name is not set. Enter Config Portal to set."));
}
#endif
// New in v1.4.0
ESP_wifiManager.getSTAStaticIPConfig(WM_STA_IPconfig);
//////
saveConfigData();
}
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
if (!configDataLoaded)
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(F("ConnectMultiWiFi in setup"));
connectMultiWiFi();
}
}
Serial.print(F("After waiting "));
Serial.print((float) (millis() - startedAt) / 1000);
Serial.print(F(" secs more in setup(), connection result is "));
if (WiFi.status() == WL_CONNECTED)
{
Serial.print(F("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();
}