Protocol Specification
Message Format (Variable Length: 4β31 bytes)
ββββββββββββ¬ββββββββββββββ¬βββββββββββ¬ββββββββββββββββββ¬βββββββββββ
β typeID β commandType β data_len β data[0..N] β crc8 β
β (1 byte) β (1 byte) β (1 byte) β (0β27 bytes) β (1 byte) β
ββββββββββββ΄ββββββββββββββ΄βββββββββββ΄ββββββββββββββββββ΄βββββββββββ
| Field | Size | Description |
|---|---|---|
typeID |
1 byte | Module type (sensor=1, motor=2, etc.) |
commandType |
1 byte | Command (read=0, set=1, reset=2, etc.) |
data_len |
1 byte | Number of payload bytes (0β27) |
data[] |
0β27 bytes | Opaque payload data (user-defined format) |
crc8 |
1 byte | CRC-8 over typeID, commandType, data_len, data[] |
Notes:
addressexists in the struct but is not serialized (used for routing at the application layer).- Maximum frame size is 31 bytes to fit within Arduino Wireβs 32-byte buffer.
- CRC excludes
addressand the CRC byte itself. - Payload is opaque bytes; applications can encode floats, ints, structs, etc.
Communication Patterns
Controller [4β31 byte message]> Peripheral # Send command
Controller [I2C request]> Peripheral # Request data
Controller <[4β31 byte response] Peripheral # Response
Standard Values
Module Types
0: Generic1: Sensor2: Actuator3: Display4: Input
Command Types
0: Read data1: Set parameters2: Reset3: Calibrate
CRC
- Polynomial: 0x07 (CRC-8)
- Calculated using
crc8_nibble_calculate()(crc8_nibble variant) - Applied to serialized header + payload (bytes 0 through 2 + data_len)
Timing Guidelines
- 10ms minimum between messages
- 50ms timeout for peripheral response
- 100kHz I2C clock speed (standard)
- Addresses 0x08-0x77 usable
Example: Encoding a Float
To send a float value in the payload:
crumbs_message_t m = {0};
m.type_id = 1;
m.command_type = 1;
float value = 3.14f;
m.data_len = sizeof(float);
memcpy(m.data, &value, sizeof(float));