跳转到内容

CANopen PDO 示例

概述

本示例展示了单 CAN 通道上的过程数据对象 (PDO):一个脚本在对象字典值发生变化时发送一个 TPDO,另一个脚本接收该帧作为 RPDO 并打印解码后的映射。

与 SDO 相比,PDO 通信开销低,适用于周期性或事件驱动的过程数据。 此处两个节点都连接到 canopen_pdo.ecb 中定义的同一模拟 CAN 设备(SIMULATE_0,500 kbit/s)。

image


demo

项目结构

文件角色
canopen_pdo.ecb包含一个 CAN 设备上两个脚本节点的 ECUBUS 项目
pdo_producer.tsCANopen 设备(节点 ID 0xB),在 COB-ID 0x180 上有一个 TPDO,映射 0x2000(计数器)+ 0x2001(电机转速,0-100
pdo_consumer.ts独立脚本实例中的相同节点 ID,在 0x180 上有一个 RPDO,映射到 0x2000 + 0x2001

每个脚本通过 Util.OnCandevice.receive(...) 将协议栈连接到总线,并通过 device.addListener('message', ...)output(...) 转发协议栈的发送。

生产者 (pdo_producer.ts)

  1. 添加对象 0x2000(8 位无符号测试值)和 0x2001(电机转速,0-100)。
  2. 声明一个发送 PDO,其 transmissionType: 254(映射值变化时发送),COB-ID 0x180,有效载荷来自 0x2000 + 0x2001
  3. 调用 device.start()device.nmt.startNode() 以使设备进入运行状态。
  4. 每 100 毫秒将 0x2000 递增三次(1 -> 2 -> 3),这会触发 TPDO 发送。
  5. 转速(0x2001)由面板变量控制:
    • MotorSpeedPlus:将转速增加 1(限制在 100
    • MotorSpeedMinus:将转速减少 1(限制在 0) 每次更改都会更新 0x2001 并触发 TPDO 的发送-变化。

消费者(pdo_consumer.ts

  1. 添加对象 0x20000x2001,并在 COB-ID 0x180 上配置一个接收 PDO,映射到这两个对象。
  2. start() / startNode() 之后,通过 device.pdo.on('pdo', ...) 监听并记录 COB-ID 及每个映射对象的值。
  3. 当接收到对象 0x2001 时,通过 setVar("MotorSpeed", value) 将其值写入全局变量 MotorSpeed

如何运行

  1. 在 ECUBUS Pro 中打开 canopen_pdo.ecb
  2. 确保两个脚本(pdo_producerpdo_consumer)使用相同的 CAN 通道(如捆绑项目中所示)。
  3. 运行项目;观察消费者输出中带有两个映射值(计数器和速度)的 Received PDO 行。
  4. 在面板中切换 MotorSpeedPlus / MotorSpeedMinus 以改变速度,并观察消费者端同步的 PDO 更新。

更多示例

底层堆栈遵循常见的 CANopen PDO 模式。 更多独立场景(NMT、SDO、SYNC、TIME、LSS、EMCY 等)请参阅 node-canopen 示例:

https://github.com/Daxbot/node-canopen/tree/main/examples