The protocol

The protocol is designed for synchronous communications in a master->slave network. The slave will only send data when requested by the master. This allows the protocol to be used on a half-duplex bus like RS485. Some devices may also provide facilities to allow asynchronous communication.

Message Format

Each message consists of a header, optional payload, and checksum. The binary format is specified as follows:

Byte Type Name Description
0 u8 start1 Start frame identifier, ASCII 'B'
1 u8 start2 Start frame identifier, ASCII 'R'
2-3 u16 payload_length Number of bytes in payload.
4-5 u16 message_id The message id.
6 u8 src_device_id The device ID of the device sending the message.
7 u8 dst_device_id The device ID of the intended recipient of the message.
8-n u8[] payload The message payload.
(n+1)-(n+2) u16 checksum The message checksum. The checksum is calculated as the sum of all the non-checksum bytes in the message.

Scheme

Messages are divided into 4 categories:

  • general: messages that are used for general purpose signalling and communication.
  • read/get: messages that are sent from the device in response to a general_request from the host. These messages are designed to read data from the device.
  • write/set: messages that are sent from the host to configure some parameters on the device. These messages are designed to write data to the device.
  • control: messages that are sent from the host to command the device to perform some action. These messages are designed to perform more complex device interactions than atomic read/write.

There are a some messages that are implemented by all devices, referred to as the 'common' message set. Message ids # 0~999 are reserved for the common messages. The request message is a special message in the common set that is used to request the device to respond with a message from the get category. Each device must also define it's own message set specific to the operation of the particular device.

Message Definitions

Device Discovery

If necessary, Ping Protocol enabled devices may be discovered and identified by the host as follows:

  1. The host first requests the protocol version from the device
  2. After receiving a protocol version reply, the host switches to the matching protocol version and requests the device type and firmware version
  3. The host then loads the appropriate message set matching the device
  4. Communication may then continue using the device-specific messages

Negotiation example

Here we demonstrate a byte-by-byte breakdown of some messages sent between the host application (master) and the device (slave). This example illustrates a few points: - how to pack and unpack some message data (the byte-order of a message) - how the request/response mechanism of the protcol works with the general_request message - how to identify the protocol version that the device is using

Establishing communication with a sensor using the ping-protocol should begin with negotiating the protocol version. This negotiation process consists of two steps: - the host application requests a protocol_version message from the device - the device responds with a protocol_version message

Before reading these examples, you should be familiar with the message format specification.

Request protocol version

In order to receive a protocol_version message from the device, we will first send a general_request message to the device to ask for the message. The general_request message has a single payload field, requested_id. We populate this field with a value of 5 to indicate that we want the sensor to respond with a protocol_version message:

Byte Value (hex) Value (decimal) Type Name Description
0 0x42 ('B') 66 u8 start1 This is a message start identifier, an ascii letter 'B'
1 0x52 ('R') 82 u8 start2 This is a message start identifier, an ascii letter 'R'
2-3 0x0002 2 u16 payload_length The number of bytes in the general_request payload
4-5 0x0006 6 u16 message_id This message is a general_request (id pingmessage-common#6) message
6 0x00 0 u8 src_device_id The device ID of the device sending the message. This field is not currently implemented and should be populated with a value of zero
7 0x00 0 u8 dst_device_id The device ID of the intended recipient of the message. This portion is not currently implemented and should be populated with a value of zero
8-9 0x0005 5 u16 requested_id This is the message id that we would like the device to transmit to us. Valid ids are those in the get category of messages
10-11 0x00a1 161 u16 checksum The message checksum. The checksum is calculated as the sum of all the non-checksum bytes in the message: 66 + 82 + 2 + 6 + 0 + 0 + 5 = 161

The bytes should be transmitted in this order: 0x42, 0x52, 0x02, 0x00, 0x06, 0x00, 0x00, 0x00, 0x05, 0x00, 0xa1, 0x00

Note that the messages are transmitted in little-endian format (observe the byte-order of the 16 bit fields)

Receive protocol version

If everything is right, the sensor will respond to our request with a protocol_version message. The protocol_version message has 4 bytes in the payload: version_major, version_minor, version_patch, and reserved.

In this example, the device is using (a hypothetical) protocol version 1.2.3: - version_major = 1 - version_minor = 2 - version_patch = 3

Byte Value (hex) Value (decimal) Type Name Description
0 0x42 ('B') 66 u8 start1 This is a message start identifier, an ascii letter 'B'
1 0x52 ('R') 82 u8 start2 This is a message start identifier, an ascii letter 'R'
2-3 0x0004 4 u16 payload_length The number of bytes in the protocol_version payload
4-5 0x0005 5 u16 message_id This message is a protocol_version (id #5) message
6 0x00 0 u8 src_device_id The device ID of the device sending the message. This field is not currently implemented and should be populated with a value of zero
7 0x00 0 u8 dst_device_id The device ID of the intended recipient of the message. This field is not currently implemented and should be populated with a value of zero
8 0x01 1 u8 version_major This is the protocol major version, the first digit in our example: v1.2.3
9 0x02 2 u8 version_minor This is the protocol minor version, the second digit in our example: v1.2.3
10 0x03 3 u8 version_patch This is the protocol patch version, the third digit in our example: v1.2.3
11 0x00 0 u8 reserved This byte is unused and will normally be zero (but it might be any value)
12-13 0x00a3 163 u16 checksum The message checksum. The checksum is calculated as the sum of all the non-checksum bytes in the message: 66 + 82 + 4 + 5 + 0 + 0 + 1 + 2 + 3 + 0 = 163

The bytes will be received in this order: 0x42, 0x52, 0x04, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x00, 0xa3, 0x00

Note that the messages are transmitted in little-endian format (observe the byte-order of the 16 bit fields)