CAN Bus Documentation
Introduction
The Controller Area Network (CAN) bus is a robust serial communication protocol designed for reliable data transfer between multiple devices (nodes) over a shared bus. It was originally developed for automotive systems but is now widely used in robotics, drones, and industrial control.
Unlike protocols like UART or I²C, CAN allows many devices to talk on the same bus without a central master, making it great for distributed systems.
How It Works
- Physical layer: Two wires (CAN High, CAN Low) use differential signaling to reduce noise.
- Message-based protocol: Devices send messages (frames) instead of addressing each other directly.
- Arbitration: If multiple devices transmit at once, the one with the highest priority (lowest ID) continues, while others wait.
- Error detection: Built-in error checking and retransmission for reliability.
Diagram – Bus Topology
TODO: Update this with a better diagram, but this will do for now
Use Cases
- Automotive systems (engine sensors, airbags, ABS)
- Robotics and drones (distributed sensor data, actuator control)
- Industrial automation (motor controllers, PLCs)
Common Pitfalls / Gotchas
- Termination resistors: A 120Ω resistor is required at each end of the bus.
- Stub length: Keep connections short to avoid reflections.
- Baud rate mismatch: All devices must use the same bit rate.
- Debugging noise: Long or unshielded wires can introduce communication errors.
Tools to Debug
- USB-to-CAN adapters (e.g., CANtact, Peak-CAN) for connecting to a PC.
- Logic analyzer with CAN decoding.
- Software like Wireshark (with CAN plugins) or manufacturer-provided tools.
References
Onboarding Tutorial (STM32)
Goal: Set up two development boards to send and receive CAN messages.
Materials
- 2× STM32 boards with CAN peripherals (or with MCP2515 + TJA1050 CAN transceivers).
- Breadboard + jumper wires.
- 2× 120Ω resistors.
Steps
- Connect CANH ↔ CANH and CANL ↔ CANL between the two nodes.
- Place 120Ω resistors at each end of the bus.
- Flash one board with a “transmitter” program that sends a counter value.
- Flash the second board with a “receiver” program that prints incoming values over serial.
// Pseudo-code (STM32 HAL style)
CAN_TxHeaderTypeDef TxHeader;
uint8_t TxData[8] = {0};
uint32_t TxMailbox;
TxHeader.StdId = 0x321;
TxHeader.DLC = 1;
TxData[0] = counter++;
HAL_CAN_AddTxMessage(&hcan, &TxHeader, TxData, &TxMailbox);
Mini Challenges
- Modify the sender to toggle an LED on the receiver board.
- Add a second receiver and confirm both get the same messages.
- Experiment with changing message IDs and observe arbitration.