Appearance
UART Protocol & Firmware Integration
Provided Files
UART communication with the module is handled by the library:
yuki_module_client.c / yuki_module_client.h
For debugging purposes a python client is also available:
These files encapsulate the protocol and provide a simple interface for integration into your own firmware.
Integration into Your Own Firmware
Initialization
c
YukiModuleInterface iface = {
.ctx = uart_ctx,
.read = uart_read_fn,
.write = uart_write_fn,
.handler = on_value_changed
};
yuki_module_init(&iface, NULL);Initialization is performed via yuki_module_init() with a configuration structure YukiModuleInterface, which registers read/write functions as well as a callback for incoming data:
Callback Mechanism
The callback handler(id, type, read_only, data, len) is called for incoming SET commands and passes:
- id: identifier of the parameter
- type: data type (e.g. TYPE_UINT8, TYPE_STRING, etc.)
- read_only: flag indicating whether the value is write-protected
- data: pointer to payload data
- len: length of the payload
UART Protocol – Technical Description
The module communicates using a binary, compact TLV protocol (Type-Length-Value) over a simple UART connection. The interface is optimized for resource-constrained systems and supports both simple values and more complex payloads.
Message Format
Each message consists of a 2-byte header, a payload of up to 511 bytes, and a 2-byte CRC checksum:

| Offset | Field | Size | Description |
|---|---|---|---|
| 0 | T | 7 bits | Type or command (e.g. CMD_SET) |
| 0 | L[8] | 1 bit | Highest bit of the payload length (bit 8 / 9) |
| 1 | L[7:0] | 8 bits | Lower 8 bits of the payload length |
| 2 | V | L bytes | Payload |
The type is left-aligned in the first 7 bits of byte 0. The 8th bit of this byte is the highest bit of the payload length. Byte 1 contains the remaining 8 bits of the payload length. This results in a maximum payload size of 511 bytes.

byte0 = (T<<1) | ((L >> 8) & 1), byte1 = L & 0xFF
Protocol Commands
| Type value | Symbol | Description | Response payload |
|---|---|---|---|
| 0x00 | CMD_GET_PUBKEY | Returns the module's public signature key | Binary public key (64 bytes) |
| 0x01 | CMD_GET_IMEI | Returns the modem IMEI | IMEI string (15 bytes) |
| 0x02 | CMD_GET_ICCID | Returns the SIM ICCID | ICCID string (20 bytes) |
| 0x04 | CMD_SET | Transfers a value to the module | None |
| 0x05 | CMD_SYNC | Synchronizes all values with the cloud | None |
| 0x06 | CMD_VERSION | Returns the module firmware version | Version number as string |
| 0x07 | CMD_STATUS | Returns the system status (0 for OK or error codes) | None |
| 0x08 | CMD_GEO_REQ | Requests the current GNSS coordinates | None |
| 0x09 | CMD_GEO_RPT | Response message with GNSS coordinates |
CMD_GEO_RPT Payload
| Offset | Size | Field name | Type | Description | Unit |
|---|---|---|---|---|---|
| 0 | 1 | fix_type | UINT8 | 0 = no fix, 1 = 2D, 2 = 3D fix | - |
| 1 | 1 | sats | UINT8 | Number of visible/used satellites | - |
| 2 | 4 | ts_utc | UINT32 | UTC timestamp (Unix time in seconds) | s |
| 6 | 4 | lat_e7 | INT32 | Latitude (WGS-84) | 1e-7 ° |
| 10 | 4 | lon_e7 | INT32 | Longitude (WGS-84) | 1e-7 ° |
| 14 | 4 | alt_cm | INT32 | Altitude above MSL | cm |
| 18 | 4 | hdop_centi | UINT32 | Horizontal accuracy (HDOP × 100) | 1 = 0.01 HDOP |
| Total | 22 bytes | - | - | Fixed payload size for CMD_GEO_RPT | - |
The commands CMD_GET_PUBKEY, CMD_GET_IMEI, CMD_GET_ICCID, CMD_SYNC, CMD_VERSION, CMD_GEO_REQ and CMD_STATUS have no payload. Only the type (command byte) and length 0 are transmitted.
CMD_SET
The payload of a CMD_SET message has the following structure:
| Offset | Field | Size | Description |
|---|---|---|---|
| 0 | ID High | 1 byte | High byte of the parameter ID |
| 1 | ID Low | 1 byte | Low byte of the parameter ID |
| 2 | Flags | 1 byte | Bit 4 = read_only; other bits reserved |
| 3 | Type | 1 byte | Data type (see below) |
| 4 | Len High | 1 byte | (for binary and string data only): payload length, MSB |
| 5 | Len Low | 1 byte | (for binary and string data only): payload length, LSB |
| 6 | Payload | n bytes | Value, depending on type |
| 6+n | Checksum | 2 bytes | CRC checksum |
For non string-based types the explicit length field is omitted; the length is implied by the data type.
Supported Data Types
| Code | Type | Description |
|---|---|---|
| 0x01 | INT32 | 4 bytes |
| 0x02 | INT16 | 2 bytes |
| 0x03 | INT8 | 1 byte |
| 0x04 | UINT32 | 4 bytes |
| 0x05 | UINT16 | 2 bytes |
| 0x06 | UINT8 | 1 byte |
| 0x07 | BOOL | 1 byte (0x00 or 0x01) |
| 0x08 | UUID | 16 bytes |
| 0x09 | FLOAT | IEEE754, 4 bytes |
| 0x0A | DATETIME | e.g. Unix timestamp |
| 0x0B | DOUBLE | 8 bytes |
| 0x0C | BIN | Length + data field |
| 0x0D | UINT64 | 8 bytes |
| 0x0E | STRING | Length + UTF-8 data |
| 0x0F | INT64 | 8 bytes, signed |
Response Messages
Every received command is acknowledged with a response message. It contains:
T: identical to the received messageL: (at least 1)V[0]: error code (ErrCode)V[1..n]: response payload, if presentCRC[n+1..n+2]: CRC16 checksum

Error Codes (ErrCode)
| Value | Meaning |
|---|---|
| 0x00 | OK |
| 0x01 | Invalid command |
| 0x02 | Invalid argument |
| 0x03 | Device busy |
| 0xFF | Internal error |
Checksum Calculation
Each message is terminated with a 16-bit checksum (CRC-16/CCITT-FALSE) used to ensure the integrity of header and payload. The checksum is calculated over all bytes of header and payload, but not over the CRC bytes themselves.
| Parameter | Value |
|---|---|
| Generator polynomial | 0x1021 |
| Initial value | 0xFFFF |
| Final XOR | none (0x0000) |
| Bit order | MSB-first |
| Checksum range | Header (2 bytes) + payload (L bytes) |
c
uint16_t crc16_ccitt_false(const uint8_t *data, size_t len)
{
uint16_t crc = 0xFFFF;
for (size_t i = 0; i < len; ++i) {
crc ^= (uint16_t)data[i] << 8;
for (int b = 0; b < 8; ++b) {
crc = (crc & 0x8000) ? (uint16_t)((crc << 1) ^ 0x1021) : (uint16_t)(crc << 1);
}
}
return crc;
}CRC Algorithm (reference implementation in C)
Example Message (CMD_SET, UINT8)
Header: **0x08 0x05** // T = 0x04 (CMD_SET), L = 5
Payload: 0x12 0x34 0x00 0x06 0x05 [IDH IDL FLG TYP VAL ]
Checksum: 0xF7 0x07
Parameter IDs and Mapping
The UART protocol commands use numeric parameter IDs that can be freely assigned by the user. There is no fixed list – instead, the developer can define the meaning of the IDs individually.
In the cloud (both in the dashboard and via the REST API), descriptive names and types can be assigned to these IDs. This ensures that all transmitted values are correctly named and processed in context – regardless of the numeric ID.
Example: The value with parameter ID 0x1234 can be registered in the cloud as "Battery voltage" and later be read or visualized under this name.