ESP32-C5双频Wi-Fi 6开发实战:MicroPython固件编译与物联网应用

📅 2026/8/2 16:11:53
ESP32-C5双频Wi-Fi 6开发实战:MicroPython固件编译与物联网应用
1. 从ESP32-C3到C5为什么这颗新芯片值得你关注如果你和我一样玩过不少Seeed Studio的XIAO系列开发板从最初的ESP32-C3到后来的ESP32-S3那么当看到XIAO ESP32-C5这个名字时第一反应可能就是“又来了一个ESP32变种” 但这次还真不一样。ESP32-C5这颗芯片是乐鑫在2023年底正式推出的一个里程碑式产品它最大的特点也是我第一时间入手这块板子的原因就是它首次在单颗芯片上同时集成了2.4GHz和5GHz双频Wi-Fi 6以及蓝牙5.0。这意味着在物联网项目里我们终于有了一款原生支持5GHz Wi-Fi的、性价比极高的微控制器选项。过去如果你想在Arduino或者MicroPython项目里用上5GHz Wi-Fi选择非常有限。要么是树莓派Pico W这类只支持2.4GHz的板子要么就得用上更复杂、功耗更高的Linux单板机。ESP32-C5的出现正好填补了这个空白。Seeed Studio的XIAO系列以其极致的紧凑尺寸大约只有拇指指甲盖大小和丰富的接口而闻名这次把C5芯片做到这个尺寸里可以说是“小身材大能量”的典型代表。板子虽然小但该有的都没少USB-C接口用于供电和编程一排排针脚引出了几乎所有的GPIO、I2C、SPI、UART等常用接口甚至还有一个用户LED和一个可编程的RGB LEDNeoPixel。那么为什么要在MicroPython的环境下玩这块板子呢这就涉及到开发效率的问题。对于物联网原型开发、快速验证想法、或者教育场景MicroPython的“交互式”和“脚本化”特性是无可比拟的。你不需要经历漫长的编译、烧录、重启循环在REPL交互式解释器里敲一行代码立刻就能看到结果。这对于调试传感器、测试网络连接、调整算法逻辑来说效率提升不是一点半点。尤其是当你面对C5这颗支持新协议Wi-Fi 6的芯片时用MicroPython可以让你更专注于网络功能的应用逻辑而不是陷在底层C语言驱动和协议栈的配置细节里。这篇文章我就结合自己把玩XIAO ESP32-C5和MicroPython的实际经历从刷机、联网、到实际项目应用给你捋一遍完整的流程和其中会遇到的各种“坑”。2. 为XIAO ESP32-C5构建专属的MicroPython固件拿到一块新的开发板第一步往往不是直接写代码而是准备“土壤”——也就是固件。对于ESP32-C5这样比较新的芯片乐鑫官方的MicroPython主分支可能还没有完全合并所有支持或者你需要一些特定的功能模块比如更快的Wi-Fi连接、低功耗模式等。因此从源码编译一个量身定制的固件通常是获得最佳体验的第一步。这个过程听起来有点硬核但跟着步骤走一遍其实并不复杂而且能让你对MicroPython的构成有更深的理解。2.1 搭建编译环境Linux子系统是关键首先你需要一个Linux环境。在Windows上最推荐的方式是使用WSL2Windows Subsystem for Linux我使用的是Ubuntu 22.04 LTS发行版。为什么不用虚拟机或者双系统因为WSL2和Windows文件系统的互通性更好后续操作起来更方便。打开Windows Terminal创建一个新的Ubuntu会话然后依次执行以下命令来安装必要的工具链sudo apt update sudo apt install -y git wget flex bison gperf python3 python3-pip python3-setuptools cmake ninja-build ccache libffi-dev libssl-dev dfu-util libusb-1.0-0这里安装的包括Git、Python3、CMake、Ninja更快的构建系统、以及ESP-IDF所需的各种库。其中dfu-util和libusb是为了后续通过USB烧录固件准备的。接下来我们需要获取乐鑫的芯片支持包和工具链。ESP32-C5基于RISC-V架构所以我们需要RISC-V的工具链。乐鑫提供了一个方便的脚本和下载工具mkdir -p ~/esp cd ~/esp git clone -b v5.1.4 --recursive https://github.com/espressif/esp-idf.git cd esp-idf ./install.sh esp32c5执行install.sh时会让你选择安装方式对于MicroPython编译我们通常只需要“最小化”安装即只安装C5所需的工具链和基础库这可以节省大量磁盘空间。安装完成后记住要执行环境变量设置脚本source export.sh或者. ./export.sh。这个操作需要在你每次打开新的终端窗口进行编译前执行。为了方便你可以把source ~/esp/esp-idf/export.sh这行命令加到你的~/.bashrc文件末尾。2.2 获取与配置MicroPython源码环境准备好后就可以拉取MicroPython的源码了。我们直接使用官方仓库的主分支因为它对最新芯片的支持最及时。cd ~ git clone https://github.com/micropython/micropython.git cd micropython git submodule update --init --recursive进入ESP32-C5的特定端口目录cd ports/esp32接下来是关键步骤配置。MicroPython使用make来管理配置。我们需要指定目标板为ESP32-C5。但请注意在MicroPython的端口目录中板型定义可能还没有一个专门的“XIAO_ESP32C5”选项。通常对于一款新芯片我们可以先用其通用板型配置。查看boards/目录你会发现有GENERIC_C5这样的目录。我们可以基于它来编译。编译命令很简单make BOARDGENERIC_C5 clean make BOARDGENERIC_C5make clean是为了确保之前可能存在的编译缓存被清除避免奇怪的问题。第一条命令会清理第二条命令则开始漫长的编译过程。这个过程可能会持续10到30分钟取决于你的电脑性能。编译成功后你会在build-GENERIC_C5/目录下找到我们需要的固件文件firmware.bin。这个文件就是我们要烧录到XIAO ESP32-C5开发板里的MicroPython固件。注意如果你在编译过程中遇到关于“esp_phy_init_data.bin”或类似分区表文件的错误这通常是ESP-IDF版本与MicroPython源码的兼容性问题。一个可行的解决方法是回到~/esp/esp-idf目录检查当前使用的版本。MicroPython的esp32端口通常紧密跟踪ESP-IDF的某个发布版本。你可以尝试切换到ESP-IDF的v5.1.x或v5.2.x的某个稳定标签如git checkout v5.1.4然后重新运行install.sh并source export.sh。编译环境的不匹配是新手在此阶段最常见的绊脚石。3. 烧录固件与首次连接避开那些“坑”有了firmware.bin下一步就是把它放到板子里。XIAO ESP32-C5支持通过USB-C口直接进行串口下载这非常方便。但这里有几个细节如果没做对你可能会对着一个毫无反应的板子发呆半天。3.1 驱动安装与端口识别将XIAO ESP32-C5通过USB-C线连接到电脑。对于Windows用户系统通常会自动安装CH340或CP210x系列的USB转串口驱动Seeed Studio常用这些芯片。你可以在设备管理器的“端口COM和LPT”下查看是否出现了一个新的COM口比如“USB-SERIAL CH340 (COM3)”。如果出现黄色感叹号你需要手动安装驱动可以去Seeed Studio的Wiki页面或芯片厂商如沁恒官网下载。在Linux包括WSL2下情况稍微特殊一点。板子会被识别为/dev/ttyACM0或/dev/ttyUSB0这样的设备。但是WSL2默认并不能直接访问Windows的USB设备。我们需要在Windows端安装一个叫usbipd的工具并将USB设备“附加”到WSL2中。具体步骤如下在Windows上以管理员身份打开PowerShell安装usbipdwinget install --interactive --exact dorssel.usbipd-win在PowerShell中列出USB设备usbipd list。找到你的XIAO板子通常描述里会有“USB Serial”或“CP210x”字样记下它的总线ID。将设备附加到WSL2usbipd attach --wsl --busid 总线ID。例如usbipd attach --wsl --busid 1-2回到WSL2的Ubuntu终端现在你应该能看到/dev/ttyACM0设备了。你需要将当前用户添加到dialout组以获得串口访问权限sudo usermod -a -G dialout $USER。执行此命令后必须完全退出WSL2终端再重新进入用户组变更才会生效。3.2 使用esptool.py进行烧录MicroPython源码目录里自带了一个强大的烧录工具——esptool.py。我们回到编译固件的位置执行烧录命令。在烧录前板子需要进入“下载模式”。对于XIAO ESP32-C5这通常通过快速双击板载的“RST”按钮或标有“BOOT”的按钮来实现。你会看到板载的RGB LED进入慢闪状态表示已准备好。假设我们的串口设备在Linux下是/dev/ttyACM0在Windows下是COM3烧录命令如下# Linux/WSL2 示例 cd ~/micropython/ports/esp32 esptool.py --chip esp32c5 --port /dev/ttyACM0 erase_flash esptool.py --chip esp32c5 --port /dev/ttyACM0 --baud 460800 write_flash -z 0x0 build-GENERIC_C5/firmware.bin# Windows PowerShell 示例 (需在ESP-IDF环境或已安装esptool的环境下运行) esptool.py --chip esp32c5 --port COM3 erase_flash esptool.py --chip esp32c5 --port COM3 --baud 460800 write_flash -z 0x0 firmware.bin命令解释--chip esp32c5 指定芯片型号这很重要不同芯片的通信协议有差异。--port 指定你的串口设备。erase_flash强烈建议先擦除整个Flash特别是从Arduino环境或其他固件切换过来时避免残留数据导致异常。--baud 460800 提高烧录波特率可以显著加快速度。如果连接不稳定可以尝试降低到921600或115200。write_flash -z 0x0 从Flash的0x0偏移地址开始写入固件。烧录过程中终端会有进度条显示。成功后按一下板子的“RST”按钮重启。此时MicroPython固件就开始运行了。3.3 连接REPL你的第一个交互窗口固件运行后我们需要一个终端工具连接到板子的REPL。推荐使用picocomLinux或PuTTY、Arduino IDE的串口监视器Windows。以picocom为例picocom -b 115200 /dev/ttyACM0连接成功后按一下回车键你应该会看到MicroPython的提示符。恭喜你已经成功进入了MicroPython的世界你可以尝试输入一些简单的命令比如print(“Hello, XIAO C5!”)或者import machine来测试。如果看到输出说明一切正常。实操心得烧录后第一次连接REPL如果没有任何反应或者输出乱码请按以下顺序排查1) 确认串口号是否正确2) 确认波特率是否为1152003) 确认板子是否已重启按RST键4) 检查USB线是否只供电而无数据功能换条线试试5) 在WSL2下确认是否已正确执行usbipd attach且未超时断开。最稳妥的方法是在Windows下用PuTTY等工具先测试连通性排除WSL2配置的问题。4. 点亮双频Wi-Fi连接5GHz网络实战让ESP32-C5连接Wi-Fi是检验其核心特性的第一步。MicroPython提供了network模块来管理网络连接使用起来非常直观。但连接5GHz网络时有一个小细节需要注意。4.1 基础连接代码与网络扫描我们先写一个简单的脚本并将其保存到板子的文件系统中。在REPL中我们可以直接输入多行代码但更常用的方式是使用文件工具。我们可以用ampyAdafruit MicroPython Tool这个Python库来管理文件。首先在电脑上安装pip install adafruit-ampy。然后创建一个名为boot.py或main.py的文件boot.py会在每次启动时自动运行。我们创建一个wifi_connect.py用于测试# wifi_connect.py import network import time # 创建WLAN接口对象STA模式表示作为客户端连接路由器 wlan network.WLAN(network.STA_IF) wlan.active(True) # 激活接口 # 扫描附近的Wi-Fi网络 print(Scanning for networks...) scan_results wlan.scan() for network_info in scan_results: ssid network_info[0].decode(utf-8) # SSID是字节串需要解码 bssid network_info[1].hex() # MAC地址 channel network_info[2] rssi network_info[3] authmode network_info[4] hidden network_info[5] # 特别标注5GHz网络通常信道大于36 band 5GHz if channel 36 else 2.4GHz print(fSSID: {ssid:20} BSSID: {bssid} Channel: {channel:3} ({band}) RSSI: {rssi:4} dBm)使用ampy将这个脚本发送到板子并运行ampy --port /dev/ttyACM0 put wifi_connect.py ampy --port /dev/ttyACM0 run wifi_connect.py在输出中你应该能看到你周围的Wi-Fi网络列表并且能根据信道区分出2.4GHz和5GHz网络。这是验证C5射频功能正常的好方法。4.2 连接5GHz网络的核心参数配置接下来是连接。连接5GHz网络与2.4GHz在代码上几乎一样但确保你的路由器5GHz网络没有启用“隐藏SSID”并且最好使用WPA2-PSKAES加密方式这是兼容性最广的。# 继续在wifi_connect.py中追加或新建一个连接函数 def connect_to_wifi(ssid, password): if not wlan.isconnected(): print(f‘Connecting to {ssid}...’) wlan.connect(ssid, password) # 等待连接最多10秒 max_wait 10 while max_wait 0: if wlan.isconnected(): break max_wait - 1 print(‘Waiting for connection...’) time.sleep(1) if wlan.isconnected(): print(‘Network connected!’) status wlan.ifconfig() print(‘IP address:’, status[0]) print(‘Subnet mask:’, status[1]) print(‘Gateway:’, status[2]) print(‘DNS server:’, status[3]) return True else: print(‘Connection failed.’) return False # 替换为你的5GHz网络信息 connect_to_wifi(‘Your_5GHz_SSID‘, ’Your_Password‘)将上述代码合并到文件中再次运行。如果一切顺利你会看到获取到的IP地址信息。这里有个关键点wlan.connect()是一个非阻塞调用它发起连接后就返回了所以我们需要一个循环来等待连接成功。等待时间不宜过短因为5GHz网络的协商可能比2.4GHz稍慢一点。4.3 处理连接失败与稳定性优化连接失败怎么办首先检查密码是否正确。其次在REPL中检查是否有更详细的错误信息可以尝试wlan.status()来获取状态码。常见的状态码有1000: STAT_IDLE 未连接。1001: STAT_CONNECTING 正在连接。1010: STAT_GOT_IP 已连接并获取到IP成功。其他如202,203等通常表示密码错误或网络未找到。为了提高连接稳定性特别是在信号边缘区域可以加入重连逻辑和信号强度检查import network import time import machine def connect_with_retry(ssid, password, retries5): wlan network.WLAN(network.STA_IF) wlan.active(True) for attempt in range(retries): if not wlan.isconnected(): print(f‘Attempt {attempt1}/{retries} to connect...’) wlan.connect(ssid, password) for _ in range(15): # 等待15秒 if wlan.isconnected(): break time.sleep(1) if wlan.isconnected(): print(f‘Connected on attempt {attempt1}’) print(‘IP:’, wlan.ifconfig()[0]) # 连接成功后可以进入深度睡眠或执行主任务 return True else: print(‘Failed. Will retry...’) time.sleep(3) # 失败后等待3秒再试 print(‘Max retries reached. Connection failed.’) # 可以选择重启或进入深度睡眠 # machine.deepsleep(10000) # 睡眠10秒 return False # 在boot.py中调用实现上电自动连接 connect_with_retry(‘Your_5GHz_SSID‘, ’Your_Password‘)注意事项在实际部署中将SSID和密码硬编码在代码中是不安全的。一种常见的做法是在首次启动时让设备进入“配网模式”如开启一个AP热点通过网页或手机App配置网络信息然后将这些信息保存到板载的Flash文件系统如network.json中。后续启动时从文件读取配置进行连接。这涉及到更复杂的Web服务器或蓝牙配网逻辑是产品化项目中必备的一环。5. 深度探索MicroPython下的外设驱动与低功耗实践连接网络只是开始XIAO ESP32-C5的GPIO、ADC、I2C、SPI等外设才是与物理世界交互的桥梁。同时作为物联网设备功耗管理至关重要。我们来看看在MicroPython下如何操作。5.1 GPIO控制与中断从点亮LED到响应按键控制板载的LED是最简单的开始。XIAO ESP32-C5的用户LED通常连接在一个固定的GPIO上需要查看原理图假设是GPIO2而RGB LED则通常通过一个GPIO控制WS2812B灯珠。import machine import neopixel import time # 控制单色用户LED (假设接在GPIO2) led_pin machine.Pin(2, machine.Pin.OUT) led_pin.value(1) # 点亮 0为熄灭 # 控制板载RGB LED (假设数据线接在GPIO8 只有1颗灯珠) np neopixel.NeoPixel(machine.Pin(8), 1) np[0] (255, 0, 0) # 设置为红色 (R, G, B) np.write() # 写入数据才能生效 time.sleep(1) np[0] (0, 255, 0) # 绿色 np.write()GPIO中断对于检测按键、传感器信号边沿非常有用。下面是一个按键消抖的中断示例import machine import time button_pin machine.Pin(3, machine.Pin.IN, machine.Pin.PULL_UP) # 假设按键接GPIO3 内部上拉 debounce_time 0 last_press_time 0 def button_handler(pin): global last_press_time current_time time.ticks_ms() # 消抖处理忽略200毫秒内的连续触发 if time.ticks_diff(current_time, last_press_time) 200: last_press_time current_time print(‘Button pressed! Pin state:’, pin.value()) # 按下通常是低电平0 # 配置中断下降沿触发按键按下从高电平到低电平 button_pin.irq(triggermachine.Pin.IRQ_FALLING, handlerbutton_handler) print(‘Waiting for button press...’) while True: time.sleep(1) # 主循环可以执行其他任务5.2 I2C与SPI通信连接传感器与屏幕XIAO的排针引出了I2C和SPI接口使得连接各种传感器模块温湿度、气压、光强和显示模块OLED变得非常容易。I2C扫描与读取传感器以BMP280气压传感器为例import machine import time from machine import I2C, Pin import bmp280 # 假设你已经将bmp280.py库上传到板子 # 初始化I2C 引脚根据XIAO的引脚定义通常SDAGPIO4 SCLGPIO5 i2c I2C(0, sclPin(5), sdaPin(4), freq400000) # I2C总线0 速率400kHz # 扫描I2C总线上的设备 devices i2c.scan() if devices: for d in devices: print(‘Found I2C device at address: 0x{:02X}’.format(d)) else: print(‘No I2C devices found’) # 初始化BMP280传感器 sensor bmp280.BMP280(i2c) while True: temp sensor.temperature pressure sensor.pressure print(‘Temperature: {:.2f} C’.format(temp)) print(‘Pressure: {:.2f} hPa’.format(pressure/100)) # 转换为百帕 time.sleep(2)SPI驱动OLED屏幕以SSD1306为例import machine import time from machine import Pin, SPI import ssd1306 # 需要ssd1306.py库 # 初始化SPI XIAO ESP32-C5的SPI引脚需要查手册确认以下为示例 spi SPI(1, baudrate10000000, polarity0, phase0, sckPin(10), mosiPin(11), misoPin(12)) # HSPI dc_pin Pin(9, Pin.OUT) # 数据/命令选择引脚 res_pin Pin(8, Pin.OUT) # 复位引脚 cs_pin Pin(7, Pin.OUT) # 片选引脚如果模块有 # 初始化OLED (128x64) oled ssd1306.SSD1306_SPI(128, 64, spi, dc_pin, res_pin, cs_pin) # 清屏并显示文字 oled.fill(0) # 清屏0为黑色1为亮 oled.text(‘Hello XIAO C5!’, 0, 0, 1) oled.text(‘Wi-Fi 6 Ready’, 0, 16, 1) oled.show()经验技巧MicroPython的I2C和SPI驱动有时会遇到时序问题。如果传感器读不出数据或屏幕不亮首先检查1) 引脚定义是否正确2) 电源是否接好3.3V3) 上拉电阻是否需要I2C总线通常需要4.7kΩ上拉电阻但很多模块已集成4) 尝试降低通信频率如I2C从400kHz降到100kHz。对于没有现成MicroPython库的传感器你需要根据其数据手册使用i2c.readfrom()和i2c.writeto()函数来手动实现读写协议这是一个很好的学习过程。5.3 低功耗模式初探让设备跑得更久物联网设备很多是电池供电低功耗设计是必修课。ESP32-C5支持多种低功耗模式在MicroPython中最常用的是lightsleep浅睡眠和deepsleep深度睡眠。深度睡眠 (Deep Sleep)在此模式下CPU、大部分RAM和所有外设都会断电仅由RTC实时时钟模块维持极低功耗的运行。设备只能通过特定的唤醒源如定时器、外部引脚唤醒唤醒后程序从头开始执行相当于复位。这是最省电的模式。import machine import time # 配置唤醒源使用RTC定时器单位微秒 (10秒后唤醒) rtc machine.RTC() sleep_time_ms 10 * 1000 # 10秒 rtc.irq(triggerrtc.ALARM0, wakemachine.DEEPSLEEP) rtc.alarm(rtc.ALARM0, sleep_time_ms) print(‘Going into deep sleep for 10 seconds...’) time.sleep(0.1) # 给串口一点时间输出信息 machine.deepsleep() # 进入深度睡眠 # 此行之后的代码在唤醒前不会执行浅睡眠 (Light Sleep)CPU暂停但RAM和部分外设保持供电网络连接可能断开取决于配置。唤醒速度比深度睡眠快功耗介于运行和深度睡眠之间。在MicroPython中可以通过machine.lightsleep()函数进入但唤醒源配置相对复杂通常需要结合网络事件或引脚中断。一个实用的低功耗场景是传感器每5分钟采集一次数据并通过Wi-Fi上传。那么工作流程可以是上电 - 连接Wi-Fi - 读取传感器 - 发送数据 - 进入深度睡眠5分钟 - 被定时器唤醒 - 重复。这样设备99%的时间都在深度睡眠中功耗可以低至10微安级别两节AA电池可以工作数月甚至数年。避坑指南深度睡眠时GPIO的状态会丢失。如果你需要某个GPIO在睡眠期间保持高电平或低电平例如控制一个MOSFET开关你需要使用具有“锁存”或“保持”功能的GPIO或者外接一个锁存电路。此外深度睡眠后唤醒所有变量都会丢失。如果你需要保存一些状态比如传感器数据的序列号必须将其存入RTC内存rtc.memory()或Flash文件系统中。另外注意machine.deepsleep()不会返回设备直接进入睡眠。所以任何想在睡眠前执行的清理工作如断开网络、关闭外设电源都必须在这条语句之前完成。6. 项目实战构建一个5GHz Wi-Fi环境监测器理论说得再多不如动手做一个项目。我们来整合前面学到的知识构建一个简单的环境监测器它通过5GHz Wi-Fi将温湿度和气压数据定时发送到网络服务器这里以HTTP POST到一个测试接口为例。6.1 硬件连接与项目规划所需材料Seeed Studio XIAO ESP32-C5 开发板BME280传感器模块集成温湿度气压I2C接口面包板和杜邦线若干连接方式BME280的VCC - XIAO的3.3VBME280的GND - XIAO的GNDBME280的SCL - XIAO的GPIO5 (I2C SCL)BME280的SDA - XIAO的GPIO4 (I2C SDA)项目逻辑设备上电从文件系统读取Wi-Fi配置。连接5GHz Wi-Fi网络。初始化BME280传感器。进入主循环读取传感器数据 - 封装为JSON格式 - 通过HTTP POST发送到服务器 - 打印结果到REPL - 进入深度睡眠10分钟 - 被定时器唤醒重复步骤4。6.2 代码实现整合网络、传感器与低功耗首先我们需要将BME280的MicroPython驱动库bme280.py上传到板子。然后创建主程序文件main.py。# main.py import network import machine import time import json import urequests as requests from machine import I2C, Pin, RTC import bme280 # 确保bme280.py已上传 import uos # 1. 读取Wi-Fi配置简化版实际应用建议用配网 def load_config(): # 尝试从config.json文件读取配置 try: with open(‘/config.json’, ‘r’) as f: config json.loads(f.read()) return config.get(‘ssid’, ‘’), config.get(‘password’, ‘’) except: # 如果文件不存在返回硬编码的配置仅用于测试 print(‘Config file not found, using hardcoded config.’) return ‘Your_5GHz_SSID‘, ’Your_Password‘ # 2. Wi-Fi连接函数带重试 def connect_wifi(ssid, password): wlan network.WLAN(network.STA_IF) wlan.active(True) if not wlan.isconnected(): print(‘Connecting to Wi-Fi...’) wlan.connect(ssid, password) for _ in range(20): # 最多等待20秒 if wlan.isconnected(): break time.sleep(1) if wlan.isconnected(): print(‘Wi-Fi connected! IP:’, wlan.ifconfig()[0]) return True else: print(‘Wi-Fi connection failed!’) return False # 3. 传感器数据读取 def read_sensor_data(): # 初始化I2C和BME280 i2c I2C(0, sclPin(5), sdaPin(4), freq100000) sensor bme280.BME280(i2ci2c) # 读取数据BME280库通常返回字符串 temp, press, hum sensor.values # 转换为浮点数并简单处理单位 temperature float(temp[:-1]) # 去掉末尾的’C‘ pressure float(press[:-3]) # 去掉末尾的’hPa‘ 假设单位是百帕 humidity float(hum[:-1]) # 去掉末尾的’%‘ return {‘temperature’: temperature, ‘pressure’: pressure, ‘humidity’: humidity} # 4. 数据上传函数 def upload_data(data_dict, server_url): try: # 将字典转换为JSON字符串 json_data json.dumps(data_dict) headers {‘Content-Type’: ‘application/json’} # 发送HTTP POST请求 response requests.post(server_url, datajson_data, headersheaders) print(‘Upload Response:’, response.status_code, response.text) response.close() # 重要关闭响应释放资源 return response.status_code 200 except Exception as e: print(‘Upload failed:’, e) return False # 5. 主程序 def main(): print(‘ XIAO ESP32-C5 Environmental Monitor ’) # 加载配置并连接Wi-Fi ssid, password load_config() if not connect_wifi(ssid, password): # 连接失败可能进入深度睡眠一段时间再试 print(‘Wi-Fi failed. Sleeping for 1 minute.’) rtc machine.RTC() rtc.irq(triggerrtc.ALARM0, wakemachine.DEEPSLEEP) rtc.alarm(rtc.ALARM0, 60 * 1000) # 1分钟 machine.deepsleep() return # 深度睡眠后程序重启会再次执行 # 读取传感器数据 print(‘Reading sensor data...’) sensor_data read_sensor_data() print(‘Data:’, sensor_data) # 上传数据替换为你的服务器URL server_url ‘http://your-server.com/api/sensor-data‘ upload_success upload_data(sensor_data, server_url) if upload_success: print(‘Data uploaded successfully.’) else: print(‘Data upload failed.’) # 任务完成进入深度睡眠10分钟 print(‘Going into deep sleep for 10 minutes...’) sleep_duration_minutes 10 rtc machine.RTC() rtc.irq(triggerrtc.ALARM0, wakemachine.DEEPSLEEP) rtc.alarm(rtc.ALARM0, sleep_duration_minutes * 60 * 1000) # 转换为毫秒 # 可选关闭Wi-Fi以节省最后一点功耗虽然深度睡眠会断掉 network.WLAN(network.STA_IF).active(False) time.sleep(0.1) # 等待一下 machine.deepsleep() # 程序入口 if __name__ ‘__main__’: main()6.3 部署、测试与优化将上述代码保存为main.py连同bme280.py库文件使用ampy上传到板子ampy --port /dev/ttyACM0 put bme280.py ampy --port /dev/ttyACM0 put main.py上传完成后按一下板子的RST键重启。你会看到程序开始运行尝试连接Wi-Fi读取传感器数据并尝试上传。由于我们没有真实的服务器URL上传会失败但你可以观察REPL中的打印信息确认传感器读取和网络连接部分是否正常。优化方向增加配网功能如前所述硬编码Wi-Fi密码不安全也不灵活。可以实现一个“SmartConfig”或“蓝牙配网”功能让设备在首次启动时进入配网模式。数据缓存与重传在网络不佳时上传可能失败。可以将数据暂存到Flash文件系统中等网络恢复后重传。功耗精细管理在进入深度睡眠前确保所有外设如I2C传感器都处于最低功耗状态。有些传感器有睡眠模式命令。使用MQTT替代HTTP对于频繁上报的物联网数据MQTT协议比HTTP更轻量、更高效。MicroPython有umqtt.simple库可以使用。电源管理如果使用电池供电需要监测电池电压。XIAO ESP32-C5的某个ADC引脚可以通过分压电阻连接电池在代码中定期检测电压在电压过低时上报报警信息。这个项目虽然简单但涵盖了从硬件连接到网络通信再到低功耗管理的物联网核心环节。通过修改传感器类型、上报频率和服务器逻辑你可以将其改造成土壤湿度监测器、空气质量检测站甚至是远程控制开关。XIAO ESP32-C5的双频Wi-Fi能力尤其适合部署在2.4GHz频段拥挤如智能家居设备众多但5GHz信号良好的环境中能提供更稳定、延迟更低的数据连接。