跳到主要内容

CANopen 通讯

Darra PLC 通过 CANopenDriver 实现 CANopen 主站功能, 支持 NMT 网络管理、PDO 过程数据、SDO 服务数据等 CANopen 核心协议。

协议概述

CANopen 基于 CAN 总线 (ISO 11898), 广泛用于运动控制、传感器网络和嵌入式系统。

支持的通讯对象

对象COB-ID 范围方向说明
NMT0x000主→从网络管理 (启动/停止/复位)
SYNC0x080主→全部同步触发
EMCY0x081~0x0FF从→主紧急报文
TPDO1~40x181~0x480从→主过程数据 (从站发送)
RPDO1~40x201~0x500主→从过程数据 (从站接收)
TSDO0x581~0x5FF从→主服务数据响应
RSDO0x601~0x67F主→从服务数据请求
Heartbeat0x701~0x77F从→主心跳检测

NMT 状态机

CANopen 从站遵循标准 NMT 状态机:

             ┌──────────────┐
上电 → │ Initializing │
└──────┬───────┘
↓ (自动)
┌──────────────┐
│ Pre-Operational │ ← SDO 配置
└──────┬───────┘
↓ (NMT Start)
┌──────────────┐
│ Operational │ ← PDO 数据交换
└──────┬───────┘
↓ (NMT Stop)
┌──────────────┐
│ Stopped │
└──────────────┘

连接配置

{
"protocol": "CANopen",
"interface": "PCAN-USB",
"channel": 1,
"baudRate": 500000,
"nodeId": 1,
"syncPeriodMs": 10,
"heartbeatMs": 1000
}

支持的 CAN 接口:

  • PCAN-USB (Peak Systems)
  • Kvaser USB
  • Ixxat USB-to-CAN
  • SocketCAN (Linux, 待支持)

PDO 映射

PDO 映射通过对象字典 (Object Dictionary) 配置:

PDO默认映射 (CiA 402)用途
RPDO10x6040 (Controlword)伺服控制字
RPDO20x607A (Target Position)目标位置
TPDO10x6041 (Statusword)伺服状态字
TPDO20x6064 (Position Actual)实际位置

SDO 读写

SDO 用于参数配置和诊断:

// 创建 CANopen 主站
var driver = new CANopenDriver();
driver.Initialize("PCAN-USB", 500000);

// SDO 读取: 节点 1, 索引 0x6041 (Statusword)
ushort status = driver.SdoRead<ushort>(nodeId: 1, index: 0x6041, subIndex: 0);

// SDO 写入: 节点 1, 索引 0x6040 (Controlword)
driver.SdoWrite(nodeId: 1, index: 0x6040, subIndex: 0, value: (ushort)0x0006);

// 启动所有从站
driver.NmtCommand(0x00, NmtState.Operational); // NodeId=0 广播

与 PLC 集成

CANopen 数据通过共享内存与 PLC 引擎交互:

  • PDO 数据 自动映射到 PLC 的 IO 区域 (DI/DO/AI/AO)
  • CiA 402 伺服 自动映射到关节数据区域 (与 EtherCAT 共享结构)
  • SYNC 周期与 PLC 扫描周期对齐
CAN 总线长度

CAN 总线波特率与最大线缆长度成反比:

  • 1 Mbps: 最大 25m
  • 500 kbps: 最大 100m
  • 125 kbps: 最大 500m

对象字典

CANopen 的核心是 Object Dictionary (对象字典), 每个节点暴露一个 64K 条目的索引空间:

索引范围用途
0x0001~0x001F标准数据类型
0x0020~0x003F标准复合类型
0x1000~0x1FFF通讯对象 (CiA 301)
0x2000~0x5FFF厂商自定义
0x6000~0x9FFF标准设备档 (CiA 401/402/...)
0xA000~0xFFFF网络变量

常用条目:

  • 0x1000 Device Type (必须)
  • 0x1001 Error Register
  • 0x1008 Manufacturer Device Name
  • 0x1017 Heartbeat Producer Time
  • 0x1018 Identity Object (Vendor ID / Product Code / Revision / Serial)
  • 0x1600~0x17FF RPDO 映射
  • 0x1800~0x1BFF TPDO 通讯参数
  • 0x1A00~0x1DFF TPDO 映射

EDS 文件

Electronic Data Sheet (EDS) 是文本格式, 描述节点的对象字典。Darra 从 EDS 导入节点:

[FileInfo]
FileName=Servo_XYZ.eds
Description=XYZ Servo Drive

[DeviceInfo]
VendorName=XYZ Industrial
ProductName=Model 100
GranularityOfFractionalPart=0

[1000]
ParameterName=Device Type
ObjectType=0x7
DataType=0x0007
AccessType=ro
DefaultValue=0x00020192

[6040]
ParameterName=Controlword
ObjectType=0x7
DataType=0x0006
AccessType=rww
PDOMapping=1

导入后 IDE 自动:

  • 生成 PDO 映射模板
  • 在变量表建立 PDO → PLC 地址映射
  • 把厂商参数暴露为 SDO 读写界面

PDO 类型

主站                节点
│ RPDO │
├──────────────→ │ (主站发给节点)
│ │
│ TPDO │
│ ←──────────── │ (节点发给主站)

PDO 触发方式 (由 0x1800.02 Transmission Type 决定):

代码含义
0同步 (SYNC), 每次 SYNC 后更新
1~240每 N 次 SYNC 后传
252同步采样, 异步传
253远程请求 (RTR) 后传
254厂商定义事件
255异步事件触发 (如值变化)

CiA 402 伺服

CiA 402 定义了伺服驱动器的标准对象和状态机:

对象索引大小说明
Controlword0x6040UINT16控制命令
Statusword0x6041UINT16当前状态
Mode of Operation0x6060INT8运行模式选择
Mode of Operation Display0x6061INT8实际运行模式
Target Position0x607AINT32CSP 模式目标位置
Target Velocity0x60FFINT32CSV 模式目标速度
Target Torque0x6071INT16CST 模式目标扭矩
Position Actual Value0x6064INT32反馈位置
Velocity Actual Value0x606CINT32反馈速度
Torque Actual Value0x6077INT16反馈扭矩
Profile Velocity0x6081UINT32PP 模式速度
Profile Acceleration0x6083UINT32加速度

典型 PDO 映射 (CiA 402):

  • RPDO1: Controlword (0x6040) + Mode of Operation (0x6060)
  • RPDO2: Target Position (0x607A)
  • TPDO1: Statusword (0x6041) + Mode of Operation Display (0x6061)
  • TPDO2: Position Actual Value (0x6064)

SDO 上传 / 下载

SDO 有两种传输模式:

快速传输 (Expedited)

≤ 4 字节数据, 一次请求响应完成:

请求: [22 40 60 00 06 00 00 00]  (Write Index 6040, SubIdx 0, Value 0x0006)
响应: [60 40 60 00 00 00 00 00] (OK)

分段传输 (Segmented)

4 字节, 多帧完成:

  1. Initiate: 协商长度
  2. Segment: 每次传 7 字节, 最多 127 段
  3. End: 最后一段

块传输 (Block)

CiA 301 v4 引入, 速度比分段快。不是所有从站都支持。

NMT 命令

命令码含义
0x01进入 Operational
0x02进入 Stopped
0x80进入 Pre-Operational
0x81Reset Node (复位整个节点)
0x82Reset Communication (仅复位通讯)

NMT 帧格式: COB-ID=0x000, 数据=[命令, 节点号], 节点号=0 表示广播。

心跳 vs 节点保护

两种检测节点在线状态的方式:

机制推荐度说明
Heartbeat推荐节点主动发心跳, 主站监听
Node Guarding过时主站询问, 节点回应; 增加总线负载

心跳配置:

  • 节点 0x1017 Producer Heartbeat Time: 例如 500ms
  • 主站侧 0x1016 Consumer Heartbeat Time: 略大于 Producer, 如 1500ms

主站超过 Consumer Time 没收到心跳 → 视为掉线 → 触发报警。

紧急报文 (EMCY)

节点发生错误时主动发 EMCY:

COB-ID: 0x081 + NodeID
数据: [错误码低, 错误码高, 错误寄存器, 厂商特定数据 (5B)]

常见错误码:

  • 0x0000 Error Reset (恢复)
  • 0x1000 Generic Error
  • 0x2000~0x2FFF Current 电流错
  • 0x3000~0x3FFF Voltage 电压错
  • 0x4000~0x4FFF Temperature 温度错
  • 0x5000~0x5FFF Hardware 硬件
  • 0x6000~0x6FFF Software 软件
  • 0x7000~0x7FFF Additional Modules 附加模块
  • 0x8000~0x8FFF Monitoring 监控 (常指通讯)
  • 0x9000~0x9FFF External Error 外部
  • 0xFF00~0xFFFF Device Specific 设备特定

同步时钟

CANopen 支持时间戳对象 (0x1012), 主站广播 TIME 消息给所有节点:

canopen.BroadcastTime(DateTime.UtcNow);

精度约 ±1ms, 适合事件时标对齐。

LSS (Layer Setting Services)

用于在未知节点号的情况下配置节点 (例如出厂初次配置):

  1. 把所有节点置于 LSS 等待模式
  2. 用 Vendor/Product/Rev/Serial 唯一标识某节点
  3. 设置该节点的 Node ID 和波特率
  4. 节点生效后退出 LSS

诊断

IDE 提供 CAN 总线监视窗:

  • 实时显示所有 CAN 帧 (时间戳 + COB-ID + 数据)
  • 按节点 / 对象类型过滤
  • CAN 错误计数 (bus off, error passive, warning)
  • 总线负载率 (%)

排错

症状处理
节点不上线波特率错 / 终端电阻缺 / 供电不足
通讯间歇性错布线问题 / 屏蔽接地
Bus Off总线上有短路或大量错误帧
SDO 超时节点忙, 加大超时; 避免 Bootup 期间访问
PDO 不更新节点不在 Operational 状态
总线负载 > 70%减少 PDO 数量 / 增大 SYNC 周期