[РЕШЕНО] Переподключение ESP8266 NodeMCU к сети Wi-Fi после потери соединения

Это краткое руководство показывает различные способы переподключения платы ESP8266 NodeMCU к сети Wi-Fi после потери соединения. Это может быть полезно, если ESP8266 временно теряет сигнал Wi-Fi; ESP8266 временно находится вне зоны действия Wi-Fi роутера; роутер перезагружается; роутер теряет интернет-соединение или в других ситуациях.

[Решено] ESP8266 NodeMCU — переподключение к Wi-Fi после потери соединения

У нас есть аналогичное руководство для платы ESP32:

Переподключение к сети Wi-Fi после потери соединения

ESP8266 имеет возможность автоматически переподключаться к вашему роутеру в случае сбоя Wi-Fi. Например, если ESP8266 подключён к вашему роутеру, и вы внезапно его выключите, когда роутер снова включится, ESP8266 может автоматически переподключиться. Однако многие наши читатели сообщают о ситуациях, в которых ESP8266 не переподключается. В таких случаях вы можете попробовать одно из следующих предложений (продолжайте читать).

Чтобы переподключиться к Wi-Fi после потери соединения, вы можете использовать WiFi.setAutoReconnect(true);, за которым следует WiFi.persistent(true);, для автоматического переподключения к ранее подключённой точке доступа:

WiFi.setAutoReconnect(true);
WiFi.persistent(true);

Добавьте эти строки сразу после подключения к вашей сети Wi-Fi. Например:

void initWiFi() {
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  Serial.print("Connecting to WiFi ..");
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print('.');
    delay(1000);
  }
  Serial.println(WiFi.localIP());
  WiFi.setAutoReconnect(true);
  WiFi.persistent(true);
}

Вот полный пример использования этого метода. Каждые 30 секунд он выводит статус подключения Wi-Fi. Вы можете временно выключить роутер и увидеть, как меняется статус Wi-Fi. Когда роутер снова включится, подключение должно восстановиться автоматически.

/*
  Rui Santos
  Complete project details at https://RandomNerdTutorials.com/solved-reconnect-esp8266-nodemcu-to-wifi/

  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files.

  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.
*/

#include <ESP8266WiFi.h>

// Replace with your network credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

unsigned long previousMillis = 0;
unsigned long interval = 30000;

void initWiFi() {
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  Serial.print("Connecting to WiFi ..");
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print('.');
    delay(1000);
  }
  Serial.println(WiFi.localIP());
  //The ESP8266 tries to reconnect automatically when the connection is lost
  WiFi.setAutoReconnect(true);
  WiFi.persistent(true);
}

void setup() {
  Serial.begin(115200);
  initWiFi();
  Serial.print("RSSI: ");
  Serial.println(WiFi.RSSI());
}

void loop() {
  //print the Wi-Fi status every 30 seconds
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >=interval){
    switch (WiFi.status()){
      case WL_NO_SSID_AVAIL:
        Serial.println("Configured SSID cannot be reached");
        break;
      case WL_CONNECTED:
        Serial.println("Connection successfully established");
        break;
      case WL_CONNECT_FAILED:
        Serial.println("Connection failed");
        break;
    }
    Serial.printf("Connection status: %d\n", WiFi.status());
    Serial.print("RRSI: ");
    Serial.println(WiFi.RSSI());
    previousMillis = currentMillis;
  }
}

Просмотреть исходный код

Другой альтернативой является вызов WiFi.disconnect(), за которым следует WiFi.begin(ssid, password), когда вы замечаете, что соединение было потеряно (WiFi.status() != WL_CONNECTED):

WiFi.disconnect();
WiFi.begin(ssid, password);

В качестве альтернативы вы также можете попробовать перезагрузить ESP8266 с помощью ESP.restart(), когда соединение потеряно.

Вы можете добавить что-то вроде приведённого ниже фрагмента в loop(), который время от времени проверяет, подключена ли плата, и пытается переподключиться, если соединение было потеряно.

unsigned long currentMillis = millis();
// if WiFi is down, try reconnecting
if ((WiFi.status() != WL_CONNECTED) && (currentMillis - previousMillis >=interval)) {
  Serial.print(millis());
  Serial.println("Reconnecting to WiFi...");
  WiFi.disconnect();
  WiFi.begin(YOUR_SSID, YOUR_PASSWORD);
  previousMillis = currentMillis;
}

Не забудьте объявить переменные previousMillis и interval. Переменная interval соответствует периоду времени между каждой проверкой в миллисекундах (например, 30 секунд):

unsigned long previousMillis = 0;
unsigned long interval = 30000;

Вот полный пример.

/*
  Rui Santos
  Complete project details at https://RandomNerdTutorials.com/solved-reconnect-esp8266-nodemcu-to-wifi/

  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files.

  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.
*/

#include <ESP8266WiFi.h>

// Replace with your network credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

unsigned long previousMillis = 0;
unsigned long interval = 30000;

void initWiFi() {
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  Serial.print("Connecting to WiFi ..");
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print('.');
    delay(1000);
  }
  Serial.println(WiFi.localIP());
}

void setup() {
  Serial.begin(115200);
  initWiFi();
  Serial.print("RRSI: ");
  Serial.println(WiFi.RSSI());
}

void loop() {
  unsigned long currentMillis = millis();
  // if WiFi is down, try reconnecting every CHECK_WIFI_TIME seconds
  if ((WiFi.status() != WL_CONNECTED) && (currentMillis - previousMillis >=interval)) {
    Serial.print(millis());
    Serial.println("Reconnecting to WiFi...");
    WiFi.disconnect();
    WiFi.begin(ssid, password);
    Serial.println(WiFi.localIP());
    //Alternatively, you can restart your board
    //ESP.restart();
    Serial.println(WiFi.RSSI());
    previousMillis = currentMillis;
  }
}

Просмотреть исходный код

Этот пример показывает, как подключиться к сети и каждые 30 секунд проверять, подключена ли плата. Если нет — она отключается и пытается подключиться снова.

Также существует функция WiFi.reconnect(). Однако после нескольких попыток нам не удалось заставить её работать. Если кто-то знает, есть ли какой-то трюк, чтобы она работала, пожалуйста, поделитесь.

Вы также можете использовать Wi-Fi Events для обнаружения потери соединения и вызова функции, которая определяет, что делать, когда это произойдёт (см. следующий раздел).

Wi-Fi события ESP8266 NodeMCU

ESP8266 способен обрабатывать различные события Wi-Fi. С помощью Wi-Fi событий вам не нужно постоянно проверять состояние Wi-Fi. Когда происходит определённое событие, автоматически вызывается соответствующая функция-обработчик.

Следующие события очень полезны для определения того, было ли соединение потеряно или восстановлено:

  • onStationModeGotIP: когда ESP8266 достигает финального шага подключения — получения сетевого IP-адреса;

  • onStationModeDisconnected: когда ESP8266 больше не подключён к точке доступа.

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

Переподключение к сети Wi-Fi после потери соединения (Wi-Fi Events)

Wi-Fi события могут быть полезны для обнаружения того, что соединение было потеряно, и попытки переподключиться сразу после этого (используйте событие onStationModeDisconnected). Вот пример кода:

/*
  Rui Santos
  Complete project details at https://RandomNerdTutorials.com/solved-reconnect-esp8266-nodemcu-to-wifi/

  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files.

  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.
*/

#include <ESP8266WiFi.h>

// Replace with your network credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

WiFiEventHandler wifiConnectHandler;
WiFiEventHandler wifiDisconnectHandler;

void initWiFi() {
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  Serial.print("Connecting to WiFi ..");
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print('.');
    delay(1000);
  }
  Serial.println(WiFi.localIP());
}

void onWifiConnect(const WiFiEventStationModeGotIP& event) {
  Serial.println("Connected to Wi-Fi sucessfully.");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
}

void onWifiDisconnect(const WiFiEventStationModeDisconnected& event) {
  Serial.println("Disconnected from Wi-Fi, trying to connect...");
  WiFi.disconnect();
  WiFi.begin(ssid, password);
}

void setup() {
  Serial.begin(115200);

  //Register event handlers
  wifiConnectHandler = WiFi.onStationModeGotIP(onWifiConnect);
  wifiDisconnectHandler = WiFi.onStationModeDisconnected(onWifiDisconnect);

  initWiFi();
  Serial.print("RRSI: ");
  Serial.println(WiFi.RSSI());
}

void loop() {
  //delay(1000);
}

Просмотреть исходный код

Как это работает?

В этом примере мы добавили два Wi-Fi события: когда ESP8266 подключается и получает IP-адрес, и когда он отключается.

Когда станция ESP8266 подключается к точке доступа и получает свой IP-адрес (событие onStationModeGotIP), вызывается функция onWifiConnect():

wifiConnectHandler = WiFi.onStationModeGotIP(onWifiConnect);

Функция onWifiConnect() просто выводит сообщение о том, что ESP8266 успешно подключился к Wi-Fi, и печатает его локальный IP-адрес. Однако вы можете изменить эту функцию для выполнения любой другой задачи (например, включить светодиод для индикации успешного подключения к сети).

void onWifiConnect(const WiFiEventStationModeGotIP& event) {
  Serial.println("Connected to Wi-Fi sucessfully.");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
}

Когда ESP8266 теряет соединение с точкой доступа (событие onStationModeDisconnected), вызывается функция onWifiDisconnect().

wifiDisconnectHandler = WiFi.onStationModeDisconnected(onWifiDisconnect);

Эта функция выводит сообщение о том, что соединение было потеряно, и пытается переподключиться:

void onWifiDisconnect(const WiFiEventStationModeDisconnected& event) {
  Serial.println("Disconnected from Wi-Fi, trying to connect...");
  WiFi.disconnect();
  WiFi.begin(ssid, password);
}

Заключение

Это краткое руководство показывает различные способы переподключения платы ESP8266 NodeMCU к сети Wi-Fi после потери соединения (если это не происходит автоматически).

Для получения дополнительной информации о функциях Wi-Fi ESP8266 мы рекомендуем ознакомиться с документацией:

Одним из лучших применений возможностей Wi-Fi ESP8266 является создание веб-серверов. Если вы хотите использовать платы ESP8266 NodeMCU или ESP32 для создания проектов веб-серверов, вам могут понравиться наши электронные книги:

Надеемся, что это руководство было для вас полезным.

Спасибо за чтение.