4. Wi-Fi 配网原理:SmartConfig 与 AirKiss 技术
好,咱们进入第四章。这一章讲的是 Wi-Fi 配网,说白了就是怎么让一个「裸机」——刚出厂的智能设备——连上你家的路由器。
你想想看,智能插座、灯泡、传感器,这些设备没有屏幕、没有键盘。你总不能拿根网线插上去配置吧?所以就有了「一键配网」这种技术。我最早接触这个是在 2015 年做智能灯项目,那时候配网成功率只有 70% 左右,用户抱怨很多。后来才慢慢摸透了里面的门道。
4.1 为什么需要配网?
设备刚买回来,它不知道你家 Wi-Fi 的 SSID 和密码。传统做法是让设备自己开一个热点,你用手机连上去,再在网页里输入 Wi-Fi 信息。这方法稳定,但操作步骤多,用户体验差。
SmartConfig 和 AirKiss 这类技术,就是想省掉「连设备热点」这一步。手机直接广播 Wi-Fi 信息,设备在监听模式下一把抓过来。嗯,听起来很神奇,但原理其实不复杂。
4.2 SmartConfig 原理
SmartConfig 是 TI(德州仪器)提出的方案。它的核心思路是:把 Wi-Fi 密码编码到数据包的长度里。
手机不断发送 UDP 广播包,每个包的长度代表一个 bit 或一组 bit。设备在混杂模式下监听这些包,解析出长度信息,再还原成 SSID 和密码。
关键点:SmartConfig 不需要设备先连上路由器。设备处于监听模式,抓取空中的无线帧。只要手机和设备在同一个 Wi-Fi 信道,就能收到。
我在项目中遇到过一个问题:有些路由器会过滤掉长度异常的包,导致配网失败。后来我们加了重传机制,手机连续发 3 轮数据,成功率才提到 95% 以上。
4.3 AirKiss 原理
AirKiss 是乐鑫(Espressif)为 ESP8266/ESP32 开发的配网协议。它和 SmartConfig 类似,但编码方式不同。
AirKiss 利用的是 802.11 数据帧中的 目的 MAC 地址 来传递信息。手机发送一系列 UDP 包,每个包的目的 MAC 地址的最后几个字节被编码成数据。设备抓取这些帧,解码出 Wi-Fi 信息。
| 特性 | SmartConfig | AirKiss |
|---|---|---|
| 提出者 | TI | 乐鑫 |
| 编码载体 | 数据包长度 | 目的 MAC 地址 |
| 兼容性 | 较广 | ESP 系列专用 |
| 成功率 | 中等(受路由器影响) | 较高(针对 ESP 优化) |
| 重传机制 | 需自行实现 | 内置 |
说白了,AirKiss 就是乐鑫给自家芯片量身定做的配网方案。如果你用 ESP32,我建议优先用 AirKiss,省心很多。
4.4 ESP32 的 Wi-Fi 库函数
ESP32 的 Wi-Fi 功能由 esp_wifi.h 和 esp_netif.h 两个核心库提供。我习惯把 Wi-Fi 操作封装成一个模块,方便复用。
先看几个最常用的函数:
// 初始化 Wi-Fi
esp_netif_init();
esp_event_loop_create_default();
esp_netif_create_default_wifi_sta();
// 配置并启动 STA 模式
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
esp_wifi_init(&cfg);
esp_wifi_set_mode(WIFI_MODE_STA);
esp_wifi_start();
// 连接指定热点
wifi_config_t wifi_config = {
.sta = {
.ssid = "你的SSID",
.password = "你的密码"
}
};
esp_wifi_set_config(WIFI_IF_STA, &wifi_config);
esp_wifi_connect();
嗯,这里要注意:esp_wifi_connect() 是异步的。你不能调完就以为连上了。得注册事件回调,监听 WIFI_EVENT_STA_CONNECTED 和 IP_EVENT_STA_GOT_IP。
我的习惯:在回调里加一个超时计时器。如果 15 秒内没收到 GOT_IP 事件,就认为连接失败,触发重试或进入配网模式。这样用户体验好很多。
4.5 STA 与 AP 模式切换
ESP32 支持三种 Wi-Fi 模式:
- STA 模式:作为客户端连接路由器
- AP 模式:自己开热点,让手机连上来
- AP+STA 模式:同时做客户端和热点
实际项目中,我经常用「先 AP 后 STA」的流程:
- 设备上电,默认进入 AP 模式,开一个叫
SmartDevice_XXXX的热点 - 手机连上这个热点,通过网页或 App 发送 Wi-Fi 信息
- 设备收到后,切换到 STA 模式,连接目标路由器
- 连接成功,保存配置;失败则回退到 AP 模式
代码实现大概是这样的:
// 切换到 AP 模式
esp_wifi_set_mode(WIFI_MODE_AP);
wifi_config_t ap_config = {
.ap = {
.ssid = "SmartDevice_001",
.ssid_len = strlen("SmartDevice_001"),
.max_connection = 1,
.authmode = WIFI_AUTH_OPEN
}
};
esp_wifi_set_config(WIFI_IF_AP, &ap_config);
esp_wifi_start();
// 收到配网信息后,切换到 STA
esp_wifi_set_mode(WIFI_MODE_STA);
wifi_config_t sta_config = {
.sta = {
.ssid = "收到的SSID",
.password = "收到的密码"
}
};
esp_wifi_set_config(WIFI_IF_STA, &sta_config);
esp_wifi_connect();
我曾经踩过的坑:切换模式前一定要先 esp_wifi_stop(),再 esp_wifi_set_mode(),最后 esp_wifi_start()。直接改模式会导致 Wi-Fi 栈状态混乱,设备死机。别问我怎么知道的……
4.6 配网流程总览
我把整个配网流程画了一张图,方便你理解:
这张图里,绿色分支是成功路径,黄色分支是异常处理。实际产品中,回退逻辑特别重要。我见过不少设备,配网失败后直接死机,用户只能断电重启——这体验太差了。
4.7 实战建议
- 信道问题:手机和设备必须在同一信道。有些路由器会自动切换信道,导致配网失败。我建议设备在监听模式下扫描所有信道,或者让手机固定信道发 3 秒。
- 加密方式:AirKiss 默认支持 WPA/WPA2。如果你的路由器用了 WPA3,部分旧版 ESP32 固件可能不兼容。升级到最新 ESP-IDF 可以解决。
- 配网超时:给配网过程加一个 60 秒的超时。超时后自动进入低功耗模式或重启,而不是一直傻等。
一个小技巧:配网成功后,把 Wi-Fi 配置写入 NVS(非易失性存储)。下次上电直接读取,不用重新配网。代码里用 nvs_set_str() 和 nvs_get_str() 就行,简单可靠。