学习CANopen --- [2] PythonCANopen简单用法

本文主要讲述如何在Linux下使用python进行简单的CANopen通信,使用了一个叫CANopen for Python的库,地址是https://github.com/christiansandberg/canopen

该库作者还写了相关的教程,地址是https://canopen.readthedocs.io/en/latest/,可以直接去看这个教程,只是这个教程是英文的,不过也不难。


一 安装CANopen for Python

要求python版本是2.7或者3.4以上,推荐使用3.4以上的版本。这里使用virtualenv去安装这个库(也可以直接使用pip3去安装,即pip3 install canopen),所以先安装virtualenv,

pip3 install virtualenv

如果速度太慢,可以指定国内镜像去安装,

pip3 install virtualenv -i https://mirrors.aliyun.com/pypi/simple/

安装好之后,我们创建一个目录叫pythonCANopen,然后进入这个目录执行virtualenv venv
在这里插入图片描述
OK之后,使用下面命令去激活这个虚拟环境,

source venv/bin/activate

这样在目录左侧就会有个venv符号,
在这里插入图片描述
如果想退出虚拟环境,只要输入deactivate命令就可以了,
在这里插入图片描述
使用virtualenv的最大好处就是可以隔离工程应用之间的互相干扰,在虚拟环境下下载的库都只会存放在工程目录下,非常方便。

最后,输入下面命令去安装canopen,也就是本文使用的库,

pip3 install canopen

目前,该库已实现如下功能,对于我们学习CANopen已经足够了。
在这里插入图片描述


二 创建虚拟CAN设备

操作方式和上一篇文章中是一样的,虚拟CAN设备的名字叫vcan0,类型是socketCAN

$ sudo modprobe vcan
$ sudo ip link add dev vcan0 type vcan
$ sudo ip link set up vcan0

三 编写Python代码

因为需要一个master和一个slave,所以需要2份代码

master.py
import time
import canopen

# 创建一个网络用来表示CAN总线
network = canopen.Network()

# 添加slave节点,其id是6,对象字典为CANopenSocket.eds
node = canopen.RemoteNode(6, 'CANopenSocket.eds')
network.add_node(node)

# 连接到CAN总线
network.connect(bustype='socketcan', channel='vcan0')

# 把slave从INITIALISING设置为PRE-OPERATIONAL状态
node.nmt.state = 'PRE-OPERATIONAL'

# 等待3s
time.sleep(3)

# 把slave从PRE-OPERATIONAL设置为OPERATIONAL状态
node.nmt.state = 'OPERATIONAL'

# 等待5s
time.sleep(5)

# 把slave的心跳报文时间改为5s
node.sdo['Producer heartbeat time'].raw = 5000
slave.py
import signal
import canopen


running = True

def sigint_handler(signum, frame):
	global running
	print('')
	running = False
	exit(0)

# 处理按键发送的信号,优雅的关闭程序
signal.signal(signal.SIGINT,  sigint_handler)
signal.signal(signal.SIGHUP,  sigint_handler)
signal.signal(signal.SIGTERM, sigint_handler)

# 创建一个网络用来表示CAN总线
network = canopen.Network()

# 连接到CAN总线
network.connect(bustype='socketcan', channel='vcan0')

# 创建slave节点,其id是6,对象字典为CANopenSocket.eds
node = network.create_node(6, 'CANopenSocket.eds')

# 向CAN总线上发送启动消息
node.nmt.send_command(0)

# 发送心跳报文,每隔1s发送一次
node.nmt.start_heartbeat(1000) # 1000ms


# 循环
while running:
	pass
运行

代码中需要eds文件,即CANopenSocket.eds,可以到这个地址上去复制保存一下就行了。

最后整体工程结构如下,
在这里插入图片描述
先开一个terminal运行candump -t d vcan0
在这里插入图片描述
然后新开一个terminal运行slave.py,
在这里插入图片描述
此时可以在candump终端下可以看到心跳报文,1s一次
在这里插入图片描述
此时slave的状态是INITIALISING

最后新开一个terminal,运行master
在这里插入图片描述
报文变化如下,最左一列显示报文间的时间间隔,
在这里插入图片描述
报文解析

  1. 第一个红线标记处是master发送NMT命令去把slave状态从INITIALISING变成PRE-OPERATIONAL
  2. 第二个红线标记处是master发送NMT命令去把slave状态从PRE-OPERATIONAL变成OPERATIONAL
  3. 第三个红线标记处是master发送SDO报文去修改slave的心跳报文时间间隔,改为5000ms
  4. 第四个红线标记处是slave对master的SDO应答,表示修改成功,没有错误

下图是状态转换的状态机,详细资料可以去查看CANopen DS301的文档
在这里插入图片描述


四 总结

本文主要讲述如何使用python去进行CANopen通信,使用库CANopen for Python,这个库最大的好处就是可以自己解析eds或dcf文件,非常方便。后续也会使用这个库进行讲解CANopen

本系列的第一篇文章讲述了如何使用库CANopenSocket去进行CANopen通信,但是这个库不支持解析eds文件,需要使用第三方工具去把eds文件转为C代码,然后集成到整体代码里来,这样就会比较麻烦。

如果有写的不对的地方,希望能留言指正,谢谢阅读。

  • 8
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 26
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 26
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值