下载后解压即可运行;包内含源码、使用说明与一键启动脚本,无需安装本仓库其他部分。
--mqtt)。…_LIVE / SYNTH)来自固件,应用只如实显示。AM2302 --单总线--> ESP32-C6 --USB(UART0, 40B 帧)--> 电脑 / 树莓派 --HDMI--> 7" 屏
└--MQTT--> broker(可选)
| 文件 | 大小 | 作用 |
|---|---|---|
| thermo_display.py | 42090 B | 应用本体(与仓库同一份,无副本分支) |
| README.md | 3161 B | 使用说明(离线可读,不依赖网络) |
| run_windows.bat | 181 B | Windows 双击即跑(默认 COM4 / AM2302) |
| run_linux.sh | 188 B | Linux/macOS 启动脚本,./run_linux.sh /dev/ttyACM0 |
| MANIFEST.json | 734 B | 逐文件 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 重现这个值,用来确认「官网这份」与「仓库这份」是同一物。
应用不是孤立的一个脚本,它依赖一份帧协议定义与一个固件。全部在
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
python -c "import serial; print(serial.__version__)"
# 报 ModuleNotFoundError 就装:
pip install pyserial
界面(--ui tk)还需要 tkinter,
Windows 官方 Python 安装包自带。只用 --ui none 则不需要。
Windows:设备管理器 → 端口(COM 和 LPT)。C6 通常是 COM4,S3 通常是 COM3。
# 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
| 参数 | 默认 | 说明 |
|---|---|---|
| --port | auto | 串口,或 auto 自动查找 |
| --node | am2302 | am2302=C6 温湿度;mpu6050=S3,只有温度 |
| --baud | 115200 | 与固件 UART0 一致,一般不用改 |
| --ui | tk | tk=窗口;none=只打印终端 |
| --geom | 无 | 窗口区域,如 1024x600+1920+0。缩放按这个区域算,不按整个桌面算。
写错会在碰 Tk 之前就被拒(rc=2),不会伪装成"没装 tkinter" |
| --kiosk | 关 | 与 --geom 合用:去标题栏 + 置顶,正好铺满该区域。
面板屏上必须加,否则最下面两条会被任务栏压住。退出按 Esc |
| --ui-smoke | 关 | 界面自检:不弹窗,断言屏上会画什么(离线可跑) |
| --mqtt | 无 | MQTT broker 主机(需 pip install paho-mqtt) |
| --t-max / --t-min | 3500 / 1000 | 温度上下限(单位 c100,即 35.00℃ / 10.00℃),超限高亮 |
| --h-max / --h-min | 6000 / 2000 | 湿度上下限(c100) |
| --seconds | 0 | 跑 N 秒后收尾并打印统计;0=一直跑 |
| --selftest | — | 离线自检,不接硬件 |
python thermo_display.py --port COM4 --node am2302 --ui tk
python thermo_display.py --port COM4 --node am2302 --ui tk --geom 1024x600+1920+0 --kiosk
把 +1920+0 换成你副屏的实际位置。
7″ 屏是 HDMI 输入,由电脑/树莓派驱动,不接 ESP32。
python thermo_display.py --port COM4 --node am2302 --ui none --seconds 10
不依赖 tkinter,也不需要 X/桌面环境。
python thermo_display.py --port /dev/ttyACM0 --mqtt 192.168.1.10
python thermo_display.py --selftest
python thermo_display.py --ui-smoke
期望结尾打印全部通过并返回 0。自检覆盖两层:
曾经出过一次事故:屏上两个大数字互相重叠(温度压到湿度栏)。 当时自检是全绿的 —— 因为它只断言「画了哪些文字」, 内容一字不差、位置全错时照样通过。判据没覆盖真正坏掉的那一维。
现在补了三类几何断言,全部用纯函数实现,不依赖 tkinter:
31.40 °C 与 51.2 %RH 重叠、右边界 1191 > 1024,rc=1。
一个判据如果从没被验证过「能失败」,就等于没有判据。
| 退出码 | 含义 | 怎么理解 |
|---|---|---|
0 | 收到帧且无 CRC 错 | 成功 |
1 | 有 CRC 错 | 链路有噪声 / 波特率不符 / 接线问题 |
2 | 参数错(如 --geom 写错) | 改参数重跑 |
3 | 一帧都没收到 | 未执行,不算成功。串口没开对 / 板子没发帧 / 器件没接 —— 三种都要查 |
STALE_S = 6 秒没有有效帧,界面会把大数字变灰并显示 NO DATA。
它不保留旧值假装还在更新 —— 因为「看起来还在跳」比「明说没数据」危险得多。
固件与界面都会声明这一帧的数据从哪来:
| 标记 | 含义 | 能当证据用吗 |
|---|---|---|
| AM2302_LIVE | 温度/湿度取自真实 AM2302 | 能。这是「器件读通」的唯一标记 |
| MPU6050_LIVE | 六轴/温度取自真实 MPU6050 | 能,但仅限该器件;湿度字段恒为 0 且标注为「无来源」 |
| SYNTH | 器件没应答,用的是合成值 | 不能。只能证明「链路通」,不能证明「传感器能用」 |
—,而不是 0.0。
把「无源」画成 0 会让人以为真的测到了 0 —— 本仓在这个坑上吃过亏,
所以这条是硬要求。
firmware/esp_thermo(C6)
或 firmware/esp_frame_tx(S3)。烧写步骤见《MOS 端到端操作手册》。paho-mqtt 也能跑,只是不能上行。| 现象 | 原因 | 处置 |
|---|---|---|
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,几何判据会指出越界/相交的具体项 |
tools/thermo_app_pack.py 重现。