ESP32 工程实践:为 Wi-Fi 断线重连加入超时与指数退避
很多入门程序在 setup() 里一直等待 WL_CONNECTED。路由器关机或密码错误时,设备就停在启动阶段,屏幕、按键和本地采集也无法继续。本篇实现有连接时限的重连流程,让设备离线时仍能执行本地任务。
示例使用 Arduino-ESP32 3.x 的 WiFi API,未完成实机验证。它只解决接入点连接和获取网络状态,不包含 MQTT、DNS 与业务服务器的健康检查。
先定义重试规则
每次连接最多等待 15 秒。失败后从约 1 秒开始等待,逐次增加到最多 60 秒,并加入少量随机抖动,减少多设备同时重连的拥塞。连接成功后恢复初始退避。
本例关闭自动重连,由一个状态机控制尝试节奏。不要再在其他任务里反复调用 WiFi.begin()。
最小示例
将网络名称和密码替换为自己的测试网络,发布代码时不要包含真实凭据。
#include <Arduino.h>
#include <WiFi.h>
#include <esp_system.h>
const char* SSID = "YOUR_SSID";
const char* PASS = "YOUR_PASSWORD";
constexpr uint32_t CONNECT_TIMEOUT = 15000;
bool attempting = false;
bool wasConnected = false;
uint32_t attemptAt = 0;
uint32_t waitAt = 0;
uint32_t waitMs = 0;
uint32_t backoffMs = 1000;
void scheduleRetry(uint32_t now) {
WiFi.disconnect(false, false); // 不关闭无线电,不擦除配置。
attempting = false;
waitAt = now;
waitMs = backoffMs + esp_random() % 501;
if (waitMs > 60000) waitMs = 60000;
backoffMs = backoffMs >= 30000 ? 60000 : backoffMs * 2;
Serial.printf("retry in %lu ms\n", (unsigned long)waitMs);
}
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
WiFi.setAutoReconnect(false);
waitAt = millis();
}
void loop() {
const uint32_t now = millis();
if (WiFi.status() == WL_CONNECTED) {
if (!wasConnected) {
Serial.print("IP: ");
Serial.println(WiFi.localIP());
}
wasConnected = true;
attempting = false;
backoffMs = 1000;
} else {
if (wasConnected) {
wasConnected = false;
scheduleRetry(now);
}
if (attempting) {
if (uint32_t(now - attemptAt) >= CONNECT_TIMEOUT) {
scheduleRetry(now);
}
} else if (uint32_t(now - waitAt) >= waitMs) {
Serial.println("connecting...");
WiFi.begin(SSID, PASS);
attempting = true;
attemptAt = now;
}
}
// 在这里推进按键、采集或显示任务;避免长时间阻塞。
delay(10);
}
这段代码采用轮询,追求流程易读。事件驱动版本可以记录断连原因,但网络事件回调可能运行在其他任务中,回调宜只更新同步状态或发送队列消息,不执行耗时业务。
连接成功不等于业务恢复
WL_CONNECTED 不能证明互联网、DNS、TLS 和 MQTT 服务全部可用。业务层应有独立的超时与重连状态,连接恢复后重新建立会话,并根据需要重新订阅。
离线采样也应设置缓存上限。恢复连接后分批补传,使用消息序号或幂等键处理重发,避免一次性补传占满内存。
建议的验证步骤
先正常连接,再关闭接入点,确认本地任务仍运行且串口重试间隔逐步增加。重新打开接入点,检查设备能否在后续尝试中恢复。然后用错误密码测试,确认程序持续工作且不会打印密码。
如长期连接不上,先核对芯片支持的频段、接入点认证方式、信号和 DHCP;经典 ESP32 仅支持 2.4 GHz Wi-Fi,不能直接连接仅启用 5 GHz 的网络。不同 ESP32 系列能力请查对应数据手册。
浙公网安备 33010602011771号