Skip to content

Latest commit

 

History

History
287 lines (212 loc) · 10.1 KB

File metadata and controls

287 lines (212 loc) · 10.1 KB

通信协议 V0.3

本文档定义 OpenKidCar「干杯一号」大脑(Raspberry Pi)与小脑(Arduino Mega)之间的串口通信协议。

这份协议是"接口契约"的一部分,与 hardware_io_map.md 配套。两端代码必须严格按此实现。


1. 物理层

参数
通信接口 UART 串口
波特率 115200
数据格式 8 数据位 / 无校验 / 1 停止位(8N1)
接线 树莓派 GPIO14/15 ↔ Arduino Serial1 (D18/D19)
电平 ⚠️ Arduino(5V) → 树莓派(3.3V) 方向必须经双向电平转换模块

⚠️ 串口专用原则:协议串口只允许传输协议帧,禁止打印任何调试日志。

  • 小脑(Arduino)的 Serial1 专用于协议,调试日志走 Serial0(USB 口)
  • 大脑(树莓派)的协议串口仅收发帧,日志走系统 stdout

否则日志字符会被当成协议解析,产生乱码和假命令。


2. 帧格式

2.1 帧结构

协议采用可读文本行格式,每帧以换行 \n 结尾:

#命令:参数;CK:XX\n
字段 说明
# 帧头,标志一帧开始
命令 命令名,大写字母(见第 3 节)
:参数 参数,冒号分隔;多个参数用逗号 , 分隔;无参数可省略
;CK:XX 校验段,XX 为 CRC8 校验和的十六进制两位(见 2.2)
\n 帧结束符

最大帧长:128 字节(含 \n)。超长帧直接丢弃,防止缓冲区溢出。

参数约束:参数不得包含 #;:,\n 这些特殊字符(当前受控枚举值均满足)。

2.2 CRC8 校验

命令:参数(不含 #;CK:XX 本身)的所有字符计算 CRC-8/ATM(多项式 0x07,初值 0x00)。

Python 参考实现:

def crc8(data: bytes) -> int:
    crc = 0
    for b in data:
        crc ^= b
        for _ in range(8):
            if crc & 0x80:
                crc = ((crc << 1) ^ 0x07) & 0xFF
            else:
                crc = (crc << 1) & 0xFF
    return crc

Arduino 参考实现:

uint8_t crc8(const char* data, size_t len) {
  uint8_t crc = 0;
  for (size_t i = 0; i < len; i++) {
    crc ^= (uint8_t)data[i];
    for (uint8_t j = 0; j < 8; j++) {
      if (crc & 0x80) crc = (crc << 1) ^ 0x07;
      else            crc = (crc << 1);
    }
  }
  return crc;
}

示例:LIGHT:ON 的 CRC8 = 0xB7,完整帧为:

#LIGHT:ON;CK:B7\n

2.3 解析规则(帧同步)

  1. 逐字符读取,遇到 # 开始缓冲
  2. 读到 \n 结束缓冲,得到一帧
  3. 校验通过 → 解析执行;校验失败 → 静默丢弃
  4. 帧重同步:若出现以下情况,清空缓冲,回到"等待 #"状态:
    • 收到非法字符(# 之前出现非空白字符,或缓冲中混入非法字节)
    • 缓冲超过 128 字节仍未见 \n
    • 帧超时(200ms 内未收到完整帧的 \n

3. 命令集

3.1 下行命令(大脑 → 小脑)

命令 参数 含义 是否需 ACK
GEAR -1(R倒车) / 1-4 设置速度档位
LIGHT ON / OFF 前大灯
STRIP 模式,颜色,亮度 RGB 灯带
TURN L / R / OFF 转向灯
STEER 0-180 转向角度(90=直行,舵机)
MUTE ON / OFF 引擎音效静音
HORN ON / OFF 鸣笛
BRAKE ON / OFF 制动(缓刹)
EBRK ON / OFF 远程急刹(最高优先级)/ 解除急刹 ✅ 安全命令
STATUS GET 请求状态上报
PING - 心跳请求

⚠️ 统一规则:所有下行命令,小脑处理后必须回复 ACK(见 4.3)。大脑据此确认命令是否生效,不回复视为未执行。

3.2 上行命令(小脑 → 大脑)

命令 参数 含义 示例
STAT 速度,油门,档位,电压,温度,电流 状态上报 STAT:12,55,3,24.6,32,3.2
BTN 按钮名,PRESS/RELEASE 按钮事件 BTN:LIGHT_BTN,PRESS
SEAT ON / OFF 就座 / 离座 SEAT:ON
EBRK ON 急刹被触发 EBRK:ON
PONG - 心跳响应 PONG
ACK OK / ERR:原因 命令应答 ACK:OK
READY 协议版本 小脑上电就绪 READY:V0.3

上行命令无需 ACK(大脑被动接收,效果由后续命令/状态体现)。

3.3 按钮名清单(BTN 命令参数)

按钮名 对应硬件 说明
LIGHT_BTN D24 大灯开关 切换大灯
MUTE_BTN D23 静音开关 切换静音
STRIP_BTN D25 灯带开关 切换灯带
HORN_BTN D26 喇叭按钮 按下=PRESS,松开=RELEASE
EBRK_BTN D22 一键刹车 自锁按钮,PRESS
TALK_BTN D27 对讲按钮 按住说话=PRESS,松开=RELEASE

3.4 刹车灯(本地逻辑,非命令)

刹车灯(D3)由小脑本地逻辑直接响应,不走命令:

  • 刹车踏板踩下 → 刹车灯亮(随踩踏深度调整亮度)
  • 收到 BRAKE:ON / EBRK:ON → 刹车灯亮
  • 以上状态解除 → 刹车灯灭

4. 通信流程

4.1 上电握手

① 小脑上电初始化完成
② 小脑 ──READY:V0.3──► 大脑        (带上协议版本)
③ 大脑 校验版本;若不符,记录告警(单机系统不强制拒绝)
④ 大脑 ──GEAR:2──► 小脑            (重新下发当前档位)
⑤ 大脑 ──LIGHT:ON──► 小脑          (重新下发灯光状态)
⑥ ... 持续下发全部执行状态,完成状态同步(见 4.5)

4.2 心跳机制

  • 大脑每 1 秒PING,小脑立即回 PONG
  • 连续 3 次未收到 PONG → 大脑判定小脑离线,进入安全模式
    • 若在行驶中 → 平滑减速至停止
    • 通过 4G 通知家长 APP
  • 小脑若超过 5 秒未收到任何 PING → 判定大脑离线,安全兜底:维持当前安全状态,若在行驶中平滑减速至停止
  • 心跳频率与容错次数为可调参数,安全关键场景可缩短(如 500ms / 2 次)

4.3 统一 ACK 应答

  • 小脑收到任何下行命令,处理后必须回复 ACK
  • ACK:OK:执行成功;ACK:ERR:UNKNOWN:未知命令;ACK:ERR:INVALID_ARG:参数非法
  • 大脑在 ACK 超时(默认 500ms)未收到 → 视为命令未执行,按 4.4 处理

4.4 安全命令可靠投递(EBRK / BRAKE)

安全命令不容丢失,大脑在收到 ACK 前持续重发:

  • EBRK:ON:每 100ms 重复发送,直到收到 ACK:OK 或超时 2s → 超时进入安全模式
  • BRAKE:每 500ms 重复,直到收到 ACK 或超时 3s

4.5 状态同步机制

  • 大脑维护一份执行状态视图(档位、灯光、静音等),以本地决策为准
  • 小脑重启 / 握手时,大脑按视图重新下发全部状态(4.1)
  • 状态变化时(如大脑收到语音指令),大脑立即下发并等待 ACK,确保两端一致

4.6 正常交互示例:按下大灯按钮

① 小脑检测到 LIGHT_BTN 按下
② 小脑 ──BTN:LIGHT_BTN,PRESS──► 大脑
③ 大脑 解析:灯当前关 → 切换为开
④ 大脑 ──LIGHT:ON──► 小脑
⑤ 小脑 执行:D2 继电器闭合 → 大灯亮起
⑥ 小脑 ──ACK:OK──► 大脑          (大脑更新状态视图)

4.7 引擎轰鸣的音效数据流

① 小脑 以 10Hz 定时上报油门深度
② 小脑 ──STAT:12,55,3,...──► 大脑
③ 大脑 根据"油门=55%"实时合成引擎音效
④ 大脑 通过音频输出 → 功放 → 扬声器播放(油门越大越响)
⑤ 若 MUTE_BTN 按下 → 小脑上报 → 大脑静音所有音源

5. 错误处理汇总

情况 处理
校验失败 静默丢弃,不回复
帧超长 / 帧超时 / 非法字符 清空缓冲,重新帧同步
未知命令 回复 ACK:ERR:UNKNOWN
参数非法 回复 ACK:ERR:INVALID_ARG
下行命令 ACK 超时 按命令类别重发;安全命令持续重发(4.4)
小脑离线(3 次心跳无响应) 大脑安全模式 + APP 通知
大脑离线(5 秒无 PING) 小脑安全兜底减速

6. 数据上报说明

6.1 状态上报频率

  • 行驶中:10Hz(100ms 一次)
  • 静止且无人:1Hz(省电)

6.2 STAT 参数顺序

STAT:速度,油门,档位,电压,温度,电流
      12 , 55 , 3 , 24.6, 32 , 3.2
参数 单位 来源
速度 km/h 轮速传感器 / 油门档位估算
油门 % A0 霍尔踏板
档位 -1(R倒车) / 1-4 当前限速档位(-1=倒车,上限 6km/h)
电压 V A3 分压采样
温度 A4 NTC
电流 A A5 霍尔电流传感器

参数为位置参数,顺序严格固定,两端实现必须一致。新增参数追加在末尾。


7. 扩展机制

  • 新增命令:命令表(第 3 节)增加一行,两端同步实现,协议版本号 +0.1
  • 新增按钮/传感器BTN 参数表增加名称;STAT 末尾追加参数位
  • 兼容性:帧格式固定,命令允许增量添加,不得删除/改序已有命令

8. 实现建议

  • 大脑(Python)pyserial 读串口,逐行解析,用状态机处理半行(粘包/断包);严格按 2.3 帧同步
  • 小脑(Arduino):串口中断或 Serial.available() 循环 + 行缓冲(128 字节);按 2.2 计算 CRC8
  • 两端通用:CRC8、帧封装、帧解析建议做成独立模块,与业务逻辑分离,便于测试与复用
  • 调试:协议串口专用(1.1),日志走独立通道;可用虚拟串口(Windows: com0com)在 PC 上联调两端

变更记录

版本 日期 说明
V0.1 - 初始文本协议雏形
V0.2 2026-08-06 加入帧头/校验/心跳/安全模式,命令集覆盖 PRD 全功能
V0.3 2026-08-06 校验升级为 CRC8;规定最大帧长 128B;加入帧重同步、统一 ACK、安全命令可靠投递、状态同步机制、串口专用原则;明确刹车灯本地逻辑

hardware_io_map.md 共同构成接口契约。