Files
2026-05-21 07:16:39 +02:00

4.2 KiB
Raw Permalink Blame History

title, date, draft, description, tags
title date draft description tags
CAN Bus IDs and Wire Format 2026-05-21 false Quick reference for CAN bus identifiers, message formats, and on-the-wire data structures.
can
protocol
wire-format

CAN Bus IDs and Wire Format

A concise technical reference for the PlantCtrl CAN bus protocol.

Quick Reference Table

CAN ID (hex) Message Type Direction Payload
0x03E8 Moisture Data - Plant 0, Slot A Sensor → Controller u8 plant + u8 slot + u16 hz
0x0400 Identify Command - Plant 0, Slot A Controller → Sensor (empty)
0x042F Moisture Data - Plant 15, Slot A Sensor → Controller u8 plant + u8 slot + u16 hz
0x0467 Firmware Build - Plant 3, Slot B Sensor → Controller u32 build_minutes

ID Calculation Formula

ID = 0x03E8 + Message_Offset + Plant_Index (+ Slot_Offset if B)

Constants

Constant Value (hex) Description
SENSOR_BASE_ADDRESS 0x03E8 Base address for all messages
MOISTURE_DATA_OFFSET 0x00 Moisture data group
IDENTIFY_CMD_OFFSET 0x20 Identify command group
FIRMWARE_BUILD_OFFSET 0x40 Firmware build group
B_SLOT_OFFSET 0x10 Offset for Slot B within a group

Message Type Offsets

pub const MOISTURE_DATA_OFFSET: u16 = 0;      // sensor → controller
pub const IDENTIFY_CMD_OFFSET: u16 = 32;      // controller → sensor
pub const FIRMWARE_BUILD_OFFSET: u16 = 64;    // sensor → controller

On-the-Wire Formats

Moisture Data Frame (Sensor → Controller)

CAN ID: 0x03E8 + offset + plant_index (or + 16 + plant_index for Slot B)

Byte Field Type
0 plant u8 (015)
1 sensor SensorSlot (A=0, B=1)
2-3 hz u16 big-endian

Example: Plant 7, Slot A, frequency 45 Hz

CAN ID: 0x0415
Payload: [07 00 00 2D]
         plant=7, sensor=A, hz=45 (0x002D)

Firmware Build Frame (Sensor → Controller)

CAN ID: 0x03E8 + 64 + plant_index (or + 80 + plant_index for Slot B)

Byte Field Type
0-3 build_minutes u32 big-endian

Example: Build timestamp 1,745,239,200 minutes since epoch (May 2026)

CAN ID: 0x0440
Payload: [00 00 6A F8]
         build_minutes = 1,745,239,200

Identify Command Frame (Controller → Sensor)

CAN ID: 0x03E8 + 32 + plant_index (or + 48 + plant_index for Slot B)

Byte Field Type
(none) (empty payload) -

Example: Identify Plant 5, Slot A

CAN ID: 0x0410
Payload: (empty)

Addressing Scheme Details

Plant Index Range

  • Valid: 015 (decimal) or 18 on hardware jumpers (mapped internally as 07)
  • Slot A: plant_index = jumper value - 1
  • Slot B: Same mapping, but ID offset differs by +16

Slot Selection

Hardware Internal Value
Jumper on PA3 (Low) Slot A (0)
Jumper on PA3 (High) Slot B (1)

Error Detection IDs

The sensor module monitors for unexpected messages:

  • Moisture Data collision: If a sensor receives moisture data addressed to itself, it triggers error code 1 (1 info blink, 2 warning blinks)
  • CAN errors: Bus-off, EWGF, EPVF flags trigger warning LED blinking

Protocol Extensions

To add new message types:

  1. Define offset in canapi/src/lib.rs:

    pub const NEW_MESSAGE_OFFSET: u16 = 96; // Next available slot
    
  2. Implement message struct with bincode serialization

  3. Add receive handler on both sides

  4. Update documentation

Binary Protocol Reference

bincode v2 Serialization

  • u8: Single byte, no sign extension
  • u16: 2 bytes big-endian (network order)
  • u32: 4 bytes big-endian (network order)
  • No varints fixed size for predictable CAN frame lengths

CAN Frame Structure

| Arbitration Field | Control Field | Data Field (8 bytes) |
|-------------------|---------------|----------------------|
| 11-bit ID         | RTR + IDE     | Payload (max 4-6 bytes)|

All PlantCtrl messages fit within the 8-byte data field with room for CAN overhead.