Files
balance-board/doc/BALANCE_BOARD_PROTOCOL.md
T
pNexus dc525ea4e7 feat(gml670x4): 所有协议帧添加 CRC-8/MAXIM 校验
使用 Zephyr crc8() 对帧头之后的载荷计算 CRC,上行发送前填充、
下行接收时校验不通过则丢弃并告警。同步更新协议文档。

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-09 14:38:28 +08:00

7.3 KiB
Raw Blame History

平衡板协议说明

本文说明当前固件里的数据包格式和 BLE 通讯方式。

1. BLE 通讯方式

平衡板工作在 BLE Peripheral 角色,通过 Nordic UART ServiceNUS)与基站通信。

  • 上行方向:平衡板 -> 基站,使用 NUS Notify
  • 下行方向:基站 -> 平衡板,使用 NUS Write
  • 广播内容:包含设备名和 NUS 128-bit UUID

1.1 NUS UUID

项目 UUID 方向 说明
Service 6E400001-B5A3-F393-E0A9-E50E24DCCA9E - NUS 主服务
TX Characteristic 6E400003-B5A3-F393-E0A9-E50E24DCCA9E 平衡板 -> 基站 Notify,上报 CoP 和编码器数据
RX Characteristic 6E400002-B5A3-F393-E0A9-E50E24DCCA9E 基站 -> 平衡板 Write,下发阻力参数和控制命令

1.2 当前连接行为

  • 连接建立后,平衡板会请求 7.5-15 ms 连接区间(min=6, max=12)。
  • 所有数据通过 NUS 二进制帧发送,不走文本协议。

2. 数据包总览

当前协议使用双帧头 0xAA 0x55 作为包起始标记。所有多字节字段按 Little Endian 编码。

每帧末尾附加 1 字节 CRC-8/MAXIM 校验(poly=0x31, init=0x00, refin=true, refout=true, xorout=0x00)。校验范围为帧头之后、CRC 字节之前的所有字段(即跳过 sync0/sync1)。调用方式:crc8(data + 2, len - 3, 0x31, 0x00, true)

类型名 方向 长度 频率 说明
PROTO_TYPE_COP 0x01 平衡板 -> 基站 18 50 Hz 压力中心帧
PROTO_TYPE_ENCODER 0x02 平衡板 -> 基站 14 TBD 电机编码器帧(预留)
PROTO_TYPE_RESISTANCE 0x10 基站 -> 平衡板 16 按需 阻力参数帧
PROTO_TYPE_SPOTTER 0x11 基站 -> 平衡板 9 按需 保护模式帧
PROTO_TYPE_HEARTBEAT 0x20 基站 -> 平衡板 5 ~1 Hz 心跳帧

3. 上行数据包

3.1 压力中心帧 (CoP)

CoP 帧固定 18 字节,结构如下:

字节偏移 字段 类型 值/范围 说明
0 sync0 uint8 0xAA 帧头第 1 字节
1 sync1 uint8 0x55 帧头第 2 字节
2 type uint8 0x01 CoP 包类型
3 seq uint8 0-255 包序号,循环递增
4 flags uint8 见下表 状态标志位
5-8 cop_x float32 LE - 压力中心 X 坐标 (mm)
9-12 cop_y float32 LE - 压力中心 Y 坐标 (mm)
13-16 force float32 LE - 总压力 (N)
17 crc uint8 - CRC-8/MAXIM 校验

flags 位定义

名称 说明
bit0 COP_FLAG_FORCE_VALID 1 表示总力超过阈值,CoP 坐标有意义
bit1-7 预留 0

CoP 解算公式

传感器布局(俯视):

  S4 (FL) -------- S1 (FR)
  |       center        |
  S3 (BL) -------- S2 (BR)

传感器坐标(单位:mm,板面中心为原点):

传感器 位置 X Y
S1 右前 (FR) +200 +200
S2 右后 (BR) +200 -200
S3 左后 (BL) -200 -200
S4 左前 (FL) -200 +200

计算公式:

F_total = F0 + F1 + F2 + F3

CoP_X = (F0 * x0 + F1 * x1 + F2 * x2 + F3 * x3) / F_total
CoP_Y = (F0 * y0 + F1 * y1 + F2 * y2 + F3 * y3) / F_total

F_total < COP_MIN_FORCE_THRESHOLD 时,CoP 坐标无意义,flags.bit0 = 0cop_xcop_y0.0f

示例

下面是一个 CoP 帧示例(CoP 有效):

AA 55 01 2A 01  00 00 F0 41  00 00 48 42  00 80 BB 44  XX

含义如下:

  • AA 55:双帧头
  • 01CoP 包
  • 2A:序号 0x2A
  • 01flags = force_valid
  • 00 00 F0 41cop_x = 30.0 mmLE float32
  • 00 00 48 42cop_y = 50.0 mmLE float32
  • 00 80 BB 44force = 1500.0 NLE float32
  • XXCRC-8/MAXIM(对字节 [2..16] 计算)

3.2 电机编码器帧(预留)

编码器帧固定 14 字节,结构如下。该帧目前仅在协议中预留定义,固件暂不实现。

字节偏移 字段 类型 值/范围 说明
0 sync0 uint8 0xAA 帧头第 1 字节
1 sync1 uint8 0x55 帧头第 2 字节
2 type uint8 0x02 编码器包类型
3 seq uint8 0-255 包序号
4 flags uint8 0 预留
5-8 cable_length float32 LE - 拉索长度 (mm)
9-12 velocity float32 LE - 拉索速度 (mm/s)
13 crc uint8 - CRC-8/MAXIM 校验

4. 下行数据包

4.1 阻力参数帧

阻力参数帧固定 16 字节,用于基站向平衡板下发电机阻力控制参数。

字节偏移 字段 类型 值/范围 说明
0 sync0 uint8 0xAA 帧头第 1 字节
1 sync1 uint8 0x55 帧头第 2 字节
2 type uint8 0x10 阻力参数包类型
3-6 K float32 LE - 刚度 (N/m)
7-10 B float32 LE - 阻尼 (Ns/m)
11-14 Tau float32 LE - 时间常数 (s)
15 crc uint8 - CRC-8/MAXIM 校验

示例

AA 55 10  00 00 C8 42  00 00 48 41  CD CC 4C 3E  XX

含义如下:

  • AA 55 10:阻力参数帧头
  • 00 00 C8 42K = 100.0 N/m
  • 00 00 48 41B = 12.5 Ns/m
  • CD CC 4C 3ETau = 0.2 s
  • XXCRC-8/MAXIM

4.2 Spotter Mode 帧

Spotter 帧固定 9 字节,用于启用或关闭保护模式。

字节偏移 字段 类型 值/范围 说明
0 sync0 uint8 0xAA 帧头第 1 字节
1 sync1 uint8 0x55 帧头第 2 字节
2 type uint8 0x11 Spotter 包类型
3-6 threshold float32 LE - 保护力阈值 (N)
7 enable uint8 01 0 = 关闭, 1 = 启用
8 crc uint8 - CRC-8/MAXIM 校验

示例

启用 Spotter Mode,阈值 500 N

AA 55 11  00 00 FA 43  01  XX

4.3 心跳帧

心跳帧固定 5 字节,基站以约 1 Hz 频率发送,用于活性检测。

字节偏移 字段 类型 值/范围 说明
0 sync0 uint8 0xAA 帧头第 1 字节
1 sync1 uint8 0x55 帧头第 2 字节
2 type uint8 0x20 心跳包类型
3 counter uint8 0-255 滚动计数
4 crc uint8 - CRC-8/MAXIM 校验

示例

AA 55 20 05 XX

含义:心跳包,计数 5XX 为 CRC。

5. 当前实现约束

  • CoP 帧固定 18 字节,可在最小 ATT MTU 23(NUS 有效负载 20 字节)下传输。
  • 50 Hz CoP 上行流隐式充当平衡板到基站的活性检测,因此心跳仅为下行。
  • 传感器通道到物理位置的映射:MUX {0x01, 0x23, 0x45, 0x67} → FL/FR/BR/BL。
  • BOARD_HALF_WIDTH_MM = 200BOARD_HALF_LENGTH_MM = 200(后续可能调整)。
  • ADC_TO_FORCE_SCALE 当前为占位值 1.0f,待 10 kg 砝码标定后修正。
  • ARM Cortex-M33 为小端架构,float32 在 packed struct 中天然符合 Little Endian 要求。