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 VTermination
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-LCAN 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 IDCommand types
| Cmd byte | Function |
|---|---|
0x00 | Enter motor mode |
0x01 | Exit motor mode |
0x02 | Zero position |
0x03 | MIT control (position + velocity + torque) |
0x04 | Read parameter |
0x05 | Write parameter |
0xFF | Fault 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:
| Interface | Form factor | Notes |
|---|---|---|
| Canable / Canable Pro | USB dongle | Cheapest, SocketCAN compatible |
| PEAK PCAN-USB | USB dongle | Industrial grade, good Linux support |
| Waveshare CAN HAT | Raspberry Pi HAT | MCP2515 + SPI, works at 1 Mbit/s |
| Kvaser Leaf Light | USB | High-end, good for logging |
All of these appear as can0 / can1 under SocketCAN on Linux.