• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

ESP8266 подключение к нескольким сетям Wi-Fi

Разве не вы программу пишете?
Установите нравящиеся вам интервалы.
Ну так я установил, только видимо не правильно сделал. Когда был делей на 1000, то писало wating... раз в секунду. Когда установил milis, то отладочная строка пишется раз в секунду, а wating... за эту секунду раз двадцать успевает вывестись.
Что значит оформить? Оформление на код не влияет, а вот алгоритм стоит придумать заранее.
Тут имелось ввиду все, и оформление, в том числе тип, и сам алгоритм. Хотя по идее алгоритм вроде как правильный. По идее, если не подключается к сети, то ждет секунду. Раньше делей это делал, теперь надеялся, что будет делать милис.
 

EvgeniyS

Member
Набросал свой вариант кода, ради спортивного интереса :) У себя проверил - работает
C++:
#include <Arduino.h>
#include <ESP8266WiFi.h>

const char* array_ssid[] = {"ssid1", "ssid2", "ssid3", "ssid4"};
const char* array_pass[] = {"pass1", "pass2", "pass3", "pass4"};
constexpr uint8_t count_ssid = sizeof(array_ssid) / sizeof(array_ssid[0]); // вычисляем размер массива на этапе компиляции
int8_t netIndex = -1; // индекс найденной сети к которой можно подключиться. Если -1 сеть не найдена, либо сканирование не требуется т.к. уже есть подкючение.

void searchTargetNet(uint8_t networksFound);
bool tryToConnect();

// Поиск сети к которой нужно подключиться
void searchTargetNet(uint8_t networksFound){
  Serial.printf("Networks found: %u\n", networksFound);
  for(uint8_t i = 0; i < networksFound; i++){
    for(uint8_t j = 0; j< count_ssid; j++){
      if(strcmp(WiFi.SSID(i).c_str(), array_ssid[j]) == 0){
        Serial.printf("Found target SSID! Index: %u , Name: %s\n",j,array_ssid[j]);
        netIndex = j;
        return;
      }
    }
  }
  Serial.printf("Not found target net\n");
};

// Попытка подключения
bool tryToConnect(){
        uint8_t tries = 11; // Количество попыток подключения
        WiFi.begin(array_ssid[netIndex], array_pass[netIndex]);
        Serial.printf("Waiting");
        while (--tries){
          Serial.print(".");
        if(WiFi.status() == WL_CONNECTED){
          IPAddress ip = WiFi.localIP();
          Serial.printf(" Status - connected, ip adress: %u.%u.%u.%u , RSSI: %i\n", ip[0],ip[1],ip[2],ip[3],WiFi.RSSI());
          WiFi.scanDelete();
          return true;
          }
          delay(800);
        }
        Serial.printf("Not connected, SSID: %s\n",array_ssid[netIndex]);
        return false;
}

void setup(void) {
  WiFi.persistent(false);
  Serial.begin(115200);
  Serial.printf("\nOur mac = %s\n",WiFi.macAddress().c_str());
  WiFi.mode(WIFI_STA);
  WiFi.scanNetworksAsync(searchTargetNet);
}

void loop(void) {
  static uint32_t timeout = 0; //время (мс) следующего опроса
  static const uint32_t interval = 10000; //интервал опроса
  if( millis()>timeout){
    timeout = millis()+interval;
    if(WiFi.status() != WL_CONNECTED){
      Serial.printf("Status - disconnected\n");
      WiFi.scanNetworksAsync(searchTargetNet);
    }
  }
  if(netIndex >= 0) {
    if(tryToConnect()) netIndex = -1;
  }
  delay(50);
}
 
Набросал свой вариант кода, ради спортивного интереса :) У себя проверил - работает
И я проверил ))) Работает. Но у меня куча вопросов:
1. Почему выбрали strcmp? Я только узнал об этой функции, и хоть она вроде как про длину строки, но даже смена места у символов оказывается влияет. Честно говоря не видь я вашего примера, не подумал бы её использовать, зная только описание и не видя примера работы. Так почему strcmp, а не обычная идентичность?
2. Не понял, что делает return в функции searchTargetNet?
3. По поводу ваших delay. А зачем они вообще? Опять же, как новичок я могу чего-то не понимать, и начинал именно с делей, но когда позавчера прочитал про милис, то вообще не понял, зачем делей используют.
 
с какого перепуга? где это написано?
Имелась ввиду моя функция arrest_time(). Но я уже понял, что она работает не так, как мне надо. Сделал пока без функции
Код:
        WiFi.begin(array_ssid[j], array_pass[j]);                           // Стартуем подключение к точке доступа
        while (WiFi.status() != WL_CONNECTED) {                             // Зупускаем ожидание поднятия вайфай сервера
//        arrest_time(1000);
          unsigned long t = 1000;
          unsigned long currentTime = millis();
          if (currentTime - previousTime >=  t){
            Serial.println (String(t)+" miliseconds"); 
            previousTime = currentTime;
            Serial.println("waiting...");
            }
        }
Но были планы как-то сделать из этого функцию.
Или вы имели ввиду, что технически сама плата имеет свой внутренний цикл обращений к точке доступа?
 
Не всегда хватает 11*0.8 сек. Попробуйте на пределе дальности от роутера.
Кстати, да. У меня к одному роутеру с 30 попытки подключается. А вообще, технически как много попыток подключиться может быть? Есть какой-то лимит у роутеров? И частота подключения? Типа если к роутеру пробуют подключиться чаще, чем 2-3 раза в секунду?
 
Объясните, как вы нашли, что strcmp это про длину.
Не до конца прочитал это пояснение по первой ссылке в гугле:
Функция возвращает целочисленное значение:

- больше нуля, если первая строка больше второй;

- 0 (нуль), если строки равны;

- меньше нуля, если первая строка меньше второй.
 

CodeNameHawk

Moderator
Команда форума
Так как сидите в цикле, нет нет никакой разницы между millis и delay, проц и так занят только пустой работой.
Кошернее делать так:
В основном цикле выполняете полезную работу.
.нп. Опрос датчиков, вывод на экран и если надо отсылка в интернет.
Но перед отправкой в "интернет", проверяете есть ли подключение к роутеру.
Если нет подключения, запускаете сканирование, потом проверяете наличие нужной сети и запускаете подключение к ней без проверки подключения и только тут есть место millis, для того, что бы через заданное время(нп. через минуту) проверить подключились ли, если нет подключится к другой сети.
Так есп все время занимается полезным делом, допустим может включать выключать вентилятор от температуры датчика, а не в пустую гоняет проц.
Типа если к роутеру пробуют подключиться чаще, чем 2-3 раза в секунду?
Думаю роутеру по барабану.
 
Последнее редактирование:

CodeNameHawk

Moderator
Команда форума
Так как сидите в цикле, нет нет никакой разницы между millis и delay, проц и так занят только пустой работой.
Даже нет так, так как вы не выходите из цикла длительное время, то через некоторое время есп перезагрузится.
Тут delay как раз даст процу время обслужить wifi, но это пример не правильной работы есп.
Все команды, в основном цикле, должны занимать как можно меньше времени, иначе или надо давать процу отдышаться или будет перезагрузка есп.
 

EvgeniyS

Member
И я проверил ))) Работает. Но у меня куча вопросов:
1. Почему выбрали strcmp? Я только узнал об этой функции, и хоть она вроде как про длину строки, но даже смена места у символов оказывается влияет. Честно говоря не видь я вашего примера, не подумал бы её использовать, зная только описание и не видя примера работы. Так почему strcmp, а не обычная идентичность?
2. Не понял, что делает return в функции searchTargetNet?
3. По поводу ваших delay. А зачем они вообще? Опять же, как новичок я могу чего-то не понимать, и начинал именно с делей, но когда позавчера прочитал про милис, то вообще не понял, зачем делей используют.
1. strcmp позволяет однозначно точно сравнивать строки.
2. return завершает функцию прерывая дальнейший поиск сети к т.к. нужная сеть уже найдена.
3. ESP под "капотом" обеспечивает работу сети, delay позволяет отдать процессорное время на эти нужды. Если пользовательский код занимает в ф-ции loop занимает длительное время (больше 50мс.), то это приведет к нестабтьной работе ESP.
 

EvgeniyS

Member
Не всегда хватает 11*0.8 сек. Попробуйте на пределе дальности от роутера.
Роутера нет под рукой :) Сейчас на работе (вахтовый метод) проверял на телефоне, вероятно вы правы, надо увеличить, но даже если с первого раза не подключится то заново будет пытаться подключиться пока сеть роутера будет присутсвовать.
 

EvgeniyS

Member
Кстати, как достать айпишник в переменную вне этой функции?
WiFi.localIP(); возвращает массив типа int, состоящий из 4 элементов.Можно создать глобальную переменную типа IPAddress и поместить массив туда, либо преобразовать в строку и сохранить как строку.
 
WiFi.localIP(); возвращает массив типа int, состоящий из 4 элементов. Можно создать глобальную переменную типа IPAddress и поместить массив туда, либо преобразовать в строку и сохранить как строку.
Что-то подобное попробовал сделать в вашем примере. Пока не получилось. А хотелось бы понять как. У меня это сделано, но и мой вариант отличается от вашего в том числе и получением айпишника в самой функции подключения.
 

EvgeniyS

Member
Что-то подобное попробовал сделать в вашем примере. Пока не получилось. А хотелось бы понять как. У меня это сделано, но и мой вариант отличается от вашего в том числе и получением айпишника в самой функции подключения.
А что мешает объявить глобальную переменную типа IPAddress а потом в любом месте кода в нее записать WiFi.localIP() ?
 
А что мешает объявить глобальную переменную типа IPAddress а потом в любом месте кода в нее записать WiFi.localIP() ?
Пока что путаюсь в типах и до сегодня не знал, что есть такой тип данных. Пока что все попытки объявить такую переменную вызывали ошибку. Кстати, пока нигде нормально об этом прочитать не могу.
А так в моем примере я и сделал аналогичным образом, объявил глобальную переменную типа Стринг. Но интересно получить адрес группами (значениями массивов).
 
Сверху Снизу