# RS485 Passthrough Mode RS485 passthrough transfers the device's raw bytes directly. The four USB serial ports correspond to four independent RS485 bus channels. ## USB Serial Ports and Mapping After connecting the board over USB, six serial ports appear: two SANPO Studio management ports and four independent RS485 ports. Windows and Linux both use their inbox drivers. On Windows, the four RS485 passthrough ports are all displayed as `SANPO USB2RS485 Port`; on Linux they appear as `/dev/ttyACM*`. Port numbering is not guaranteed to follow the board silkscreen. On first use, connect or test only one motor at a time to identify each port's physical RS485-1/2/3/4 mapping. ## Data Transfer Open the target dedicated RS485 port and set the baud rate, stop bits, and parity to match the motor. Every transmitted byte then enters that RS485 bus, and device replies return unchanged on the same serial port. A serial terminal, Python `pyserial`, or the motor vendor's serial application can be used directly. For example, Unitree GO-M8010 commonly uses 4 Mbps, 8-N-1. In hexadecimal send mode, transmit: ```text FE EE 11 00 00 00 00 00 00 00 00 00 00 00 00 18 7C ``` Normal replies usually begin with `FD EE`. Interpret fields and checksums according to the motor vendor's protocol. ## Serial Settings Dedicated ports support `2400` to `4000000`, `5000000`, `6000000`, and `7500000` bit/s, one or two stop bits, no/odd/even parity, and eight data bits. Serial settings selected by the operating system when the port is opened are applied at runtime to that RS485 interface. ### Byte Stream and Length USB CDC and RS485 are byte streams. One `write()` may be split into multiple USB packets, and one `read()` may contain a partial frame or multiple frames. The firmware does not add, remove, or interpret motor-protocol bytes. The host must continuously assemble frames using the motor protocol's header, length, and checksum. The firmware submits received data on RS485 idle events. A continuous receive block contains at most 96 bytes; longer streams are returned in multiple blocks. ## Python Example After installing `pyserial`, use the [RS485 raw passthrough example](https://gitcode.com/sanpo/robot/blob/main/products/spine/v8/demo/rs485/native_rs485_v8.py) to list ports and send raw hexadecimal data: ```bash python -m pip install pyserial python native_rs485_v8.py --list python native_rs485_v8.py COM8 --baudrate 4000000 --data FEEE11000000000000000000000000187C ``` On Linux, replace `COM8` with the actual `/dev/ttyACM*` path. The program does not add a SANPO header or Channel. For a Unitree GO-M8010 motion example, see [native_unitree_gm8010_v8.py](https://gitcode.com/sanpo/robot/blob/main/products/spine/v8/demo/rs485/native_unitree_gm8010_v8.py). That program sends control commands only when `--enable-motion` is explicitly provided; the first run must be unloaded and small-amplitude, with a physical emergency-stop method available. ## Serial Terminal or Motor Application In a serial terminal or motor application that supports standard serial ports, select `SANPO USB2RS485 Port`, set the serial parameters to match the device, and exchange raw protocol frames in hexadecimal mode. Do not select `SANPO Studio Management Port`, and do not add `RT`, Channel, or any other SANPO header. ## Troubleshooting | Symptom | Action | | --- | --- | | The computer shows six serial ports | Normal: two management ports, one for each STM32 MCU, and four independent RS485 passthrough ports | | No reply after sending on a dedicated port | Check port mapping, serial settings, device ID, A/B wiring, and power | | The dedicated port returns `52 54` | A management port was selected; dedicated RS485 ports return raw data only | | Garbled data or unexpected length | Check baud rate, stop bits, parity, data bits, and A/B wiring; handle stream fragmentation according to the motor protocol | | Data occasionally interleaves on one bus | Make sure the dedicated port, management port, SPI, and offline tasks are not transmitting on the same interface |