學習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,點擊這裏下載,提取碼wi2y,本人上傳到百度雲了。也可以到這個地址上去複製保存一下就行了。

最後整體工程結構如下,
在這裏插入圖片描述
先開一個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代碼,然後集成到整體代碼裏來,這樣就會比較麻煩。

如果有寫的不對的地方,希望能留言指正,謝謝閱讀。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章