Skip to content

机器人通信协议速查

概念速览

  • 机器人通信分层
    • 板内 (芯片 ↔ 芯片):I²C / SPI / UART
    • 板间 (板 ↔ 板):CAN / RS485
    • 实时总线 (工控):EtherCAT / Profinet
    • 分布式 (跨主机):ROS 2 DDS / MQTT / Zenoh
  • 关键指标:实时性、带宽、线缆长度、节点数、成本

协议对比表

协议实时性带宽线缆长度节点数成本典型场景
I²C1 ms400 kHz - 3.4 MHz< 1 m127 (7-bit)¥0板内 (传感器 / EEPROM)
SPIμs1-100 MHz< 0.5 m1 主多从¥0高速 ADC / 显示
UARTms115.2k - 1M baud< 15 m1 对 1¥0调试 / GPS / 串口屏
RS485ms10 Mbps< 1200 m32-256¥5/节点工业总线 / 传感器
CAN 2.0< 1 ms (1 Mbps)1 Mbps< 40 m (1M)8-32¥10/节点机器人 / 汽车
CAN FD< 1 ms5 Mbps< 40 m (5M)8-32¥15/节点新能源车 / 机器人
EtherCAT< 100 μs100 Mbps< 100 m65535¥30/节点工业实时控制
ROS 2 DDSms (网络 RTT)1 Gbps网线 (无限)任意¥0 (软件)多机协同
MQTT100 ms+1 Gbps网线任意¥0 (软件)云端遥测

实时性金字塔

flowchart TB
    subgraph tier1 ["硬实时 (μs 级)"]
        H1["SPI 板内高速"] --> H2["UART 调试/串口"] --> H3["CAN 经典机器人"] --> H4["CAN-FD 新能源车"] --> H5["EtherCAT 工业机械臂"]
    end
    subgraph tier2 ["软实时 (ms-s 级)"]
        S1["I²C 板内低速"] --> S2["RS485 工业传感器"] --> S3["ROS 2 DDS 多机"] --> S4["MQTT 云端"]
    end
    tier1 --> tier2

1. CAN bus — 机器人主流

物理层

[节点 1] ──┐ ┌── [节点 2]
│ │
[120Ω] CANH ═══════════ CANH [120Ω]
│ │
[节点 3] CANL ═══════════ CANL [节点 4]
│ │
[GND] ──── ──── [GND]
  • 终端电阻 120Ω × 2 (总线两端)
  • 差分信号 (CANH / CANL) — 抗干扰
  • 1 Mbps 最长 40 m · 125 kbps 最长 500 m
  • 最多 8 字节 / 帧 (CAN 2.0) / 64 字节 (CAN FD)

帧格式

struct CAN_Frame {
uint32_t id; // 11-bit (CAN 2.0A) 或 29-bit (CAN 2.0B)
uint8_t dlc; // 0-8 (CAN 2.0) / 0-64 (CAN FD)
uint8_t data[8];
};
  • 仲裁机制:ID 越小优先级越高
  • ACK 机制:任何节点收到都回 ACK,错误自动重传

ROS 2 + CAN

# 装 socketcan
sudo apt install can-utils ros-${ROS_DISTRO}-ros2socketcan
# 启动 CAN 接口
sudo ip link set can0 up type can bitrate 1000000
# ROS 2 桥接 (用 ros2_socketcan)
ros2 run ros2socketcan ros2socketcan --can-id 0x18FF50E5

2. EtherCAT — 工业级硬实时

  • 带宽:100 Mbps
  • 周期:100 μs (典型) — 比 CAN 快 10×+
  • 拓扑:菊花链 (daisy chain) — 一根线接所有节点
  • 节点数:65535
  • 典型应用:六轴机械臂 (Franka / UR) · CNC · 高速传送带
# pysoem (Python EtherCAT master)
import pysoem
master = pysoem.Master()
master.open("eth0")
master.config_init()
master.state = pysoem.PSTATE_OPERATIONAL
# 1 kHz 实时循环
while True:
master.send_processdata()
master.receive_processdata()
time.sleep(0.001) # 1 ms

3. RS485 — 工业传感器 / 充电桩

  • 半双工 (一对双绞线)
  • 最远 1200 m (10 kbps)
  • Modbus RTU 协议 (主流)
  • 场景:储能 BMS 集群、工业传感器、充电桩
# Modbus RTU 读 BMS SOC
from pymodbus.client import ModbusSerialClient
client = ModbusSerialClient(port='/dev/ttyUSB0', baudrate=9600, parity='E')
result = client.read_holding_register(address=0, count=1, slave=1)
soc = result.registers[0] / 100 # 0-100 %

4. ROS 2 DDS — 跨主机分布式

  • 基于 UDP (默认) 或 TCP / SHM (共享内存)
  • 自动发现:多机间自动组网
  • 实时性:网络 RTT 1-5 ms (局域网) / 50-200 ms (公网)
  • 代价:CPU 开销大 (5-15% per node)
Terminal window
# 跨主机协同 (两台 ROS 2 Jazzy)
# 主机 A (IP 192.168.1.10)
export ROS_DOMAIN_ID=42
ros2 run demo_nodes_cpp talker
# 主机 B (IP 192.168.1.11)
export ROS_DOMAIN_ID=42
ros2 run demo_nodes_py listener
# 自动发现 + 自动话题

5. I²C / SPI — 板内通信

I²C (慢但省脚位)

  • 2 根线 (SDA / SCL)
  • 板内 < 1 m
  • 多主多从
  • 例子:MPU6050 IMU / OLED 屏 / EEPROM

SPI (快但占脚)

  • 4 根线 (MOSI / MISO / SCK / CS)
  • 板内 < 0.5 m
  • 1 主多从 (每从 1 根 CS)
  • 例子:SD 卡 / TFT 屏 / 高速 ADC

选型决策树

flowchart TD
    Q1{"Q1 跨主机/上云?"}
    Q1 --> A1["是: ROS 2 DDS 局域网"]
    Q1 --> A2["是: MQTT 公网"]
    Q1 --> A3["是: Zenoh 低带宽"]
    Q1 --> Q2{"Q2 硬实时 < 1ms?"}
    Q2 --> B1["是: EtherCAT 机械臂"]
    Q2 --> B2["是: SPI 板内高速"]
    Q2 --> Q3{"Q3 节点 > 32 或 距离 > 40m?"}
    Q3 --> C1["是: RS485"]
    Q3 --> C2["是: CAN FD"]
    Q3 --> D["否: CAN 2.0 最经典"]

常见组合

  • 移动机器人 (扫地机 / AGV):CAN 2.0 (主控 ↔ 驱动轮 / 电池) + RS485 (BMS)
  • 人形机器人 (G1):EtherCAT (主控 ↔ 关节) + CAN (辅助) + ROS 2 (主机 ↔ 工控)
  • 无人机:SPI (板内) + CAN (飞控 ↔ 电调) + 数传 (SBUS / CRSF)
  • 工业机械臂 (Franka):EtherCAT 全程 (主控 ↔ 7 关节)
  • 智能家居:MQTT (传感器) + Zigbee (低功耗设备) + WiFi (网关)

📋 复现条件

类别必备备注
硬件USB-CAN 适配器 (¥100) · CANable · 2 个 CAN 节点CAN FD 推荐 CANable 2.0
软件Linux · can-utils · python-canROS 2 可选
时间CAN 接线 1 h · EtherCAT 配 2 h · 跑通 30 min全套
难度⭐⭐ 中需要懂总线 + 终端电阻
预算¥100-500 (适配器 + 线材)EtherCAT 主站需工控机

⛔ 别这么做 (Anti-patterns)

❌ 错误做法💥 后果⚠️ 风险范围
不要在 CAN 总线两端忘了接 120Ω 终端电阻信号反射 = 错误率 100%🟡CAN / CAN FD
不要把 CAN 与电源线走在同一束共模干扰 = 偶发丢帧🟡走线
不要用 CAN 跑超过 8 字节的数据CAN 2.0 限制,要 CAN FD 或拆包🟢CAN 2.0
不要在公网直接跑 ROS 2 DDSUDP 明文 = 任何人都能伪造话题🔴公网部署
不要用 USB-TTL 接 50m 远距离的传感器UART 距离 < 15m,要换 RS485🟡远距离
不要在 I²C 上接 5V 设备到 3.3V MCU烧 IO 口🔴I²C 板内

🚨 风险总览 (Risk Matrix)

风险等级含义例子
🟢 低改错可回滚 / 几分钟恢复CAN 帧超 8 字节
🟡 中需要重新刷机 / 重装 / 1-2 小时恢复缺终端电阻,UART 远距离
🔴 高不可逆 / 烧板 / 安全风险5V 接 3.3V,公网 DDS

参考资料