Files
PlantCtrl/rust/website/content/Hardware/CAN-Bus-Protocol/1745239200000-CAN-Bus-Protocol/index.md
2026-05-21 07:16:39 +02:00

7.0 KiB
Raw Blame History

title, date, draft, description, tags
title date draft description tags
CAN Bus Protocol 2026-05-21 false Complete documentation of the CAN bus communication protocol between PlantCtrl sensor modules and main controller.
can
protocol
sensor

CAN Bus Protocol

The PlantCtrl system uses a custom CAN bus-based communication protocol to connect sensor modules (moisture sensors) with the MainBoard controller. This modular design allows for scalable, reliable digital communication even over long cable runs and in electrically noisy environments.

Overview

  • Protocol: Standard CAN 2.0A (11-bit identifier)
  • Baud Rate: 50 kbps
  • Base Address: 0x03E8 (decimal 1000)
  • Maximum Plants: 16 per sensor module
  • Sensors per Plant: 2 slots (A and B) for redundancy or larger planters

CAN Bus IDs

All messages use the standard base address 0x03E8 with message-specific offsets. The ID structure is:

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

Message Groups

Group Offset (hex) Direction Description
Moisture Data 0x00 Sensor → Controller Periodic moisture readings
Identify Command 0x20 Controller → Sensor LED identification command
Firmware Build 0x40 Sensor → Controller Compile-time build timestamp

Plant Addressing (Slots A & B)

Each plant gets two sensor slots:

  • Slot A: Base offset + plant index (015)
  • Slot B: Base offset + 16 + plant index (015)

Example ID Calculations

Message Type Plant Slot CAN ID (hex)
Moisture Data 0 A 0x03E8
Moisture Data 7 A 0x0415
Moisture Data 15 A 0x042F
Identify Command 0 A 0x0400
Firmware Build 3 B 0x0467

Message Formats

All messages are serialized using bincode v2 (fixed-size integers, no varints). Each message fits within a single CAN frame.

Moisture Data (Sensor → Controller)

Sent periodically by each sensor module. Contains:

Field Type Description
plant u8 Plant index (015)
sensor SensorSlot A or B slot
hz u16 Measured frequency in Hz

Total size: 4 bytes (fits easily in CAN frame)

Identify Command (Controller → Sensor)

Sent by the controller to trigger an LED identification sequence on the sensor module.

Field Type Description
(empty) - No payload data

Purpose: When received, the sensor blinks its status LED for a few seconds to confirm it's online and properly configured.

Firmware Build (Sensor → Controller)

Sent immediately after receiving an Identify Command. Contains:

Field Type Description
build_minutes u32 Compile-time timestamp in minutes since Unix epoch

Purpose: Allows the controller to track firmware versions and deployment history without requiring a separate request.

Sensor Configuration

Each sensor module is configured via hardware jumpers on startup. The configuration is read by the CH32V203 MCU and determines:

  • Whether it's Slot A or B for a plant
  • The plant index (18)

Hardware Switches

Pin Function
PA3 Slot selector: Low = A, High = B
PA4 Address bit 1 (value: 1)
PA5 Address bit 2 (value: 2)
PA6 Address bit 3 (value: 4)
PA7 Address bit 4 (value: 8)

Valid Addresses

  • Allowed: 18 (binary combinations of bits 1,2,4,8)
  • Invalid: 0 or >8 (will trigger error code)

Example Configurations

Address Binary Jumpers
1 0001 PA4 only
3 0011 PA4 + PA5
7 0111 PA4 + PA5 + PA6
8 1000 PA7 only

The sensor module performs floating pin detection at startup. If any configuration pin is left floating (not connected to VCC or GND), the system enters an error state and blinks a diagnostic code.

Error Code Table

Code Cause LED Pattern
1 PB4 floating (bit 1) 1 blink info, 2 blinks warning
2 PB5 floating (bit 2) 2 blinks info, 2 blinks warning
3 PB6 floating (bit 3) 3 blinks info, 2 blinks warning
4 PB7 floating (bit 4) 4 blinks info, 2 blinks warning
5 PB3 floating (A/B selector) 5 blinks info, 2 blinks warning
6 Invalid address (0 or >8) 6 blinks info, 2 blinks warning

LED Indicators

  • Info LED (PA10): Green indicates information state
  • Warning LED (PA9): Yellow/Orange indicates error/warning state

The blink pattern repeats 5 times, then the system resets automatically.

Address Collision Detection

The protocol includes built-in collision detection. If a sensor receives a moisture data packet addressed to itself, it triggers an error sequence:

  • Blink code: 1 info blink, 2 warning blinks
  • Log message: "We should never receive moisture packets addressed to ourselves"

This indicates another node is using the same jumper configuration.

CAN Bus Robustness Features

The firmware implements several features for reliable operation:

Automatic Retransmission (NART)

Enabled on the CH32V203 CAN controller to recover from transient errors without manual intervention.

Resync Jump Width (SJW = 4TQ)

Increased from default (1TQ) to improve jitter tolerance over long cable runs. This allows the receiver to resynchronize with the bit stream even if timing drifts slightly.

Error Status Monitoring

The controller monitors CAN error registers for:

  • Bus-off condition (BOFF)
  • Error warning flag (EWGF)
  • Error passive flag (EPVF)

When errors are detected, warning LEDs blink and the system logs the status.

Troubleshooting

Sensor Not Detected

  1. Check all jumpers ensure no floating pins
  2. Verify address is 18 (not 0 or >8)
  3. Confirm slot selector (A/B) matches expected configuration
  4. Listen for CAN traffic with a CAN analyzer
  5. Check error blink codes on the sensor module

Address Collision

  • Two sensors using identical jumper settings will cause collisions
  • Use the collision detection feature to identify duplicate addresses
  • Reconfigure one of the conflicting sensors to a different address

Communication Errors

  • Bus-off: Check CAN termination resistors (120Ω at each end)
  • High error rate: Verify cable quality and shielding
  • Intermittent errors: Check for electrical noise from pumps or motors

Future Extensions

The protocol is designed to be extensible. New message types can be added by:

  1. Defining a new offset in canapi/src/lib.rs
  2. Implementing the corresponding message struct with bincode serialization
  3. Adding receive handlers on both sensor and controller sides
  4. Documenting the new ID range and format

The current design supports up to 64 distinct message types (16 plants × 2 slots × 2 directions) while maintaining a clean, plant-indexed addressing scheme.