CANopen for Python 使用教程(二)

系列文章目录

 


前言

CANopen 标准的 Python 实现。该项目的目的是在一个简单的 Pythonic 接口中支持 CiA 301 标准中最常见的部分。它主要针对测试和自动化任务,而不是符合标准的主实施。

该库支持 Python 3.6 及以上版本。


 

一、特点

该库主要用作主库。

  • NMT 主站
  • SDO 客户端
  • PDO 生产者/消费者
  • SYNC 生产者
  • EMCY 消费者
  • 时间生产者
  • LSS 主站
  • 来自 EDS 的对象字典
  • 402 配置文件支持

还不完全支持创建从节点。

  • SDO 服务器
  • PDO 生产者/消费者
  • NMT 从节点
  • EMCY 生产者
  • 来自 EDS 的对象字典

二、安装

使用 pip 从 PyPI 安装: 

pip install canopen

从 GitHub 上的最新主站安装:

pip install https://github.com/christiansandberg/canopen/archive/master.zip

如果您希望在使用过程中更改代码,请克隆它,然后在开发模式下安装:

git clone https://github.com/christiansandberg/canopen.git
cd canopen
pip install -e .

单元测试可使用 pytest 框架运行:

pip install pytest
pytest -v

三、文档

文档可在阅读文档中找到:

http://canopen.readthedocs.io/en/latest/

也可使用 Sphinx 从本地克隆生成:

python setup.py build_sphinx

四、硬件支持

该库通过 python-can 软件包支持多种硬件和驱动程序。请参阅支持的设备列表。

还可将此库与自定义后端集成。

五、快速启动

下面是一些快速操作示例:

可以通过三种形式访问 PDO:

第 1 种:node.tpdo[n] 或 node.rpdo[n] 。

第 2 种: node.pdo.tx[n] 或 node.pdo.rx[n]

第 3 次: 节点.pdo[0x1A00] 或节点.pdo[0x1600]

n 是 PDO 索引(通常为 1 至 4)。第二种访问方式用于向后兼容。

import canopen

# Start with creating a network representing one CAN bus
network = canopen.Network()

# Add some nodes with corresponding Object Dictionaries
node = canopen.RemoteNode(6, '/path/to/object_dictionary.eds')
network.add_node(node)

# Connect to the CAN bus
# Arguments are passed to python-can's can.Bus() constructor
# (see https://python-can.readthedocs.io/en/latest/bus.html).
network.connect()
# network.connect(bustype='socketcan', channel='can0')
# network.connect(bustype='kvaser', channel=0, bitrate=250000)
# network.connect(bustype='pcan', channel='PCAN_USBBUS1', bitrate=250000)
# network.connect(bustype='ixxat', channel=0, bitrate=250000)
# network.connect(bustype='vector', app_name='CANalyzer', channel=0, bitrate=250000)
# network.connect(bustype='nican', channel='CAN0', bitrate=250000)

# Read a variable using SDO
device_name = node.sdo['Manufacturer device name'].raw
vendor_id = node.sdo[0x1018][1].raw

# Write a variable using SDO
node.sdo['Producer heartbeat time'].raw = 1000

# Read PDO configuration from node
node.tpdo.read()
node.rpdo.read()
# Re-map TPDO[1]
node.tpdo[1].clear()
node.tpdo[1].add_variable('Statusword')
node.tpdo[1].add_variable('Velocity actual value')
node.tpdo[1].add_variable('Some group', 'Some subindex')
node.tpdo[1].trans_type = 254
node.tpdo[1].event_timer = 10
node.tpdo[1].enabled = True
# Save new PDO configuration to node
node.tpdo[1].save()

# Transmit SYNC every 100 ms
network.sync.start(0.1)

# Change state to operational (NMT start)
node.nmt.state = 'OPERATIONAL'

# Read a value from TPDO[1]
node.tpdo[1].wait_for_reception()
speed = node.tpdo[1]['Velocity actual value'].phys
val = node.tpdo['Some group.Some subindex'].raw

# Disconnect from CAN bus
network.sync.stop()
network.disconnect()
# 导入canopen库以实现与CANopen设备的通信
import canopen

# 初始化一个CAN网络,代表一条CAN总线
# 创建一个网络实例,用于管理CAN总线上的节点与通信
network = canopen.Network()

# 向网络中添加一个节点,节点ID为6,并指定对象字典(Object Dictionary)的路径
# 该对象字典包含了设备的数据结构和通信参数
node = canopen.RemoteNode(6, '/path/to/object_dictionary.eds')
# 将新创建的节点添加到网络中
network.add_node(node)

# 连接到CAN总线
# 连接参数将传递给python-can库中的can.Bus构造器
# 更多关于连接参数的信息请参考python-can文档:https://python-can.readthedocs.io/en/latest/bus.html
network.connect()
# 根据实际使用的CAN接口和配置选择合适的连接方式,例如:
# network.connect(bustype='socketcan', channel='can0')
# network.connect(bustype='kvaser', channel=0, bitrate=250000)
# ...其他连接示例省略...

# 通过SDO读取变量
# 读取设备制造商名称和供应商ID
device_name = node.sdo['Manufacturer device name'].raw
vendor_id = node.sdo[0x1018][1].raw

# 使用SDO写入变量
# 设置生产者心跳时间
node.sdo['Producer heartbeat time'].raw = 1000

# 读取PDO配置
# 分别读取TPDO和RPDO的当前配置
node.tpdo.read()
node.rpdo.read()

# 重新映射TPDO[1]
# 清除现有映射
node.tpdo[1].clear()
# 添加新的变量到TPDO[1]
node.tpdo[1].add_variable('Statusword')
node.tpdo[1].add_variable('Velocity actual value')
# 支持通过组名和子索引映射变量
node.tpdo[1].add_variable('Some group', 'Some subindex')
# 设置传输类型、事件定时器并启用该PDO
node.tpdo[1].trans_type = 254
node.tpdo[1].event_timer = 10
node.tpdo[1].enabled = True
# 保存新的PDO配置至节点,以便重启后仍生效
node.tpdo[1].save()

# 设置每100毫秒发送一次SYNC报文
network.sync.start(0.1)

# 改变节点状态为运行中(NMT启动命令)
node.nmt.state = 'OPERATIONAL'

# 从TPDO[1]接收数据并读取值
# 等待TPDO[1]的接收完成
node.tpdo[1].wait_for_reception()
# 获取实际速度的物理值
speed = node.tpdo[1]['Velocity actual value'].phys
# 通过组名和子索引读取原始值
val = node.tpdo['Some group.Some subindex'].raw

# 断开与CAN总线的连接
# 停止发送SYNC报文
network.sync.stop()
# 断开网络连接
network.disconnect()

 

六、调试

如果需要更详细地了解发生了什么,可以提高日志记录级别:

import logging
logging.basicConfig(level=logging.DEBUG)

 

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值