Probe actuators on a CAN bus
Quick recipes for inspecting what's on a CAN bus without loading the controller_manager. Use these before a real-hardware bringup to verify wiring and DIP-switch IDs, or as the first step in any "motors aren't responding" debug.
All of these are read-only: no Enable, no MIT operation control, no parameter writes. Safe against a powered robot in any state.
Confirm the kernel sees the bus
ip -br link show type can
# Expected:
# can0 UP <NOARP,UP,LOWER_UP,ECHO>
# can1 UP <NOARP,UP,LOWER_UP,ECHO>
UP is what you want. DOWN means run the bring-up commands.
UNKNOWN (no state column) means the kernel sees the adapter but no
ip link set has configured a bitrate yet.
Detail per interface:
ip -d link show can0
# Look for: state UP, can state ERROR-ACTIVE, bitrate 1000000
ERROR-ACTIVE is the healthy state — frames are flowing both ways
and the bus is acking. ERROR-WARNING is transient and self-recovers;
ERROR-PASSIVE means many errors lately (often actuator power off);
BUS-OFF is hard-stop and requires a power-cycle of the adapter.
Scan all IDs on a bus
cd bar_ws
pixi shell
bar bus discover --iface can0
bar bus discover --iface can1
Default scan range: 1..32. Sends one GetDeviceId per ID with 8 ms
spacing, then collects replies for 200 ms after the last ping. Output:
=== Scan results on can0 ===
scanned : 1..32 (32 ids)
found : 7 actuator(s)
id=11 (0x0B) uid=3A58300194613802
id=12 (0x0C) uid=578F3002A042320E
...
The uid is the motor's MCU UID, useful for distinguishing two
otherwise-identical motors that have the same firmware ID.
For Lite the expected set is 11..17 on can0 (left arm) and 21..27
on can1 (right arm).
Wider scan ranges
# Default range is 1..32; widen if you suspect IDs outside that.
bar bus discover --iface can0 \
--scan-from 1 --scan-to 127
# Tighter scan (faster) if you only want to check specific IDs:
bar bus discover --iface can0 \
--scan-from 11 --scan-to 17
Slowing the scan
If the bus is slow / cheap-USB-adapter, raise --per-id-wait-ms:
bar bus discover --iface can0 \
--per-id-wait-ms 20
Single-motor probe
When you know the ID and want a deeper status check:
bar bus ping --iface can0 --id 11
# TX GetDeviceId id=...
# RX GetDeviceId reply device=11 uid=...
# stats: rx=1 tx=1 rx_dropped=0 tx_failed=0
With --read-status the ping briefly Enables, prompts an
OperationStatus, then Disables — useful for confirming the motor
responds with calibrated-looking values:
bar bus ping --iface can0 --id 11 --read-status
# RX OperationStatus device=11 pos= 4.9200 rad vel= 0.0 torque= 0.0 temp=24.0 C fault_bits=0x00
The pos value is motor-frame, no calibration (this CLI doesn't
load calibration.yaml). It's the raw absolute-encoder reading. If
it's plausibly in [-4π, 4π] and the motor reports temp around room
temp with fault_bits=0x00, the motor is healthy.
Watch live traffic
# Print every frame in real time
candump can0
# Just framing — useful for "is anything being sent?"
candump -n 50 can0 # first 50 frames then exit
In a healthy bringup with zero_torque_controller active, you'll see
14 MIT-mode frames per tick (7 each on can0 / can1) plus the
occasional OperationStatus reply.
In a quiet bus (everything stopped), candump is silent — that's
how you confirm on_deactivate's Disable made it through.
Common findings
bar bus discover reports | Likely cause |
|---|---|
found : 0 actuator(s) | Bus down, adapter unplugged, or motors not powered. Check ip -d link and the bench power. |
found : N < expected | Some motors are off the bus. Trace the daisy-chain — usually a connector. |
warning : N ping(s) dropped at write time | TX qdisc filling, motors not ACKing → see Diagnose ENOBUFS. |
id=X for an ID you don't recognise | Two motors with overlapping IDs, or a leftover from a different rig. Renumber via the vendor tool. |
See also
- Hardware specs → Bus-bring-up checklist
- Diagnose ENOBUFS
- First real-hardware bringup — uses these probes as its sanity step.