4. Station模式配网原理:设备作为客户端、扫描周围AP、自动连接已知网络、手动触发重新配网

好,咱们进入第四讲。前面几章我们把WiFi的角色和基本概念捋了一遍,现在该聊聊最核心的配网模式——Station模式了。

说白了,你的设备在Station模式下,就是一个“客户端”。它得主动去找周围的路由器(也就是AP),然后尝试连上去。这个过程,我习惯叫它“找网-连网-上网”三步走。

核心理解:Station模式下的设备,就像你拿着手机去咖啡馆连WiFi。手机是Station,咖啡馆的路由器是AP。手机得先扫描到咖啡馆的WiFi信号,输入密码,才能连上。

4.1 扫描周围AP:设备怎么“看见”网络?

设备上电后,第一件事就是“看”周围有哪些AP。这个动作叫扫描(Scan)。

我刚开始做物联网项目时,以为扫描就是简单发个广播包。后来发现,这里面的门道还挺多。扫描分两种:

  • 主动扫描:设备主动发Probe Request帧,问“附近有AP吗?报上名来”。AP收到后回复Probe Response。这种方式快,但耗电。
  • 被动扫描:设备啥也不发,就等着AP每隔100ms左右广播一次Beacon帧。Beacon帧里包含了AP的SSID、信号强度、加密方式等信息。这种方式省电,但慢。

你想想看,一个电池供电的传感器,如果每5分钟才需要上报一次数据,用被动扫描就挺合适。但如果是智能插座,用户按一下按钮就要立刻配网,那主动扫描更靠谱。

我的习惯:在产品开发中,我通常让设备先做一次主动扫描(快速发现),如果没找到目标网络,再切到被动扫描(省电等待)。这样兼顾了速度和功耗。

扫描完成后,设备会拿到一个AP列表。每个AP的信息大概长这样:

字段 说明 示例值
SSID 网络名称 MyHome_WiFi
BSSID AP的MAC地址 AA:BB:CC:DD:EE:FF
RSSI 信号强度(dBm) -65
Auth Mode 加密方式 WPA2-PSK
Channel 信道编号 6

嗯,这里要注意:RSSI值越大(越接近0),信号越好。一般-30dBm是满格,-80dBm基本就断流了。

4.2 自动连接已知网络:设备怎么“记住”家?

设备扫描到AP列表后,怎么知道该连哪个?总不能每次都让用户选吧?

这里就要引入已知网络列表的概念。设备内部会维护一个NVS(Non-Volatile Storage,非易失性存储)区域,专门存已经配过网的SSID和密码。我习惯叫它“WiFi小本本”。

自动连接的逻辑其实很简单:

  1. 设备扫描周围AP,拿到列表。
  2. 遍历“WiFi小本本”里的每个已知网络。
  3. 如果某个已知网络的SSID出现在扫描列表中,就尝试用存储的密码去连接。
  4. 连接成功,皆大欢喜。连接失败(比如密码改了),就跳过,试下一个。

我曾经在一个项目中遇到过这样的坑:设备只存了一个网络,结果用户搬家了,路由器换了。设备每次上电都去连旧路由,连不上就死循环,用户只能干瞪眼。后来我加了一个连接超时重试机制——连续3次连不上,就自动进入配网模式。

避坑指南:千万不要让设备在“连接失败-重试-再失败”的循环里卡死。一定要设置最大重试次数,比如3次或5次。超过次数后,要么重启扫描,要么主动进入配网模式。否则用户会以为设备坏了。

代码层面,自动连接的伪代码大概是这样的:

// 伪代码:自动连接已知网络
void auto_connect() {
    list known_networks = read_from_nvs();  // 从存储读取已知网络列表
    list scanned_aps = wifi_scan();         // 扫描周围AP

    for (each known in known_networks) {
        for (each ap in scanned_aps) {
            if (known.ssid == ap.ssid) {
                // 尝试连接
                int ret = wifi_connect(known.ssid, known.password);
                if (ret == SUCCESS) {
                    return;  // 连接成功,退出
                }
            }
        }
    }

    // 所有已知网络都连不上,进入配网模式
    enter_provisioning_mode();
}

这段代码看起来简单,但实际产品中要考虑的细节很多。比如,扫描列表里可能有多个同名AP(Mesh组网场景),你得选信号最强的那个。

4.3 手动触发重新配网:用户想换网怎么办?

设备已经连上家里的WiFi了,但用户换了新路由器,或者想把它带到公司用。这时候就需要手动触发重新配网。

触发方式通常有几种:

  • 物理按键:长按某个按键3秒以上,设备清空已知网络列表,进入配网模式。这是最可靠的方式。
  • App指令:通过已连接的WiFi,App发送一个“重置配网”的指令。设备收到后主动断开连接,进入配网模式。
  • 上电时序:连续上电断电3次,设备检测到异常启动,自动进入配网模式。这种方式适合没有按键的设备。

我个人比较推荐物理按键+App指令的组合。物理按键是最后的“救命稻草”,App指令则方便用户远程操作。

我的经验:在智能家居项目中,我见过太多用户把设备带到新家后,不知道怎么重新配网。后来我在产品说明书里加了一句话:“长按设备侧面按钮5秒,听到‘嘀’一声后松开,即可重新配网。”用户反馈好多了。

手动触发重新配网后,设备要做几件事:

  1. 清空NVS中的已知网络列表。
  2. 断开当前WiFi连接。
  3. 启动配网服务(比如开启SoftAP或BLE广播)。
  4. 等待用户通过手机App重新配置。

这里有个细节:清空列表时,要不要保留一些“出厂默认网络”?比如某些设备在工厂测试时用的专用网络。我建议保留一个出厂保留区,只清空用户配网的部分,这样工厂测试网络不会被误删。

4.4 整体流程:一张图看懂Station配网

说了这么多,咱们用一张SVG图把整个流程串起来。这张图我画了好几次才满意,你仔细看看。

Station模式配网流程图 Station模式配网完整流程 设备上电 扫描周围AP 检查已知网络列表 有匹配网络? 是 连接已知网络 否 进入配网模式 正常上网 手动触发重新配网 说明:虚线表示用户主动触发;实线表示设备自动流程

这张图把整个Station配网流程串起来了。你从上往下看:设备上电→扫描AP→检查已知网络→有就连接,没有就进入配网模式。用户如果想换网,随时可以手动触发重新配网。

4.5 实际项目中的几个坑

最后,我分享几个实际项目中踩过的坑,你以后遇到了可以少走弯路。

  • 扫描列表为空:有些设备在射频干扰强的环境里,扫描不到任何AP。我建议加一个“强制扫描”机制——如果第一次扫描结果为空,等2秒再扫一次,最多扫3次。
  • SSID隐藏:有些用户喜欢隐藏WiFi的SSID。设备被动扫描是看不到隐藏SSID的,必须用主动扫描,并且知道SSID名称才能连上。所以配网时最好让用户手动输入SSID。
  • 5GHz vs 2.4GHz:很多IoT设备只支持2.4GHz频段。如果用户的路由器开了双频合一,设备可能扫描到5GHz的AP但连不上。我一般会在配网时提示用户“请确保手机连接的是2.4GHz WiFi”。
  • 密码中的特殊字符:有些WiFi密码包含空格、引号等特殊字符。设备在存储和解析密码时,一定要做转义处理,否则连接会失败。

重要提醒:千万不要把WiFi密码明文存储在Flash中。至少要做简单的加密或混淆。虽然不能完全防住黑客,但至少能防住普通用户通过串口工具读取固件后直接拿到密码。