/** | |
* WiFiAutoSelector.h - Include file for class WiFiAutoSelector | |
* Copyright (c) 2016 Andreas Schaefer <asc@schaefer-it.net> | |
* | |
* A class to pick a wifi network from a list, based on the | |
* highest receive signal strength, and connect to it. | |
* Inspired by "WiFiMulti" | |
* | |
* This source code 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 file 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. | |
* | |
* Usage example: | |
* | |
* #include <ESP8266WiFi.h> | |
* #include "WiFiAutoSelector.h" | |
* | |
* #define WIFI_CONNECT_TIMEOUT 8000 | |
* WiFiAutoSelector wifiAutoSelector(WIFI_CONNECT_TIMEOUT); | |
* | |
* void setup() { | |
* Serial.begin(9600); | |
* wifiAutoSelector.add("myApOne", "s4crzt"); | |
* wifiAutoSelector.add("anotherApTwo", "moreSecret"); | |
* } | |
* | |
* void loop() { | |
* if(WiFi.status() != WL_CONNECTED) { | |
* Serial.print("Connecting wifi "); | |
* if(-1 < wifiAutoSelector.scanAndConnect()) { | |
* int connectedIndex = wifiAutoSelector.getConnectedIndex(); | |
* Serial.print("to '"); | |
* Serial.print(wifiAutoSelector.getSSID(connectedIndex)); | |
* Serial.println("'. Done."); | |
* }else{ | |
* Serial.println("failed."); | |
* } | |
* } | |
* delay(1000); | |
* } | |
* | |
*/ | |
class WiFiAutoSelector { | |
private: | |
typedef struct _NetworkInfo { | |
int rssi; | |
char ssid[32]; | |
char key[64]; | |
} NetworkInfo; | |
protected: | |
const int _WAIT_CONNECT_DELAY = 500; | |
NetworkInfo* _networks; | |
int _count; | |
int _capacity; | |
int _connectedIndex; | |
int _connectTimeout; | |
int _debug; | |
bool resize(int newCapacity) { | |
if(newCapacity <= _capacity) return true; | |
NetworkInfo* tni = (NetworkInfo*)malloc( sizeof(NetworkInfo) * newCapacity ); | |
if(!tni) return false; | |
memset(tni, 0, sizeof(NetworkInfo) * newCapacity); | |
for(int i=0; i < _count; i++) { | |
tni[i] = _networks[i]; | |
} | |
if(_networks) free(_networks); | |
_networks = tni; | |
_capacity = newCapacity; | |
return true; | |
} | |
public: | |
int getCount() { return _count; } | |
int getCapacity() { return _capacity; } | |
int getConnectedIndex() { return _connectedIndex; } | |
int getRSSI(int index) { return _networks[index].rssi; } | |
char* getSSID(int index) { return _networks[index].ssid; } | |
char* getKey(int index) { return _networks[index].key; } | |
void clear() { | |
memset(_networks, 0, sizeof(NetworkInfo) * _capacity ); | |
_count = 0; | |
} | |
int add(const char* ssid, const char* key) { | |
bool canAdd = true; | |
if((_count + 1) >= _capacity) { canAdd = resize( _capacity + 4 ); } | |
if(canAdd) { | |
_networks[_count].rssi = -1000; | |
strncpy(_networks[_count].ssid, ssid, sizeof(_networks[_count].ssid)); | |
strncpy(_networks[_count].key, key, sizeof(_networks[_count].key)); | |
_count++; | |
return _count - 1; | |
} | |
// Could not add the ssid so return -1 | |
return -1; | |
} | |
int scanAndConnect() { | |
// Initialize some variables | |
_connectedIndex = -1; | |
// No networks, then return; | |
if(!_networks || !_count) return _connectedIndex; | |
// Reset RSSI for every known network to lowest value | |
for(int i = 0; i < _count; i++) { | |
_networks[i].rssi = -1000; | |
} | |
int foundNetworkCount = WiFi.scanNetworks(); | |
if(0 >= foundNetworkCount) return _connectedIndex; | |
int bestRSSI = -1000; | |
int bestNetworkIndex = -1; | |
while(foundNetworkCount-- > 0 ) { | |
String foundSSID = WiFi.SSID(foundNetworkCount); | |
if(_debug) { | |
Serial.print("WiFiAutoSelector found network: "); | |
Serial.println(foundSSID); | |
} | |
for(int i = 0; i < _count; i++ ) { | |
if(foundSSID.equals(_networks[i].ssid)) { | |
// RSSI : the current RSSI / Received Signal Strength in dBm | |
_networks[i].rssi = WiFi.RSSI(foundNetworkCount); | |
// Keep the network index with the best signal strength | |
if(bestRSSI < _networks[i].rssi) { | |
bestRSSI = _networks[i].rssi; | |
bestNetworkIndex = i; | |
} | |
break; | |
} | |
} // for(int i = 0; i < _count; i++ ) ... | |
} // while(foundNetworkCount > 0 ) ... | |
// If we have found a best network, connect to it. | |
if(-1 < bestNetworkIndex) { | |
if(_debug) { | |
Serial.print("WiFiAutoSelector will connect to: "); | |
Serial.print(_networks[bestNetworkIndex].ssid); | |
} | |
WiFi.disconnect(); | |
delay(_WAIT_CONNECT_DELAY); | |
WiFi.begin(_networks[bestNetworkIndex].ssid, _networks[bestNetworkIndex].key); | |
// Wait for the wifi to connect. This should happen within the timeout period. | |
for(int loop = _connectTimeout; loop > 0; loop -= _WAIT_CONNECT_DELAY ) { | |
delay(_WAIT_CONNECT_DELAY); | |
if(WiFi.status() == WL_CONNECTED) { | |
_connectedIndex = bestNetworkIndex; | |
if(_debug) { | |
Serial.print("WiFi IP Address: "); | |
Serial.println(WiFi.localIP()); | |
} | |
break; | |
} | |
} | |
} | |
return _connectedIndex; | |
} | |
~WiFiAutoSelector() { | |
if(_networks) free(_networks); | |
} | |
WiFiAutoSelector(int connectTimeout, int debug = false) : | |
_networks(0L), _count(0), _capacity(0) | |
, _connectedIndex(-1) , _connectTimeout(connectTimeout), _debug(debug) { | |
} | |
}; |
This comment has been minimized.
This comment has been minimized.
where can i get the wifiautoselector.h file from |
This comment has been minimized.
This comment has been minimized.
You can get it from here. Just click on the "raw" button in the top right corner. The comment section on top of th file contains an example how to use it. |
This comment has been minimized.
This comment has been minimized.
Thanks for sharing. It's a very nice code. |
This comment has been minimized.
This comment has been minimized.
Hello. Thanks for sharing this library, it works pretty well for me. Does your library works with hidden SSID ? I tried it with 2 AP broadcasting networks with hidden SSID and I could not connect to them with this library. Regards, |
This comment has been minimized.
This comment has been minimized.
Hello Raphael
I think the library will not work with hidden SSIDs.
The point is that the known SSIDs are matched against the list of available networks found by the wifi device.
So if a SSID is hidden the device will not “see” it and also cannot determine the signal quality. And this is the basic input for matching known SSIDs against the list of available networks in the air.
The library will pick the network with the highest signal strength.
regards
Andi
… On 14. Nov 2020, at 18:54, RaphaelGirardRioTinto ***@***.***> wrote:
@RaphaelGirardRioTinto commented on this gist.
Hello.
Thanks for sharing this library, it works pretty well for me.
Does your library works with hidden SSID ? I tried it with 2 AP broadcasting networks with hidden SSID and I could not connect to them with this library.
Regards,
Raphael
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub, or unsubscribe.
|
This comment has been minimized.
This comment has been minimized.
Hi, thanks for the code, it’s very useful and works perfectly. I have two questions, if I can ask you:
|
This comment has been minimized.
This comment has been minimized.
Hello albe62. Line 103
Line 126 & 131 I got an updated version of the class/file with some optional debugging output. Thanks for the notes. |
This comment has been minimized.
This is brilliant, thank you for sharing this