Skip to content

Commit e2afeae

Browse files
Add simple WiFiMulti support (#771)
Takes a list of APs, finds the one with highest RSSI, and tries to connect.
1 parent 2b6ab6c commit e2afeae

File tree

6 files changed

+144
-5
lines changed

6 files changed

+144
-5
lines changed

libraries/WiFi/examples/WiFiClient/WiFiClient.ino

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ const char* password = STAPSK;
1616
const char* host = "djxmmx.net";
1717
const uint16_t port = 17;
1818

19+
WiFiMulti multi;
20+
1921
void setup() {
2022
Serial.begin(115200);
2123

@@ -26,11 +28,12 @@ void setup() {
2628
Serial.print("Connecting to ");
2729
Serial.println(ssid);
2830

29-
WiFi.begin(ssid, password);
31+
multi.addAP(ssid, password);
3032

31-
while (WiFi.status() != WL_CONNECTED) {
32-
delay(500);
33-
Serial.print(".");
33+
if (multi.run() != WL_CONNECTED) {
34+
Serial.println("Unable to connect to network, rebooting in 10 seconds...");
35+
delay(10000);
36+
rp2040.reboot();
3437
}
3538

3639
Serial.println("");

libraries/WiFi/keywords.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ WiFiClient KEYWORD1
1313
WiFiSSLClient KEYWORD1
1414
WiFiServer KEYWORD1
1515
WiFiUDP KEYWORD1
16+
WiFiMulti KEYWORD1
1617
NTP KEYWORD1
1718

1819

@@ -48,6 +49,7 @@ parsePacket KEYWORD2
4849
remoteIP KEYWORD2
4950
remotePort KEYWORD2
5051
mode KEYWORD2
52+
addAP KEYWORD2
5153

5254
beginAP KEYWORD2
5355
beginEnterprise KEYWORD2

libraries/WiFi/src/WiFi.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,6 @@
1212
#include "WiFiServerSecure.h"
1313
#include "WiFiUdp.h"
1414

15+
#include "WiFiMulti.h"
16+
1517
#include "WiFiNTP.h"

libraries/WiFi/src/WiFiClient.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
#pragma once
2424

2525
#include <memory>
26-
#include "WiFi.h"
2726
#include "Print.h"
2827
#include "Client.h"
2928
#include "IPAddress.h"

libraries/WiFi/src/WiFiMulti.cpp

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/*
2+
WiFiMulti.cpp - Choose best RSSI and connect
3+
Copyright (c) 2022 Earle F. Philhower, III
4+
5+
This library is free software; you can redistribute it and/or
6+
modify it under the terms of the GNU Lesser General Public
7+
License as published by the Free Software Foundation; either
8+
version 2.1 of the License, or (at your option) any later version.
9+
10+
This library is distributed in the hope that it will be useful,
11+
but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
Lesser General Public License for more details.
14+
15+
You should have received a copy of the GNU Lesser General Public
16+
License along with this library; if not, write to the Free Software
17+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18+
19+
Modified by Ivan Grokhotkov, January 2015 - esp8266 support
20+
*/
21+
22+
#include "WiFi.h"
23+
#include <string.h>
24+
#include <algorithm>
25+
26+
WiFiMulti::WiFiMulti() {
27+
}
28+
29+
WiFiMulti::~WiFiMulti() {
30+
while (!_list.empty()) {
31+
struct _AP ap = _list.front();
32+
_list.pop_front();
33+
free(ap.ssid);
34+
free(ap.pass);
35+
}
36+
}
37+
38+
bool WiFiMulti::addAP(const char *ssid, const char *pass) {
39+
struct _AP ap;
40+
ap.ssid = strdup(ssid);
41+
if (!ap.ssid) {
42+
return false;
43+
}
44+
if (pass) {
45+
ap.pass = strdup(pass);
46+
if (!ap.pass) {
47+
free(ap.ssid);
48+
return false;
49+
}
50+
} else {
51+
ap.pass = nullptr;
52+
}
53+
_list.push_front(ap);
54+
return true;
55+
}
56+
57+
uint8_t WiFiMulti::run(uint32_t to) {
58+
int cnt = WiFi.scanNetworks();
59+
if (!cnt) {
60+
return WL_DISCONNECTED;
61+
}
62+
63+
// Find the highest RSSI network in our list. Probably more efficient searches, but the list
64+
// of APs will have < 5 in > 99% of the cases so it's a don't care.
65+
int maxRSSID = -999;
66+
std::list<struct _AP>::iterator hit;
67+
bool found = false;
68+
for (int i = 0; i < cnt; i++) {
69+
if (WiFi.RSSI(i) > maxRSSID) {
70+
for (auto j = _list.begin(); j != _list.end(); j++) {
71+
if (!strcmp(j->ssid, WiFi.SSID(i))) {
72+
hit = j;
73+
maxRSSID = WiFi.RSSI(i);
74+
found = true;
75+
}
76+
}
77+
}
78+
}
79+
if (!found) {
80+
return WL_DISCONNECTED;
81+
}
82+
83+
// Connect!
84+
uint32_t start = millis();
85+
WiFi.begin(hit->ssid, hit->pass);
86+
while (!WiFi.connected() && (millis() - start < to)) {
87+
delay(5);
88+
}
89+
return WiFi.status();
90+
}

libraries/WiFi/src/WiFiMulti.h

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
WiFiMulti.h - Choose best RSSI and connect
3+
Copyright (c) 2022 Earle F. Philhower, III
4+
5+
This library is free software; you can redistribute it and/or
6+
modify it under the terms of the GNU Lesser General Public
7+
License as published by the Free Software Foundation; either
8+
version 2.1 of the License, or (at your option) any later version.
9+
10+
This library is distributed in the hope that it will be useful,
11+
but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
Lesser General Public License for more details.
14+
15+
You should have received a copy of the GNU Lesser General Public
16+
License along with this library; if not, write to the Free Software
17+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18+
19+
Modified by Ivan Grokhotkov, January 2015 - esp8266 support
20+
*/
21+
22+
#pragma once
23+
24+
#include <list>
25+
#include <stdint.h>
26+
#include "wl_definitions.h"
27+
28+
class WiFiMulti {
29+
public:
30+
WiFiMulti();
31+
~WiFiMulti();
32+
33+
bool addAP(const char *ssid, const char *pass = NULL);
34+
35+
uint8_t run(uint32_t to = 5000);
36+
37+
private:
38+
struct _AP {
39+
char *ssid;
40+
char *pass;
41+
};
42+
std::list<struct _AP> _list;
43+
};

0 commit comments

Comments
 (0)