Files
FilmForge/protocols.md
T

4.0 KiB
Raw Blame History

FilmForge RS485 协议 v1.0(GUI 上位机开发权威参考)

本文件为 FilmForge 热压模具固件的对外协议权威定义。所有帧 hex 由脚本生成 (算法见文末,勿手算 CRC)。GUI 工具按本文件实现即可完整驱动设备。

物理层

  • RS485 半双工,115200-8-N-1,无流控
  • 固件为从机:上位机发命令帧,固件回响应帧;另有 M2 开启的周期上报帧(主→从单向)

帧格式(五段式,与 DLPilot 协议同构)

命令帧(上位机 → 固件):D5 <BOARD=01> <LEN> <payload ASCII> <CRC>
响应帧(固件 → 上位机):B5 <TYPE>     <LEN> <payload>      <CRC>
  • LEN = payload 字节数
  • CRC = 8 位累加和:从 BOARD 字节累加到 LEN+payload 末尾(即跳过包头 D5/B5, 不含 CRC 本身),取低 8 位
  • payload 一律 ASCII 文本

响应 TYPE 码

TYPE 含义 payload
F0 成功 命令相关数据或 ok
F1 CRC 校验错 err
F3 板类型错 err
F4 命令格式错 err
FD 参数越界 err
FE 未知命令 err

命令表(hex 全部脚本生成)

命令 功能 命令帧 hex 成功响应 payload
M1 单次查询温度 D5 01 02 4D 31 81 ASCII 摄氏度(如 24.5);OPEN=NTC 开路 / SHRT=短路
M2 查询上报状态 D5 01 02 4D 32 82 ON <ms> 或 OFF
M2S500 设上报间隔并开启 D5 01 06 4D 32 53 35 30 30 6E ok;范围 100~60000ms,10ms 步进
M2S0 停止上报 D5 01 04 4D 32 53 30 07 ok
M3 查询加热状态 D5 01 02 4D 33 83 ON / OFF(预留,当前仅软件状态)
M3S1 开启加热 D5 01 04 4D 33 53 31 09 ok(预留)
M3S0 关闭加热 D5 01 04 4D 33 53 30 08 ok(预留)
M4 查询目标温度 D5 01 02 4D 34 84 ASCII 摄氏度(如 120.0)
M4S120 设定目标温度 D5 01 06 4D 34 53 31 32 30 6E ok;整数摄氏度 0~200,越界回 PARAM_ERR
M888 软件复位 D5 01 04 4D 38 38 38 FA ok 后复位(慎发)
M999 查询固件版本 D5 01 04 4D 39 39 39 FD 如 v41.0.0.1
M9999 进入 OTA 模式 D5 01 05 4D 39 39 39 39 37 直接复位进 Bootloader(未部署 Bootloader 前等同复位)

温度上报帧(M2S 开启后)

固件按设定周期主动发送,格式与 M1 响应完全相同: B5 F0 <LEN> <ASCII 摄氏度> <CRC>,如 24.5℃ → B5 F0 04 32 34 2E 35 BD。 GUI 曲线解析:匹配 B5 F0,取 payload 按 ASCII float 解析;payload 为 OPEN/SHRT 时为传感器故障态,不画点。

温度数据说明

  • 后台每 100ms 采样一次(16 次采样修剪均值滤波),M1/M2/上报读同一全局最新值
  • 单次测量耗时约 10~20ms,查询响应延迟 < 主循环周期(10ms 级)

加热控制(M3/M4,预留)

  • 当前固件仅维护软件状态(M3S1/M4S 设定会 ack 并可查询回读), 真实加热硬件驱动尚未接入;GUI 可先行完成全部协议联调
  • 目标温度范围 0~200℃(整数),越界回 FD
  • 上电默认:加热 OFF,目标 0.0℃
  • 后续接入硬件执行体后协议不变

通信注意事项

  1. 全部命令幂等:ack 丢失后直接重发,状态不会错乱(无翻转语义)
  2. 建议命令间隔 ≥ 50ms;响应超时建议 300ms 后重发,重发 3 次判失败
  3. M888/M9999 会复位设备,GUI 需在点击时二次确认
  4. 半双工:固件响应/上报期间(约 1ms/帧)不会接收,无需冲突处理

CRC 算法参考实现

def crc8_sum(frame_without_hdr: bytes) -> int:
    # frame_without_hdr = BOARD + LEN + payload(不含包头 D5/B5,不含 CRC)
    return sum(frame_without_hdr) & 0xFF

# 组帧示例
payload = b'M2S500'
body = bytes([0xD5, 0x01, len(payload)]) + payload
frame = body + bytes([crc8_sum(body[1:])])
# -> D5 01 06 4D 32 53 35 30 30 6E