用 Python 把一块 20 块钱的无线模块“喂”给云

举报
i-WIFI 发表于 2025/10/27 11:11:25 2025/10/27
【摘要】 一、为什么又是 ESP8266?我手头的项目需要一个「低功耗 + 能发 HTTPS + 成本别超过一顿外卖」的终端节点。ESP32-C3 功耗更香,但淘宝现货贵 8 块;LoRa 模组距离炸裂,却只能点对点。思来想去,还是老朋友 ESP8266 最对胃口:价格:¥19.8(包邮,带天线)Flash:4 MB,够用社区:十年沉淀,踩坑贴比 Stack Overflow 还多唯一不爽的是原厂 ...

一、为什么又是 ESP8266?

我手头的项目需要一个「低功耗 + 能发 HTTPS + 成本别超过一顿外卖」的终端节点。ESP32-C3 功耗更香,但淘宝现货贵 8 块;LoRa 模组距离炸裂,却只能点对点。思来想去,还是老朋友 ESP8266 最对胃口:

  • 价格:¥19.8(包邮,带天线)
  • Flash:4 MB,够用
  • 社区:十年沉淀,踩坑贴比 Stack Overflow 还多

唯一不爽的是原厂 AT 固件不支持 TLS 1.2,而甲方爸爸强制 HTTPS。于是我决定自己刷 MicroPython,顺便把云端对接彻底打通。


二、Python 库选型:少即是多

在 PC 端,我的需求只有三件事:串口烧录、批量 OTA、云端日志拉取。调研了一圈,最终留下 3 个库,其他全部踢出 requirements.txt

库名 版本 作用简述 坑点记录
esptool 4.7 一键擦除+烧录固件 在 macOS 14 需关闭 SIP 才能访问串口
mpremote 1.22 REPL + 文件同步,比 ampy 稳 首次连接需手动 soft-reset
minio 7.2 私有 S3 对象存储,当 OTA 服务器 记得把 part_size 调到 5 MB,否则上传大固件会 400

小贴士:不要装所谓「一键物联网套件」。它们往往包裹了 20 多个依赖,半年后你再看 pip list,已经找不到北。


三、无线模块固件裁剪:省 200 KB,多跑 3 天

MicroPython 官方固件 1.22 默认把 urequestsuasyncio 全塞进去,8266 内存瞬间吃紧。我按 80/20 法则做了裁剪,最终固件 590 KB,空闲 RAM 还剩 46 KB,足够跑主循环 + TLS。

裁剪步骤:

  1. 克隆源码:git clone --depth=1 https://github.com/micropython/micropython.git
  2. 修改 ports/esp8266/boards/manifest.py,把不用的库注释掉
  3. make USER_C_MODULES=../../examples/usercmodule 编译
  4. 用 esptool 烧录,一气呵成

四、与云服务的握手:自建还是托管?

起初我准备直接上阿里云 IoT 套娃,但一想到要“产品-设备-三元组”三级跳就头大。于是退而求其次:

  • 终端 HTTPS POST 到云函数 → 云函数写 Kafka → ClickHouse 持久化
  • 控制指令走 MQTT over TLS,双向证书校验,杜绝中间人

架构图如下(ASCII 手绘,凑合看):

+----------+      +------------+      +------------+
| ESP8266  |----->| Cloud Func |----->| ClickHouse |
|  NodeMCU |<-----|  (Python)  |<-----|   Broker   |
+----------+      +------------+      +------------+

五、代码片段:最简洁的 HTTPS POST

import urequests, ujson, machine

URL = "https://iot.example.com/upload"
def upload(data):
    try:
        r = urequests.post(URL,
                           data=ujson.dumps(data),
                           headers={'Content-Type': 'application/json'})
        print('status:', r.status_code)
        r.close()
    except OSError as e:
        print("net fail:", e)
        machine.reset()

真·一行多余都没有。8266 的 SSL 证书我直接烧进 cert/cert.der,省得运行时握手再跑 TLS 解析。


六、OTA 全流程:从 Kafka 到 Flash

步骤 触发条件 关键命令/代码片段 耗时
1 CI 推送新固件 mc cp firmware.bin myminio/ota/ 3 s
2 云函数下发通知 MQTT topic: /ota/<chip_id> <1 s
3 终端拉取固件 urequests.get("https://.../firmware.bin") 8 s
4 校验 SHA256 hashlib.sha256(data).hexdigest() 1 s
5 写 Flash & 重启 esp.check_fw() + machine.reset() 2 s

最难调的是第 3 步:如果一口气读 512 KB,8266 直接 OOM。我改成 4 KB 流式写入,边下载边刷 Flash,才算稳定。


七、功耗实测:数字不会骗人

把板子丢进老化房,3.7 V 锂电 → MCP1700 LDO → 整机,测得:

模式 平均电流 占空比 续航估算 (1000 mAh)
DeepSleep 0.18 mA 95 % 约 231 天
唤醒+发数据 82 mA 5 %

嗯,三个月换一次电池,客户勉强能接受。


八、踩坑杂烩(排名不分先后)

  1. MicroPython 的 ussl 模块居然不支持 SNI,得打补丁 ussl.wrap_socket(..., server_hostname=host)
  2. 阿里云函数 Python 3.9 默认时区是 UTC,我日志时间全部错位 8 小时,调了半天。
  3. 用 macOS 14 的自带 screen 进 REPL 会乱码,改用 mpremoteconnect 子命令。
  4. ESP8266 的 Pin(16) 只能做 OUT,不能 IN,别问我是怎么知道的……

九、结语

折腾到凌晨四点的意义,大概就是第二天早上甲方群里的一句「测试通过」。
源码我放 Gitee 了,仓库名 esp8266-minimal-cloud,欢迎拍砖。如果你也在用 20 块钱的模块干着 200 块钱的事,留言聊聊你的故事吧。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。