测温应用(AM2302)

ESP32-C6 单总线温湿度节点 → 40 字节定长帧 → 屏幕实时显示 · 源码与应用同源
版本 v0.1.0 · 2026-09-22 应用包:thermo-display-v0.1.0.zip sha256 6ee15679…fc194e(E官网组包版)

⬇️ 下载应用包(17.1 KB) 查看源码

下载后解压即可运行;包内含源码、使用说明与一键启动脚本,无需安装本仓库其他部分。

1 · 它是什么 / 能做什么 / 不能做什么

能做什么

不能做什么(先说清楚)

典型拓扑:
AM2302 --单总线--> ESP32-C6 --USB(UART0, 40B 帧)--> 电脑 / 树莓派 --HDMI--> 7" 屏
                                                       └--MQTT--> broker(可选)

2 · 应用包内容(逐文件)

文件大小作用
thermo_display.py42090 B应用本体(与仓库同一份,无副本分支)
README.md3161 B使用说明(离线可读,不依赖网络)
run_windows.bat181 BWindows 双击即跑(默认 COM4 / AM2302)
run_linux.sh188 BLinux/macOS 启动脚本,./run_linux.sh /dev/ttyACM0
MANIFEST.json734 B逐文件 sha256,供第三方复核包内容
可复核:整包 sha256 = 6ee15679eb8642b60d08f2b3d0512ca258e85a5fd421896cd4251a87defc194e(E 官网 0922 组包版,17124 字节;包内 thermo_display.py 与仓库 42c7838 版逐字节相同,差异仅 README/启动脚本,见包内 MANIFEST)。上游确定性打包器 tools/thermo_app_pack.py(产物 19031B/sha 1e66cc75…)随 commit 5deacc2 待推送,推送后本站重跑官方打包器对账换包。 打包是确定性的(zip 内时间戳固定),所以同一份源码每次打出来的 sha256 完全相同 —— 任何人都可以用 tools/thermo_app_pack.py 重现这个值,用来确认「官网这份」与「仓库这份」是同一物。

3 · 源码清单

应用不是孤立的一个脚本,它依赖一份帧协议定义与一个固件。全部在 mos/bootstrap 分支:

角色路径说明
上位机应用tools/thermo_display.py 帧解析 + 界面 + MQTT 上行。本文的主角
协议规范firmware/frame-spec.md 40 字节定长帧的字段偏移表与 CRC32 参数。协议 = 字节序列定义,不是 C 结构体内存布局
节点固件firmware/esp_thermo/main/thermo_tx.c C6 + AM2302:RMT 硬件捕获脉宽 → 5 字节 → 40 字节帧 → UART0
S3 帧源固件firmware/esp_frame_tx/main/frame_tx.c S3 + MPU6050:E 发射产物解码六轴 → 40 字节帧
帧打包/解包firmware/meos_frame.c / .h 大端 + CRC32;两块板共用同一份,不复制副本
应用打包器tools/thermo_app_pack.py 产出上述应用包,确定性 zip
采集/桥接tools/serial_capture.py · serial_frame_bridge.py 抓原始串口 / 收帧存盘喂 Gateway

获取方式:

git clone http://gitlab.ptteng.com/openclaw-bot/elang-eos.git
cd elang-eos && git checkout mos/bootstrap

4 · 使用方式(快速开始)

第 0 步 · 确认依赖

python -c "import serial; print(serial.__version__)"
# 报 ModuleNotFoundError 就装:
pip install pyserial

界面(--ui tk)还需要 tkinter, Windows 官方 Python 安装包自带。只用 --ui none 则不需要。

第 1 步 · 插上板子,确认串口号

Windows:设备管理器 → 端口(COM 和 LPT)。C6 通常是 COM4,S3 通常是 COM3。

第 2 步 · 跑起来

# Windows(或直接双击 run_windows.bat)
python thermo_display.py --port COM4 --node am2302 --ui tk

# 接 S3 / MPU6050
python thermo_display.py --port COM3 --node mpu6050 --ui tk

# 无显示器,只在终端看(排障用)
python thermo_display.py --port COM4 --node am2302 --ui none --seconds 10

5 · 参数表

参数默认说明
--portauto串口,或 auto 自动查找
--nodeam2302 am2302=C6 温湿度;mpu6050=S3,只有温度
--baud115200与固件 UART0 一致,一般不用改
--uitktk=窗口;none=只打印终端
--geom无 窗口区域,如 1024x600+1920+0。缩放按这个区域算,不按整个桌面算。 写错会在碰 Tk 之前就被拒(rc=2),不会伪装成"没装 tkinter"
--kiosk关 与 --geom 合用:去标题栏 + 置顶,正好铺满该区域。 面板屏上必须加,否则最下面两条会被任务栏压住。退出按 Esc
--ui-smoke关界面自检:不弹窗,断言屏上会画什么(离线可跑)
--mqtt无MQTT broker 主机(需 pip install paho-mqtt)
--t-max / --t-min3500 / 1000温度上下限(单位 c100,即 35.00℃ / 10.00℃),超限高亮
--h-max / --h-min6000 / 2000湿度上下限(c100)
--seconds0跑 N 秒后收尾并打印统计;0=一直跑
--selftest—离线自检,不接硬件

6 · 四种运行场景

A · 用开发机自己的屏幕(最省事)

python thermo_display.py --port COM4 --node am2302 --ui tk

B · 接成第二块屏(7″ 1024×600,不占主屏)

python thermo_display.py --port COM4 --node am2302 --ui tk --geom 1024x600+1920+0 --kiosk

把 +1920+0 换成你副屏的实际位置。 7″ 屏是 HDMI 输入,由电脑/树莓派驱动,不接 ESP32。

C · 无显示器(只在终端,排障首选)

python thermo_display.py --port COM4 --node am2302 --ui none --seconds 10

不依赖 tkinter,也不需要 X/桌面环境。

D · 上行到 MQTT

python thermo_display.py --port /dev/ttyACM0 --mqtt 192.168.1.10

7 · 不接硬件也能验:自检

python thermo_display.py --selftest
python thermo_display.py --ui-smoke

期望结尾打印全部通过并返回 0。自检覆盖两层:

7.1 协议解析层

7.2 界面排版层(这一层是补出来的)

曾经出过一次事故:屏上两个大数字互相重叠(温度压到湿度栏)。 当时自检是全绿的 —— 因为它只断言「画了哪些文字」, 内容一字不差、位置全错时照样通过。判据没覆盖真正坏掉的那一维。

现在补了三类几何断言,全部用纯函数实现,不依赖 tkinter:

负向对照已验证有效:把旧写法灌回一份副本,自检当场报出 31.40 °C 与 51.2 %RH 重叠、右边界 1191 > 1024,rc=1。 一个判据如果从没被验证过「能失败」,就等于没有判据。

8 · 退出码与 NO DATA

退出码含义怎么理解
0收到帧且无 CRC 错成功
1有 CRC 错链路有噪声 / 波特率不符 / 接线问题
2参数错(如 --geom 写错)改参数重跑
3一帧都没收到 未执行,不算成功。串口没开对 / 板子没发帧 / 器件没接 —— 三种都要查
屏幕上出现 NO DATA 是设计行为,不是 bug。 超过 STALE_S = 6 秒没有有效帧,界面会把大数字变灰并显示 NO DATA。 它不保留旧值假装还在更新 —— 因为「看起来还在跳」比「明说没数据」危险得多。

9 · 数据来源的诚实声明

固件与界面都会声明这一帧的数据从哪来:

标记含义能当证据用吗
AM2302_LIVE温度/湿度取自真实 AM2302 能。这是「器件读通」的唯一标记
MPU6050_LIVE六轴/温度取自真实 MPU6050 能,但仅限该器件;湿度字段恒为 0 且标注为「无来源」
SYNTH器件没应答,用的是合成值 不能。只能证明「链路通」,不能证明「传感器能用」
「没有来源」与「测得 0」必须分开显示。 MPU6050 没有湿度传感器,界面上湿度显示为 —,而不是 0.0。 把「无源」画成 0 会让人以为真的测到了 0 —— 本仓在这个坑上吃过亏, 所以这条是硬要求。

10 · 已知边界与限制

11 · 常见问题

现象原因处置
ModuleNotFoundError: serial 没装 pyserial,或用的解释器不对 pip install pyserial;确认跑的是你装包的那个 python
ModuleNotFoundError: tkinter 该 Python 没带 Tk 改用 --ui none,或换一个带 tkinter 的 Python
一直 NO DATA / rc=3 串口不对 / 板子没发帧 / 器件没接 先用 tools/serial_capture.py COM4 10 看板子到底在说什么; 没有 #thermo 行就说明固件根本没发帧
rc=1(有 CRC 错) 波特率不符 / 线太长 / 没共地 / 没上拉 核对 --baud 115200、共地、补上拉
界面铺不满屏 / 底下两条被挡住 没加 --kiosk,或 --geom 尺寸给了整屏 加 --kiosk;--geom 用副屏的区域尺寸
数字互相重叠 排版问题(不是编码问题) 跑 --selftest,几何判据会指出越界/相交的具体项
相关页面:《MOS 端到端操作手册 · 从 S3/C6 到上位机 APP》、 《MOS 硬件接线指导》。
本页所有版本号、sha256、文件大小均取自 2026-09-22 的实际产物, 可用仓库内 tools/thermo_app_pack.py 重现。