2. ESP32基础回顾

在进入配网与远程诊断之前,有必要把 ESP32 的“底座”重新梳理一遍。很多配网失败、连接不稳定、诊断信息缺失的问题,根源并不在配网逻辑本身,而在于对芯片架构、协议栈分层和开发环境细节理解不清。本节从硬件架构、无线协议栈、开发环境到第一个联网程序,建立一条完整的认知链路。

一、ESP32 芯片架构:双核、内存与外设

ESP32 不是一颗简单的 Wi-Fi 单片机,而是一个集成度很高的 SoC。典型型号如 ESP32-D0WDQ6 内部包含两个 Xtensa LX6 核心:PRO_CPU 与 APP_CPU,主频可配置为 80MHz、160MHz 或 240MHz。双核的意义在于:协议栈、网络任务和用户应用可以分核运行,避免单一核心被阻塞导致 Wi-Fi 断流。

存储方面,ESP32 内部有约 520KB SRAM,其中部分被协议栈和 ROM 占用;外部通常挂载 4MB 或 8MB SPI Flash,用于存放固件、文件系统和配网参数。外设包括 GPIO、UART、I2C、SPI、I2S、ADC、DAC、PWM、RMT 等,配网中常用的按键、LED 指示、串口日志都依赖这些外设。

理解架构的关键是:Wi-Fi/蓝牙协议栈运行在独立任务中,用户代码通过事件循环和回调与协议栈交互。如果用户代码长时间阻塞,协议栈任务得不到调度,就会出现掉线、重连失败、扫描不到 AP 等现象。

ESP32 芯片架构与协议栈分层示意 双核 CPU 与内存 PRO_CPU 协议栈 / 系统任务 APP_CPU 用户应用任务 520KB SRAM 堆 / 栈 / 缓冲 SPI Flash 固件 / NVS 参数 无线协议栈分层 Wi-Fi 协议栈 STA / AP / Sniffer 蓝牙协议栈 BLE GAP / GATT TCP/IP 与 LwIP Socket / MQTT / HTTP 用户应用与事件交互 事件循环 esp_event_loop WIFI_EVENT / IP_EVENT 配网与诊断任务 按键 / LED / 日志 NVS 参数存储 SSID / 密码 / 设备ID

二、Wi-Fi 与蓝牙协议栈:配网的两条通道

ESP32 的无线能力是配网方案的基础。Wi-Fi 协议栈支持 STA(连接路由器)、AP(自身热点)、AP+STA 共存以及 Sniffer 抓包;蓝牙协议栈支持经典蓝牙和 BLE,其中 BLE 因低功耗、手机兼容性好,常用于“蓝牙辅助配网”。

在 ESP-IDF 中,Wi-Fi 初始化遵循固定顺序:esp_netif_init() → esp_event_loop_create_default() → esp_netif_create_default_wifi_sta() → esp_wifi_init() → 配置 wifi_config_t → esp_wifi_start()。每一步都可能成为配网失败的检查点。

BLE 配网通常使用 GATT 服务:设备广播自定义 Service UUID,手机连接后写入 SSID 和密码,设备收到后切换到 STA 模式连接路由器。理解 GAP 广播、GATT 读写、Notify 通知,是排查“手机搜不到设备”“写入无响应”等问题的前提。

配网前先确认:Wi-Fi 与 BLE 是否共用射频?ESP32 的 Wi-Fi 和蓝牙共享 2.4GHz 射频,AP+STA+BLE 同时工作时需要关注共存策略和内存占用。

三、开发环境搭建:从工具链到烧录

ESP32 主流开发方式有两类:一是乐鑫官方的 ESP-IDF,适合深度控制和量产;二是 Arduino-ESP32,适合快速验证。配网与远程诊断涉及事件循环、NVS、协议栈参数,建议以 ESP-IDF 为主。

环境搭建的核心步骤:安装 Python 与 Git;获取 ESP-IDF;运行安装脚本;设置环境变量;使用 idf.py 创建、配置、编译、烧录和监视。常见命令如下:

# 获取并安装 ESP-IDF
git clone -b v5.1.2 --recursive https://github.com/espressif/esp-idf.git
cd esp-idf
./install.sh esp32

# 激活环境
. ./export.sh

# 创建工程并配置
idf.py create-project wifi_demo
cd wifi_demo
idf.py set-target esp32
idf.py menuconfig

# 编译、烧录、查看日志
idf.py build
idf.py -p /dev/ttyUSB0 flash monitor

烧录时注意串口权限、波特率(默认 115200)和下载模式。若出现 Failed to connect to ESP32,通常需要按住 BOOT 键再复位,或检查 USB 转串口芯片驱动。

四、第一个联网程序:STA 连接与事件处理

第一个联网程序的目标很明确:让 ESP32 以 STA 模式连接指定路由器,获取 IP,并打印连接状态。关键不是“连上”,而是理解事件驱动模型。

static void wifi_event_handler(void* arg, esp_event_base_t event_base,
                               int32_t event_id, void* event_data) {
    if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
        esp_wifi_connect();
    } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
        ESP_LOGW(TAG, "断开,准备重连");
        esp_wifi_connect();
    } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
        ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;
        ESP_LOGI(TAG, "获取IP: " IPSTR, IP2STR(&event->ip_info.ip));
    }
}

这段代码体现了配网与诊断的雏形:连接成功要记录 IP,断开要记录原因并重连。后续章节的配网状态机、远程诊断日志,都是在这个骨架上扩展。

检查项 常见现象 排查方向
Wi-Fi 模式 扫描不到 AP 确认 STA 已 start,射频未关闭
SSID/密码 反复断开,reason=15/201 密码错误或 AP 拒绝,检查 2.4GHz 频段
事件循环 收不到 GOT_IP 事件回调未注册或任务阻塞
NVS 重启后参数丢失 未初始化 NVS 或未提交写入
串口日志 无输出或乱码 波特率、串口权限、下载模式

五、误区与复盘

误区一:把 Wi-Fi 连接写成阻塞式。在事件回调里执行 while 等待 IP,会阻塞事件循环,导致后续事件无法处理。正确做法是状态机 + 事件驱动。

误区二:忽略断开原因码。WIFI_EVENT_STA_DISCONNECTED 携带 reason,如 15 表示四次握手超时,201 表示无 AP。配网诊断必须记录原因码,否则只能“盲重连”。

误区三:AP+STA 共存时内存不足。同时开启 AP、STA 和 BLE 会显著增加内存占用,建议在 menuconfig 中调整 Wi-Fi 缓冲区数量,并监控剩余堆空间。

复盘要点:芯片架构决定任务划分,协议栈分层决定事件来源,开发环境决定调试效率,第一个联网程序决定后续配网与诊断的代码骨架。把这四层打通,后面的配网方案才有稳定的落脚点。