Files
P4-USB-transfer/蓝牙指令测试文档.md
T
zhengxinandCursor 851e347cf5 初始提交卡包 USB 工程
纳入固件源码、屏幕组件、nand_xfer 工具和文档。忽略本机构建产物、sdkconfig,以及含本机路径的依赖锁。

Co-authored-by: Cursor <[email protected]>
2026-10-13 21:54:50 +08:00

19 KiB
Raw Blame History

车机 & 机器人蓝牙指令测试文档

本文档用于蓝牙协议联调与测试。所有完整帧中的 CRC16 均按下方计算规则得出。


一、协议约定

1. 帧结构

字段 帧头 类(Cmd) 指令 动作/参数 方向等 CRC16 帧尾
长度 1 2 2 视指令 视指令 2 1
取值 0xAA 大端 大端 — — 见下节 0x55

2. CRC16 计算规则

与工程内 main/ALGORITHM/crc.c 中 crc16_ccitt_calculate() 行为一致,本文档中所有完整帧的 CRC16 均按下列规则计算并填入。

  • 算法:CRC16-CCITT
  • 多项式:0x1021
  • 初始值:0xFFFF
  • 校验范围:从帧头(0xAA)到 CRC 前一字节(不含 CRC 两字节、不含帧尾 0x55)
  • 字节序:CRC 结果 2 字节按大端填入帧(高字节在前,低字节在后)
  • 无反转、无异或:计算得到的 16 位值直接取高 8 位、低 8 位写入

计算步骤:从 0xFFFF 开始,按字节顺序对“校验范围”内每一字节做迭代:当前 CRC 高 8 位与数据字节异或后,若最高位为 1 则左移 1 位再异或 0x1021,否则仅左移 1 位;重复 8 位后得到更新后的 CRC。全部字节处理完后得到的 16 位值,高字节、低字节依次写入帧。

3. 方向 (direction)

值 含义
0x00 电机无动作
0x01 电机转向主驾
0x02 电机转向副驾
0x03 电机转向后背
0x04 主驾+副驾
0x05 左后唤醒
0x06 右后唤醒
0x07 行驶中转头 180°

4. 类 (Cmd)

  • 0xFFFE:车机下发指令 (Cmd)
  • 0xFFFF:机器人反馈 (Feedback)

二、指令类协议 (Play_stick, Cmd=0xFFFE, 指令=0x0001)

帧格式:帧头(1) + 类(2) + 指令(2) + 动作Action_id(2) + 方向(1) + CRC16(2) + 帧尾(1)
CRC16 按上述规则对前 8 字节计算。

2.1 无方向指令 (direction=0x00)

序号 指令名称 Action_id 完整帧 (十六进制,含 CRC16)
1.1 驾车出发 0x0001 AA FF FE 00 01 00 01 00 D7 40 55
1.2 开始播放音乐 0x0002 AA FF FE 00 01 00 02 00 82 13 55
1.3 暂停播放音乐 0x0003 AA FF FE 00 01 00 03 00 B1 22 55
1.4 停止播放音乐 0x0004 AA FF FE 00 01 00 04 00 28 B5 55
1.5 播放音乐中(表情 40%~75% 循环) 0x0005 AA FF FE 00 01 00 05 00 1B 84 55
1.6 冷风 0x0006 AA FF FE 00 01 00 06 00 4E D7 55
1.7 暖风 0x0007 AA FF FE 00 01 00 07 00 7D E6 55
1.8 打开窗户 0x0008 AA FF FE 00 01 00 08 00 6D D8 55
1.9 开始充电 0x0009 AA FF FE 00 01 00 09 00 5E E9 55
1.10 完成充电 0x000A AA FF FE 00 01 00 0A 00 0B BA 55
1.11 接听电话 0x000B AA FF FE 00 01 00 0B 00 38 8B 55
1.12 挂断电话 0x000C AA FF FE 00 01 00 0C 00 A1 1C 55
1.13 开始导航 0x000D AA FF FE 00 01 00 0D 00 92 2D 55
1.14 结束导航 0x000E AA FF FE 00 01 00 0E 00 C7 7E 55
1.15 露营模式 0x000F AA FF FE 00 01 00 0F 00 F4 4F 55
1.16 小憩模式 0x0010 AA FF FE 00 01 00 10 00 E7 02 55
1.17 洗车模式 0x0011 AA FF FE 00 01 00 11 00 D4 33 55
1.18 迎宾模式 0x0012 AA FF FE 00 01 00 12 00 81 60 55
1.19 唤醒机器人 0x0013 AA FF FE 00 01 00 13 00 B2 51 55

| 1.20 | 到达 | 0x0014 | AA FF FE 00 01 00 14 00 2B C6 55 | | 1.21 | 哨兵模式guard | 0x0015 | AA FF FE 00 01 00 15 00 18 F7 55 | | 1.22 | 哨兵模式protect| 0x0016 | AA FF FE 00 01 00 16 00 4D A4 55 | | 1.23 | 冥想 | 0x0017 | AA FF FE 00 01 00 17 00 7E 95 55 | | 1.24 | 星座 | 0x0018 | AA FF FE 00 01 00 18 00 6E AB 55 | | 1.24 | 抽签 | 0x0019 | AA FF FE 00 01 00 19 00 5D 9A 55 |

电机微调代码

1.向主驾微调 | AA FF FE 00 01 00 00 11 E6 61 55| 1.向副驾微调 | AA FF FE 00 01 00 00 12 D6 02 55 |

2.2.1 带方向指令(direction 置 0x00 变体)

上述 2.2 中指令的方向字节统一置为 0x00(电机无动作)、并重新计算 CRC16 后的完整帧,便于测试“仅动作、不转向”场景。

序号 指令名称 Action_id direction 完整帧 (十六进制,含 CRC16)
1.2.1 主驾唤醒 0x0020 0x00 AA FF FE 00 01 00 20 00 E2 97 55
1.2.2 副驾唤醒 0x0021 0x00 AA FF FE 00 01 00 21 00 D1 A6 55
1.2.3 主驾系安全带 0x0022 0x00 AA FF FE 00 01 00 22 00 84 F5 55
1.2.4 副驾系安全带 0x0023 0x00 AA FF FE 00 01 00 23 00 B7 C4 55
1.2.5 震惊(turn_to_back) 0x0024 0x00 AA FF FE 00 01 00 24 00 2E 53 55
1.2.6 查看后排 0x0025 0x00 AA FF FE 00 01 00 25 00 1D 62 55
1.2.7 主驾开门 0x0026 0x00 AA FF FE 00 01 00 26 00 48 31 55
1.2.8 副驾开门 0x0027 0x00 AA FF FE 00 01 00 27 00 7B 00 55
1.2.9 全车开门 0x0028 0x00 AA FF FE 00 01 00 28 00 6B 3E 55
1.2.10 主驾未系好安全带 0x0029 0x00 AA FF FE 00 01 00 29 00 58 0F 55
1.2.11 副驾未系好安全带 0x002A 0x00 AA FF FE 00 01 00 2A 00 0D 5C 55
1.2.12 主驾开窗 0x002B 0x00 AA FF FE 00 01 00 2B 00 3E 6D 55
1.2.13 主驾制冷 0x002C 0x00 AA FF FE 00 01 00 2C 00 A7 FA 55
1.2.14 左后唤醒 0x002E 0x00 AA FF FE 00 01 00 2E 00 C1 98 55
1.2.15 右后唤醒 0x002F 0x00 AA FF FE 00 01 00 2F 00 F2 A9 55
1.2.16 行驶中转头 180° 0x0030 0x00 AA FF FE 00 01 00 30 00 E1 E4 55
1.2.17 主驾制热 0x002D 0x00 AA FF FE 00 01 00 2D 00 94 CB 55

2.2 带方向指令

序号 指令名称 Action_id direction 完整帧 (十六进制,含 CRC16)
1.2.1 主驾唤醒 0x0020 0x01 AA FF FE 00 01 00 20 01 F2 B6 55
1.2.2 副驾唤醒 0x0021 0x02 AA FF FE 00 01 00 21 02 F1 E4 55
1.2.3 主驾系安全带 0x0022 0x01 AA FF FE 00 01 00 22 01 94 D4 55
1.2.4 副驾系安全带 0x0023 0x02 AA FF FE 00 01 00 23 02 97 86 55
1.2.5 震惊(turn_to_back) 0x0024 0x03 AA FF FE 00 01 00 24 03 1E 30 55
1.2.6 查看后排 0x0025 0x03 AA FF FE 00 01 00 25 03 2D 01 55
1.2.7 主驾开门 0x0026 0x01 AA FF FE 00 01 00 26 01 58 10 55
1.2.8 副驾开门 0x0027 0x02 AA FF FE 00 01 00 27 02 5B 42 55
1.2.9 全车开门 0x0028 0x04 AA FF FE 00 01 00 28 04 2B BA 55
1.2.10 主驾未系好安全带 0x0029 0x01 AA FF FE 00 01 00 29 01 48 2E 55
1.2.11 副驾未系好安全带 0x002A 0x02 AA FF FE 00 01 00 2A 02 2D 1E 55
1.2.12 主驾开窗 0x002B 0x01 AA FF FE 00 01 00 2B 01 2E 4C 55
1.2.13 主驾制冷 0x002C 0x01 AA FF FE 00 01 00 2C 01 B7 DB 55
1.2.14 左后唤醒 0x002E 0x05 AA FF FE 00 01 00 2E 05 91 3D 55
1.2.15 右后唤醒 0x002F 0x06 AA FF FE 00 01 00 2F 06 92 6F 55
1.2.16 行驶中转头 180° 0x0030 0x07 AA FF FE 00 01 00 30 07 91 03 55
1.2.17 主驾制热 0x002D 0x01 AA FF FE 00 01 00 2D 01 84 EA 55

2.3 待机表情(随机待机表情包 action_id 0x0201-0x020A)

序号 指令名称 Action_id direction 完整帧 (十六进制,含 CRC16)
1.2.513 左转弯 0x0201 0x09 AA FF FE 00 01 02 01 09 28 09 55
1.2.514 右转弯 0x0202 0x08 AA FF FE 00 01 02 02 08 6D 7B 55
1.2.515 drink coffee 0x0203 0x00 AA FF FE 00 01 02 03 00 DF 42 55
1.2.516 急加速 0x0204 0x00 AA FF FE 00 01 02 04 00 46 D5 55
1.2.517 眩晕 0x0205 0x00 AA FF FE 00 01 02 05 00 75 E4 55
1.2.518 蜗牛 0x0206 0x00 AA FF FE 00 01 02 06 00 20 B7 55
1.2.519 散金币 0x0207 0x00 AA FF FE 00 01 02 07 00 13 86 55
1.2.520 唱歌 0x0208 0x00 AA FF FE 00 01 02 08 00 03 B8 55
1.2.521 庆祝 0x0209 0x00 AA FF FE 00 01 02 09 00 30 89 55
1.2.522 深呼吸/冷静 0x020A 0x00 AA FF FE 00 01 02 0A 00 65 DA 55

三、哨兵模式 (Cmd=0xFFFE, 指令=0x0002)

帧格式:帧头(1) + 类(2) + 指令(2) + 动作Action_id(2) + CRC16(2) + 帧尾(1)。CRC16 对前 8 字节计算。

  • 进入哨兵后:先显示 guard_emojo,约 5s 后持续播放 protect_emojo,直到退出哨兵模式。
序号 指令名称 Action_id 完整帧 (十六进制,含 CRC16)
1.3.1 开启监听脉冲模式 0x0001 AA FF FE 00 02 00 01 1D 8F 55
1.3.2 关闭监听脉冲模式 0x0002 AA FF FE 00 02 00 02 2D EC 55
1.3.3 打开哨兵模式 0x0003 AA FF FE 00 02 00 03 3D CD 55
1.3.4 关闭哨兵模式 0x0004 AA FF FE 00 02 00 04 4D 2A 55

四、退出所有模式 (Cmd=0xFFFE, 指令=0x0003, Cancel_all_modes)

帧格式:帧头(1) + 类(2) + 指令(2) + 动作 Action_id(2) + CRC16(2) + 帧尾(1)。CRC16 对前 8 字节计算。

字段 帧头 类(Cmd) 指令(Cancel_all_modes) 动作(Action_id) CRC16 帧尾
长度 1 2 2 2 2 1
取值 0xAA 0xFFFE 0x0003 0x0000 3A 9E 0x55

接收到退出所有模式指令后:仅退出哨兵模式,不处理持续播放音乐等其它持续运行表情。

序号 指令名称 完整帧 (十六进制,含 CRC16)
1.4.1 退出所有模式 AA FF FE 00 03 00 00 3A 9E 55

五、调节屏幕亮度 (Cmd=0xFFFE, 指令=0x0004)

帧格式:帧头(1) + 类(2) + 指令(2) + 亮度(2) + CRC16(2) + 帧尾(1)。亮度 0~100,大端。CRC16 对前 8 字节计算。

示例 亮度值 完整帧 (十六进制,含 CRC16)
亮度 50 0x0032 AA FF FE 00 04 00 32 A9 1F 55
亮度 0 0x0000 AA FF FE 00 04 00 00 BF 0E 55
亮度 100 0x0064 AA FF FE 00 04 00 64 93 2C 55

六、发送日期 (Cmd=0xFFFE, 指令=0x0005)

帧格式:帧头(1) + 类(2) + 指令(2) + 年(2) + 月(1) + 日(1) + CRC16(2) + 帧尾(1)。CRC16 对前 8 字节计算。

示例 年(2) 月 日 完整帧 (十六进制,含 CRC16)
2026-01-28 0x07EA 0x01 0x1C AA FF FE 00 05 07 EA 01 1C 93 FD 55

七、发送时间 (Cmd=0xFFFE, 指令=0x0006)

帧格式:帧头(1) + 类(2) + 指令(2) + 时(1) + 分(1) + 秒(1) + CRC16(2) + 帧尾(1)。CRC16 对前 8 字节计算。

示例 时 分 秒 完整帧 (十六进制,含 CRC16)
22:53:10 0x16 0x35 0x0A AA FF FE 00 06 16 35 0A 1F B5 55

八、发送城市 (Cmd=0xFFFE, 指令=0x0007)

帧格式:帧头(1) + 类(2) + 指令(2) + 城市名长度(2) + 城市名(UTF-8) + CRC16(2) + 帧尾(1)。CRC16 校验范围为帧头到 CRC 前一字节(含城市名字节)。

示例 长度 城市名(UTF-8) 完整帧说明
芜湖市 0x0009 9 字节 UTF-8 AA FF FE 00 07 00 09 E8 8A 9C E6 B9 96 E5 B8 82 [CRC16 2 字节] 55(CRC 对前 6+9=15 字节计算)

九、发送天气与温度 (Cmd=0xFFFE, 指令=0x0008)

帧格式:帧头(1) + 类(2) + 指令(2) + 时机(1) + 温度(2) + 天气长度(2) + 天气(UTF-8) + CRC16(2) + 帧尾(1)。CRC16 校验范围为帧头到 CRC 前一字节。

  • 温度:Temp = 实际温度×10 + 1000(如 -4.3℃ → 957 → 0x03BD)。
  • 时机:0x00=当前,0x010x06=16 小时后。
示例 时机 温度(2) 天气 说明
当前晴天 0x00 0x03BD 晴天(6字节) 帧头+类+指令+0x00+03 BD+00 03+E6 99 B4+[CRC16]+55,CRC 对前述全部数据计算

十、WiFi 配网 (Cmd=0xFFFE, 指令=0x0009)

帧格式:帧头(1) + 类(2) + 指令(2) + Wifi_info(1) + 长度(2) + SSID/密码(x) + CRC16(2) + 帧尾(1)。CRC16 校验范围:帧头到 CRC 前一字节(含可变长度数据)。

  • Wifi_info:0x00=发送 SSID,0x01=发送密码。
  • 长度:2 字节大端,表示后续 SSID 或密码的字节数。
  • 获取到 SSID 和密码并尝试连接后,无论连上与否,机器人都会通过 BLE 发送 WiFi 状态反馈(见下方 1.10_A)。

示例:SSID = "11111111",密码 = "11111111"(各 8 字节)

  • 发 SSID:数据部分为 00 00 08 31 31 31 31 31 31 31 31,再计算 CRC16(对 AA FF FE 00 09 00 00 08 31 31 31 31 31 31 31 31 共 15 字节),填入 2 字节后加 55。
  • 发密码:数据部分为 01 00 08 31 31 31 31 31 31 31 31,同样按 CRC16 规则计算后填入。

(31 31 31 31 31 31 31 31 为 ASCII "11111111")

1.10_A 反馈:WiFi 状态(机器人发出)

  • 帧格式:AA FF FF 00 10 [Wifi状态] [CRC16] 55,CRC16 对前 6 字节计算。
  • Wifi 状态:0x01=已连接,0x00=断开/未连上。连接尝试完成后会主动上报。

WiFi 配网流程与目的

  1. 目的:车机通过 BLE 把当前要连接的 WiFi 的 SSID 和密码下发给机器人,机器人尝试连接该热点;无论连上与否,都通过 1.10_A 把结果反馈给车机。
  2. 流程:车机先发 SSID 帧、再发密码帧;机器人收到后缓存,收齐后发起连接;连接结果通过 1.10_A 反馈。
  3. 可变长度:协议中“长度”为 x 的字段均由帧内“长度(2)”指定,x 不能为 0;解析时严格按 帧长 = 固定头 + 长度字段值 + CRC + 帧尾 校验。

十一、OTA / 表情包下载 (Cmd=0xFFFE)

CRC16 均按校验范围从帧头到 CRC 前一字节计算。

序号 指令名称 指令 说明 完整帧 (十六进制,含 CRC16)
1.11 OTA_request 0x000A 无参数 AA FF FE 00 0A 6F 7C 55
1.12 表情包下载 0x000B Target_pack 2 字节,如 A=0x0041 AA FF FE 00 0B 00 41 CB DA 55(下载 A 系列)
1.13 OTA_升级取消 0x000C 无参数 AA FF FE 00 0C 0F BA 55

1.13 帧格式:帧头(1)+类(2)+指令(2)+CRC16(2)+帧尾(1),共 8 字节。CRC16 对前 5 字节计算。


十二、车机查询 get_system_info (Cmd=0xFFFE, 指令=0x0010)

帧格式:帧头(1)+类(2)+指令(2)+CRC16(2)+帧尾(1)。CRC16 对前 5 字节计算。

序号 指令名称 完整帧 (十六进制,含 CRC16)
2.1 get_system_info AA FF FE 00 10 DC 07 55

十三、表情包使用 (Cmd=0xFFFE, 指令=0x0020)

帧格式:帧头(1)+类(2)+指令(2)+op(1)+[可选 Target_pack 等]+CRC16(2)+帧尾(1)。CRC16 对帧头到 CRC 前一字节计算。

序号 操作 操作码 完整帧 (十六进制,含 CRC16)
3.1 查询已安装表情包 0x00 AA FF FE 00 20 00 08 64 55
3.2 查询正在使用 0x01 AA FF FE 00 20 01 18 45 55
3.3 切换到表情包 A 0x02 + 0x41 AA FF FE 00 20 02 41 DB 8F 55
3.4 删除指定的表情包 0x03 + Target_pack 示例删除 A:AA FF FE 00 20 03 41 E8 BE 55

3.4 删除表情包反馈 (Feedback 3.4):帧头(1)+类(0xFFFF)(2)+指令(0x0020)(2)+op(0x03)(1)+Exchange_result(1)+CRC16(2)+帧尾(1)=10 字节。Exchange_result:0x00 删除失败,0x01 删除成功。CRC16 对前 8 字节计算。


十四、机器人反馈帧 (Feedback, Cmd=0xFFFF)

机器人端回复的 CRC16 同样按 CRC16-CCITT,初始 0xFFFF,多项式 0x1021,校验范围从帧头到 CRC 前一字节,大端写入。

反馈类型 指令(2) 说明
get_system_ok 0x0004 AA FF FF 00 04 01 [CRC16] 55
brightness 0x0005 AA FF FF 00 05 [0-100] [CRC16] 55
version 0x0006 AA FF FF 00 06 [长度(2)][版本号] [CRC16] 55
WiFi 状态 0x0010 AA FF FF 00 10 [0x00/0x01] [CRC16] 55
OTA 结果 0x0001 AA FF FF 00 01 [0x00/0x01] [CRC16] 55
OTA 进度 0x0002 AA FF FF 00 02 [0-100] [CRC16] 55
表情包下载结果 0x0003 AA FF FF 00 03 [0x00/0x01] [CRC16] 55
表情包查询/切换 0x0020 按协议格式,CRC16 对帧头到 CRC 前一字节计算
表情包删除结果 (Feedback 3.4) 0x0020 op=0x03 帧头+FFFF+0020+03+[0x00/0x01]+CRC16+55

十五、可变长度字段约定

协议中“长度”标为 x 的字段表示由帧内“长度(2)”指定,且不能为 0:

  • 城市名、天气、SSID/密码等:均以帧内 2 字节大端“长度”为准,解析时用 总帧长 = 固定头 + 长度值 + CRC(2) + 帧尾(1) 校验,不假定固定 x。
  • 代码中对 x=0 的帧会直接报错并丢弃。

十六、使用说明

  1. CRC16:本文档中所有完整帧的 CRC16 均按**第一节“CRC16 计算规则”**对“帧头~CRC 前一字节”计算后填入(大端);与代码中 crc16_ccitt_calculate() 行为一致。
  2. 校验:接收端校验不通过则丢弃该帧,不执行后续处理。
  3. 多字节字段均为大端序(高字节在前)。