SANPO SPI to RS485

SANPO SPI to RS485 is suitable for periodic control of RS485 motors and devices from a Jetson, Raspberry Pi, or another host controller. The host puts the raw device command into a fixed-length RT frame and reads feedback in the current or a later SPI transfer.

The factory RS485 settings are 4 Mbps, one stop bit, no parity, and eight data bits. However, some Linux serial enumeration may change the live communication settings. Therefore, before starting an SPI control program and sending application data, explicitly reapply the RS485 settings through the management serial port SANPO Studio Management Port; the SPI data channel itself does not accept text AT+ commands.

Send AT+ commands in text mode with the line ending set to CRLF. Do not send the characters \r\n as ordinary text.

AT+SETRS485=<baudrate>,<stop_bits>,<parity>,<data_bits>

For example, configure the common Unitree motor setting of 4 Mbps, 8-N-1:

AT+SETRS485=4000000,1,0,8

SPI Settings and Length

Item

SHORT

LONG

Total transfer

23 bytes

73 bytes

Payload

22 bytes

72 bytes

RS485 data area

18 bytes

68 bytes

Final byte

CRC-8

CRC-8

Both modes use SPI Mode 0 and MSB First. CRC-8 uses polynomial 0x07, initial value 0x00, and no final XOR.

Select an RS485 Interface

SPI chip select

Channel

Target

CS0 (first STM32)

0x01

RS485-1

CS0 (first STM32)

0x02

RS485-2

CS1 (second STM32)

0x03

RS485-3

CS1 (second STM32)

0x04

RS485-4

CS0 or CS1 (either chip select)

0x00

Both RS485 interfaces on the current MCU

When sending, 1/3 select the first interface on the selected STM32 and 2/4 select the second. Replies use local Channel 1/2 on the current STM32. CS0 and CS1 on the host normally connect to the board’s two external chip selects. The host and board must share ground; two GND connections are recommended for stable data transfer.

SHORT Message

Send and receive use the same layout:

Byte positions

Content

0-1

Fixed 52 54, or RT

2

Channel

3

RS485 data length 0-18

4-21

18-byte RS485 data area; unused bytes are 00

22

CRC-8 of the first 22 bytes

When sending a 17-byte Unitree control frame to Channel 2, the payload before CRC is:

52 54 02 11 FE EE 11 00 00 00 00 00 00 00 00 00 00 00 00 18 7C 00

Append the CRC-8 calculated over those 22 bytes.

LONG Message

Byte positions

Content

0-1

Fixed 52 54, or RT

2

Channel

3

RS485 data length 0-68

4-71

68-byte RS485 data area; unused bytes are 00

72

CRC-8 of the first 72 bytes

The CRC algorithm is the same as SANPO SPI to CAN.

Read RS485 Feedback

After receiving RS485 data, the board places it in the same RT layout in the SPI transmit queue:

  • Byte 2 identifies the first or second RS485 interface on the current MCU.

  • Byte 3 is the length of this feedback block.

  • Data starts at byte 4.

  • Unused data-area bytes are 00.

SPI is full duplex. Data read while sending a control frame may be old data or all 00; if the target has not replied, continue sending an empty frame of the same length to poll for feedback.

One RS485 receive event is not guaranteed to correspond to one complete motor protocol frame. Use Channel to identify the bus, then reassemble data according to the motor protocol’s header, length, and checksum.

Unitree GO-M8010 Example

Example program: SPI to RS485 Unitree motor example

sudo python3 spi2rs485_unitree_GM8010_demo_v8.py \
  --spibus 0 \
  --cs 0 \
  --motors 1

Use the current help output of the example as the authority for parameter names. On first use, reduce the motion amplitude and keep an immediate power disconnect available.

Troubleshooting

Symptom

Action

All bytes are 00

No feedback is queued; continue polling with an empty frame of the same length

Reply Channel is 1/2

Replies use the local numbering of the current MCU; this is normal

A 17-byte command works in SHORT but a longer command fails

SHORT supports at most 18 bytes; switch to LONG

CRC error

Check Mode 0, MSB First, fixed length, SPI clock, and chip-select timing

Device does not reply

Check chip select, Channel, RS485 parameters, device ID, command checksum, A/B wiring, and power

Feedback is split into multiple blocks

Reassemble it on the host according to the device protocol; do not treat one SPI read as one motor reply