3. Wi-Fi 连接与网络基础:ESP32 Station 与 AP 模式、Wi-Fi 事件处理、自动重连机制、网络状态监控

Wi-Fi 连接是 ESP32 物联网项目的基础。说白了,没有稳定的网络连接,后面那些 WebSocket 通信、前端交互都是空谈。这一章我们就把 ESP32 的 Wi-Fi 底层机制彻底讲透。

我个人习惯把 Wi-Fi 模块比作一个「网络开关」——你不仅要学会怎么打开它,还要知道它什么时候断开、为什么断开、以及如何优雅地重新连上。嗯,这里面的门道不少。

本章核心目标:掌握 ESP32 的 Station 与 AP 双模式配置、事件驱动编程模型、自动重连策略以及实时网络状态监控。

3.1 Station 模式与 AP 模式:两种角色,两种场景

ESP32 的 Wi-Fi 可以工作在两种模式下,你可以把它想象成手机:

  • Station 模式(客户端):像你的手机连接家里路由器一样,ESP32 作为客户端去连接一个已有的 Wi-Fi 热点。这是最常见的物联网设备工作模式。
  • AP 模式(热点):ESP32 自己变成一个 Wi-Fi 热点,其他设备(如手机)可以连接它。常用于设备配网或临时控制。
  • AP+Station 共存模式:同时作为客户端和热点。我在项目中经常用这个模式——设备连上互联网的同时,还能让手机直连设备进行本地调试。
模式 角色 典型场景 注意事项
Station 客户端 传感器数据上报、远程控制 需要已知的 Wi-Fi SSID/密码
AP 热点 设备配网、本地 Web 配置页面 最多连接 4 个客户端,信道固定
AP+Station 双角色 设备既联网又提供本地接口 内存占用增加,需注意 IP 路由

配置代码其实很简单,但要注意顺序。我曾经踩过一个坑:先初始化了 AP 模式,再初始化 Station 模式,结果两个模式的 IP 地址冲突了。后来我养成了一个习惯——先配置模式,再启动 Wi-Fi。

#include <WiFi.h>

void setup() {
  Serial.begin(115200);
  
  // 设置为 Station 模式
  WiFi.mode(WIFI_STA);
  
  // 开始连接
  WiFi.begin("你的SSID", "你的密码");
  
  Serial.print("正在连接");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("\n连接成功!");
  Serial.print("IP 地址: ");
  Serial.println(WiFi.localIP());
}
小技巧:如果你想让 ESP32 记住上次连接的 Wi-Fi,可以用 WiFi.persistent(true)。这样断电重启后它会自动尝试重连上次的网络,省去每次配网的麻烦。

3.2 Wi-Fi 事件处理:别再用轮询了

很多初学者喜欢在 loop() 里不断检查 WiFi.status()。说实话,这太浪费 CPU 了。ESP32 提供了事件驱动机制——当 Wi-Fi 状态发生变化时,系统会自动触发回调函数。

为什么推荐事件驱动?你想想看,如果设备正在处理传感器数据,突然 Wi-Fi 断开了,你难道要等到下一轮 loop() 循环才发现吗?事件回调可以让你立即响应网络变化。

void onWiFiEvent(WiFiEvent_t event) {
  switch (event) {
    case SYSTEM_EVENT_STA_CONNECTED:
      Serial.println("已连接到路由器");
      break;
    case SYSTEM_EVENT_STA_GOT_IP:
      Serial.print("获取到 IP: ");
      Serial.println(WiFi.localIP());
      break;
    case SYSTEM_EVENT_STA_DISCONNECTED:
      Serial.println("Wi-Fi 断开连接");
      // 在这里触发自动重连
      WiFi.reconnect();
      break;
    default:
      break;
  }
}

void setup() {
  WiFi.onEvent(onWiFiEvent);
  WiFi.begin("SSID", "密码");
}
注意:事件回调函数里不要做耗时操作,比如 delay() 或复杂的计算。它运行在 Wi-Fi 任务上下文中,阻塞太久会影响网络稳定性。我一般只在回调里设置标志位,真正的重连逻辑放在 loop() 里处理。

3.3 自动重连机制:别让设备变成「孤儿」

设备部署到现场后,Wi-Fi 断开是家常便饭。路由器重启、信号干扰、电源波动……任何一个原因都可能导致连接中断。如果没有自动重连,设备就成了一块「废铁」。

ESP32 的 WiFi.reconnect() 函数可以发起重连,但直接调用它是不够的。我曾经遇到过一个问题:设备断线后疯狂重连,每秒尝试几十次,结果把路由器搞崩溃了。后来我加了一个退避策略——重连间隔逐渐增大,避免雪崩效应。

unsigned long lastReconnectAttempt = 0;
int reconnectDelay = 1000;  // 初始 1 秒

void checkWiFi() {
  if (WiFi.status() != WL_CONNECTED) {
    unsigned long now = millis();
    if (now - lastReconnectAttempt >= reconnectDelay) {
      lastReconnectAttempt = now;
      Serial.println("尝试重连...");
      WiFi.reconnect();
      
      // 退避策略:每次增加 2 秒,最大 60 秒
      reconnectDelay = min(reconnectDelay + 2000, 60000);
    }
  } else {
    // 连接成功后重置延迟
    reconnectDelay = 1000;
  }
}
重连策略总结:
  • 指数退避:重连间隔从 1 秒开始,每次翻倍,最大 60 秒
  • 有限重试:尝试 10 次后仍未成功,进入深度休眠或重启
  • 状态保存:重连前保存当前工作状态,避免数据丢失

3.4 网络状态监控:看得见的连接质量

光知道「连上了」还不够。在实际项目中,我们需要知道连接的质量——信号强度、丢包率、IP 地址变化等。这些信息能帮助我们诊断网络问题。

我个人习惯在设备上实现一个网络健康检查功能:定时 ping 网关或云服务器,如果连续 3 次超时,就认为网络不可用,主动触发重连。

监控指标 获取方式 说明
RSSI(信号强度) WiFi.RSSI() 单位 dBm,-30 为极好,-80 以下基本不可用
IP 地址 WiFi.localIP() DHCP 分配的 IP,变化时需通知上层应用
MAC 地址 WiFi.macAddress() 设备唯一标识,常用于服务器端设备识别
连接状态 WiFi.status() 返回 WL_CONNECTED 等枚举值
void printNetworkStatus() {
  Serial.println("===== 网络状态 =====");
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());
  Serial.print("信号强度 (RSSI): ");
  Serial.print(WiFi.RSSI());
  Serial.println(" dBm");
  Serial.print("IP 地址: ");
  Serial.println(WiFi.localIP());
  Serial.print("MAC 地址: ");
  Serial.println(WiFi.macAddress());
  Serial.print("网关: ");
  Serial.println(WiFi.gatewayIP());
  Serial.print("子网掩码: ");
  Serial.println(WiFi.subnetMask());
  Serial.println("====================");
}
实用技巧:在 Web 管理页面中显示 RSSI 信号强度,用颜色区分——绿色(>-50)、黄色(-50 ~ -70)、红色(<-70)。这样现场维护人员一眼就能看出哪个设备信号不好。

3.5 知识体系总览

下面这张图总结了本章的核心知识点和它们之间的关系。你可以把它当作一个快速参考地图。

ESP32 Wi-Fi 连接与网络基础 Station 模式 AP 模式 AP+Station 共存 Wi-Fi 事件处理(事件驱动) 自动重连机制(指数退避策略) 网络状态监控(RSSI / IP / 健康检查) 核心原则:先配置模式 → 注册事件回调 → 实现退避重连 → 持续监控健康状态
避坑提醒:我曾经在一个项目中同时使用了 WiFi.reconnect() 和 WiFi.onEvent() 中的重连逻辑,结果两个重连任务互相竞争,导致设备反复断开重连。记住:重连逻辑只在一个地方实现,要么在事件回调里,要么在 loop() 里,不要混用。

好了,这一章的内容就到这里。Wi-Fi 连接看似基础,但它是整个物联网系统的命脉。把模式配置、事件处理、自动重连和状态监控这四个环节做扎实了,你的设备才能在各种网络环境下稳定运行。