CANopen IO
Darra PLC 支持 CANopen 协议,用于连接 CAN 总线上的 IO 模块和电机驱动器。通过 PDO 实现实时数据交换,通过 SDO 进行参数配置。
协议概述
| 特性 | 说明 |
|---|---|
| 物理层 | CAN 2.0B (1 Mbps @ 40m) |
| 最大节点数 | 127 |
| PDO 数量 | 每节点最多 4 TxPDO + 4 RxPDO |
| 同步方式 | SYNC 报文触发 |
架构
节点配置
var canopen = new CANopenDriver();
canopen.Configure(new CANopenConfig {
Interface = "CAN0",
Baudrate = 500000, // 500 kbps
SyncInterval = 1000 // SYNC 周期 1ms
});
// 添加节点
canopen.AddNode(new CANopenNode {
NodeId = 1,
DeviceType = "CiA 401", // 数字 IO
EdsFile = "node1.eds" // 电子数据表
});
PDO 映射
PDO (Process Data Object) 用于周期性实时数据交换:
TxPDO (节点 → 主站)
| PDO | 默认内容 (CiA 401) | 字节数 | PLC 映射 |
|---|---|---|---|
| TxPDO1 | 8 路 DI 状态 | 1 | %IB |
| TxPDO2 | 模拟输入 CH1-2 | 4 | %IW |
| TxPDO3 | 模拟输入 CH3-4 | 4 | %IW |
| TxPDO4 | 自定义 | ≤8 | 按配置 |
RxPDO (主站 → 节点)
| PDO | 默认内容 (CiA 401) | 字节数 | PLC 映射 |
|---|---|---|---|
| RxPDO1 | 8 路 DO 控制 | 1 | %QB |
| RxPDO2 | 模拟输出 CH1-2 | 4 | %QW |
| RxPDO3 | 模拟输出 CH3-4 | 4 | %QW |
| RxPDO4 | 自定义 | ≤8 | 按配置 |
SDO 参数配置
SDO (Service Data Object) 用于在运行前/运行中读写节点参数:
// 读取设备类型
uint deviceType = canopen.SdoRead<uint>(nodeId: 1, index: 0x1000, subIndex: 0);
// 设置心跳时间
canopen.SdoWrite(nodeId: 1, index: 0x1017, subIndex: 0, value: (ushort)500);
EDS (Electronic Data Sheet) 文件描述了 CANopen 节点的完整对象字典。Darra PLC 通过解析 EDS 文件自动生成 PDO 映射和参数配置界面。
NMT 状态管理
| 状态 | PDO | SDO | 说明 |
|---|---|---|---|
| Pre-Operational | — | ✅ | 配置阶段 |
| Operational | ✅ | ✅ | 正常运行 |
| Stopped | — | — | 停止 |
心跳监控
通过心跳协议检测节点在线状态:
| 参数 | 说明 | 默认值 |
|---|---|---|
| Producer Heartbeat | 节点发送心跳间隔 | 500ms |
| Consumer Heartbeat | 主站超时检测阈值 | 1500ms |
CAN 总线带宽有限 (1 Mbps)。节点数量多或 PDO 数据量大时需注意总线负载率,建议不超过 70%。高负载场景应考虑使用 EtherCAT 替代。
地址映射示例
| CANopen 对象 | PLC 地址 | 说明 |
|---|---|---|
| Node 1 TxPDO1 (DI) | %IB20 | 8 路数字输入 |
| Node 1 RxPDO1 (DO) | %QB20 | 8 路数字输出 |
| Node 2 TxPDO2 (AI) | %IW300 | 2 路模拟输入 |
| Node 3 StatusWord | %IW310 | 伺服状态字 |
典型 CANopen IO 模块
| 厂商 | 型号 | 特点 |
|---|---|---|
| Wago 750-337 | CANopen 耦合器 + 各种扩展 | 可扩展 |
| Beckhoff BK5120 | 耦合器 + K-Bus 总线端子 | 与 EL 模块兼容 |
| Phoenix Inline IL | 模块化 | IP20 |
| ifm AL1100 series | 单模块 | IP67 现场安装 |
| Turck TBEN series | 块模块 | 电器安装 |
配置流程
- 项目树 → IO 设备 → 添加 → CANopen
- 选择 CAN 接口硬件 (PCAN-USB / Kvaser / Ixxat / SocketCAN)
- 设置波特率 (125k / 250k / 500k / 1M)
- 扫描总线 → 列出所有上线节点
- 对每个节点:
- 导入 EDS 文件 (厂商提供)
- 查看默认 PDO 映射
- 可选: 修改 PDO 映射 (取消不需要的条目, 添加新的)
- 设置启动 SDO (Startup list)
- 编译下载, Runtime 会按配置初始化总线
EDS 导入
EDS 文件是文本格式, 内含:
- 设备标识 (Vendor ID, Product Code)
- 支持的对象字典条目
- PDO 模板
- 默认配置参数
IDE 导入时自动解析, 把对象字典里可映射的条目填到"可选 PDO"列表, 用户勾选需要的。
PDO 映射修改
默认 PDO 一般够用, 但有时需要定制:
示例: 把节点 2 的 TxPDO1 改为同时传 2 路温度:
原 TxPDO1 (默认):
0x1A00 Mapping:
[0] 0x60000108 (0x6000:01, 8-bit)
使用 0x1800.02 = 255 (异步事件触发)
修改为:
0x1A00 Mapping:
[0] 0x60000110 (0x6000:01, 16-bit 温度 CH1)
[1] 0x60000210 (0x6000:02, 16-bit 温度 CH2)
0x1800.02 = 1 (SYNC 触发)
0x1800.05 = 100 (事件时间 100ms)
IDE 的 PDO 编辑器可视化这一过程, 不需要手工填十六进制。
启动 SDO
有些节点需要在进入 Operational 前完成 SDO 配置:
节点 3 启动 SDO:
1. 0x1017:00 = 1000 (心跳 1000ms)
2. 0x1800:02 = 255 (TPDO1 异步触发)
3. 0x1401:03 = 254 (RPDO2 异步)
4. 进入 OP
配置在节点属性 → "启动配置" 标签。
与 CiA 402 伺服集成
CANopen 伺服和 EtherCAT 伺服共享 CiA 402 规范, 程序层面几乎一致:
(* SCL 程序 *)
MC_Power(Axis := CanopenAxis1, Enable := TRUE);
MC_MoveAbsolute(
Axis := CanopenAxis1,
Position := 1000.0,
Velocity := 100.0,
Execute := TRUE
);
底层驱动自动:
- 把 MC 指令翻译为 0x607A (Target Position) 等 PDO
- 读 0x6064 (Actual Position) 作为反馈
- 管理 0x6040/0x6041 状态字
多主站协同
CAN 总线天然支持多主, 但 CANopen 通常规定一个 NMT Master。多主站场景 (如冗余):
- 主主站: NMT Master, 发 SYNC, 管理 NMT 状态
- 备主站: 仅监听, 主主站故障时接管
CiA 302 定义了 "Flying Master" 协议, Darra 尚不支持, 一般单主即可。
SYNC 周期
SYNC 报文是 CANopen 的节拍器:
| SYNC 周期 | 说明 |
|---|---|
| 1 ms | 最小, 仅 1M 波特率可行, 节点数 < 5 |
| 2 ms | 500k 波特率, 节点数 5~10 |
| 5~10 ms | 250k 波特率, 20 节点 |
| 20~50 ms | 125k 波特率, 长距离 |
| 0 (无 SYNC) | 纯异步, PDO 事件触发 |
SYNC 必须由一个节点 (一般是主站) 发出, 其他节点都监听。
总线负载计算
CAN 总线带宽受波特率限制:
总线负载 = (Σ 每 PDO 字节数 × 发送频率 × 每帧开销 120%) / 波特率
例: 500k 波特率, 10 个节点, 每个 TPDO 8 字节, 10ms 周期:
负载 = (10 × 8 × 100 × 1.2) / 500000 ≈ 19.2%
建议负载 < 70%, 超过要减少节点/增加周期/升级波特率。
CAN 接口硬件
| 接口卡 | 接口 | 驱动 | 价格 |
|---|---|---|---|
| PCAN-USB (Peak) | USB 2.0 | 成熟, Windows/Linux | 中等 |
| Kvaser USBcan | USB | 稳定, 驱动好 | 中高 |
| Ixxat USB-to-CAN | USB | 稳定 | 中等 |
| ZLGCAN | USB/PCI | 国产, 中文文档好 | 实惠 |
| SocketCAN (Linux) | 芯片级 (MCP2515, CAN-PCIe) | Linux 原生 | 低 |
Windows 下推荐 PCAN-USB, 驱动最稳。
诊断
IDE 的 CANopen 诊断面板:
- 总线视图: 所有节点的在线状态 (心跳健康度)
- 帧跟踪: 实时显示 CAN 帧, 类似 candump
- EMCY 日志: 所有节点的紧急消息历史
- SDO 浏览器: 读任意节点的任意对象
- PDO 实时值: 每个 PDO 的当前字节内容
排错
| 症状 | 处理 |
|---|---|
| 节点不上线 | 波特率错 / 终端电阻缺 / 节点号重复 |
| 总线 Bus Off | 总线上出现大量错误帧, 检查物理层 |
| PDO 不更新 | 节点不在 Operational; SYNC 没发 |
| SDO 超时 | 节点忙, 加大 SDO timeout (默认 500 ms 到 2 s) |
| EMCY 0x8110 | Heartbeat 丢失, 检查网线 |
| 负载 > 90% | 减少节点/加大周期/升级波特率 |