ESP8266: сканировать вайфай сети и подключиться, если есть известная (нужная)

DyadyaGenya
Offline
Зарегистрирован: 23.06.2022

Доброго времени суток. Приходится часто переезжать и разбираться с ардуино (ESP) то в одном месте, то в другом. Руками постоянно перебивать пару ссид/пароль уже надоело. Решил написать функцию сканирования доступных сетей и подключаться, если есть ссид из моего списка. Вроде все сканирует, но не подключается, ну или по крайней мере не выводит полученный айпишник.

01#include <ESP8266WiFi.h>                                                // Библиотека для создания Wi-Fi подключения (клиент или точка доступа)
02#include <WiFiClient.h>
03 
04char* array_ssid[] = {"ssid1", "ssid2"};                        // Массив необходимых ссидов
05char* array_pass[] = {"pass1", "pass2"};                    // Массив необходимых паролей к этим ссидам
06 
07int count_ssid = sizeof(array_ssid) / sizeof(array_ssid[0]);            // Размер массива ссидов
08 
09// Функция скарирования и подключения к найденной известной сети из нашего списка, другие будут игнорится
10void 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 
31void 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 
45void loop() {}

Блок "else" тут не приводил, смысла нет, потому что зацикливается на подключении и выдает что-то типа этого:

01(IP unset)
02waiting...
03--------------- CUT HERE FOR EXCEPTION DECODER ---------------
04 
05Soft WDT reset
06 
07>>>stack>>>
08 
09ctx: sys
10sp: 3fffec40 end: 3fffffb0 offset: 01a0
113fffede0:  00000000 00000002 3ffe8889 4020299a 
123fffedf0:  00000000 00000002 3ffe8889 40204557 
133fffee00:  3ffe888a 00000001 00000020 3ffee638 
143fffee10:  3fffee70 3ffe85d8 3ffee638 3ffee638 
153fffee20:  40201cac 3ffe8888 3ffee638 40201cb8 
163fffee30:  40201cac 3ffe8888 3ffee638 40201fec

 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

всё давно придумано до нас - wifimulti
Забиваешь все известные тебе точки и будет тебе счастье

DyadyaGenya
Offline
Зарегистрирован: 23.06.2022

ua6em пишет:

всё давно придумано до нас - wifimulti
Забиваешь все известные тебе точки и будет тебе счастье

Да уж... счастье получил... спасибо.

Но все же хотелось понять, почему мой код не работает. Понятно, что надо бы подправить массивы, сделать парными ссид-пароль, но не думаю, что в этом проблема. Ведь сеть сканируется. Нужная находится. Но вот почему не подключается?

DyadyaGenya
Offline
Зарегистрирован: 23.06.2022

И все же хотелось бы знать/понять, почему мой вариант не работает. Дело в том, что предложенный "стандартный", "давно придуманный до нас" способ имеет одну, на мой взгляд не очень хорошую штуку. Возможно я ошибаюсь, но мне не нравится, когда пары логин-пароль вбивают в самой функции. По идее такие списки должны корректироваться вне функции. А тут они в сетапе указаны.

У меня тоже способ не самый лучший с разбивкой на отдельные массивы ссидов и паролей. Но соединить их теоретически можно. Тут ведь работает многоуровневый массив. Значит можно и соединить.

DyadyaGenya
Offline
Зарегистрирован: 23.06.2022

Таки сделал один способ без использования доп библиотеки мультивайфай. И без метода стандартной билиотеки вайфай 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 
08char* array_ssid[] = {"ssid1","ssid2","ssid3"};                   // Массив необходимых ссидов
09char* array_pass[] = {"pas1","pas2","pas3"};         // Массив необходимых паролей к этим ссидам
10int count_ssid = sizeof(array_ssid) / sizeof(array_ssid[0]);            // Размер массива ссидов
11 
12 
13void 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 
45void loop() {
46  // put your main code here, to run repeatedly:
47 
48}

В таком виде плата не отчитывается о других сетях, только пробует подключиться к существующему списку, перебирая его по кругу, пока не найдет сеть из списка.

По идее по такому же принципу можно переделать и мой первый вариант.

 

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

Да потому шта... Выведи в терминал значение networksFound, после десятой строки. И сам все поймешь.

DyadyaGenya
Offline
Зарегистрирован: 23.06.2022

brokly пишет:

Да потому шта... Выведи в терминал значение networksFound, после десятой строки. И сам все поймешь.

Да, тут мой косяк. Сделал по инерции... Тут же показывает число найденных сетей и отсчет идет с единицы, а не с нуля. Но я переделал вот так:

1for (int i = 1; i <= networksFound; i++)

И ничего не поменялось