# FilmForge GUI — 热压模具温控闭环监视台 FilmForge 热压模具温控板(GD32F405, RS485 数据口)的桌面上位机:实时温度曲线、 目标温度/加热/周期上报控制、收发日志与 CSV 数据记录。协议权威定义见固件仓根目录 [`../protocols.md`](../protocols.md)(v1.0,帧 hex 由脚本生成)。 ## 功能 - **实时温度曲线**(自绘 QPainter 控件,无第三方图表依赖):实测温度折线 + 目标温度橙色阶梯线同图对照(闭环监视),NTC 开路/短路处曲线断开并打故障标记; 时间窗 2/5/15/60 分钟/全部,暂停/恢复,窗口统计(最小/最大/平均); Y 轴(温度轴)量程可选**自动**(随可见数据自适应)或**手动**——直接拖动 图表右缘滑条(固定参考域 -20~120℃,把手位置=℃ 读数):上把手=上限、 下把手=下限、拖动把手中段上下=整段平移并把跨度保持不变、点击轨道空白直接 把对应边界设到该处;首次任意拖拽自动切入手动("Y轴自动/手动"按钮同步), 把手数值标签仅悬停/拖拽时显示(不常驻遮挡曲线),曲线越界时裁剪回绘图区; 模式与量程记忆在 `filmforge_gui.json`。 - **温度数据**:温度监控统一走固件 M2 周期上报帧(M2S 开启后主动推送入曲线); M1 仅作手动单点查询(命令区按钮/预设)。 - **控制面板**:目标温度 M4S(0~200 整数℃,滑条+输入框)、加热 M3S1/M3S0 (真实 PID 闭环控温,开启需确认)、周期上报 M2S(100~60000,10ms 步进)、 预设/自定义命令。 - **状态联动**:连接后自动查询版本(M999)/上报(M2)/加热(M3)/目标(M4)并同步到状态芯片; 软件复位(M888)/进 OTA(M9999) 二次确认,复位后 2 秒自动重查状态。 - **收发日志**:译码 + 原始 hex,500 行上限防卡顿。 - **CSV 记录**:逐行写入 `logs/temp_*.csv`(时间/相对秒/温度/目标/加热/传感器)。 ## 快速开始 源码运行(Python 3.12+,Windows): ```powershell py -m pip install PySide6 PySide6-Fluent-Widgets pyserial python filmforge_gui.py ``` 选择串口(板上 RS485 数据口,本机通常 COM5)→ 连接,115200-8-N-1。 命令行模式(自动化/无 GUI 联调): ```powershell python filmforge_gui.py --port COM5 --cmd M999 --cmd M1 # 逐条命令并打印译码响应 python filmforge_gui.py --port COM5 --cmd M2S500 --seconds-report 3 # 收 3s 上报帧 python filmforge_gui.py --seconds 5 # GUI 冒烟(自动关闭) ``` ## 打包 / 自检 / 发布 ```powershell python selftest_rs485.py # 协议回归(对照 protocols.md 帧向量, 无硬件) python selftest_gui.py # GUI 离屏回归(曲线渲染/帧派发/主题/CSV) python build_exe.py # → release/FilmForge.exe + 发布 zip python publish_gitea.py release/FilmForge-GUI-v<版本>-win64.zip --replace --insecure ``` ## 实现要点(改代码前必读) - 分层:`filmforge_rs485.py`(协议+串口线程,纯标准库+可选 pyserial)/ `app_fluent.py`(PySide6-Fluent 呈现层)/ `config.py`(运行目录+设置记忆)/ `filmforge_gui.py`(入口+CLI)。协议模块不依赖 GUI。 - **应答派发是 FIFO 队列**(`app_fluent._pending`):半双工上固件严格按收到顺序应答, 连接序列(150ms 间隔连发)场景下单 pending 槽会被乱序击穿——实测踩坑: M2 的 OFF 被 M3 槽吃掉、M4 的目标值混进温度曲线。应答形态与队首期望匹配才消费, 不匹配记杂散,1.2s 超时自清。 - **M4 查询走"暂停上报→查询→恢复"应答驱动链**:M4 应答与周期上报帧同为 ASCII 浮点,仅靠时间窗拆分在 100ms 上报下实测必现误占(目标 chip 显示成实测温度)—— 上报开启时查目标自动执行 M2S0(ok)→M4→M2S 恢复;连接同步序列同样走此路径。 - **晚到 ok 补偿**:USB-RS485 适配器换向延迟实测可 >4s,设定命令的 ok 迟到超过 1.2s 已按超时清队,8s 内的迟到 ok 按发送时记录的计划补偿应用(否则状态 chip 与设备脱节,实测:M2S100 ok 迟到,chip 停在 OFF 而设备在报)。 - **连接按钮按"意图"翻转**:点击立即切换文本,实际开/关由串口线程异步完成, 已连接/已断开/丢失全部写入日志;期望连接但 2s 未建立按丢失处理回退按钮。 连接同步序列每步发送前确认在线(线程异步打开期间早发会被"未连接串口"丢弃)。 - **时间戳在串口线程读取点打**(`FF485.on_frame(fr, t_rx)`),不晚于 GUI 轮询消费—— 避免重蹈 SerialMate 的时间戳失真问题(见 `E:\Hulk-Coding\HW-Debug-Tools\SerialMate`)。 - **发送入口幂等去重**:同一命令已有未决应答时忽略重复发送(状态栏提示 "应答中, 已忽略重复发送")——真机实测连点"停止"12 次会把 8 条 pending 队列 挤爆("丢弃积压命令"刷屏);协议全幂等,同命令一条在途足够,超时自清后 自然允许重发。 - **串口读取按到达量收,不攒大块**:固定 `read(256)` 在持续帧流下要攒满 256 字节 才返回(Windows 串口"字节间隔超时"150ms 因帧间隔更短永不触发,100ms 上报时 ≈2.5s 一批),表现为曲线/命令全部 3 秒一卡、一股脑一大坨。已改为 `read(in_waiting or 1)`,延迟回到 ≤150ms 量级(v0.2.2,真机实测确认)。 - **日志裁剪走原生 `setMaximumBlockCount(500)`**:手工 `textCursor` 裁剪用了 `cursor.Start`/`cursor.BlockUnderCursor` 实例级枚举访问,PySide6 6.11 已移除 (类上仍在),必然抛 AttributeError——日志超 500 行(100ms 上报 ≈50s)后每个 100ms tick 在 `_log` 处异常中止:`_tick` 后半段(应答超时清理/连接状态机/统计 节流)永不执行(pending 永不清 → "停止"点击被幂等去重永久拦截)、RX 队列积压 ratchet(帧处理滞后涨到 1~2.7s,日志/chip/曲线显示全面滞后)、日志无限增长。 v0.2.8 改原生环形裁剪修复(离屏 A/B 实测:修复后 6 分钟漂移 ≤15ms、零异常、 零积压;selftest 新增 3 条回归用例)。 - **日志自动滚动仅在贴底时跟随**:上报运行时可上翻查看历史(每行强制滚底会抢 滚动条);CSV 写失败(磁盘满/记录盘被拔)自动停止记录并提示——`_csv_write` 在 `_tick` 帧处理路径上,未捕获异常会中止主循环(v0.2.8 日志裁剪同款教训);故障 标记封顶 1000 条;冻结视图切片右缘二分(暂停时长不增加渲染成本);串口写超时 只丢该条命令、链路保留(不按设备拔出断链)。均 v0.2.9。 - Fluent 控件自定义样式必须走 `setCustomStyleSheet`(覆盖 hover/pressed/disabled), 直接 `setStyleSheet` 会在切主题时被库重刷(DLPilot 同款坑);标题字号走 QFont。 - 图表刷新双节流:数据到达即重绘(≤10Hz)+ 0.5s 时间轴推进;“全部”窗口超 4000 点 按步进抽稀(NaN 断口保留)。 - **是否有数据由绘制时实时判定**(`paintEvent` 直接看数据列表引用):图表只在 构建时调用一次 `set_source`,旧版在这里缓存过 `_has_data` 布尔——数据经引用 追加后永不刷新,“暂无数据”提示文字在有数据后仍绘在曲线上(实测截图暴露)。 手动 Y 轴模式下曲线/目标线**裁剪回绘图区**(`setClipRect`),当前值标记 超出量程时不画(实时读数卡片仍可见)。v0.2.10。 - **Y 轴滑条的两套坐标系别混用**:把手像素位置在**参考域**(全量数据范围 ±15%,`_y_ref`)上映射,与"显示量程"是两回事;拖拽中的界值必须取**实时 显示范围**(manual=`_y_manual`,auto=当前自适应值),不能取绘制缓存 `_cached_layout` 的陈旧范围——连续两次拖拽之间没有重绘,实测曾把 pan 的 量程整段拖跳(v0.2.11)。 ## 已知事项 - 当前 USB-RS485 适配器自动换向偶发丢响应/大延迟(固件侧已立”适配器更换”TODO): 查询 1.2s 超时提示后重发即可;设定命令的晚到 ok 已自动补偿应用;曲线走上报帧 (设备单向推送),不受影响。 - 加热(M3S1)为真实 PID 闭环:开启后模具真实升温(NTC 故障/过温 150℃ 固件自动 断电保护,上电默认关闭);当前占空比无查询命令,从温度曲线间接观察。