1. Before you start
The UART API is a firmware build option and works with RTLS firmware. Firmware built
for the Ethernet API does not listen for these commands, so check this first:
- Connect at 115200 baud, 8N1, no flow control.
- Restart the device. It sends a 50-byte PROPERTIES frame once it has started.
- Send
23 23 00 00 24 03. The device replies with the same PROPERTIES frame.
If neither frame appears, the cause is the firmware build or the connection, not your
message format. The serial port depends on the hardware, and some builds use the USB
port instead. Contact support@rtloc.com with
your hardware type to confirm which port and firmware to use.
4. Commands
The stream is off after every start of the device. Send
STREAM (START) to receive DISTANCES.
PROPERTIES (GET)
TO DEVICE
cmd 36
Request the device properties.
| Field | Type | Bytes | Example | Description |
| preamble | uint16 | 2 | '##' | Two '#' characters |
| length | uint16 | 2 | 0 | Payload bytes only |
| cmd | uint8 | 1 | 36 | |
| version | uint8 | 1 | 3 | Send 3. The device does not check it. |
PROPERTIES
FROM DEVICE
cmd 24
Device properties. Also sent once, unrequested, after the device has started.
| Field | Type | Bytes | Example | Description |
| preamble | uint16 | 2 | '##' | Two '#' characters |
| length | uint16 | 2 | 50 | Complete message, including this header |
| cmd | uint8 | 1 | 24 | |
| version | uint8 | 1 | 2 | Command protocol version |
| runmode | uint8 | 1 | 3 | Obsolete. Ignore. |
| inner length | uint16 | 2 | — | Internal size value. It is not the number of bytes sent. Ignore. |
| uptime | uint32 | 4 | 100 | Uptime of the device, in seconds |
| antenna delay (RX) | uint16 | 2 | 16500 | RX antenna delay of the device |
| antenna delay (TX) | uint16 | 2 | 16500 | TX antenna delay of the device |
| reserved | uint8 | 1 | — | Not filled in. Ignore. |
| hw version | uint8 | 1 | 1 | Hardware version |
| reserved | uint32 | 4 | — | Not filled in. Ignore. |
| FW version | uint16 | 2 | 566 | Firmware version: major * 100 + minor. 566 means 5.66. |
| FW CRC | uint16 | 2 | — | Firmware CRC |
| config version | uint16 | 2 | 1 | Version stored inside the active config file. 0 or 0xFFFF means there is no valid config. Frame offset 27. |
| tagspeed version | uint16 | 2 | 1 | Tagspeed version |
| FW version (sub) | uint8 | 1 | 1 | Firmware patch number |
| reserved | bytes | 6 | — | Not filled in. Ignore. |
| uid | uint64 | 8 | — | Unique ID. Frame offset 38. |
| bootloader version | uint16 | 2 | — | Bootloader version |
| bootloader CRC | uint16 | 2 | — | Bootloader CRC |
UNIQUE ID (GET)
TO DEVICE
cmd 3
Request the short device ID.
| Field | Type | Bytes | Example | Description |
| preamble | uint16 | 2 | '##' | Two '#' characters |
| length | uint16 | 2 | 0 | Payload bytes only |
| cmd | uint8 | 1 | 3 | |
| version | uint8 | 1 | 3 | Send 3. The device does not check it. |
UNIQUE ID
FROM DEVICE
cmd 4
The short device ID.
| Field | Type | Bytes | Example | Description |
| preamble | uint16 | 2 | '##' | Two '#' characters |
| length | uint16 | 2 | 8 | Complete message, including this header |
| cmd | uint8 | 1 | 4 | |
| version | uint8 | 1 | 3 | Command protocol version |
| id | uint16 | 2 | 101 | Short device ID |
BATTERY (GET)
TO DEVICE
cmd 7
Request the battery value.
| Field | Type | Bytes | Example | Description |
| preamble | uint16 | 2 | '##' | Two '#' characters |
| length | uint16 | 2 | 0 | Payload bytes only |
| cmd | uint8 | 1 | 7 | |
| version | uint8 | 1 | 3 | Send 3. The device does not check it. |
BATTERY
FROM DEVICE
cmd 8
The battery value.
| Field | Type | Bytes | Example | Description |
| preamble | uint16 | 2 | '##' | Two '#' characters |
| length | uint16 | 2 | 8 | Complete message, including this header |
| cmd | uint8 | 1 | 8 | |
| version | uint8 | 1 | 3 | Command protocol version |
| battery | uint16 | 2 | — | Battery voltage value. The unit depends on the hardware. |
TX POWER (GET)
TO DEVICE
cmd 44
Request the current TX power.
| Field | Type | Bytes | Example | Description |
| preamble | uint16 | 2 | '##' | Two '#' characters |
| length | uint16 | 2 | 0 | Payload bytes only |
| cmd | uint8 | 1 | 44 | |
| version | uint8 | 1 | 3 | Send 3. The device does not check it. |
TX POWER
FROM DEVICE
cmd 46
The current TX power.
| Field | Type | Bytes | Example | Description |
| preamble | uint16 | 2 | '##' | Two '#' characters |
| length | uint16 | 2 | 8 | Complete message, including this header |
| cmd | uint8 | 1 | 46 | |
| version | uint8 | 1 | 3 | Command protocol version |
| tx power | uint16 | 2 | 33 | TX power amplification, in dB |
HAIRS (SET)
TO DEVICE
cmd 48
Configure the hairs: the broadcast of the config over UWB.
| Field | Type | Bytes | Example | Description |
| preamble | uint16 | 2 | '##' | Two '#' characters |
| length | uint16 | 2 | 4 | Payload bytes only |
| cmd | uint8 | 1 | 48 | |
| version | uint8 | 1 | 3 | Send 3. The device does not check it. |
| enable | uint8 | 1 | 1 | 0 = disable, 1 = enable |
| save | uint8 | 1 | 0 | 1 = save to permanent storage |
| size | uint8 | 1 | 0 | 0 = small (128 bytes), 1 = big (512 bytes) |
| continuous | uint8 | 1 | 0 | 1 = always transmit, instead of only on request |
HAIRS ACK
FROM DEVICE
cmd 49
Confirms that HAIRS (SET) was received. It does not report the settings.
| Field | Type | Bytes | Example | Description |
| preamble | uint16 | 2 | '##' | Two '#' characters |
| length | uint16 | 2 | 8 | Complete message, including this header |
| cmd | uint8 | 1 | 49 | |
| version | uint8 | 1 | 3 | Command protocol version |
| ack | uint16 | 2 | 6666 | Always 6666 |
STREAM (START)
TO DEVICE
cmd 5
Start the distance stream.
| Field | Type | Bytes | Example | Description |
| preamble | uint16 | 2 | '##' | Two '#' characters |
| length | uint16 | 2 | 0 | Payload bytes only |
| cmd | uint8 | 1 | 5 | |
| version | uint8 | 1 | 3 | Send 3. The device does not check it. |
STREAM (STOP)
TO DEVICE
cmd 6
Stop the distance stream.
| Field | Type | Bytes | Example | Description |
| preamble | uint16 | 2 | '##' | Two '#' characters |
| length | uint16 | 2 | 0 | Payload bytes only |
| cmd | uint8 | 1 | 6 | |
| version | uint8 | 1 | 3 | Send 3. The device does not check it. |
STREAM (GET)
TO DEVICE
cmd 50
Request the stream status.
| Field | Type | Bytes | Example | Description |
| preamble | uint16 | 2 | '##' | Two '#' characters |
| length | uint16 | 2 | 0 | Payload bytes only |
| cmd | uint8 | 1 | 50 | |
| version | uint8 | 1 | 3 | Send 3. The device does not check it. |
STREAM (STATUS)
FROM DEVICE
cmd 51
The stream status.
| Field | Type | Bytes | Example | Description |
| preamble | uint16 | 2 | '##' | Two '#' characters |
| length | uint16 | 2 | 7 | Complete message, including this header |
| cmd | uint8 | 1 | 51 | |
| version | uint8 | 1 | 3 | Command protocol version |
| status | uint8 | 1 | 1 | 0 = not streaming, 1 = streaming |
DISTANCES
FROM DEVICE
cmd 2
Measured distances, sent while the stream is on. Devices in the anchor role and tags in TWR3 mode send these.
| Field | Type | Bytes | Example | Description |
| preamble | uint16 | 2 | '##' | Two '#' characters |
| length | uint16 | 2 | 11 + nb_distances * 6 | Complete message, including this header |
| cmd | uint8 | 1 | 2 | |
| version | uint8 | 1 | 4 | Command protocol version |
| nb distances | uint8 | 1 | 5 | Number of distance reports that follow |
| frame | uint32 | 4 | 12345 | Current frame of the system |
| repeat nb_distances times |
| id | uint16 | 2 | 101 | ID of the other device |
| distance | uint16 | 2 | 167 | Distance to that device, in cm. Only values from 1 to 9999 are reported. |
| quality 1 | uint8 | 1 | 43 | Link quality indicator. Use it as a relative value. |
| quality 2 | uint8 | 1 | 44 | Link quality indicator. Use it as a relative value. |
CONFIG UPLOAD
TO DEVICE
cmd 10
Send one part of a config file to the device. See Config transfer.
| Field | Type | Bytes | Example | Description |
| preamble | uint16 | 2 | '##' | Two '#' characters |
| length | uint16 | 2 | 19 or 51 | Payload bytes only |
| cmd | uint8 | 1 | 10 | |
| version | uint8 | 1 | 3 | Send 3. The device does not check it. |
| target | uint8 | 1 | 1 | 1 = config |
| file version | uint16 | 2 | — | Version of the config |
| crc total | uint16 | 2 | — | CRC-16 of the complete config file |
| size | uint32 | 4 | 4096 | Size of the complete config file, in bytes |
| part | uint16 | 2 | 1 | Number of this part |
| parts total | uint16 | 2 | 128 | Number of data parts |
| part size | uint16 | 2 | 32 | Always 32 |
| crc part | uint16 | 2 | — | CRC-16 of the data bytes in this part |
| hw version | uint8 | 1 | 0 | Send 0 |
| flags | uint8 | 1 | 0 | Send 0 |
| data | bytes | 0 or 32 | — | Empty in part 0, 32 bytes in every other part |
CONFIG UPLOAD REPLY
FROM DEVICE
cmd 11
Says which part the device wants next.
| Field | Type | Bytes | Example | Description |
| preamble | uint16 | 2 | '##' | Two '#' characters |
| length | uint16 | 2 | 21 | Complete message, including this header |
| cmd | uint8 | 1 | 11 | |
| version | uint8 | 1 | 3 | Command protocol version |
| target | uint8 | 1 | 1 | Copied from the request |
| part req | uint16 | 2 | 2 | Next part to send. Anything other than the sent part + 1 means the part failed. |
| file version | uint16 | 2 | — | Copied from the request |
| hw version | uint8 | 1 | 0 | Copied from the request |
| reserved | bytes | 8 | — | Ignore |
| end | uint8 | 1 | 124 | End marker, '|' |
CONFIG DOWNLOAD
TO DEVICE
cmd 12
Request one 32-byte part of the config file on the device. See Config transfer.
| Field | Type | Bytes | Example | Description |
| preamble | uint16 | 2 | '##' | Two '#' characters |
| length | uint16 | 2 | 15 | Payload bytes only |
| cmd | uint8 | 1 | 12 | |
| version | uint8 | 1 | 3 | Send 3. The device does not check it. |
| target | uint8 | 1 | 1 | 1 = config |
| part req | uint16 | 2 | 0 | Requested part. The first part is 0. |
| reserved | bytes | 11 | 0 | Send 0 |
| end | uint8 | 1 | 124 | End marker, '|' |
CONFIG DOWNLOAD REPLY
FROM DEVICE
cmd 11
One part of the config file. It uses the same cmd as the upload reply, but is 57 bytes long.
| Field | Type | Bytes | Example | Description |
| preamble | uint16 | 2 | '##' | Two '#' characters |
| length | uint16 | 2 | 57 | Complete message, including this header |
| cmd | uint8 | 1 | 11 | |
| version | uint8 | 1 | 3 | Command protocol version |
| target | uint8 | 1 | 1 | 1 = config |
| file version | uint16 | 2 | — | Version of the stored config |
| crc total | uint16 | 2 | — | CRC-16 of the complete config file |
| size | uint32 | 4 | 4096 | Size of the complete config file, in bytes |
| part | uint16 | 2 | 0 | Number of this part |
| parts total | uint16 | 2 | 128 | Size divided by 32, rounded down. Use size to find the end. |
| part size | uint16 | 2 | 32 | Always 32 |
| crc part | uint16 | 2 | — | CRC-16 of the 32 data bytes |
| reserved | bytes | 2 | — | Ignore |
| data | bytes | 32 | — | The data of this part |
RESET
TO DEVICE
cmd 37
Restart the device.
| Field | Type | Bytes | Example | Description |
| preamble | uint16 | 2 | '##' | Two '#' characters |
| length | uint16 | 2 | 0 | Payload bytes only |
| cmd | uint8 | 1 | 37 | |
| version | uint8 | 1 | 3 | Send 3. The device does not check it. |
5. Config transfer
A config file is transferred in parts of 32 data bytes. Treat the file
as binary data: its contents are the same as what a download returns. The largest
possible file depends on the hardware, because the config area ranges from 8 KB to 32 KB.
CRC
Both CRC fields use CRC-16/CCITT-FALSE: polynomial 0x1021, initial value
0xFFFF, no reflection and no final XOR. The check value for the text
123456789 is 0x29B1.
Upload
- Send STREAM (STOP) and wait for the status. The upload also stops ranging.
- Send CONFIG UPLOAD part 0 without data (length 19). The device erases its stored config, which can take seconds, and then asks for part 1.
- Send parts 1 up to and including
parts total (length 51), and wait for each reply. Fill the last part up to 32 bytes with 0xFF. crc part covers all 32 bytes; crc total and size cover the file without the fill bytes.
- If
part req is not the sent part + 1, or a reply does not arrive, start again from part 0. Do not resend a single part.
- Send RESET and wait for the PROPERTIES frame after the restart.
- Check
config version in that frame. It must match the version stored inside your config file. This is the only confirmation: the last reply looks the same when the total CRC is wrong. In that case the device reports version 0.
Download
- Send STREAM (STOP) and wait for the status.
- Request PROPERTIES. Only continue if
config version is not 0 or 0xFFFF: on some hardware, reading an empty config area crashes the device.
- Send CONFIG DOWNLOAD with
part req 0. The reply contains size and crc total.
- Request the next parts until you have received
size bytes. Never request a part beyond that point. The device does not signal the end of the file.
- Cut the result to
size bytes, and check it against crc total.
- Send RESET. This is required: the device sends no distances after a download until it restarts.
6. Not available over UART
The device does not reply to any of these:
| Item | Status |
| Heartbeat | The UART API has no heartbeat, in either direction. Use PROPERTIES (GET) to check that a device is responding. |
| '@CX@' frames | This is the Ethernet format. Over UART, the device only accepts frames that start with ## and discards all others. |
| cmd 45 | Setting the TX power is not supported. It can only be read, with cmd 44. |
| cmd 47 | Reading the hairs configuration is not supported. |
| cmd 28, 38–42 | Not usable. Do not use these. |
Firmware upload is not covered on this page. Contact support@rtloc.com if you need it.
7. Examples
| Action | Bytes to send (hex) |
| Request properties | 23 23 00 00 24 03 |
| Start the stream | 23 23 00 00 05 03 |
| Stop the stream | 23 23 00 00 06 03 |
| Request the stream status | 23 23 00 00 32 03 |
| Request TX power | 23 23 00 00 2C 03 |
| Enable small hairs, without saving | 23 23 04 00 30 03 01 00 00 00 |
| Request config part 0 | 23 23 0F 00 0C 03 01 00 00 00 00 00 00 00 00 00 00 00 00 00 7C |
| Restart the device | 23 23 00 00 25 03 |