Skip to content

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

Node A ─┬───────┬─ Node B
        |      |
      CANH    CANL
        |      |
Node C ─┴───────┴─ Node D


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

  1. Connect CANH ↔ CANH and CANL ↔ CANL between the two nodes.
  2. Place 120Ω resistors at each end of the bus.
  3. Flash one board with a “transmitter” program that sends a counter value.
  4. 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.