-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathESP32WifiSmartConfig.ino
291 lines (246 loc) · 8.39 KB
/
ESP32WifiSmartConfig.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
#include "FS.h"
#include "esp_system.h"
#include <esp_wifi.h>
#include <string.h>
#include <WiFi.h>
#include <Preferences.h> // WiFi storage
const char* rssiSSID; // NO MORE hard coded set AP, all SmartConfig
const char* password;
String PrefSSID, PrefPassword; // used by preferences storage
int WFstatus;
int UpCount = 0;
int32_t rssi; // store WiFi signal strength here
String getSsid;
String getPass;
String MAC;
// For SSID storage
Preferences preferences; // declare class object
void setup() {
Serial.begin(115200);
Serial.printf("\tWiFi Setup -- \n" );
wifiInit(); // get WiFi connected
IP_info();
MAC = getMacAddress();
//delay(2000);
} // END setup()
void loop()
{
if ( WiFi.status() == WL_CONNECTED ) // Main connected loop
{
// ANY MAIN LOOP CODE HERE
} // END Main connected loop()
else // WiFi DOWN
{
WFstatus = getWifiStatus( WFstatus );
WiFi.begin( PrefSSID.c_str() , PrefPassword.c_str() );
int WLcount = 0;
while (WiFi.status() != WL_CONNECTED && WLcount < 200 )
{
delay( 100 );
Serial.printf(".");
if (UpCount >= 60) // keep from scrolling sideways forever
{
UpCount = 0;
Serial.printf("\n");
}
++UpCount;
++WLcount;
}
/*if( getWifiStatus( WFstatus ) == 3 ) //wifi returns
{
// stop LED flasher, wifi going up
}*/
if( getWifiStatus( WFstatus ) == 1 ) //wifi returns
{
initSmartConfig();
}
delay( 1000 );
} // END WiFi down
} // END loop()
void wifiInit() //
{
WiFi.mode(WIFI_AP_STA); // required to read NVR before WiFi.begin()
// load credentials from NVR, a little RTOS code here
wifi_config_t conf;
esp_wifi_get_config(WIFI_IF_STA, &conf); // load wifi settings to struct comf
rssiSSID = reinterpret_cast<const char*>(conf.sta.ssid);
password = reinterpret_cast<const char*>(conf.sta.password);
// Open Preferences with "wifi" namespace. Namespace is limited to 15 chars
preferences.begin("wifi", false);
PrefSSID = preferences.getString("ssid", "none"); //NVS key ssid
PrefPassword = preferences.getString("password", "none"); //NVS key password
preferences.end();
// keep from rewriting flash if not needed
if( !checkPrefsStore() ) // see is NV and Prefs are the same
{ // not the same, setup with SmartConfig
if( PrefSSID == "none" ) // New...setup wifi
{
initSmartConfig();
delay(3000);
ESP.restart(); // reboot with wifi configured
}
}
// I flash LEDs while connecting here
WiFi.begin( PrefSSID.c_str() , PrefPassword.c_str() );
int WLcount = 0;
while (WiFi.status() != WL_CONNECTED && WLcount < 200 ) // can take > 100 loops depending on router settings
{
delay( 100 );
Serial.printf(".");
++WLcount;
}
delay( 3000 );
// stop the led flasher here
} // END wifiInit()
// match WiFi IDs in NVS to Pref store, assumes WiFi.mode(WIFI_AP_STA); was executed
bool checkPrefsStore()
{
bool val = false;
String NVssid, NVpass, prefssid, prefpass;
NVssid = getSsidPass( "ssid" );
NVpass = getSsidPass( "pass" );
// Open Preferences with my-app namespace. Namespace name is limited to 15 chars
preferences.begin("wifi", false);
prefssid = preferences.getString("ssid", "none"); //NVS key ssid
prefpass = preferences.getString("password", "none"); //NVS key password
preferences.end();
if( NVssid.equals(prefssid) && NVpass.equals(prefpass) )
{ val = true; }
return val;
}
// optionally call this function any way you want in your own code
// to remap WiFi to another AP using SmartConfig mode. Button, condition etc..
void initSmartConfig()
{
// start LED flasher
int loopCounter = 0;
WiFi.mode( WIFI_AP_STA ); //Init WiFi, start SmartConfig
Serial.printf( "Entering SmartConfig\n" );
WiFi.stopSmartConfig(); //Stop previous SmartConfig
delay(1000);
WiFi.beginSmartConfig();
while (!WiFi.smartConfigDone())
{
// flash led to indicate not configured
Serial.printf( "." );
if( loopCounter >= 40 ) // keep from scrolling sideways forever
{
loopCounter = 0;
Serial.printf( "\n" );
}
delay(600);
++loopCounter;
}
loopCounter = 0;
// stopped flasher here
Serial.printf("\nSmartConfig received.\n Waiting for WiFi\n\n");
delay(2000 );
while( WiFi.status() != WL_CONNECTED ) // check till connected
{
delay(500);
}
IP_info(); // connected lets see IP info
preferences.begin("wifi", false); // put it in storage
preferences.putString( "ssid" , getSsid);
preferences.putString( "password", getPass);
preferences.end();
delay(300);
} // END SmartConfig()
void IP_info()
{
getSsid = WiFi.SSID();
getPass = WiFi.psk();
rssi = getRSSI( rssiSSID );
WFstatus = getWifiStatus( WFstatus );
MAC = getMacAddress();
Serial.printf( "\n\n\tSSID\t%s, ", getSsid.c_str() );
Serial.print( rssi); Serial.printf(" dBm\n" ); // printf??
Serial.printf( "\tPass:\t %s\n", getPass.c_str() );
Serial.print( "\n\n\tIP address:\t" ); Serial.print(WiFi.localIP() );
Serial.print( " / " );
Serial.println( WiFi.subnetMask() );
Serial.print( "\tGateway IP:\t" ); Serial.println( WiFi.gatewayIP() );
Serial.print( "\t1st DNS:\t" ); Serial.println( WiFi.dnsIP() );
Serial.printf( "\tMAC:\t\t%s\n", MAC.c_str() );
}
int getWifiStatus( int WiFiStatus )
{
WiFiStatus = WiFi.status();
Serial.printf("\tStatus %d", WiFiStatus );
switch( WiFiStatus )
{
case WL_IDLE_STATUS : // WL_IDLE_STATUS = 0,
Serial.printf(", WiFi IDLE \n");
break;
case WL_NO_SSID_AVAIL: // WL_NO_SSID_AVAIL = 1,
Serial.printf(", NO SSID AVAIL \n");
break;
case WL_SCAN_COMPLETED: // WL_SCAN_COMPLETED = 2,
Serial.printf(", WiFi SCAN_COMPLETED \n");
break;
case WL_CONNECTED: // WL_CONNECTED = 3,
Serial.printf(", WiFi CONNECTED \n");
break;
case WL_CONNECT_FAILED: // WL_CONNECT_FAILED = 4,
Serial.printf(", WiFi WL_CONNECT FAILED\n");
break;
case WL_CONNECTION_LOST: // WL_CONNECTION_LOST = 5,
Serial.printf(", WiFi CONNECTION LOST\n");
WiFi.persistent(false); // don't write FLASH
break;
case WL_DISCONNECTED: // WL_DISCONNECTED = 6
Serial.printf(", WiFi DISCONNECTED ==\n");
WiFi.persistent(false); // don't write FLASH when reconnecting
break;
}
return WiFiStatus;
}
// END getWifiStatus()
// Get the station interface MAC address.
// @return String MAC
String getMacAddress(void)
{
WiFi.mode(WIFI_AP_STA); // required to read NVR before WiFi.begin()
uint8_t baseMac[6];
esp_read_mac( baseMac, ESP_MAC_WIFI_STA ); // Get MAC address for WiFi station
char macStr[18] = { 0 };
sprintf(macStr, "%02X:%02X:%02X:%02X:%02X:%02X", baseMac[0], baseMac[1], baseMac[2], baseMac[3], baseMac[4], baseMac[5]);
return String(macStr);
}
// END getMacAddress()
// Return RSSI or 0 if target SSID not found
// const char* SSID = "YOUR_SSID"; // declare in GLOBAL space
// call: int32_t rssi = getRSSI( SSID );
int32_t getRSSI( const char* target_ssid )
{
byte available_networks = WiFi.scanNetworks();
for (int network = 0; network < available_networks; network++)
{
if ( strcmp( WiFi.SSID( network).c_str(), target_ssid ) == 0)
{
return WiFi.RSSI( network );
}
}
return 0;
} // END getRSSI()
// Requires; #include <esp_wifi.h>
// Returns String NONE, ssid or pass arcording to request
// ie String var = getSsidPass( "pass" );
String getSsidPass( String s )
{
String val = "NONE"; // return "NONE" if wrong key sent
s.toUpperCase();
if( s.compareTo("SSID") == 0 )
{
wifi_config_t conf;
esp_wifi_get_config( WIFI_IF_STA, &conf );
val = String( reinterpret_cast<const char*>(conf.sta.ssid) );
}
if( s.compareTo("PASS") == 0 )
{
wifi_config_t conf;
esp_wifi_get_config( WIFI_IF_STA, &conf );
val = String( reinterpret_cast<const char*>(conf.sta.password) );
}
return val;
}