Esp8266 контроль соединения wifi

Arduino.ru

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

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

#include // Библиотека для создания Wi-Fi подключения (клиент или точка доступа) #include char* array_ssid[] = ; // Массив необходимых ссидов char* array_pass[] = ; // Массив необходимых паролей к этим ссидам int count_ssid = sizeof(array_ssid) / sizeof(array_ssid[0]); // Размер массива ссидов // Функция скарирования и подключения к найденной известной сети из нашего списка, другие будут игнорится void conekt_to_wifi(int networksFound) < // for (int i = 0; i < networksFound; i++) < for (int j = 0; j < count_ssid; j++) < if (WiFi.SSID(i)==array_ssid[j]) < Serial.println("One of ouer ssid was found = " +WiFi.SSID(i)); WiFi.begin(array_ssid[j], array_pass[j]); // Инициализируем подключение к указанной вайфай сети WiFi.setHostname("Host_MDNS"); // Устанавливаем новое имя нашего клиента Serial.println(WiFi.hostname()); // Распечатываем имя клиента while (WiFi.status() != WL_CONNECTED) < // Зупускаем ожидание поднятия вайфай сервера Serial.println("waiting. "); delay(1000); Serial.println(WiFi.localIP()); // Выводим в монитор порта айпишник нашей платы >> > > > void setup() < Serial.begin(9600); while (!Serial) < // ждём, пока не откроется монитор последовательного порта // для того, чтобы отследить все события в программе >WiFi.mode(WIFI_OFF); // Останавливаем вайфай delay(1000); WiFi.mode(WIFI_STA); // Запускаем вайфай Serial.println("Ouer mac else" тут не приводил, смысла нет, потому что зацикливается на подключении и выдает что-то типа этого:

(IP unset) waiting. --------------- CUT HERE FOR EXCEPTION DECODER --------------- Soft WDT reset >>>stack>>> ctx: sys sp: 3fffec40 end: 3fffffb0 offset: 01a0 3fffede0: 00000000 00000002 3ffe8889 4020299a 3fffedf0: 00000000 00000002 3ffe8889 40204557 3fffee00: 3ffe888a 00000001 00000020 3ffee638 3fffee10: 3fffee70 3ffe85d8 3ffee638 3ffee638 3fffee20: 40201cac 3ffe8888 3ffee638 40201cb8 3fffee30: 40201cac 3ffe8888 3ffee638 40201fec

Источник

Нужна помощь Определение наличия подключения к сети WiFi

Нужно чтобы ESP при включении работала не зависмо от наличия сети WiFi, т.е. снимала показания датчиков, щелкала реле и т.д. Как только появляется сеть - подключалась к серверу mqtt и передавала на него показания. В случае пропадания сети продолжала нормальную работу.
Начал с простенького кода

#include #include #include char *ssid = "********"; // Имя роутера char *pass = "********"; // Пароль роутера OLED myOLED(D2, D1); extern uint8_t SmallFont[]; extern uint8_t MediumNumbers[]; extern uint8_t BigNumbers[]; void setup() < Serial.begin(115200); WiFi.begin(ssid, pass); if(!myOLED.begin(SSD1306_128X32)) while(1); // In case the library failed to allocate enough RAM for the display buffer. myOLED.setFont(SmallFont); >void loop() < if(WiFi.status() == WL_CONNECTED) < digitalWrite(LED_BUILTIN, LOW); Serial.println("WiFi");>> if(WiFi.status() != WL_CONNECTED) < digitalWrite(LED_BUILTIN, HIGH); Serial.println("NO WiFi"); >>

Включаю ESP - светодиод загорается, в сериал сыпятся сообщения о наличии WiFi. Выключаю на роутере WiFi - светодиод гаснет, в порт сыпятся сообщения об отсутствии сети. Опять включаю на роутере сеть и . вот здесь начинаются непонятки. ESP может подключится к сети (светодиод загорается), а может и не подключиться. Аналогичная ситуация происходит если включить ESP при отсутствии сети WiFi. Какой либо закономерности не заметил.
Подскажите что я делаю не так?

CodeNameHawk

Moderator

Так наверное вы все практически и сделали. События отключения и подключения отстают от фактического состояния сети.
Установите свойства autoconnect и autoreconect, есп будет сама пере подключаться к сети.

enjoynering

Well-known member

WiFi.status() == WL_CONNECTED показывает только наличие соединения с точкой доступа/роутером, а у него то как раз связи с инетом может не быть . Вам нужен ping

перед отправкой пингуете google.com или православный yandex.ru и если ответ пришел значит интернет есть. Неплохая библиотека обертка ping для arduino esp8266 framework-а ТУТ

nikolz

Well-known member

если сеть формируется роутером, то в общем случае надо определять три события
1) работает ли роутер
2) тот ли адрес дал вам роутер (нужный адрес, если он задан фиксировано в ESP, может быть занят)
3) работает в сети устройство с котором обмениваемся данными
подумайте над этим

CodeNameHawk

Moderator

1) работает ли роутер
2) тот ли адрес дал вам роутер (нужный адрес, если он задан фиксировано в ESP, может быть занят)
3) работает в сети устройство с котором обмениваемся данными
подумайте над этим

Первые два пункты и проверяются WiFi.status().
Насчет третьего, важно проверять, принял ли сервер посланные данные, а не доступен ли он.
Проверка доступен ли сервер ничего не дает, проверка может пройти, а следующее обращение к нему может не пройти.

kotyara12

New member

Не знаю, пригодится ли. Но я делаю это примерно так (см. ниже).
wifiLoop() вставляю в основной цикл, вся "работа внутри" соединения выполняется в callback функции _cbWiFiConnWork().
В этом случае ESP в случае обрыва соединения самостоятельно его восстановит, а при отсутствии - может спокойно функционировать и без интернета, автоматика спокойно работает в автономном режиме.

typedef enum < wifiNotConnected, wifiConnectWait, wifiConnectInit, wifiConnectWork >wifiConnStage_t; bool wifiConnect() < _ledWiFi->ledBlinkOn(_wifiBlinkConn); _wifiTryConnect++; Serial.print(F("WiFi :: Connect to network '")); Serial.print(_wifiSSID); Serial.print(F("', try ")); Serial.print(_wifiTryConnect); Serial.print(F(" ")); #if defined(ESP32) // -- ESP32 :: begin -------------------------------------------------- _wifiConnectedEvent = WiFi.onEvent(onWiFiConnected, WiFiEvent_t::SYSTEM_EVENT_STA_CONNECTED); _wifiGotIPEvent = WiFi.onEvent(onWiFiGotIP, WiFiEvent_t::SYSTEM_EVENT_STA_GOT_IP); if (_wifiDisconnectedEvent != 0) WiFi.removeEvent(_wifiDisconnectedEvent); _wifiDisconnectedEvent = 0; // -- ESP32 :: end ---------------------------------------------------- #else // -- ESP8266 :: begin ------------------------------------------------ _wifiConnectedHandler = WiFi.onStationModeConnected(onWiFiConnected); _wifiGotIPHandler = WiFi.onStationModeGotIP(onWiFiGotIP); _wifiDisconnectedHandler = nullptr; // -- ESP8266 :: end -------------------------------------------------- #endif WiFi.mode(WIFI_STA); WiFi.setAutoReconnect(false); #if defined(ESP32) // -- ESP32 :: begin -------------------------------------------------- WiFi.begin(_wifiSSID.c_str(), _wifiPass.c_str(), 0, NULL, false); // -- ESP32 :: end ---------------------------------------------------- #else // -- ESP8266 :: begin ------------------------------------------------ WiFi.begin(_wifiSSID, _wifiPass, 0, NULL, false); // -- ESP8266 :: end -------------------------------------------------- #endif _wifiStage = wifiConnectWait; wifiConnTimerStart(); WiFi.reconnect(); > bool wifiConnectionFailed(wl_status_t wifiStatus, const byte printStatus) < Serial.println(); Serial.println(F("WiFi :: Connection failed!")); if (printStatus >0) < wifiPrintStatus(wifiStatus, printStatus >1); >; wifiConnTimerStop(); WiFi.disconnect(true); #if defined(ESP32) // -- ESP32 :: begin -------------------------------------------------- if (_cbWiFiConnLost != nullptr) < _cbWiFiConnLost(WIFI_REASON_UNSPECIFIED); >; // -- ESP32 :: end ---------------------------------------------------- #else // -- ESP8266 :: begin ------------------------------------------------ if (_cbWiFiConnLost != nullptr) < _cbWiFiConnLost(WIFI_DISCONNECT_REASON_UNSPECIFIED); >; // -- ESP8266 :: end -------------------------------------------------- #endif if (_wifiTryConnect >= _wifiTryConnectMax) < Serial.println(); Serial.println(F("*****************************************************************************************")); Serial.println(F("$$$ SYSTEM RESTART $$$")); Serial.println(F("*****************************************************************************************")); wifiConnTimerStop(); fixResetReason(RR_WIFI_CONN_ATTEMPTS_EXCEEDED); ESP.restart(); >; > bool wifiLoop() < bool _result = false; // Проверяем статус подключения к WiFi wl_status_t _wifiStatus = WiFi.status(); // Подключение к WiFi еще не было установлено if ((_wifiStatus == WL_IDLE_STATUS) || (_wifiStatus == WL_DISCONNECTED)) < switch (_wifiStage) < // Нет подключения, запускаем процедуру соединяемся. case wifiNotConnected: wifiConnect(); break; // В процессе подключения. case wifiConnectWait: yield(); // -- ESP8266 ONLY ------------------------------------------------------ #if defined(ESP8266) // -- ESP8266 :: begin ------------------------------------------------ if (_connTimer.onRestart()) < wifiConnTimerDo(); >; // -- ESP8266 :: end -------------------------------------------------- #endif // -- ESP8266 ONLY ------------------------------------------------------ break; // Что-то пошло не так, пожалуй лучше всего будет сбросить соединение default: wifiConnectionFailed(_wifiStatus, 2); break; >; > // Подключение к WiFi установлено else if (_wifiStatus == WL_CONNECTED) < switch (_wifiStage) < // Соединение установлено только что case wifiConnectWait: _result = true; // Меняем частоту мигания светодиода _ledWiFi->ledBlinkOn(_wifiBlinkInit); // Останавливаем таймер подключения и сбрасываем счетчики wifiConnTimerStop(); _wifiTimeSyncRun = 0; _wifiStage = wifiConnectInit; break; // Соединение установлено в предыдущем рабочем цикле case wifiConnectInit: // Синхронизация времени с NTP, но только если она еще не была ни разу запущена if (year() < 2000) < // Считаем количество попыток синхронизации времени (так как она почему-то иногда не проходит совсем) _wifiTimeSyncRun++; if (_wifiTimeSyncRun >_wifiTimeSyncRunMax) < // Не удалось синхронизировать время - собрасываем соединение wifiConnectionFailed(_wifiStatus, 0); >else < // Запускаем синхронизацию времени c NTP _result = true; ntpTimeSyncRun(); >; > else < // Ставим отметку, что инициализация завершена _wifiStage = wifiConnectWork; // Сбрасываем счетчик попыток соединения _wifiTryConnect = 0; // Выполняем процедуру при установлении соединения if (_cbWiFiConnInit != nullptr) < _result = true; _cbWiFiConnInit(_wifiFisrtConnect); >; // Сбрасываем флаг _wifiFisrtConnect if (_wifiFisrtConnect) < _wifiFisrtConnect = false; >; // Отключаем мигание светодиода _ledWiFi->ledBlinkOff(); >; break; // Соединение установлено и инициализировано case wifiConnectWork: // Выполняем процедуру при постоянном соединении if (_cbWiFiConnWork != nullptr) < _result = true; _cbWiFiConnWork(); >; break; // Другое состояние default: wifiConnectionFailed(_wifiStatus, 2); break; >; > // Ошибки : WL_NO_SSID_AVAIL, WL_CONNECTION_LOST, WL_CONNECT_FAILED, WL_SCAN_COMPLETED else < wifiConnectionFailed(_wifiStatus, 1); >; return _result; >;

Я не утверждаю, что код идеален. Нет, он далек от совершенства, но я над ним постоянно работаю

Выглядит это примерно так:

16:30:41.382 -> Initialization. 16:30:41.382 -> Sketch version: 20190628.01 16:30:41.382 -> Inititailize PINs. 16:30:41.382 -> Inititailize WiFi connection. 16:30:41.460 -> Inititailize MQTT connection. 16:30:41.460 -> Inititailize NTP. 16:30:41.460 -> Inititailize sensors. 16:30:41.460 -> Read settings from EEPROM. 16:30:41.460 -> syncRequests = 1 16:30:41.460 -> intvPublishSensors = 300 16:30:41.492 -> publThingSpeak = 1 16:30:41.492 -> Start timers. 16:30:41.492 -> Initialization complete 16:30:41.492 -> 16:30:41.492 -> WiFi :: Connect to network 'Kotyara12', try 1 . 16:30:42.748 -> WiFi :: Connected to ssid 'Kotyara12', channel 12, rssi: -61 16:30:43.054 -> WiFi :: Local IP address: 192.168.1.41 16:30:43.088 -> NTP :: Transmit NTP request to 'ntp1.stratum2.ru' / '88.147.254.230': ok 16:30:43.292 -> NTP :: Current time: 29.06.2019 16:30:48 16:30:43.292 -> TELEGRAM :: Message " Устройство запущено, версия скетча 20190628.01" :: added to queue, total 1 messages 16:30:43.292 -> TELEGRAM :: Send message " Устройство запущено, версия скетча 20190628.01": HTTP/1.1 200 OK 16:30:46.348 -> MQTT :: Connecting to MQTT server '********:***************@m**.cloudmqtt.com:******'. 16:30:46.958 -> MQTT :: Connection completed 16:30:47.264 -> MQTT :: publish '/village/smarthome/sync_status': "1" [0,1] :: ok 16:30:47.366 -> MQTT :: subscribe on topic '/village/smarthome/sync_status' 16:30:47.774 -> MQTT :: subscribe on topic '/village/smarthome/ota' 16:30:48.080 -> MQTT :: subscribe on topic '/village/smarthome/settings/+' 16:30:48.386 -> MQTT :: subscribe on topic '/village/smarthome/settings/+/+'

Источник

Читайте также:  Посмотреть сохраненные пароли wifi айфон
Оцените статью
Adblock
detector