Ping Protocol 声呐通信协议
协议旨在用于 P30 测距声呐 和 P360 扫描声呐 等设备的主从通信。Ping Protocol 协议中,从机仅在主机请求时才发送数据,这使该协议可以在半双工总线(如RS485)上使用。一些设备还可能提供允许异步通信的功能。
消息格式
每个消息都包含一个标头,可选的有效负载和校验和。二进制格式指定如下:
字节 | 类型 | 名称 | 描述 |
---|---|---|---|
0 | u8 | start1 | 起始帧标识符,ASCII'B' |
1 | u8 | start2 | 起始帧标识符,ASCII'R' |
2-3 | u16 | payload_length | 数据长度 |
4-5 | u16 | message_id | 消息ID |
6 | u8 | src_device_id | 发送消息的设备ID |
7 | u8 | dst_device_id | 接受消息的设备ID |
8-n | u8[] | payload | 数据内容 |
(n+1)-(n+2) | u16 | checksum | 和校验 |
消息分类
消息分为4类:
-
通用消息:用于通用消息的通信。
-
读取消息:设备响应 general_request 主机发送的消息。这些消息旨在从设备读取数据。
-
写入消息:从主机发送的消息,用于在设备上配置某些参数。这些消息旨在将数据写入设备。
-
控制消息:从主机发送的命令使设备执行某些操作的消息。这些消息旨在执行比通用读/写更复杂的设备交互。
一部分消息适用于所有设备(P30、Ping360),这些消息被称为通用消息,消息ID从0-999保留在常见消息目录中。其中部分请求消息是一种通用消息,设备收到此类消息后通过查找消息目录,回复对应的消息完成对上位机(主机)的响应。除此之外,针对不同种类设备,还需定义一些特殊消息,用以区分不同种类的设备消息响应。
消息定义
设备查找
如有必要,主机可能会发现并标识启用Ping协议的设备,如下所示:
- 主机首先从设备请求协议版本
- 主机收到协议版本答复后,切换到匹配的协议版本,并请求设备类型和固件版本
- 然后,主机加载与设备匹配的适当消息集
- 然后可以继续使用设备特定的消息进行通信
数据发送接收例子
在这里,我们演示了主机应用程序(主机)和设备(从机)之间发送的某些消息的逐字节细分。此示例说明了以下几点:
-
如何打包和解压缩某些消息数据(消息的字节顺序)
-
协议的请求/响应机制
general_request
如何与消息一起工作 -
如何识别设备所正在使用的协议版本
使用 ping协议与传感器建立通信应从获取协议版本开始。此协商过程包括两个步骤:
-
主机应用程序protocol_version从设备请求消息
-
设备响应protocol_version消息
在阅读这些示例之前,您应该熟悉消息格式规范。
请求协议版本
为了接收 protocol_version 消息,将先向发送 general_request 消息询问。
该 general_request 消息具有单个有效字节requested_id
= 5,表明我们希望得到响应的协议版本:
字节 | 数值(十六进制) | 数值(十进制) | 类型 | 名称 | 描述 |
---|---|---|---|---|---|
0 | 0x42('B') | 66 | u8 | 开始1 | 消息开始标识符 “ B” |
1 | 0x52('R') | 82 | u8 | 开始2 | 消息开始标识符 “ R” |
2-3 | 0x0002 | 2 | u16 | payload_length | 有效数据长度 |
4-5 | 0x0006 | 6 | u16 | message_id | 通用消息id |
6 | 0x00 | 0 | u8 | src_device_id | 发送设备ID。填零 |
7 | 0x00 | 0 | u8 | src_device_id | 接收设备ID。填零 |
8-9 | 0x0005 | 5 | u16 | 请求消息ID | 获取通信协议版本命令 |
10-11 | 0x00a1 | 161 | u16 | 和校验 | 66 + 82 + 2 + 6 + 0 + 0 + 5 = 161 |
字节应按以下顺序发送:0x42, 0x52, 0x02, 0x00, 0x06, 0x00, 0x00, 0x00, 0x05, 0x00, 0xa1, 0x00
请注意,消息以小端格式传输(请注意16位字段的字节顺序)
接收协议版本
如果一切正常,设备将通过一条 protocol_version消息响应请求。该 protocol_version 消息具有4个有效字节:
- version_major
- version_minor
- version_patch
- reserved
在此示例中,假设设备正在使用协议版本 1.2.3,则:
- version_major = 1
- version_minor = 2
- version_patch = 3
字节 | 值(十六进制) | 值(十进制) | 类型 | 名称 | 描述 |
---|---|---|---|---|---|
0 | 0x42('B') | 66 | u8 | 开始1 | 消息开始标识符“B” |
1 | 0x52('R') | 82 | u8 | 开始2 | 消息开始标识符“R” |
2-3 | 0x0004 | 4 | u16 | payload_length | 数据有效字节数 |
4-5 | 0x0005 | 5 | u16 | message_id | 协议版本命令(id#5)消息 |
6 | 0x00 | 0 | u8 | src_device_id | 发送设备ID。填充零 |
7 | 0x00 | 0 | u8 | dst_device_id | 接受设备ID。填充零 |
8 | 0x01 | 1 | u8 | version_major | 协议主要版本,v1.2.3的 "1" |
9 | 0x02 | 2 | u8 | version_minor | 协议次要版本,v1.2.3的 “2” |
10 | 0x03 | 3 | u8 | 版本补丁 | 协议补丁版本,v1.2.3的 "3" |
11 | 0x00 | 0 | u8 | 保留的 | 该字节未使用,填零 |
12-13 | 0x00a3 | 163 | u16 | 校验和 | 消息校验和。 |
字节将按以下顺序接收: 0x42, 0x52, 0x04, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x00, 0xa3, 0x00
请注意,消息保存以小端格式传输(请注意16位字段的字节顺序)