Skip to Content
Hardware OverviewCAN Protocol

CAN Protocol

Controller Area Network (CAN) is a robust, differential serial bus designed for real-time embedded systems. It is the standard communication layer for Robstride and most MIT-derived QDD actuators.

Why CAN?

  • Multi-drop — up to 127 nodes share a single twisted pair, no hub needed
  • Deterministic — priority-based arbitration gives hard latency bounds
  • Differential signaling — immune to ground-loop noise in motor cabinets
  • Error detection — hardware CRC, bit stuffing, and ACK checks
  • Speed — 1 Mbit/s gives a ~1 kHz control loop with eight motors on the bus

Physical Layer

CAN uses two wires: CAN-H (dominant high, ~3.5 V) and CAN-L (dominant low, ~1.5 V). The differential voltage is ≈2 V for a dominant (logic 0) bit and 0 V for a recessive (logic 1) bit.

dominant bit recessive bit CAN-H: ────────────┐ ┌───────────── │ │ CAN-L: ────────────┘ └───────────── 3.5 V / 1.5 V 2.5 V / 2.5 V

Termination

Both ends of the bus must have 120 Ω termination resistors across CAN-H and CAN-L. Without termination you will see reflections and intermittent errors.

Host interface Node 1 Node N [120Ω]────────────────────────────────[120Ω] CAN-H ═══════════════════════════════ CAN-H CAN-L ═══════════════════════════════ CAN-L

CAN 2.0B Frame Format

Robstride uses the extended frame (29-bit identifier):

┌──────┬────────┬─────┬──────┬────────────────────┬─────┐ │ SOF │ ID │ RTR │ DLC │ Data (0–8 bytes) │ CRC │ │ 1 b │ 29 b │ 1 b │ 4 b │ 0–64 bits │15+1 │ └──────┴────────┴─────┴──────┴────────────────────┴─────┘

The Robstride protocol encodes motor ID and command type inside the 29-bit extended ID field, following the MIT Mini Cheetah motor driver convention.

MIT Motor Protocol (Robstride)

Extended ID layout

Bits 28–24: Command type Bits 23–8: Parameter (depends on command) Bits 7–0: Motor CAN ID

Command types

Cmd byteFunction
0x00Enter motor mode
0x01Exit motor mode
0x02Zero position
0x03MIT control (position + velocity + torque)
0x04Read parameter
0x05Write parameter
0xFFFault reset

MIT Control frame (Cmd 0x03)

This is the main motion command. The 8-byte payload encodes desired position, velocity, stiffness (Kp), damping (Kd), and feedforward torque:

Byte 0–1: position (uint16, mapped from –π…+π rad) Byte 2–3: velocity (uint16, mapped from –30…+30 rad/s) Byte 4: Kp (uint8, mapped from 0…500 N·m/rad) Byte 5: Kd (uint8, mapped from 0…5 N·m·s/rad) Byte 6–7: torque_ff (uint16, mapped from –18…+18 N·m)

All values are linearly mapped to the wire format using:

raw = (value − min) / (max − min) × (2^bits − 1)

See the Software section for Python helper functions that handle this packing automatically.

Interface Cards

To connect a Linux host to the CAN bus you need a CAN interface:

InterfaceForm factorNotes
Canable / Canable ProUSB dongleCheapest, SocketCAN compatible
PEAK PCAN-USBUSB dongleIndustrial grade, good Linux support
Waveshare CAN HATRaspberry Pi HATMCP2515 + SPI, works at 1 Mbit/s
Kvaser Leaf LightUSBHigh-end, good for logging

All of these appear as can0 / can1 under SocketCAN on Linux.

Last updated on