目录
- ❤️ 博客主页 单片机菜鸟哥,一个野生非专业硬件IOT爱好者 ❤️
- ❤️ 本篇创建记录 2022-10-14 ❤️
- ❤️ 本篇更新记录 2022-10-14 ❤️
- ???? 欢迎关注 ????点赞 ????收藏 ⭐️留言 ????
- ???? 此博客均由博主单独编写,不存在任何商业团队运营,如发现错误,请留言轰炸哦!及时修正!感谢支持!
- ???? Arduino ESP8266教程累计帮助过超过1W+同学入门学习硬件网络编程,入选过选修课程,刊登过无线电杂志????
1.前言
在网上看到一些比较好的案例代码,可惜是纯英文文献,这里博哥主要是翻译为中文以及加上自己的一些思考。
参考文献:
主要就是介绍检测网络断开(路由器断电
)或者网络无法连接外网(运营商网络问题
),如何科学重连的几种方式。
2.重连网络方式
2.1 方式1 —— 利用station提供的重连api
使用station里面的 setAutoReconnect 和 persistent 两个api。
// 设置当断开连接的时候自动重连
WiFi.setAutoReconnect(true);
// 该方法设置将WiFi参数保存于Flash
WiFi.persistent(true);
比如给个初始化案例代码:
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);
}
连接上网络之后设置一下重连的标签。
完整demo:
#include <ESP8266WiFi.h>
// 替换信息
const char* ssid = "REPLACE_WITH_YOUR_SSID"; // wifi账号
const char* password = "REPLACE_WITH_YOUR_PASSWORD"; // wifi密码
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());
// 设置当网络断开连接的时候自动重连
WiFi.setAutoReconnect(true);
WiFi.persistent(true);
}
void setup() {
Serial.begin(115200);
initWiFi();
Serial.print("RSSI: ");
Serial.println(WiFi.RSSI());
}
void loop() {
//每间隔30s打印一下网络状态
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;
}
}
2.2 方式2 —— 利用 disconnect 方法
当我们检测到 WiFi.status() != WL_CONNECTED
,我们可以使用:
// 断开原本的网络连接
WiFi.disconnect();
// 重新连接网络
WiFi.begin(ssid, password);
完整demo:
#include <ESP8266WiFi.h>
// 替换为个人wifi账号密码
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();
// 如果wifi状态不对,尝试每隔30s重连一次
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());
Serial.println(WiFi.RSSI());
previousMillis = currentMillis;
}
}
2.3 方式3 —— 利用 ESP.restart 重启模块
当我们检测到 WiFi.status() != WL_CONNECTED
,我们可以使用:
// 重启整个模块
ESP.restart();
完整demo:
#include <ESP8266WiFi.h>
// 替换为个人wifi账号密码
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();
// 如果wifi状态不对,尝试每隔30s重启一次,走初始化流程
if ((WiFi.status() != WL_CONNECTED) && (currentMillis - previousMillis >=interval)) {
Serial.print(millis());
Serial.println("Restart WiFi...");
ESP.restart();
}
}
2.4 方式4 —— 利用 Wi-Fi Events
ESP8266可以处理不同的wifi事件。
具体可以参考
我们可以在一些网络事件里面做处理来达到重连的效果。
这里有两个跟wifi连接有关的api。
/**
* 注册事件处理器
* 事件类型:STA模式下模块获取到IP地址
* @param 事件处理回调函数(函数的入参是 WiFiEventStationModeGotIP)
* @return WiFiEventHandler
*/
WiFiEventHandler onStationModeGotIP(std::function<void(const WiFiEventStationModeGotIP&)>);
/**
* 注册事件处理器
* 事件类型:STA模式下断开网络
* @param 事件处理回调函数(函数的入参是 WiFiEventStationModeDisconnected)
* @return WiFiEventHandler
*/
WiFiEventHandler onStationModeDisconnected(std::function<void(const WiFiEventStationModeDisconnected&)>);
完整demo:
#include <ESP8266WiFi.h>
// 替换个人wifi账号密码
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);
//注册事件处理
wifiConnectHandler = WiFi.onStationModeGotIP(onWifiConnect);
// 当检测到断开网络的情况下响应 onWifiDisconnect 方法
wifiDisconnectHandler = WiFi.onStationModeDisconnected(onWifiDisconnect);
initWiFi();
Serial.print("RRSI: ");
Serial.println(WiFi.RSSI());
}
void loop() {
//delay(1000);
}
2.5 额外方式5 —— 利用应用层协议的心跳机制
如果你用到mqtt协议,可以考虑mqtt协议心跳是否正常收发,收发不了也可以考虑一下重连网络。
如果你用到http协议,也可以考虑一个心跳Ping接口,一收一发表示网络通路。