CAN盒是CAN总线通信的必要设备,USBCAN盒大致可以分为Vector/Kvaser/周立功/PCAN。国内的pcan大都是兼容周立功,peak兼容pcan, 那种便宜的一般不支持linux。 汽车can总线一般是使用pcan,今天主要讲解PEAK PCAN。
驱动下载地址: http://www.peak-system.com/fileadmin/media/linux/
sudo apt-get install libpopt-dev
tar -xzf peak-linux-driver-8.15.1.tar.gz
cd peak-linux-driver-8.15.1/
make clean
make
sudo make install
安装成功后查看
pcaninfo
(1) 修改devid
因为多个can盒接入同一个设备上,往往devid统一默认为0, 所以需要修改其值,保证每个设备编号唯一
方法一:通过文档修改
有时同一个工控机需要接入多个can分析仪,会用到devid 值,但是can分析仪都是默认值为devid=0x00, 容易重复,所以需要修改devid值。在路径/sys/下搜索 devid文档,修改内容即可
方法二:命令修改
##修改id号为2
pcan-settings -f=/dev/pcanusbX -d 2 或
echo 2 | sudo tee /sys/class/pcan/pcanusbX/devid
方法三:devid 永久固定
以上两种方法,重新上电后,devid还是会改变,所以建议永久固定
估计是需要烧写程序 ,但是我不会,哪位大佬有好的建议,欢迎留言,一起交流!!!
(2) 编写程序,实现通信
import os
import can
can.rc['interface'] = 'pcan' # 配置硬件类型
can.rc['channel'] = 'PCAN_USBBUS1' # 配置通道,根据具体的硬件,int或者str
can.rc['bitrate'] = 500000 # 波特率
def getPcanChannel(id):
channel = None
result = os.popen('pcaninfo') #执行pcaninfo 命令
res = result.read() # 读取pcaninfo中的内容
for line in res.splitlines(): #以"\n" 分割,将元素保存在列表
if line.startswith(" * pcanusb"): #以" * pcanusb" 开头
if "devid="+id in line:
line_split = line.split(' ') # 空格分割
for temp in line_split:
if 'PCAN_USBBUS' in temp:
channel = temp
print(channel) ##输出 "PCAN_USBBUS1"
return channel
if __name__ == "__main__":
pcan_channel = getPcanChannel("0x02")
if pcan_channel == None:
print("PCAN通道获取失败,程序退出!")
exit()
print(pcan_channel) # "PCAN_USBBUS1"
pcanbus = can.interface.Bus(channel=pcan_channel.replace('"', "")) #实例化can 通道
(1) udev规则编写
#1. 查看pcan设备是否连接
ls -l /dev/pcan*
# 2.查看设备属性
udevadm info --attribute-walk --name=/dev/pcanusb32
#3.通过ATTRS{serial} 建立udev规则
cd /etc/udev/rules.d/
sudo gedit mypcan.rules
#4.udev规则内容,serial 根据设备属性实际情况填写
KERNEL=="pcanusb*",ATTRS{serial}=="8D8C6EC00352",MODE:="0777",SYMLINK+="pcan_0"
KERNEL=="pcanusb*",ATTRS{serial}=="8D8C67C40352",MODE:="0777",SYMLINK+="pcan_1"
#5.重新加载udev规则, 拔插设备之后生效
sudo systemctl daemon-reload
sudo service udev reload
sudo service udev restart
##6.查看设备
ls -l /dev/pcan_0
(2)编写程序实现通信
import os
import can
def getDev():
channel = None
result = os.popen('ls -l /dev/pcan_0') #实现pcan_0通信
res = result.read()
for line in res.splitlines():
if "pcan_0" in line:
temp = line[-9:]
# print(temp)
rt = os.popen('pcaninfo')
rs = rt.read()
for ln in rs.splitlines():
if temp in ln:
ln_solit = ln.split(' ')
for tp in ln_solit:
if 'PCAN_USBBUS' in tp:
channel = tp
print(channel)
return channel
if __name__ == "__main__":
pcan_channel = getDev() ### "PCAN_USBBUS1"
if pcan_channel == None:
print("PCAN通道获取失败,程序退出!")
exit()
pcanbus = can.interface.Bus(channel=pcan_channel.replace('"', "")) #实例化can 通道
参考链接:PEAK-System Forum
python-can介绍