ESP8266, ESP32 автоматическое подключение к разным WIFI сетям
- Войдите на сайт для отправки комментариев
Сб, 19/12/2020 - 21:13
Вопрос простой, кто и как реализует задачу автоматического подключения к разным WiFi cетям (по логину, паролю) при перемещении девайса. Скан сетей, проверка Точек по имени, определение и выбор точки с наибольшей силой сигнала?
Не могу сказать за esp32, но дома две точки WiFi и на даче три. Решил тему вышеописанную просто. Одинаково назвал все точки доступа. Задал одинаковые имя и пароль. Я не знаю как это работает, но работает отлично и стабильно. Где бы я не находился с планшетом в зоне доступа любой из точек - все подключается и работает. Есть ещё репитеры WiFi, но они (вроде бы) по тому же принципу работают.
Или я не про то подумал?
можно и так, но если нет возможности переименования, то интересует, кто и как эту проблему решал
У меня тоже так, все роутеры с одним и тем же ssid и паролем
это не наш метод, так что буду решать задачу далее, думал, может уже кто озадачился и сделал давно
Видится, набить и далее сравнивать имя и скан_имя:
char * ssid[] = {"NODE1","NODE2","NODE3"}; // your network SSID (name) char * password[] = {"pass1","pass2","pass3"}; // your network keyПрямое сравнение компилируется но не работает, как надо правильно?
strcmp
Прямое сравнение компилируется но не работает, как надо правильно?
if(WiFi.SSID(j) == ssid[i])
так ты сравниваешь не саму строку, а только ссылки на них, которые, очевидно, не равны никогда
Прямое сравнение компилируется но не работает, как надо правильно?
if(WiFi.SSID(j) == ssid[i])
так ты сравниваешь не саму строку, а только ссылки на них, которые, очевидно, не равны никогда
а как по этим ссылкам взять строки и их сравнить?
strcmp
error: cannot convert 'String' to 'const char*' for argument '1' to 'int strcmp(const char*, const char*)'
if(strcmp(s1, s2) == 0 )
Вам же выше написали: http://all-ht.ru/inf/prog/c/func/strcmp.html
Если ещё не догоняете, то как бэ вот так:
if ( ! strcmp((char*)WiFi.SSID(j), (char*)ssid[i] ) { // что то делаем }Капец, вы же (вроде бы) умеете с указателями работать?
Посмотрите внимательнее мой пример.
strcmp
error: cannot convert 'String' to 'const char*' for argument '1' to 'int strcmp(const char*, const char*)'
if(strcmp(s1, s2) == 0 )
ты вроде дядька взрослый и не глупый, но тут тебя хочется послать... в раздел новичков:))
strcmp
error: cannot convert 'String' to 'const char*' for argument '1' to 'int strcmp(const char*, const char*)'
if(strcmp(s1, s2) == 0 )
ты вроде дядька взрослый и не глупый, но тут тебя хочется послать... в раздел новичков:))
второй день конкретно туплю )))
у меня пока не сложится на уровне машинных кодов, что там и как преобразовывается, не укладывается в голове...
Вам же выше написали: http://all-ht.ru/inf/prog/c/func/strcmp.html
Если ещё не догоняете, то как бэ вот так:
if ( ! strcmp((char*)WiFi.SSID(j), (char*)ssid[i] ) { // что то делаем }invalid cast from type 'String' to type 'char*'
if(!strcmp((char*)WiFi.SSID(j), (char*)ssid[i]))
Вам же выше написали: http://all-ht.ru/inf/prog/c/func/strcmp.html
Если ещё не догоняете, то как бэ вот так:
if ( ! strcmp((char*)WiFi.SSID(j), (char*)ssid[i] ) { // что то делаем }invalid cast from type 'String' to type 'char*'
if(!strcmp((char*)WiFi.SSID(j), (char*)ssid[i]))
ептать, ну сравнивать надо два указателя, а не стринг и указатель, последний раз
У меня при компиляции
ошибка:
А вот как я написал - компилируется:
Может разные версии wifi.h для дуни и ESP32?
если запустится IDE (сто лет не запускал) проверю, вечером...
Может разные версии wifi.h для дуни и ESP32?
да!
Вот универсальный код для библиотек
если запустится IDE (сто лет не запускал) проверю, вечером...
Хорошо! а если и код поправите буду премного благодарен...
PS вот как-то сложно верится, что никто не реализовывал автоматизацию подключения к РАЗНЫМ точкам доступа
О! Так ESP еще и подглядывает за нами:
Заливаю код:
#include "Adafruit_Sensor.h" #include "Adafruit_AM2320.h" Adafruit_AM2320 am2320 = Adafruit_AM2320(); void setup() { Serial.begin(115200); while (!Serial) { delay(10); // hang out until serial port opens } Serial.println("Adafruit AM2320 Basic Test"); am2320.begin(); } void loop() { Serial.print("Temp: "); Serial.println(am2320.readTemperature()); Serial.print("Hum: "); Serial.println(am2320.readHumidity()); delay(5000); }Включен DEBUG и что видим:
Посмотрите здесь https://esp8266.ru/forum/threads/esp8266-podkljuchenie-k-neskolkim-setja...
Посмотрите здесь https://esp8266.ru/forum/threads/esp8266-podkljuchenie-k-neskolkim-setja...
Как вариант, рабочее решение, но хочется через сканирование сетей и потом добавить подключаться к точке в списке и с наибольшим RSSI
Код скину сюда:
#define BLYNK_PRINT Serial #include <ESP8266WiFi.h> #include <BlynkSimpleEsp8266.h> char auth[] = "your_token"; char* ssid[] = {"ssid_1","ssid_2","ssid_Mobil"}; //list a necessary wifi networks char* pass[] = {"pass_1","pass_2","pass_Mobil"}; //list a passwords void setup() { Serial.begin(9600); MultyWiFiBlynkBegin(); //instead Blynk.begin(auth, ssid, pass); } void MultyWiFiBlynkBegin() { int ssid_count=0; int ssid_mas_size = sizeof(ssid) / sizeof(ssid[0]); do { Serial.println("Trying to connect to wi-fi " + String(ssid[ssid_count])); WiFi.begin(ssid[ssid_count], pass[ssid_count]); int WiFi_timeout_count=0; while (WiFi.status() != WL_CONNECTED && WiFi_timeout_count<50) { //waiting 10 sec delay(200); Serial.print("."); ++WiFi_timeout_count; } if (WiFi.status() == WL_CONNECTED) { Serial.println("Connected to WiFi! Now I will check the connection to the Blynk server"); Blynk.config(auth); Blynk.connect(5000); //waiting 5 sec } ++ssid_count; } while (!Blynk.connected() && ssid_count<ssid_mas_size); if (!Blynk.connected() && ssid_count==ssid_mas_size) { Serial.println("I could not connect to blynk =( Ignore and move on. but still I will try to connect to wi-fi " + String(ssid[ssid_count-1])); } } void loop() { Blynk.run(); }https://github.com/espressif/arduino-esp32/blob/master/libraries/WiFi/ex...
Все украдено до нас.
https://github.com/espressif/arduino-esp32/blob/master/libraries/WiFi/examples/WiFiMulti/WiFiMulti.ino
Все украдено до нас.
библиотека сия - #include <WiFiMulti.h> под esp8266 подходит?
Чтобы было информативней, чуток поправил:
/* * This sketch trys to Connect to the best AP based on a given list * */ #include <WiFi.h> //#include <ESP8266WiFi.h> #include <WiFiMulti.h> WiFiMulti wifiMulti; void setup() { Serial.begin(115200); delay(10); wifiMulti.addAP("ssid_from_AP_1", "your_password_for_AP_1"); wifiMulti.addAP("ssid_from_AP_2", "your_password_for_AP_2"); wifiMulti.addAP("ssid_from_AP_3", "your_password_for_AP_3"); Serial.println("Connecting Wifi..."); if(wifiMulti.run() == WL_CONNECTED) { Serial.println(""); Serial.println("WiFi connected"); Serial.print("IP address: "); Serial.println(WiFi.localIP()); Serial.print("SSID: "); Serial.println(WiFi.SSID()); Serial.print("RSSI: "); Serial.println(WiFi.RSSI()); } } void loop() { if(wifiMulti.run() != WL_CONNECTED) { Serial.println("WiFi not connected!"); delay(1000); } }Дык почитай.
Дык почитай. Скорее нет, чем да. Но половину твоего вопроса решает.
Дык почитай. Скорее нет, чем да. Но половину твоего вопроса решает.
я из тех парней, что "проверяет, какого пола твой сосед"
Да, выбирает лучшую точку:
Поправить библиотеку под ESP8266 точно выше моих возможностей
в ESP8266 эта библиотека называется -ESP8266WiFiMulti.h )))
посмотрел библиотеку, по мне очень красиво сделано
Поправить библиотеку под ESP8266 точно выше моих возможностей
в ESP8266 эта библиотека называется -ESP8266WiFiMulti.h )))
посмотрел библиотеку, по мне очень красиво сделано
Да, тем более, что это библиотека от производителя чипа :) Ничего не скажу про качество библиотеки, но при обнаружении ошибок правят их они достаточно быстро. Правда сколько эти еспшки живут столько в них ошибки и находят :)
Поправить библиотеку под ESP8266 точно выше моих возможностей
в ESP8266 эта библиотека называется -ESP8266WiFiMulti.h )))
посмотрел библиотеку, по мне очень красиво сделано
Да, тем более, что это библиотека от производителя чипа :) Ничего не скажу про качество библиотеки, но при обнаружении ошибок правят их они достаточно быстро. Правда сколько эти еспшки живут столько в них ошибки и находят :)
это да, задача решена, сделал универсально и для ESP8266 и для ESP32, нашел один глюк, но как они его могут принципиально решить пока не знаю. Глюк следующий, если видятся несколько точек доступа с одним именем и пытается подключиться не на отраженную в скетче (пароль не совпадает) долбит в чужую ноду до посинения...
Благодарю!!!
нашел один глюк, но как они его могут принципиально решить пока не знаю. Глюк следующий, если видятся несколько точек доступа с одним именем и пытается подключиться не на отраженную в скетче (пароль не совпадает) долбит в чужую ноду до посинения...
ну можно добавить логику - если в текущую сеть пароль не подошел, после трех-пяти попыток переходим к следующей в списке. Если сети закончились - делаем перерыв, потом по новой
Пока не представляю, как в рамках этого кода это можно реализовать?
У меня при компиляции
ошибка:
А вот как я написал - компилируется:
Может разные версии wifi.h для дуни и ESP32?
И что, сравнивает строки?
У меня нет
И что, сравнивает строки?
У меня нет
для ЕСП32 правильная запись
И что, сравнивает строки?
У меня нет
для ЕСП32 правильная запись
можешь пояснить почему так?
для ЕСП32 правильная запись
можешь пояснить почему так?
strcmp хочет такие параметры:
strcmp(const char* one, const char* two)
а WiFi.SSID(j) возвращает String. поэтому нужно его конвертировать в char* посредством c_str()
для ЕСП32 правильная запись
можешь пояснить почему так?
strcmp хочет такие параметры:
strcmp(const char* one, const char* two)
а WiFi.SSID(j) возвращает String. поэтому нужно его конвертировать в char* посредством c_str()
ну я протупил, а ведь видел жеж, что надо char*...как всё просто оказывается )))
на ESP8266 получается полная хрень:
код сканирования сетей:
// Set WiFi to station mode and disconnect from an AP if it was Previously connected WiFi.mode(WIFI_STA); WiFi.disconnect(); delay(100); // WiFi.scanNetworks will return the number of networks found int n = WiFi.scanNetworks(); int i = 0; int j = 0; Serial.println("scan done"); if (n == 0) { Serial.println("no networks found"); } else { for( j = 1; j <= n; j++ ) { for ( i = 0; i < n; i++ ) { Serial.print(WiFi.SSID(i)); Serial.print(" = "); Serial.println(ssid[i]); if(strcmp((char*)(WiFi.SSID(j).c_str()), (char*)ssid[i]) != 0 ) { WiFi.begin(ssid[i], password); Serial.print(WiFi.SSID(j)); Serial.print(" = + = "); Serial.println(ssid[i]); } } } }Вывод в монитор порта:
блин, ну что за бардак в коде...
- почему в строке 16 условие <= n, а в 18 - < n
- почему вообще оба цикла до n, если мы сравниваем два разных списка разного размера - список запомненных и список сканированных сетей?
- почему в строке 21 ты печатаешь WiFi.SSID(i), а в строке 25 сравниваешь уже WiFi.SSID(j) ?
- функция strcmp() выдает ноль, если строки РАВНЫ. а у тебя условие наоборот...
Нельзя так...
Нельзя так...
не понял ты полёт мысли свободного художника
сканирование даст количество сетей > 1
SSID храню в массиве чаров с нуля (цикл перебора из массива получается смещён вниз на 1)
По J - да, правил я сей косяк, видимо взял не правленный скетч, вылез опять
!= сделано намерено, вывести в порт, что и с чем сравнивается...
PS можно было конечно и забить...но я зануда...хочу понять...
но я зануда...хочу понять...
ну тогда разбирайся
ну тогда разбирайся
И что, сравнивает строки?
У меня нет
для ЕСП32 правильная запись
Спорить не буду, так как нет таких контроллеров и ничего в IDE не настроено под них.
Спорить не буду, так как нет таких контроллеров и ничего в IDE не настроено под них.
я в исходник библиотеки смотрю
И что, сравнивает строки?
У меня нет
для ЕСП32 правильная запись
Спорить не буду, так как нет таких контроллеров и ничего в IDE не настроено под них.
завтра проверю на esp32, их есть у меня, тока скетч перепишу на универсальный
Код проверен, скетчик сделан универсальным и для ESP32 и для ESP8266...строка разбора - РАБОТАЕТ!!!
Так как сам код практического смысла не имеет, не выкладываю...
Добрый день!
Видно, что тема подзаглохла. Наверное для программистов это не проблема, но для меня это все очень сложно.
Может кто поможет с готовым кодом для есп8266 (V3 Nodemcu). Если кратко хотелось иметь несколько подключений, если у меня роутер зависает, то переключалось на другую сеть, а если с ней связь теряется, то еще на одну)
С программированием я не знаком (закончил школу еще в СССР, т.ч. сами понимаете.....) Есть скетч кое как работающий на одно соединение, но оно теряется из-за дальности.
Может кто поделится готовой наработкой или поможет с моей?
Может кто поможет с готовым кодом для есп8266 (V3 Nodemcu).
Это Вы ошиблись разделом. Для готового кода существует раздел "Ищу исполнителя".
С программированием я не знаком (закончил школу еще в СССР, т.ч. сами понимаете.....)
Я тоже закончил школу еще в СССР. И институт - в СССР. И кандидатскую - тоже в СССР. Так что, честно говоря, не очень понимаю.
Имеется в виду готовый "кусок" кода, про который писал UA6EM.
Про раздел с исполнителями все понятно.
Программы не склеивают из кусков, тем более такие сложные.
Имеется в виду готовый "кусок" кода, про который писал UA6EM.
Про раздел с исполнителями все понятно.
все сети известны, так что реализовано простым перебором, нужны подробности?
Имеется в виду готовый "кусок" кода, про который писал UA6EM.
Про раздел с исполнителями все понятно.
все сети известны, так что реализовано простым перебором, нужны подробности?
Добрый вечер.
Использовал из поста #30 , пытался внедрить в свой скетч, у меня только одно соединение. Телефон с раздачей находится на чердаке (иначе не ловит), сигнал доходит до WiFI репитера на 2 эт., с репитера уже на первый. Но увы моих знаний не хватает. Отдельно ваш скетч с подключением работает, при потере сигнала с одной сети переходит на другую. Что в общем и нужно.
Правильней здесь опубликовать мой скетч? Может кто чего подскажет.
73!
видимо да
#include <ESP8266WiFi.h> #include <WiFiClientSecure.h> #include <UniversalTelegramBot.h> #include "DHT.h" #define DHTPIN D4 //D1 ojriginal pin my chang pin D4 #define DHTTYPE DHT11 // DHT 11 DHT dht(DHTPIN, DHTTYPE); // Замените на свои сетевые данные #define WIFI_SSID "cqcq" #define WIFI_PASSWORD "qth1234" // Инициализация Telegram бота #define BOT_TOKEN "123:XXXXXX" // Ваш Токен #define CHAT_ID "123123" // ID чата const unsigned long BOT_MTBS = 1000; // среднее время между сообщениями сканирования X509List cert(TELEGRAM_CERTIFICATE_ROOT); WiFiClientSecure secured_client; UniversalTelegramBot bot(BOT_TOKEN, secured_client); unsigned long bot_lasttime; // последнее сканирование сообщений было сделано const int Relay1 = D5; //Реле1 подключено к D5 const int Relay2 = D6; //Реле2 подключено к D6 int Relay1Status = 0; //Переменная для хранения статуса Реле1 int Relay2Status = 0; //Переменная для хранения статуса Реле2 int t = dht.readTemperature()-2; // int h = dht.readHumidity(); // void handleNewMessages(int numNewMessages) { // Serial.println("handleNewMessages"); // Serial.print("обработка Новых Сообщений "); Serial.println(numNewMessages); for (int i = 0; i < numNewMessages; i++) { String chat_id = bot.messages[i].chat_id; String text = bot.messages[i].text; String from_name = bot.messages[i].from_name; if (from_name == "") from_name = "Guest"; if (text == "/on") { digitalWrite(Relay1, LOW); // включить Свет (НИЗКИЙ уровень реле) Relay1Status = 1; // меняем статус на 1 bot.sendMessage(chat_id, "Свет включен", ""); } if (text == "/off") { digitalWrite(Relay1, HIGH); // выключить Свет (ВЫСОКИЙ уровень реле) Relay1Status = 0; // меняем статус на 0 bot.sendMessage(chat_id, "Свет выключен", ""); } if (text == "/on2") { digitalWrite(Relay2, LOW); // включить Реле (НИЗКИЙ уровень реле) Relay2Status = 1; // меняем статус на 1 bot.sendMessage(chat_id, "Реле включено", ""); } if (text == "/off2") { digitalWrite(Relay2, HIGH); // выключить Реле (ВЫСОКИЙ уровень реле) Relay2Status = 0; // меняем статус на 0 bot.sendMessage(chat_id, "Реле выключено", ""); } if (text == "/offall") { digitalWrite(Relay1, HIGH); // выключить Свет (ВЫСОКИЙ уровень реле) digitalWrite(Relay2, HIGH); // выключить Реле (ВЫСОКИЙ уровень реле) Relay1Status = 0; // меняем статус на 0 Relay2Status = 0; // меняем статус на 0 bot.sendMessage(chat_id, "Всё выключено", ""); } if (text == "/status") { if (Relay1Status)bot.sendMessage(chat_id, "Свет включен", ""); else bot.sendMessage(chat_id, "Свет выключен", ""); if (Relay2Status)bot.sendMessage(chat_id, "Реле включено", ""); else bot.sendMessage(chat_id, "Реле выключено", ""); } if (text == "/temperatura") { int t = dht.readTemperature()-2; String temp = "Температура: "; temp += int(t); temp +=" *C\n"; bot.sendMessage(chat_id,temp, ""); } if (text == "/humidity") { int h = dht.readHumidity(); String temp = "Влажность: "; temp += int(h); temp += " %"; bot.sendMessage(chat_id,temp, ""); } if (text == "/start") { String welcome = "Добро пожаловать, " + from_name + ".\n\n"; welcome += "Включить-выключить реле.\n"; welcome += "------------------------------\n"; welcome += "/on : включить свет\n"; welcome += "------------------------------\n"; welcome += "/off : выключить свет\n"; welcome += "------------------------------\n"; welcome += "/on2 : включить реле\n"; welcome += "------------------------------\n"; welcome += "/off2 : выключить реле\n"; welcome += "------------------------------\n"; welcome += "/offall : выключить всё\n"; welcome += "------------------------------\n"; welcome += "/status : показывает включено или выключено\n"; welcome += "------------------------------\n"; welcome += "/temperatura : Температура\n"; // mi welcome += "------------------------------\n"; welcome += "/humidity : Влажность\n"; //mi welcome += "------------------------------\n"; bot.sendMessage(chat_id, welcome, ""); } } } void setup() { Serial.begin(115200); Serial.println(); dht.begin(); // mi pinMode(Relay1, OUTPUT); // Инициализируем как Выход pinMode(Relay2, OUTPUT); // Инициализируем как Выход digitalWrite(Relay1, HIGH); // Выключаем свет digitalWrite(Relay2, HIGH); // Выключаем реле // attempt to connect to Wifi network: configTime(0, 0, "pool.ntp.org"); // Сервер точного времени UTC NTP secured_client.setTrustAnchors(&cert); // Добавляем сертификат api.telegram.org Serial.print("Соединяемся с Wifi "); Serial.print(WIFI_SSID); WiFi.begin(WIFI_SSID, WIFI_PASSWORD); while (WiFi.status() != WL_CONNECTED) { Serial.print("."); delay(500); } Serial.print("\nСоединились. IP адрес: "); Serial.println(WiFi.localIP()); Serial.print("Получение времени: "); time_t now = time(nullptr); while (now < 24 * 3600) { Serial.print("."); delay(100); now = time(nullptr); } Serial.println(now); } void loop() { if (millis() - bot_lasttime > BOT_MTBS) { int numNewMessages = bot.getUpdates(bot.last_message_received + 1); while (numNewMessages) { Serial.println("Ответ получен"); handleNewMessages(numNewMessages); numNewMessages = bot.getUpdates(bot.last_message_received + 1); } bot_lasttime = millis(); } }