# 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

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐