CircuitPython 10.1.3 静态 WIFI 配置指南
使用 `subnet` 而不是 `netmask`:`set_ipv4_address(ipv4=ip, subnet=subnet, gateway=gw)` - 报错:`'netmask' argument required`- **静态 IP 配置被忽略**:系统不会自动读取 `settings.toml` 中的静态 IP 配置,仍会使用 DHCP 分配的 IP。4. **检查 IP 地址*
# CircuitPython 10.1.3 静态 WIFI 配置指南
## 一、经验教训总结
经过实际测试,我们发现 CircuitPython 10.1.3 在 WiFi 配置方面有以下特点:
### 1. settings.toml 配置项自动应用情况
| 配置项 | 是否自动应用 | 如何处理 |
|--------|-------------|----------|
| SSID/密码 | ✅ 是 | Web Workflow 自动连接 |
| 静态 IP | ❌ 否 | 需要在 code.py 中手动设置 |
| Web API 密码 | ✅ 是 | Web Workflow 自动使用 |
### 2. 关键发现
- **部分生效**:只有 WiFi 连接信息(SSID/密码)和 Web API 密码会被自动使用
- **静态 IP 配置被忽略**:系统不会自动读取 `settings.toml` 中的静态 IP 配置,仍会使用 DHCP 分配的 IP
- **必须手动设置**:静态 IP 需要在 code.py 中手动设置才能生效
- **需要保持运行**:WiFi 连接在程序退出后可能会中断,建议添加死循环保持程序运行
## 二、详细配置指南
### 1. 基础配置文件(settings.toml)
虽然静态 IP 配置在 `settings.toml` 中无效,但仍建议保留 WiFi 连接信息,方便管理:
```toml
# settings.toml - 配置文件
# WiFi设置
CIRCUITPY_WIFI_SSID="WIFI"
CIRCUITPY_WIFI_PASSWORD="abc12345"
CIRCUITPY_WEB_API_PASSWORD="123456"
# 静态IP设置(仅作为参考,不会自动生效)
# CIRCUITPY_WIFI_IP="192.168.1.75"
# CIRCUITPY_WIFI_NETMASK="255.255.255.0"
# CIRCUITPY_WIFI_GATEWAY="192.168.1.1"
```
### 2. 手动配置代码(code.py)
**必须在 code.py 中手动实现 WiFi 连接和静态 IP 设置**:
```python
# code.py - 系统入口
"""
系统启动文件 - 手动配置 WiFi 和静态 IP
"""
print("=" * 60)
print("🚀 启动系统调度器")
print("=" * 60)
import time
import wifi
import ipaddress
try:
# 配置
ssid = "WIFI"
password = "abc12345"
static_ip = "192.168.1.75"
netmask = "255.255.255.0"
gateway = "192.168.1.1"
print("\n[WiFi] 配置静态 IP...")
print(f"[WiFi] 静态 IP: {static_ip}")
print(f"[WiFi] 子网掩码: {netmask}")
print(f"[WiFi] 网关: {gateway}")
# 连接到 WiFi
print(f"\n[WiFi] 连接到: {ssid}")
# 先断开(如果已连接)
if wifi.radio.connected:
print("[WiFi] 断开当前连接...")
wifi.radio.stop_station()
time.sleep(1)
# 连接 WiFi
print("[WiFi] 正在连接...")
start_time = time.monotonic()
wifi.radio.connect(ssid, password)
connect_time = time.monotonic() - start_time
print(f"[WiFi] ✅ 连接成功! 耗时: {connect_time:.2f}秒")
# 设置静态 IP
print("\n[WiFi] 设置静态 IP...")
ipv4 = ipaddress.IPv4Address(static_ip)
nm = ipaddress.IPv4Address(netmask)
gw = ipaddress.IPv4Address(gateway)
# 使用正确的参数格式
wifi.radio.set_ipv4_address(
ipv4=ipv4,
netmask=nm,
gateway=gw
)
print(f"[WiFi] ✅ 静态 IP 设置成功: {wifi.radio.ipv4_address}")
# 获取开机时间
try:
from rtc import RTC
rtc = RTC()
dt = rtc.datetime
boot_time = f"{dt.tm_year}-{dt.tm_mon:02d}-{dt.tm_mday:02d} {dt.tm_hour:02d}:{dt.tm_min:02d}:{dt.tm_sec:02d}"
except:
boot_time = f"启动时间: {int(time.monotonic())}s"
print(f"\n[系统] 开机时间: {boot_time}")
# 日志记录
try:
with open('boot.log', 'a') as f:
f.write(f"[{boot_time}] 系统启动 - WiFi: {wifi.radio.ipv4_address}\n")
print("[系统] 日志记录成功")
except Exception as e:
print(f"[系统] 日志记录失败: {e}")
print("\n" + "=" * 60)
print("✅ 系统启动完成")
print("=" * 60)
print(f"\n[提示] 当前 IP: {wifi.radio.ipv4_address}")
print()
print("\n[系统] 系统启动完成,准备退出...")
print("[系统] WiFi 连接会持续保持")
except Exception as e:
print(f"\n❌ 启动失败: {e}")
print("错误信息:", e)
```
## 三、关键技术点
### 1. 静态 IP 设置方法
**正确的参数格式**:
- 使用关键字参数:`ipv4`, `netmask`, `gateway`
- 参数值需要是 `ipaddress.IPv4Address` 对象
**错误的参数格式**:
- 三个独立参数:`set_ipv4_address(ip, subnet, gateway)` - 报错:`extra positional arguments given`
- 元组参数:`set_ipv4_address((ip, subnet, gateway))` - 报错:`extra positional arguments given`
- 使用 `subnet` 而不是 `netmask`:`set_ipv4_address(ipv4=ip, subnet=subnet, gateway=gw)` - 报错:`'netmask' argument required`
### 2. 保持 WiFi 连接稳定
- **无需添加死循环**:程序执行完成后,WiFi 连接会持续保持
- **不要使用 settings.toml 静态 IP 配置**:系统不会自动读取这些配置
- **重启后自动连接**:code.py 会在设备重启时自动执行,重新连接 WiFi 并设置静态 IP
## 四、常见问题及解决方案
| 问题 | 原因 | 解决方案 |
|------|------|----------|
| 静态 IP 设置失败 | 参数格式错误 | 使用正确的关键字参数格式:`ipv4`, `netmask`, `gateway` |
| WiFi 连接中断 | 程序执行完成后退出 | 添加死循环保持程序运行 |
| settings.toml 静态 IP 不生效 | CircuitPython 10.1.3 不支持 | 在 code.py 中手动设置静态 IP |
| 连接失败 | SSID 或密码错误 | 检查 WiFi 配置是否正确 |
| 静态 IP 冲突 | IP 地址已被其他设备使用 | 选择一个未使用的 IP 地址 |
## 五、最佳实践
1. **使用 code.py 手动配置**:始终在 code.py 中实现 WiFi 连接和静态 IP 设置
2. **保留 settings.toml**:虽然静态 IP 配置无效,但可以在其中保留 WiFi 连接信息,方便管理
3. **添加错误处理**:捕获异常并提供详细的错误信息
4. **无需保持程序运行**:WiFi 连接会在程序退出后持续保持
5. **记录日志**:记录系统启动和 WiFi 连接状态,方便调试
6. **定期检查**:定期测试 WiFi 连接状态,确保系统正常运行
## 六、测试验证
### 验证步骤
1. **上传配置文件**:将 `settings.toml` 和 `code.py` 上传到设备
2. **重启设备**:手动复位设备或通过代码重启
3. **检查连接状态**:使用 `wifi.radio.connected` 检查连接状态
4. **检查 IP 地址**:使用 `wifi.radio.ipv4_address` 检查 IP 地址是否为静态 IP
5. **测试网络连接**:使用 `ping` 命令测试设备是否可以正常访问
### 预期结果
- ✅ WiFi 连接成功
- ✅ 静态 IP 设置为指定值
- ✅ 网络连接正常
- ✅ 重启后自动重新连接
## 七、特殊情况说明
### 1. 关于"幽灵连接"现象
**现象**:在某些特定情况下,WiFi 连接可能会出现"幽灵连接"现象,即连接看似存在但实际上已中断,或者连接不稳定。
**原因**:
- 网络环境干扰
- 路由器信号不稳定
- 电源波动
- 特定固件版本的 bug
**解决方案**:
- 确保使用稳定的电源
- 避免在信号弱的环境中使用
- 定期检查 WiFi 连接状态
- 必要时重启设备
### 2. 关于代码循环的必要性
**普通情况**:在正常情况下,CircuitPython 10.1.3 中 WiFi 连接会在程序退出后持续保持,不需要添加死循环。
**特殊情况**:
- 在某些特定的固件版本中
- 在网络环境不稳定的情况下
- 在使用某些特定功能时
**建议**:
- 对于关键应用,可以考虑添加简单的循环来监控 WiFi 连接状态
- 对于一般应用,无需添加循环,WiFi 连接会自动保持
## 八、与 MicroPython WiFi 架构对比
### CircuitPython WiFi 架构
- **共享 CPU**:WiFi 功能与主程序共享同一个 CPU 核心
- **事件驱动**:WiFi 连接由系统事件驱动,程序退出后仍保持
- **简化 API**:提供更简洁的 `wifi` 模块 API
- **配置方式**:部分支持 `settings.toml` 自动配置
### MicroPython WiFi 架构
- **独立核心**:ESP32/ESP8266 等设备中,WiFi 功能运行在独立的 CPU 核心上
- **后台运行**:WiFi 连接在后台持续运行,不受主程序影响
- **更底层控制**:提供更底层的网络控制 API
- **配置方式**:通常需要在代码中手动配置
### 优缺点对比
| 特性 | CircuitPython | MicroPython |
|------|--------------|-------------|
| WiFi 稳定性 | 良好 | 优秀 |
| API 易用性 | 优秀 | 良好 |
| 自动配置 | 部分支持 | 不支持 |
| 资源占用 | 较高 | 较低 |
| 后台运行 | 支持 | 支持 |
## 九、总结
CircuitPython 10.1.3 虽然支持从 `settings.toml` 自动读取 WiFi 连接信息,但**不支持自动读取静态 IP 配置**。因此,必须在 `code.py` 中手动实现 WiFi 连接和静态 IP 设置。
**关键发现**:
- ✅ WiFi 连接会在程序退出后持续保持,无需添加死循环
- ✅ 设备重启时会自动执行 code.py,重新连接 WiFi 并设置静态 IP
- ✅ 静态 IP 设置需要使用正确的参数格式:`ipv4`, `netmask`, `gateway`
**建议**:
- 保持 code.py 简洁,只包含必要的 WiFi 配置代码
- 定期检查 WiFi 连接状态,确保系统正常运行
- 根据实际应用场景选择合适的配置方式
通过本指南的配置方法,您可以确保设备在每次重启后都能自动连接到指定的 WiFi 网络并使用指定的静态 IP 地址,为后续的网络通信和远程调试做好准备。
我在web workflow中运行重启,可以断线重连,不错:
>>> microcontroller.reset()
disconnected
connected
Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.
Press any key to enter the REPL. Use CTRL-D to reload.
Adafruit CircuitPython 10.1.3 on 2026-02-21; VCC-GND YD-ESP32-S3 (N16R8) with ESP32S3
>>>
来自 192.168.1.75 的回复: 字节=32 时间=69ms TTL=64
请求超时。
请求超时。
请求超时。
来自 192.168.1.75 的回复: 字节=32 时间=298ms TTL=64
来自 192.168.1.75 的回复: 字节=32 时间=107ms TTL=64
来自 192.168.1.75 的回复: 字节=32 时间=105ms TTL=64
更多推荐
所有评论(0)