# SocketCAN SocketCAN is suitable for directly controlling CAN and CAN FD devices on Linux. After the board is connected over USB, Linux exposes the four CAN/CAN FD channels as four `canX` network interfaces. They can be used with `can-utils`, `python-can`, or other SocketCAN software. Windows does not provide SocketCAN network interfaces. To exchange CAN/FDCAN data on Windows, use [SANPO USB to CAN](usb_can) and [SANPO USB to FDCAN](usb_fdcan) protocol mode. For graphical CAN/CAN FD debugging on Windows, use online [SANPO Studio](https://sanporobot.com/sanpo-studio) or offline [CANgaroo](https://gitcode.com/sanpo/robot/blob/main/products/spine/v8/tools/CANgaroo/CANgaroo-Windows-MinGW-Qt6.zip). ## Connect and Identify the Board 1. Connect the board to a Linux or Windows host over USB. The board is USB powered; ensure the USB voltage is at least 5 V. 2. Connect the motor to the board's CAN interface and connect motor power to XT60. 3. On Linux, install the tools and load the driver: ```bash sudo apt update sudo apt install can-utils sudo modprobe gs_usb ``` List the interfaces: ```bash ip link show type can ``` A complete board normally shows four `canX` interfaces. Linux numbering depends on enumeration order and cannot be used alone to identify the board connector. On first use, connect one motor and send a query through each interface to confirm the physical mapping. You can also inspect the USB device path: ```bash readlink -f /sys/class/net/can0/device udevadm info -q property -p "$(readlink -f /sys/class/net/can0/device)" ``` For long-term use, create `udev` rules based on the USB physical path or device serial number to assign stable interface names. ### Configure Classic CAN Set `can0` to 1 Mbit/s: ```bash sudo ip link set can0 down sudo ip link set can0 type can bitrate 1000000 sudo ip link set can0 up ``` Listen to the bus: ```bash candump can0 ``` Send a standard frame: ```bash cansend can0 123#11223344 ``` The data above is only an example. Replace it with the ID and data required by the connected motor protocol. Send an extended frame: ```bash cansend can0 0000FD01#0102030405060708 ``` `cansend` normally prints nothing when the send succeeds. Whether the motor replies depends on its protocol, ID, and current state. ### Configure CAN FD Configure `can0` for a 1 Mbit/s arbitration phase, a configurable 2/3/4/5 Mbit/s data phase, and CAN FD: ```bash sudo ip link set can0 down sudo ip link set can0 type can bitrate 1000000 dbitrate 5000000 fd on sudo ip link set can0 up ``` Send a CAN FD standard frame with BRS enabled: ```bash cansend can0 123##11122334455667788 ``` The data above is only an example. Replace it with the ID and data required by the connected motor protocol. Send a CAN FD extended frame with BRS enabled: ```bash cansend can0 0000FD01##11122334455667788 ``` After `##`, the first hexadecimal digit is the CAN FD flag. `1` enables BRS; the remaining digits are data. ## Check Interface State ```bash ip -s -details link show can0 ``` When CAN FD is enabled, the output includes `fd on`, `bitrate`, and `dbitrate`. If error counters continue increasing, stop transmission and check the bit rate, termination resistors, wiring, and device power. SocketCAN settings are not saved in the board. After power-cycling, reconnecting, or re-enumerating the device, configure the interfaces again with `ip link`. ## Xiaomi CyberGear Example Example program: [SocketCAN CyberGear example](https://gitcode.com/sanpo/robot/blob/main/products/spine/v8/demo/socketcan/socketcan_cybergear_demo_v8.py) Control motor ID 1 on `can0`: ```bash sudo python3 socketcan_cybergear_demo_v8.py \ --setup-links \ --motor-map "can0:1" ``` Multiple-interface example: ```text --motor-map "can0:1,2,3;can1:4,5,6" ``` Before running, adjust interface names and motor IDs to the actual enumeration and wiring. ## SANPO J8108-R8 FDCAN Example Example program: [read-only SocketCAN J8108-R8 FDCAN probe](https://gitcode.com/sanpo/robot/blob/main/products/spine/v8/demo/fdcan/socketcan_j8108_demo_v8.py) The program sends only SANPO FDCAN v1 `HELLO` and `STATE_REQUEST` messages and reads `CAPABILITY` and `STATE`. It never enables the motor or sends a motion target. Without `--interfaces`, it probes every detected `canX` interface (`can0` through `can3` on a complete SPINE board). The following command configures all four interfaces for a 1 Mbit/s arbitration phase, a 5 Mbit/s data phase, and CAN FD+BRS, then probes them one by one: The J8108-R8 must already be configured and rebooted into the `SANPO FDCAN Profile`; the example does not switch or write the motor Profile. ```bash python3 socketcan_j8108_demo_v8.py \ --setup-links \ --node-id 1 ``` Use `--list-only` to enumerate interfaces without sending a test frame. To check multiple verified interfaces: ```bash python3 socketcan_j8108_demo_v8.py \ --setup-links \ --interfaces can0,can1 \ --node-id 1 ``` For an existing J8108-R8 configured for 1M/2M, add `--data-bitrate 2000000`. `MISS` is expected on interfaces without a motor. A path that passes both `CAPABILITY` and `STATE` confirms bidirectional CAN FD communication. See the [J8108-R8 FDCAN demo guide](https://gitcode.com/sanpo/robot/blob/main/products/spine/v8/demo/guides/j8108-fdcan.md) for complete instructions. ## Troubleshooting | Symptom | Action | | --- | --- | | `canX` cannot be found | Run `sudo modprobe gs_usb`, then reconnect the USB cable | | `Network is down` | Run `sudo ip link set can0 up` for the selected interface | | `Device or resource busy` | Run `sudo ip link set can0 down`, then configure it again | | `No buffer space available` | Check bus wiring, bit rate, and termination resistors; after fixing the issue, bring the interface down and up again | | Frames send but the motor does not reply | Check the `canX`-to-connector mapping, motor ID, protocol, power, and bus settings |