Нужна помощь Определение наличия подключения к сети 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/+/+'
ESP8266 уроки. Подключение к сети Wi-Fi.
Возможность подключения устройства к сети Wi-Fi — очень мощная функция, которая открывает возможность использования интернет-протоколов для связи с другими устройствами. Например, после подключения к сети можем выполнять HTTP-запросы к серверу, что позволяет нам публиковать измерения датчиков, собранные ESP8266. И многое другое.
Это делает ESP8266 очень хорошим микроконтроллером для реализации Интернета вещей. Другой важный фактор — это относительно дешевая стоимость устройства реализованных на ESP8266.
В предыдущем уроке рассказал, как можно подключиться к сети Wi-Fi с помощью ESP32.
Прежде чем приступить к уроку, нужно настроить Arduino IDE для работы с ESP8266.
Описание скетча подключение к сети Wi-Fi ESP8266.
Прежде всего, подключаем библиотеку ESP8266WiFi.h, которая сделает доступной глобальную переменную с именем WiFi, она является объектом класса ESP8266WiFiClass. В этом классе есть методы, необходимые для подключения к сети Wi-Fi.
Чтобы сделать код более читабельным, создадим две глобальные переменные для хранения учетных данных, необходимых для регистрации в сети. Первый соответствует SSID (Service Set IDentifier), который является именем беспроводной сети, к которой мы хотим подключиться. Естественно, чтобы иметь возможность подключиться, нам также необходимо указать пароль от сети.
const char* ssid = "NetworkName"; const char* password = "NetworkPass";
Внимание , используйте учетные данные вашей сети.
Теперь мы укажем функцию настройки, в которой подключимся к сети. Но сначала откроем последовательное соединение, чтобы мы могли вывести результат работы программы.
Затем вызываем метод begin для объекта WiFi, передавая в качестве аргументов SSID (имя сети) и переменную пароля, указанные ранее. Это инициализирует подключение к сети.
После этого выполним цикл while, пока соединение не будет установлено. Для этого можем вызвать метод status для объекта WiFi и дождаться, пока результат не совпадет с перечислением WL_CONNECTED. Между каждой итерацией мы вводим небольшую задержку, чтобы избежать постоянного опроса.
while (WiFi.status() != WL_CONNECTED)
После успешного установления соединения можем проверить IP-адрес, назначенный ESP8266, вызвав метод localIP . Это полезно, если мы хотим отправлять данные на ESP8266 из этой сети. Имейте в виду, что это локальный IP-адрес, и поэтому мы не можем связаться с устройством из-за пределов этой сети.
Полная функция настройки setup() показана ниже.
void setup () < Serial.begin(115200); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) < delay(1000); Serial.println("Connecting.."); >Serial.println(WiFi.localIP()); >
Данный скетч не выводит информацию, если ESP8266 не подключилась к сети. Это может произойти, если у нас отключено сетевое оборудование или указаны неверные данные для подключения. Давайте дополним код и ограничим попытки подключения до 10, и вывод сообщения, если подключиться не удалось.
#include const char* ssid = "NetworkName"; const char* password = "NetworkPass"; byte tries = 10; // Попыткок подключения к точке доступа void setup() < Serial.begin(115200); WiFi.begin(ssid, password); while (--tries && WiFi.status() != WL_CONNECTED) < delay(500); Serial.println("."); >if (WiFi.status() != WL_CONNECTED) < Serial.println("Non Connecting to WiFi.."); >else < // Иначе удалось подключиться отправляем сообщение // о подключении и выводим адрес IP Serial.println(""); Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); >> void loop() <>
В мониторе порта должны увидеть следующий результат, если подключиться удалось.
И вот такое уведомление, если ESP8266 не удалось подключиться к Wi-Fi сети.
Этот пример показывает только основы подключения к сети Wi-Fi. В следующем уроке рассмотрим, как выполнять более сложные процедуры, такие как отправка HTTP-запросов.
Понравился ESP8266 уроки. Подключение к сети Wi-Fi ? Не забудь поделиться с друзьями в соц. сетях.
А также подписаться на наш канал на YouTube, вступить в группу Вконтакте, в группу на Facebook.
Спасибо за внимание!
Технологии начинаются с простого!