3、WiFi基础与network模块:WiFi工作模式(Station/Access Point)、network.WLAN类核心API
说实话,做IoT开发这么多年,我见过太多新手一上来就调WiFi,结果连不上就懵了。其实WiFi没那么玄乎,咱们先把底层的两个工作模式搞清楚,后面配网、重连才能写得顺手。
3.1 WiFi的两种工作模式
MicroPython的network模块把WiFi抽象成两种模式:Station(站点)和Access Point(接入点)。说白了,一个负责连别人,一个负责让别人连。
| 模式 | 角色 | 典型场景 |
|---|---|---|
| Station (STA) | 客户端,连接路由器 | 传感器采集数据后上传云端 |
| Access Point (AP) | 热点,提供WiFi信号 | 手机直连设备进行配网配置 |
| STA + AP 共存 | 同时扮演两种角色 | 设备连路由器,同时开放热点供调试 |
我个人习惯把STA模式叫「打工模式」——设备老老实实连上家里的路由器干活。AP模式则是「老板模式」——设备自己开个热点,等着手机来连它。嗯,这里要注意:ESP32这类芯片支持STA和AP同时开启,但会多耗点内存和功耗。
3.2 network.WLAN类核心API
MicroPython的network.WLAN类是我们操作WiFi的唯一入口。我刚开始用的时候也被一堆方法搞晕过,其实常用的就这几个。
3.2.1 创建WLAN对象
import network
# 创建Station模式对象
sta = network.WLAN(network.STA_IF)
# 创建Access Point模式对象
ap = network.WLAN(network.AP_IF)
这里有个坑:创建对象后,WiFi默认是关闭的。你得手动激活它。
3.2.2 激活与状态查询
# 激活Station接口
sta.active(True)
# 检查是否激活
if sta.active():
print("WiFi接口已开启")
# 获取MAC地址
print("MAC:", sta.config('mac'))
我曾经在项目里犯过一个低级错误——创建了WLAN对象但忘了调active(True),结果扫描不到任何网络,排查了半天。所以每次初始化后,我都会加一句状态打印。
3.2.3 连接与断开
# 连接WiFi
sta.connect('SSID', 'password')
# 检查连接状态
if sta.isconnected():
print("已连接,IP:", sta.ifconfig()[0])
# 断开连接
sta.disconnect()
isconnected()返回布尔值,ifconfig()返回一个元组:(IP, 子网掩码, 网关, DNS)。
3.2.4 扫描可用网络
# 扫描周围WiFi
networks = sta.scan()
for net in networks:
ssid = net[0].decode()
bssid = net[1]
channel = net[2]
rssi = net[3]
auth_mode = net[4]
print(f"SSID: {ssid}, 信号强度: {rssi} dBm")
扫描返回的是列表,每个元素是一个元组。注意SSID是bytes类型,需要decode()转成字符串。信号强度RSSI是负数,数值越大(越接近0)信号越好。
3.2.5 配置AP热点
# 配置AP模式
ap = network.WLAN(network.AP_IF)
ap.active(True)
ap.config(essid='MyDevice_Config', password='12345678', authmode=network.AUTH_WPA2_PSK)
# 查看AP的IP地址
print("AP IP:", ap.ifconfig()[0])
AP模式下,设备自己就是DHCP服务器,默认IP通常是192.168.4.1。密码至少8位,否则会报错。
3.3 核心API速查表
| 方法 | 说明 | 返回值 |
|---|---|---|
active([bool]) |
激活/关闭接口 | 当前状态(bool) |
connect(ssid, password) |
连接WiFi | None |
disconnect() |
断开连接 | None |
isconnected() |
检查是否已连接 | bool |
ifconfig() |
获取/设置网络配置 | tuple |
scan() |
扫描周围WiFi | list |
config(param) |
获取/设置配置参数 | 根据参数而定 |
status() |
获取连接状态码 | int |
status()获取更详细的连接状态码。比如network.STAT_CONNECTING表示正在连接,network.STAT_GOT_IP表示已获取IP。这些常量在network模块里都有定义。
3.4 知识体系总览
下面这张图把本章的核心知识点串起来了。你想想看,从创建WLAN对象开始,到选择模式,再到具体操作,整个流程其实很清晰。
3.5 实战:初始化WiFi的推荐写法
说了这么多理论,咱们直接看一段我项目里常用的初始化代码。这段代码兼顾了STA和AP两种模式,还做了异常处理。
import network
import time
def wifi_init_sta(ssid, password):
"""初始化Station模式并连接WiFi"""
sta = network.WLAN(network.STA_IF)
sta.active(True)
if not sta.isconnected():
print(f"正在连接 {ssid}...")
sta.connect(ssid, password)
# 等待连接,超时10秒
timeout = 10
while timeout > 0:
if sta.isconnected():
print("连接成功!")
print("IP:", sta.ifconfig()[0])
return sta
time.sleep(1)
timeout -= 1
print("连接超时,请检查SSID和密码")
return None
else:
print("已连接,无需重复连接")
return sta
def wifi_init_ap(essid='MyDevice', password='12345678'):
"""初始化Access Point模式"""
ap = network.WLAN(network.AP_IF)
ap.active(True)
ap.config(essid=essid, password=password, authmode=network.AUTH_WPA2_PSK)
print(f"AP已开启,SSID: {essid}, IP: {ap.ifconfig()[0]}")
return ap
connect()对某些特殊字符支持不太好,建议密码只用字母和数字。另外,连接超时一定要加,否则设备会卡死在等待状态。
3.6 状态码解读
status()方法返回的整数状态码,很多人不知道具体含义。我整理了一份对照表:
| 状态码 | 常量名 | 含义 |
|---|---|---|
| 1000 | STAT_IDLE |
空闲状态,未连接 |
| 1001 | STAT_CONNECTING |
正在连接中 |
| 1010 | STAT_GOT_IP |
已获取IP,连接成功 |
| 201 | STAT_WRONG_PASSWORD |
密码错误 |
| 202 | STAT_NO_AP_FOUND |
未找到指定SSID |
| 203 | STAT_CONNECT_FAIL |
连接失败 |
调试的时候,我习惯先调status()看看状态码,而不是盲目等isconnected()。比如返回201,直接就知道是密码错了,不用怀疑硬件问题。
核心要点回顾:
- STA模式连路由器,AP模式开热点,两者可以共存
- 创建WLAN对象后必须调
active(True)激活 connect()是非阻塞的,需要轮询isconnected()判断结果status()能提供更详细的连接失败原因- AP模式默认IP是
192.168.4.1,密码至少8位