Esp32WifiManager
WifiManager.cpp
Go to the documentation of this file.
1 /*
2  * WifiManager.cpp
3  *
4  * Created on: Jun 13, 2018
5  * Author: hephaestus
6  */
7 
8 #include "WifiManager.h"
10 
11 static void WiFiEventWifiManager(WiFiEvent_t event) {
12  if (WifiManager::staticRef != NULL)
13  WifiManager::staticRef->WiFiEvent(event);
14 }
15 
17 }
18 
20  WifiManager::staticRef = NULL;
21 }
23  return state;
24 }
26  switch (state) {
27  case firstStart:
28  Serial.println("WifiManager.getState()=firstStart");
29  break;
30  case Disconnected:
31  Serial.println("WifiManager.getState()=Disconnected");
32  break;
33  case InitialConnect:
34  Serial.println("WifiManager.getState()=InitialConnect");
35  break;
36  case Connected:
37  Serial.println("WifiManager.getState()=Connected");
38  break;
39  case HaveSSIDSerial:
40  Serial.println("WifiManager.getState()=HaveSSIDSerial");
41  break;
42  case reconnect:
43  Serial.println("WifiManager.getState()=reconnect");
44  break;
45  case APWaitingForSTA:
46  Serial.println("WifiManager.getState()=APWaitingForSTA");
47  break;
48  default:
49  break;
50  }
51 }
53  APMode = true;
54  WiFi.mode(WIFI_STA);
55  WiFi.disconnect();
56  delay(100);
57  setup();
58  state = reconnect;
59 }
64  setup();
65  disconnect();
66 }
68  if (setupDone)
69  return;
70  Serial.begin(115200);
71 
72 
73  WiFi.mode(WIFI_MODE_AP);
74  uint8_t mac[6];
75  char macStr[18] = { 0 };
76  esp_wifi_get_mac(WIFI_IF_STA, mac);
77  sprintf(macStr, "%02X-%02X", mac[4], mac[5]);
78  String defaultap = "esp32-" + String(macStr);
79 
80  preferences.begin("wifi", true);
81  networkNameServer = preferences.getString("ssid", "none"); //NVS key ssid
82  networkPswdServer = preferences.getString(networkNameServer.c_str(), "none"); //NVS key password
83  apNameServer = preferences.getString("apssid", defaultap); //NVS key ssid
84  apPswdServer = preferences.getString(apNameServer.c_str(), "Wumpus3742"); //NVS key password
85  preferences.end();
86 
87  state = reconnect;
88  staticRef = this;
90  WiFi.onEvent(WiFiEventWifiManager);
92  setupDone = true;
93 }
95  WiFi.disconnect(true);
96  Serial.println("\n\n\nAP starting " + apNameServer);
97 //Initiate connection
98  WiFi.mode(WIFI_MODE_AP);
99  String mac = WiFi.macAddress();
100  WiFi.softAP(apNameServer.c_str(), apPswdServer.c_str());
101 
102  timeOfLastConnect = 0;
104 
105  Serial.println("Mac Address: " + mac);
106 
107  preferences.begin("wifi", false); // Note: Namespace name is limited to 15 chars
108  if (preferences.getString("apssid", "none").compareTo(apNameServer) != 0) {
109  preferences.putString("apssid", apNameServer);
110 
111  delay(300);
112  }
113  if (preferences.getString(apNameServer.c_str(), "none").compareTo(
114  apPswdServer) != 0) {
115  preferences.putString(apNameServer.c_str(), apPswdServer);
116  delay(300);
117  }
118 
119  preferences.end();
120  Serial.println("Starting AP:" + apNameServer + "\npass = " + apPswdServer);
121  timeSinceAPStart=millis();
122 }
123 void WifiManager::connectToWiFi(const char * ssid, const char * pwd) {
124 
125  Serial.println("Attempting to connect to WiFi network: " + String(ssid));
126 //Initiate connection
127 
128  WiFi.mode(WIFI_STA);
129  WiFi.disconnect(true);
130  delay(300);
132 
133  timeOfLastConnect = 0;
135  String mac = WiFi.macAddress();
136  Serial.println("Mac Address: " + mac);
137  Serial.println("Waiting for WIFI connection... \n\n");
138  if(state==Disconnected)
139  WiFi.begin(ssid, pwd);
140  else
141  Serial.println("Wifi state already changed ");
142 }
151  Serial.println("scan start");
152  // WiFi.scanNetworks will return the number of networks found
153  WiFi.mode(WIFI_STA);
154  WiFi.disconnect(true);
155  delay(100);
156  int16_t n = WiFi.scanComplete();
157  WiFi.scanNetworks(true, false, false, 300);
158  state = scanRunning;
160  return n;
161 }
162 
164  bool myNetworkPresent = false;
165  preferences.begin("wifi", true);
166  int16_t n = WiFi.scanComplete();
167  if (n >= 0) {
168  if (n == 0) {
169  Serial.println("no networks found");
170  } else {
171  Serial.println(String(n) + " networks found");
172  if (preferences.getString(networkNameServer.c_str(), "none").compareTo(
173  "none") != 0) {
174  for (int i = 0; i < n && myNetworkPresent == false; ++i) {
175  // Print SSID and RSSI for each network found
176  if (networkNameServer.compareTo(WiFi.WiFiScanClass::SSID(i))
177  == 0) {
178  myNetworkPresent = true;
179  Serial.println(
180  "Default network found: "
181  + WiFi.WiFiScanClass::SSID(i));
182  networkPswdServer = preferences.getString(networkNameServer.c_str(), "none"); //NVS key password
183  }
184 
185  }
186  }
187  if (!myNetworkPresent) {
188  Serial.println(" Default AP is missing, searching for new one");
189  String bestNet="none";
190  int32_t bestStren=-5000;
191  for (int i = 0; i < n; ++i) {
192  // Print SSID and RSSI for each network found
193  String tmp = WiFi.WiFiScanClass::SSID(i);
194  if (preferences.getString(tmp.c_str(), "none").compareTo("none") != 0) {
195  myNetworkPresent = true;
196  if(WiFi.WiFiScanClass::RSSI(i)>bestStren){
197  bestNet=WiFi.WiFiScanClass::SSID(i);
198  bestStren=WiFi.WiFiScanClass::RSSI(i);
199  networkPswdServer = preferences.getString(
200  tmp.c_str(), "none"); //NVS key password
201  }
202  }
203  Serial.print(i + 1);
204  Serial.print(": ");
205  Serial.print(tmp);
206  Serial.print(" (");
207  Serial.print(WiFi.WiFiScanClass::RSSI(i));
208  Serial.print(")");
209  Serial.println(
210  (WiFi.encryptionType(i) == WIFI_AUTH_OPEN) ?
211  " " : "*");
212  delay(10);
213  }
214  if(myNetworkPresent){
215  networkNameServer=bestNet;
216  }
217  }
218 
219  Serial.println("");
220 
221  }
222  } else {
223  Serial.println("Scan Failed!! " + String(n));
224  }
225 
226  preferences.end();
227  if (!myNetworkPresent) {
228  Serial.println("NO availible AP/Pass stored");
229 
230  APMode = true;
231  }else
233 }
235  if (state != HaveSSIDSerial) {
236  if (Serial.available() > 1) {
237  String tmp = Serial.readString();
238  tmp.trim();
239  if (tmp.substring(0, 3).compareTo("AP:") == 0
240  || tmp.substring(0, 3).compareTo("ap:") == 0) {
241  String got = tmp.substring(3, 18); // ensure SSID is less than 15 char to use the SSID as key for password
242  if (got.length() > 1) {
243  apNameServer = got;
245  } else
246  state = reconnect;
247  APMode = true;
248  Serial.println("AP Mode ssid: " + apNameServer);
249  } else if ((tmp.compareTo("STA") == 0 || tmp.compareTo("sta") == 0)
250  && tmp.length() == 3) {
251  Serial.println(
252  "Switching to STA mode New ssid: " + networkNameServer);
253  APMode = false;
254  state = reconnect;
255  } else if ((tmp.compareTo("ERASE") == 0
256  || tmp.compareTo("erase") == 0) && tmp.length() == 5) {
257  Serial.println("Erasing all stored passwords");
258  erase();
259  ESP.restart();
260  } else if ((tmp.compareTo("scan") == 0
261  || tmp.compareTo("SCAN") == 0) && tmp.length() == 4) {
262  Serial.println("Re-scanning and reconnecting");
263  disconnect();
264  }else {
265  networkNameServer = tmp;
266  Serial.println("New ssid: " + networkNameServer);
267  APMode = false;
269  }
270  if (state == HaveSSIDSerial)
271  Serial.println("New password: ");
272 
273  }
274  }
275 }
277  long now = millis();
278  runSerialLoop();
279  switch (state) {
280  case firstStart:
281  //staticRef->printState();
282 
283  state = reconnect;
284  printState();
285  break;
286  case InitialConnect:
287  preferences.begin("wifi", false); // Note: Namespace name is limited to 15 chars
288  if (preferences.getString("ssid", "none").compareTo(networkNameServer)
289  != 0) {
290  Serial.println("Writing new ssid " + networkNameServer);
291  preferences.putString("ssid", networkNameServer);
292  delay(300);
293  }
294  if (preferences.getString(networkNameServer.c_str(), "none").compareTo(
295  networkPswdServer) != 0) {
296  Serial.println("Writing new pass ****");
297  preferences.putString(networkNameServer.c_str(), networkPswdServer);
298  delay(300);
299  }
300  preferences.end();
301  state = Connected;
302  printState();
303  break;
304  case APWaitingForSTA:
305  if ((timeSinceAPPrint + timeoutTime) < millis()) {
306  timeSinceAPPrint = millis();
307  Serial.println("Waiting for client to connect to AP "+String(millis()-timeSinceAPStart));
308  }
309  if ((timeSinceAPStart + 60000*5) < millis()){
310  disconnect();// No connections after 5 minute, try connecting
311  }// @suppress("No break at end of case")
312  case apconnected:
313  case Connected:
314  break;
315  case Disconnected:
316  //printState();
317 
318  if ((timeoutTime + timeOfLastConnect) <now)
319  if ((timeoutTime+ timeOfLastDisconnect) < now) {
320  Serial.println(
321  "Timeouts for connection wait, reconnecting last connected: "
322  + String( timeOfLastConnect)
323  + " last disconnected: "
324  + String(timeOfLastDisconnect)+
325  " now "+String(now));
326  state = reconnect;
327  printState();
330  connectionAttempts = 0;
331  updateApList();
334  }
335  }
336  break;
337  case scanRunning:
338  if(WiFi.scanComplete()!=WIFI_SCAN_RUNNING){
340  Serial.println("scan DONE!");
341  }
342  break;
343  case scanDone:
344  rescan();
346  break;
347  case reconnect:
348  if (!APMode) {
349  Serial.println("connect to WiFi network");
350  //Connect to the WiFi network
353  } else {
355  startAP();
356  }
357  //printState();
358  break;
359  case HaveSSIDSerial:
360  if (Serial.available() > 0) {
361  if (!APMode){
362  networkPswdServer = Serial.readString();
363  networkPswdServer.trim();
364  }
365  else{
366  apPswdServer = Serial.readString();
367  apPswdServer.trim();
368  }
369  state = reconnect;
370  printState();
371  }
372  break;
373  }
374 }
375 
382  printState();
383  WiFi.disconnect(true);
384  delay(300);
386  timeOfLastConnect = millis()-timeoutTime-1;
387  timeOfLastDisconnect =millis()-timeoutTime-1;
388  networkNameServer="none";
389  APMode=false;
390 
391 }
392 void WifiManager::WiFiEvent(WiFiEvent_t event) {
393  if (state == HaveSSIDSerial)
394  return;
395  //Pass the event to the UDP Simple packet server
396  switch (event) {
397  case SYSTEM_EVENT_STA_GOT_IP:
398  if (!APMode) {
400  printState();
401 
402  //When connected set
403  Serial.print("\n\n\nWiFi connected! DHCP took "+String(millis()-timeOfLastConnect)+" IP address: ");
404  Serial.print(WiFi.localIP());
405  Serial.print("\n\n\n");
406  timeOfLastConnect = millis();
407  }
408  break;
409  case SYSTEM_EVENT_STA_DISCONNECTED:
410  timeOfLastDisconnect = millis();
411  if (!APMode) {
413  printState();
414  WiFi.disconnect(true);
415  Serial.println("\n\nWiFi lost connection, retry " + String(
417  timeOfLastDisconnect=millis();
418  }
419  break;
420  case SYSTEM_EVENT_WIFI_READY:
421  if (state == Connected && !APMode) {
422  disconnect();
423  Serial.println("WiFi lost connection, retry " + String(
425  } else {
426  Serial.println("ESP32 WiFi ready ");
427  }
428  break;
429  case SYSTEM_EVENT_SCAN_DONE:
430  Serial.println("SYSTEM_EVENT_SCAN_DONE");
431  break;
432  case SYSTEM_EVENT_STA_START:
433  //Serial.println("ESP32 station start ");
434  break;
435  case SYSTEM_EVENT_STA_STOP:
436  Serial.println("SYSTEM_EVENT_STA_STOP");
437  break;
438  case SYSTEM_EVENT_STA_CONNECTED:
439  Serial.println(" ESP32 station connected to AP ");
440  if (!APMode) {
441  state = apconnected;
442  timeOfLastConnect = millis();
443  }
444  break;
445  case SYSTEM_EVENT_STA_AUTHMODE_CHANGE:
446  Serial.println("SYSTEM_EVENT_STA_AUTHMODE_CHANGE");
447  break;
448  case SYSTEM_EVENT_STA_LOST_IP:
449  Serial.println("SYSTEM_EVENT_STA_LOST_IP");
450  break;
451  case SYSTEM_EVENT_STA_WPS_ER_SUCCESS:
452  Serial.println("SYSTEM_EVENT_STA_WPS_ER_SUCCESS");
453  break;
454  case SYSTEM_EVENT_STA_WPS_ER_FAILED:
455  Serial.println("SYSTEM_EVENT_STA_WPS_ER_FAILED");
456  break;
457  case SYSTEM_EVENT_STA_WPS_ER_TIMEOUT:
458  Serial.println("SYSTEM_EVENT_STA_WPS_ER_TIMEOUT");
459  break;
460  case SYSTEM_EVENT_STA_WPS_ER_PIN:
461  Serial.println("SYSTEM_EVENT_STA_WPS_ER_PIN");
462  break;
463  case SYSTEM_EVENT_AP_START:
464  Serial.println("SYSTEM_EVENT_AP_START");
465  break;
466  case SYSTEM_EVENT_AP_STOP:
467  Serial.println("SYSTEM_EVENT_AP_STOP");
468  break;
469  case SYSTEM_EVENT_AP_STACONNECTED:
470  Serial.println("SYSTEM_EVENT_AP_STACONNECTED");
471  state = Connected;
472  break;
473  case SYSTEM_EVENT_AP_STADISCONNECTED:
474  Serial.println("SYSTEM_EVENT_AP_STADISCONNECTED");
476  break;
477  case SYSTEM_EVENT_AP_PROBEREQRECVED:
478  Serial.println("SYSTEM_EVENT_AP_PROBEREQRECVED");
479  break;
480  case SYSTEM_EVENT_AP_STA_GOT_IP6:
481  Serial.println("SYSTEM_EVENT_AP_STA_GOT_IP6");
482  break;
483  case SYSTEM_EVENT_ETH_START:
484  Serial.println("SYSTEM_EVENT_ETH_START");
485  break;
486  case SYSTEM_EVENT_ETH_STOP:
487  Serial.println("SYSTEM_EVENT_ETH_STOP");
488  break;
489  case SYSTEM_EVENT_ETH_CONNECTED:
490  Serial.println("SYSTEM_EVENT_ETH_CONNECTED");
491  break;
492  case SYSTEM_EVENT_ETH_DISCONNECTED:
493  Serial.println("SYSTEM_EVENT_ETH_DISCONNECTED");
494  break;
495  case SYSTEM_EVENT_ETH_GOT_IP:
496  Serial.println("SYSTEM_EVENT_ETH_GOT_IP");
497  break;
498  case SYSTEM_EVENT_MAX:
499  Serial.println("SYSTEM_EVENT_MAX");
500  break;
501  default:
502  break;
503  }
504 }
505 
510  return APMode;
511 }
512 
518  preferences.begin("wifi", false); // Note: Namespace name is limited to 15 chars
519  preferences.clear(); // erase all stored passwords
520  delay(300);
521  preferences.end();
522 }
void runSerialLoop()
static void WiFiEventWifiManager(WiFiEvent_t event)
Definition: WifiManager.cpp:11
void setup()
Definition: WifiManager.cpp:67
String apPswdServer
Definition: WifiManager.h:40
void WiFiEvent(WiFiEvent_t event)
String apNameServer
Definition: WifiManager.h:39
#define rescanIncrement
Definition: WifiManager.h:14
enum connectionState whatToDoAfterScanning
Definition: WifiManager.h:47
connectionState
Definition: WifiManager.h:16
void disconnect()
void startAP()
Definition: WifiManager.cpp:94
bool setupDone
Definition: WifiManager.h:48
static WifiManager * staticRef
Definition: WifiManager.h:54
int updateApList()
String networkNameServer
Definition: WifiManager.h:37
virtual ~WifiManager()
Definition: WifiManager.cpp:19
Preferences preferences
Definition: WifiManager.h:42
void setupAP()
Definition: WifiManager.cpp:52
String networkPswdServer
Definition: WifiManager.h:38
long timeOfLastConnect
Definition: WifiManager.h:36
bool isApMode()
#define timeoutTime
Definition: WifiManager.h:15
long timeSinceAPStart
Definition: WifiManager.h:45
void printState()
Definition: WifiManager.cpp:25
long timeOfLastDisconnect
Definition: WifiManager.h:35
void connectToWiFi(const char *ssid, const char *pwd)
enum connectionState state
Definition: WifiManager.h:46
enum connectionState getState()
Definition: WifiManager.cpp:22
int connectionAttempts
Definition: WifiManager.h:41
long timeSinceAPPrint
Definition: WifiManager.h:44
void setupScan()
Definition: WifiManager.cpp:63