ESP8266: сканировать вайфай сети и подключиться, если есть известная (нужная)
- Войдите на сайт для отправки комментариев
Чт, 07/07/2022 - 02:09
Доброго времени суток. Приходится часто переезжать и разбираться с ардуино (ESP) то в одном месте, то в другом. Руками постоянно перебивать пару ссид/пароль уже надоело. Решил написать функцию сканирования доступных сетей и подключаться, если есть ссид из моего списка. Вроде все сканирует, но не подключается, ну или по крайней мере не выводит полученный айпишник.
01 | #include <ESP8266WiFi.h> // Библиотека для создания Wi-Fi подключения (клиент или точка доступа) |
02 | #include <WiFiClient.h> |
03 |
04 | char * array_ssid[] = { "ssid1" , "ssid2" }; // Массив необходимых ссидов |
05 | char * array_pass[] = { "pass1" , "pass2" }; // Массив необходимых паролей к этим ссидам |
06 |
07 | int count_ssid = sizeof (array_ssid) / sizeof (array_ssid[0]); // Размер массива ссидов |
08 |
09 | // Функция скарирования и подключения к найденной известной сети из нашего списка, другие будут игнорится |
10 | void conekt_to_wifi( int networksFound) { // |
11 | for ( int i = 0; i < networksFound; i++) { |
12 | for ( int j = 0; j < count_ssid; j++) { |
13 | if (WiFi.SSID(i)==array_ssid[j]) { |
14 | Serial .println( "One of ouer ssid was found = " +WiFi.SSID(i)); |
15 | WiFi.begin(array_ssid[j], array_pass[j]); // Инициализируем подключение к указанной вайфай сети |
16 | WiFi.setHostname( "Host_MDNS" ); // Устанавливаем новое имя нашего клиента |
17 | Serial .println(WiFi.hostname()); // Распечатываем имя клиента |
18 | while (WiFi.status() != WL_CONNECTED) { // Зупускаем ожидание поднятия вайфай сервера |
19 | Serial .println( "waiting..." ); |
20 | delay(1000); |
21 |
22 | Serial .println(WiFi.localIP()); // Выводим в монитор порта айпишник нашей платы |
23 | } |
24 | } |
25 | } |
26 |
27 | } |
28 | } |
29 |
30 |
31 | void setup () { |
32 | Serial .begin(9600); |
33 | while (! Serial ) { |
34 | // ждём, пока не откроется монитор последовательного порта |
35 | // для того, чтобы отследить все события в программе |
36 | } |
37 | WiFi.mode(WIFI_OFF); // Останавливаем вайфай |
38 | delay(1000); |
39 | WiFi.mode(WIFI_STA); // Запускаем вайфай |
40 | Serial .println( "Ouer mac = " +WiFi.macAddress()); // Выводим мак адрес |
41 |
42 | WiFi.scanNetworksAsync(conekt_to_wifi); // Сканируем вайфай сети и подклоючаемся, если есть из нашего списка |
43 | } |
44 |
45 | void loop () {} |
Блок "else" тут не приводил, смысла нет, потому что зацикливается на подключении и выдает что-то типа этого:
01 | (IP unset) |
02 | waiting... |
03 | --------------- CUT HERE FOR EXCEPTION DECODER --------------- |
04 |
05 | Soft WDT reset |
06 |
07 | >>>stack>>> |
08 |
09 | ctx: sys |
10 | sp: 3fffec40 end: 3fffffb0 offset: 01a0 |
11 | 3fffede0: 00000000 00000002 3ffe8889 4020299a |
12 | 3fffedf0: 00000000 00000002 3ffe8889 40204557 |
13 | 3fffee00: 3ffe888a 00000001 00000020 3ffee638 |
14 | 3fffee10: 3fffee70 3ffe85d8 3ffee638 3ffee638 |
15 | 3fffee20: 40201cac 3ffe8888 3ffee638 40201cb8 |
16 | 3fffee30: 40201cac 3ffe8888 3ffee638 40201fec |
всё давно придумано до нас - wifimulti
Забиваешь все известные тебе точки и будет тебе счастье
всё давно придумано до нас - wifimulti
Забиваешь все известные тебе точки и будет тебе счастье
Да уж... счастье получил... спасибо.
Но все же хотелось понять, почему мой код не работает. Понятно, что надо бы подправить массивы, сделать парными ссид-пароль, но не думаю, что в этом проблема. Ведь сеть сканируется. Нужная находится. Но вот почему не подключается?
И все же хотелось бы знать/понять, почему мой вариант не работает. Дело в том, что предложенный "стандартный", "давно придуманный до нас" способ имеет одну, на мой взгляд не очень хорошую штуку. Возможно я ошибаюсь, но мне не нравится, когда пары логин-пароль вбивают в самой функции. По идее такие списки должны корректироваться вне функции. А тут они в сетапе указаны.
У меня тоже способ не самый лучший с разбивкой на отдельные массивы ссидов и паролей. Но соединить их теоретически можно. Тут ведь работает многоуровневый массив. Значит можно и соединить.
Таки сделал один способ без использования доп библиотеки мультивайфай. И без метода стандартной билиотеки вайфай WiFi.scanNetworksAsync(), которую я использовал в первый раз. Получилось что-то типа такого:
01
#include <ESP8266WiFi.h> // Библиотека для создания Wi-Fi подключения (клиент или точка доступа)
02
#include <WiFiClient.h>
03
#include <ESP8266WebServer.h> // Библиотека для управления устройством по HTTP (например из браузера)
04
#include <FS.h> // Библиотека для работы с файловой системой
05
#include <ESP8266FtpServer.h> // Библиотека для работы с SPIFFS по FTP
06
#include <ESP8266mDNS.h> // Библиотека МДНС, позволяющая обращаться к плате по имени, а не по адресу
07
08
char
* array_ssid[] = {
"ssid1"
,
"ssid2"
,
"ssid3"
};
// Массив необходимых ссидов
09
char
* array_pass[] = {
"pas1"
,
"pas2"
,
"pas3"
};
// Массив необходимых паролей к этим ссидам
10
int
count_ssid =
sizeof
(array_ssid) /
sizeof
(array_ssid[0]);
// Размер массива ссидов
11
12
13
void
setup
() {
14
// put your setup code here, to run once:
15
Serial
.begin(9600);
// Инициализируем вывод данных на серийный порт со скоростью 9600 бод
16
while
(!
Serial
) {
17
// ждём, пока не откроется монитор последовательного порта
18
// для того, чтобы отследить все события в программе
19
}
20
WiFi.mode(WIFI_OFF);
// Останавливаем вайфай
21
delay(1000);
22
WiFi.mode(WIFI_STA);
23
WiFi.setHostname(
"Host_MDNS"
);
// Устанавливаем новое имя нашего клиента
24
Serial
.println(WiFi.hostname());
// Распечатываем имя клиента
25
// Serial.println(WiFi.status());
26
while
(WiFi.status() != WL_CONNECTED) {
// Зупускаем ожидание поднятия вайфай сервера
27
for
(
int
i = 0; i < count_ssid; i++) {
28
WiFi.begin(array_ssid[i], array_pass[i]);
// Инициализируем подключение к указанной вайфай сети
29
while
(WiFi.status() != WL_CONNECTED) {
// Зупускаем ожидание поднятия вайфай сервера
30
for
(
int
j = 0; j < 10; j++) {
31
Serial
.println(
"waiting..."
);
32
delay(1000);
33
int
ip = WiFi.localIP();
34
Serial
.println(WiFi.localIP());
// Выводим в монитор порта айпишник нашей платы
35
if
(ip ==
true
) {
36
break
;
37
}
38
}
39
break
;
40
}
41
}
42
}
43
}
44
45
void
loop
() {
46
// put your main code here, to run repeatedly:
47
48
}
В таком виде плата не отчитывается о других сетях, только пробует подключиться к существующему списку, перебирая его по кругу, пока не найдет сеть из списка.
По идее по такому же принципу можно переделать и мой первый вариант.
Да потому шта... Выведи в терминал значение networksFound, после десятой строки. И сам все поймешь.
Да потому шта... Выведи в терминал значение networksFound, после десятой строки. И сам все поймешь.
Да, тут мой косяк. Сделал по инерции... Тут же показывает число найденных сетей и отсчет идет с единицы, а не с нуля. Но я переделал вот так:
1
for
(
int
i = 1; i <= networksFound; i++)
И ничего не поменялось