> ## Documentation Index
> Fetch the complete documentation index at: https://motorbridge.seeedstudio.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Transports

# Transports

<mintly-toc>
  The motorbridge SDK supports multiple transport layers for communicating with motors. This guide explains each transport option and when to use it.
</mintly-toc>

## Overview

The SDK exposes four transport constructors:

| Constructor                                       | Protocol       | Use Case                                              |
| ------------------------------------------------- | -------------- | ----------------------------------------------------- |
| `Controller(channel)`                             | SocketCAN      | Standard CAN 2.0, most common                         |
| `Controller.from_socketcanfd(channel)`            | CAN-FD         | High-bandwidth, Hexfellow motors                      |
| `Controller.from_dm_serial(port, baud)`           | Serial         | Damiao serial bridge adapter                          |
| `Controller.from_dm_device(device_type, channel)` | DM\_Device SDK | Damiao USB2CANFD / USB2CANFD\_DUAL / LINKX4C adapters |

## SocketCAN (Standard CAN)

The default transport for most motor vendors.
Linux uses SocketCAN directly, and Windows/macOS use the PCAN backend with `canX` channel aliases.

### Usage

```python theme={null}
from motorbridge import Controller

# Open standard CAN interface
with Controller("can0") as ctrl:
    motor = ctrl.add_damiao_motor(0x01, 0x11, "4340P")
    # ... control motor
```

### Supported Vendors

* Damiao (all models)
* RobStride
* MyActuator
* HighTorque

### System Setup (3 Platforms)

Linux (SocketCAN):

```bash theme={null}
# Configure CAN interface at 1M bitrate
sudo ip link set can0 type can bitrate 1000000
sudo ip link set can0 up

# Increase TX queue to prevent buffer overflow
sudo ifconfig can0 txqueuelen 1000
```

macOS (PCAN via PCBUSB):

```bash theme={null}
# Verify PCBUSB runtime is available
python3 -c "import ctypes; ctypes.CDLL('libPCBUSB.dylib'); print('PCBUSB load OK')"

# Run a scan check on can0
motorbridge-cli scan --vendor damiao --transport auto --channel can0 --start-id 1 --end-id 16
```

Windows (PCAN):

```powershell theme={null}
# Verify PCAN runtime is available
python -c "import ctypes; ctypes.CDLL('PCANBasic.dll'); print('PCANBasic load OK')"

# can0@1000000 maps to PCAN_USBBUS1
motorbridge-cli scan --vendor damiao --transport auto --channel can0@1000000 --start-id 1 --end-id 16
```

### Multiple CAN Interfaces

```python theme={null}
# Control motors on different CAN buses
with Controller("can0") as ctrl0:
    motor0 = ctrl0.add_damiao_motor(0x01, 0x11, "4340P")

with Controller("can1") as ctrl1:
    motor1 = ctrl1.add_robstride_motor(127, 0xFD, "rs-06")
```

## CAN-FD (SocketCAN-FD)

Extended CAN with larger payload and higher bandwidth. Required for some vendors.

### Usage

```python theme={null}
from motorbridge import Controller

# Open CAN-FD interface
with Controller.from_socketcanfd("can0") as ctrl:
    motor = ctrl.add_hexfellow_motor(0x01, 0x00, "hexfellow")
    # ... control motor
```

### Supported Vendors

* Hexfellow (required)
* Damiao (optional, for higher bandwidth)

### System Setup

```bash theme={null}
# Configure CAN-FD interface
sudo ip link set can0 type can bitrate 1000000 dbitrate 5000000 fd on
sudo ip link set can0 up
```

<Note>
  CAN-FD examples above are Linux-first. On Windows/macOS, prefer standard CAN (`Controller(channel)`) unless your adapter stack explicitly supports FD.
</Note>

## DM Serial Bridge

Serial-to-CAN bridge for Damiao motors using the official Damiao serial adapter.

### Usage

```python theme={null}
from motorbridge import Controller

# Open serial bridge
with Controller.from_dm_serial("/dev/ttyACM0", baud=921600) as ctrl:
    motor = ctrl.add_damiao_motor(0x01, 0x11, "4340P")
    # ... control motor
```

### Parameters

| Parameter     | Type | Default        | Description                       |
| ------------- | ---- | -------------- | --------------------------------- |
| `serial_port` | str  | "/dev/ttyACM0" | Serial device path                |
| `baud`        | int  | 921600         | Baud rate (use 921600 for Damiao) |

### Supported Vendors

* Damiao only

## DM\_Device SDK

DaMiao DM\_Device\_SDK controls CAN/CAN FD adapter hardware. In motorbridge, this
transport is wired to the Damiao motor protocol only, and the adapter must be in
USB mode.

### Supported Adapter Types

| Adapter         | SDK enum         | Channels | `dm_device_type` | `dm_channel`          |
| --------------- | ---------------- | -------- | ---------------- | --------------------- |
| USB2CANFD       | `USB2CANFD`      | 1        | `usb2canfd`      | `0`                   |
| USB2CANFD\_DUAL | `USB2CANFD_DUAL` | 2        | `usb2canfd-dual` | `0` / `1`             |
| LINKX4C         | `LINKX4C`        | 4        | `linkx4c`        | `0` / `1` / `2` / `3` |

### Python Usage

```python theme={null}
from motorbridge import Controller

# USB2CANFD_DUAL channel 0
with Controller.from_dm_device("usb2canfd-dual", "0") as ctrl:
    motor = ctrl.add_damiao_motor(0x04, 0x14, "4310")

# LINKX4C channel 0
with Controller.from_dm_device("linkx4c", "0") as ctrl:
    motor = ctrl.add_damiao_motor(0x04, 0x14, "4310")
```

### CLI Usage

```bash theme={null}
# Scan all channels on USB2CANFD_DUAL: 0 and 1
motorbridge-cli scan \
  --vendor damiao \
  --transport dm-device \
  --dm-device-type usb2canfd-dual \
  --model 4310 \
  --start-id 1 \
  --end-id 16

# Scan all channels on LINKX4C: 0, 1, 2, 3
motorbridge-cli scan \
  --vendor damiao \
  --transport dm-device \
  --dm-device-type linkx4c \
  --model 4310 \
  --start-id 1 \
  --end-id 8

# Control one physical channel
motorbridge-cli run \
  --vendor damiao \
  --transport dm-device \
  --dm-device-type linkx4c \
  --dm-channel 0 \
  --model 4310 \
  --motor-id 0x04 \
  --feedback-id 0x14 \
  --mode enable \
  --loop 1
```

<Note>
  In scan mode, omit `--dm-channel` to scan every channel for the selected
  adapter. Pass `--dm-channel` only when you want one physical channel.
</Note>

### Serial Port Setup (3 Platforms)

Linux:

```bash theme={null}
# Check available serial ports
ls -la /dev/ttyACM* /dev/ttyUSB*

# Add user to dialout group for permission
sudo usermod -a -G dialout $USER
# Log out and back in
```

macOS:

```bash theme={null}
# Typical serial devices
ls -la /dev/cu.usbmodem* /dev/cu.usbserial*
```

Windows (PowerShell):

```powershell theme={null}
# List COM ports
[System.IO.Ports.SerialPort]::GetPortNames()
```

### Common Serial Devices

| Device             | Path         | Notes              |
| ------------------ | ------------ | ------------------ |
| Damiao USB-CAN     | /dev/ttyACM0 | Default            |
| USB-Serial Adapter | /dev/ttyUSB0 | Check with `dmesg` |

## Transport Selection Guide

### Decision Tree

```
What motor vendor are you using?
│
├── Hexfellow ──→ from_socketcanfd (required)
│
├── Damiao with DM_Device USB2CANFD/DUAL/LINKX4C ──→ from_dm_device
│
├── Damiao with USB-CAN adapter ──→ from_dm_serial
│
├── Damiao with CAN card ──→ Controller (SocketCAN)
│
├── RobStride ──→ Controller (SocketCAN)
│
├── MyActuator ──→ Controller (SocketCAN)
│
└── HighTorque ──→ Controller (SocketCAN)
```

### Mixed Vendor Setup

When using multiple vendors on the same CAN bus, create separate `Controller` instances:

```python theme={null}
from motorbridge import Controller

# Each vendor gets its own controller
with Controller("can0") as dm_ctrl:
    dm_motor = dm_ctrl.add_damiao_motor(0x01, 0x11, "4340P")
    dm_ctrl.enable_all()

with Controller("can0") as rs_ctrl:
    rs_motor = rs_ctrl.add_robstride_motor(127, 0xFD, "rs-06")
    rs_ctrl.enable_all()
```

<Warning>
  Do not add motors from different vendors to the same `Controller` instance. Each controller is optimized for a specific vendor protocol.
</Warning>

## Transport Performance

### Latency Comparison

| Transport | Typical Latency | Max Throughput |
| --------- | --------------- | -------------- |
| SocketCAN | \~1-2 ms        | \~5000 msg/s   |
| CAN-FD    | \~0.5-1 ms      | \~10000 msg/s  |
| DM Serial | \~2-5 ms        | \~2000 msg/s   |

### Recommendations

* **Real-time control**: Use SocketCAN or CAN-FD
* **Development/Debug**: DM Serial is convenient for quick testing
* **High-speed loops**: Use CAN-FD with `dt_ms >= 10`

## Troubleshooting

### SocketCAN: "No buffer space available" (Error 105)

```bash theme={null}
# Stop other CAN senders
# Increase TX queue
sudo ifconfig can0 txqueuelen 1000

# Increase control loop period
# dt_ms = 20 or higher
```

### Serial: Permission Denied

```bash theme={null}
sudo usermod -a -G dialout $USER
# Log out and back in
```

### CAN-FD: "Invalid argument"

```bash theme={null}
# Ensure CAN-FD is enabled on interface
sudo ip link set can0 type can bitrate 1000000 dbitrate 5000000 fd on
sudo ip link set can0 up
```

## Next Steps

* [Quickstart](quickstart) - Your first motor control program
* [API: Controller](api/controller) - Full controller API reference
