wip website docu

This commit is contained in:
2026-05-21 07:16:39 +02:00
parent ac8305953a
commit d989b41bdd
3 changed files with 336 additions and 73 deletions

View File

@@ -0,0 +1,194 @@
---
title: "CAN Bus Protocol"
date: 2026-05-21
draft: false
description: "Complete documentation of the CAN bus communication protocol between PlantCtrl sensor modules and main controller."
tags: ["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 |
## Error Detection & Blink Codes
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.

View File

@@ -0,0 +1,142 @@
---
title: "CAN Bus IDs and Wire Format"
date: 2026-05-21
draft: false
description: "Quick reference for CAN bus identifiers, message formats, and on-the-wire data structures."
tags: ["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
```rust
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`:
```rust
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.