ESP32 WiFi/MQTT断开后自动重连需求:无需外部重启且避免频繁重启
ESP32 WiFi与MQTT自动重连实现方案
针对ESP32 WiFi连接及MQTT传输时的自动重连需求,以下是无需外部干预、故障恢复后自动上线且避免频繁重启的实现方案:
WiFi自动重连机制
- 利用ESP32原生WiFi事件监听,捕获
SYSTEM_EVENT_STA_DISCONNECTED断开事件 - 触发重连时采用指数退避算法:初始重试间隔1秒,每次失败后间隔翻倍,最大设为60秒,避免频繁请求路由
- 重连前检查当前WiFi状态,防止重复发起无效连接请求
MQTT自动重连机制
- 基于PubSubClient库,在MQTT连接断开时标记状态,主循环中定期检查连接状态
- 仅当WiFi已连接成功时,才尝试MQTT重连,避免依赖未就绪的网络发起无效请求
- MQTT重连同样采用指数退避策略,失败后延长重试间隔,保护MQTT Broker资源
防频繁重启策略
- 维护全局失败计数器,记录连续重连失败的次数
- 当连续失败次数达到阈值(示例设为10次),启动1小时长延迟定时器,到期后执行设备重启
- 每次WiFi或MQTT连接成功后,立即重置失败计数器,避免误触发重启
核心代码实现
#include <WiFi.h> #include <PubSubClient.h> // WiFi配置参数 const char* ssid = "YOUR_WIFI_SSID"; const char* password = "YOUR_WIFI_PASSWORD"; // MQTT配置参数 const char* mqtt_broker = "YOUR_MQTT_BROKER_IP"; const int mqtt_port = 1883; const char* mqtt_client_id = "ESP32_MQTT_Client"; WiFiClient espClient; PubSubClient mqtt_client(espClient); // 重连控制变量 unsigned long wifi_retry_delay = 1000; unsigned long mqtt_retry_delay = 1000; unsigned long last_retry_time = 0; int continuous_fail_count = 0; const int MAX_FAIL_THRESHOLD = 10; const unsigned long REBOOT_DELAY = 3600000; // 1小时后重启 // WiFi事件回调函数 void WiFiEventHandler(WiFiEvent_t event) { switch(event) { case SYSTEM_EVENT_STA_DISCONNECTED: Serial.println("WiFi连接断开,启动重连流程"); continuous_fail_count++; break; case SYSTEM_EVENT_STA_CONNECTED: Serial.println("WiFi连接成功"); continuous_fail_count = 0; wifi_retry_delay = 1000; // 重置退避间隔 break; default: break; } } // MQTT重连函数 bool reconnectMQTT() { if (mqtt_client.connect(mqtt_client_id)) { Serial.println("MQTT连接成功"); // 订阅业务主题(按需添加) mqtt_client.subscribe("device/data/recv"); mqtt_retry_delay = 1000; continuous_fail_count = 0; return true; } else { Serial.print("MQTT连接失败,错误码: "); Serial.println(mqtt_client.state()); // 指数退避,最大间隔60秒 mqtt_retry_delay = min(mqtt_retry_delay * 2, 60000UL); continuous_fail_count++; return false; } } // WiFi重连函数 void reconnectWiFi() { if (WiFi.status() != WL_CONNECTED) { Serial.printf("尝试连接WiFi,延迟: %d秒\n", wifi_retry_delay / 1000); WiFi.begin(ssid, password); // 等待5秒超时 unsigned long start_time = millis(); while (WiFi.status() != WL_CONNECTED && millis() - start_time < 5000) { delay(500); Serial.print("."); } if (WiFi.status() != WL_CONNECTED) { wifi_retry_delay = min(wifi_retry_delay * 2, 60000UL); } } } void setup() { Serial.begin(115200); // 注册WiFi事件监听 WiFi.onEvent(WiFiEventHandler); WiFi.begin(ssid, password); mqtt_client.setServer(mqtt_broker, mqtt_port); // 若需处理MQTT消息,可设置回调函数 // mqtt_client.setCallback(mqttMessageCallback); } void loop() { // 检查是否触发重启条件 if (continuous_fail_count >= MAX_FAIL_THRESHOLD) { Serial.println("连续重连失败次数超限,1小时后重启设备"); delay(REBOOT_DELAY); ESP.restart(); } // WiFi重连逻辑 if (WiFi.status() != WL_CONNECTED) { unsigned long now = millis(); if (now - last_retry_time >= wifi_retry_delay) { last_retry_time = now; reconnectWiFi(); } } else { // MQTT重连逻辑 if (!mqtt_client.connected()) { unsigned long now = millis(); if (now - last_retry_time >= mqtt_retry_delay) { last_retry_time = now; reconnectMQTT(); } } else { // 保持MQTT客户端心跳 mqtt_client.loop(); // 此处添加MQTT数据发送逻辑 // mqtt_client.publish("device/data/send", "hello world"); } } }
内容的提问来源于stack exchange,提问作者Ehsanul Karim
相关产品推荐
相关产品推荐

