当前位置: 首页 > 工具软件 > python-mode > 使用案例 >

python-can简述

戴树
2023-12-01

摘要:最近用到python-can,发现网上参考资料实在不多,也缺乏一定的系统性,特此进行一番整理。——by catmemo
注:
抱歉一段时间以来没有时间和精力去更新这份博文,在这段时间以来,主要基于python-can这个库,开发了一个CAN节点模拟仿真工具,有需要的可以去下载来用,当然也欢迎二次开发。后面,时间会相对宽裕些,会继续更新这篇博文。
(当然也包括CAN收发、诊断、图形化显示等功能,详细内容可以在抖音搜索:47:/ 复制打开抖音,看看【一夜春风的作品】CAN 仿真神器——QX工具链之UltraSim… ЭmAELbZr5bntmw8ππ )。

1、简述

python-can库为Python提供了控制器局域网的支持,为不同的硬件设备提供了通用的抽象,并提供了一套实用程序,用于在CAN总线上发送和接收消息。

python-can可以在Python运行的任何地方运行; 从具有商用CAN的高功率计算机到USB设备,再到运行Linux的低功率设备(例如BeagleBone或RaspberryPi)。

更具体地说,该库的一些示例用法如下:

  • 被动记录CAN总线上发生的情况。 例如,使用其OBD-II端口监视商用车辆。
  • 测试通过CAN交互的硬件。在现代汽车,摩托车,轮船甚至轮椅上找到的模块已经使用此库通过Python测试了组件。
  • 在回路中对新的硬件模块或软件算法进行原型设计。 轻松与现有总线进行交互。
  • 创建虚拟模块以原型化CAN总线通信。

连接到CAN总线,创建和发送消息的简单实例:

#!/usr/bin/env python
# coding: utf-8

"""
This example shows how sending a single message works.
"""

from __future__ import print_function

import can

def send_one():

	# this uses the default configuration (for example from the config file)
    # see https://python-can.readthedocs.io/en/stable/configuration.html
	
	bus = can.interface.Bus()

	# Using specific buses works similar:
    # bus = can.interface.Bus(bustype='socketcan', channel='vcan0', bitrate=250000)
    # bus = can.interface.Bus(bustype='pcan', channel='PCAN_USBBUS1', bitrate=250000)
    # bus = can.interface.Bus(bustype='ixxat', channel=0, bitrate=250000)
    # bus = can.interface.Bus(bustype='vector', app_name='CANalyzer', channel=0, bitrate=250000)
    # ...
    
    msg = can.Message(arbitration_id=0xc0ffee, data=[0, 25, 0, 1, 3, 1, 4, 1], is_extended_id=True)
	
	try:
		bus.send(msg)
		print("Message sent on {}".format(bus.channel_info))
	except can.CanError:
		print("Message NOT sent")

if __name__ == '__main__':
	send_one()

2、安装

可以使用pip命令进行安装:

$ pip install python-can

由于您很可能与某些硬件连接,因此可能还必须安装对应的平台依赖项。
许多接口可以像安装python依赖项一样,通过如下命令进行安装:

$ pip install python-can[serial]

2.1 GNU/Linux 依赖项

理论上来说,现代Linux内核(2.6.25或更新版本)有一个socketcan的实现。如果用Python3.3或更高版本调用,此版本的python can将直接使用socketcan,否则将通过ctypes的类型来判断。

2.2 Windows 依赖项

2.2.1 Kvaser

使用Kvaser CANLib SDK作为后端安装python-can:
安装Kvaser最新的Windows CANLib驱动程序
测试Kvaser自己的工具是否正常工作,以确保驱动程序安装正确,以及硬件是否能正常工作。

2.2.2 PCAN

为您的接口下载并安装最新的驱动:
Windows (also supported on Cygwin)
Linux(also works without, see also Linux installation)
macOS

请注意,PCANBasic API时间戳从系统启动开始计算秒数。要将这些时间转换为纪元时间,请使用uptime库。否则,时间将以系统启动后的秒数返回。要安装uptime库,请运行pip install python can[pcan]

如果安装了Python for Windows Extensions库,此库将可以很好的被用于获得新消息的通知,而不是不得不使用的CPU密集型轮询。

2.2.3 IXXAT

使用IXXAT VCI V3 或者 V4 SDK 作为后端安装python-can:
(1)安装IXXAT’s latest Windows VCI V3 SDK or VCI V4 SDK (Win10) drivers
(2)测试IXXAT自己的工具(例如MiniMon)是否正常工作,以确保驱动程序安装正确,以及硬件是否能正常工作。

2.2.4 NI-CAN

下载并安装National Instruments
当前该驱动在Windows平台只支持32位python。

2.2.5 neoVI

查看neoVI

2.2.6 Vector

使用XL Driver Library作为后端安装python-can:
(1)为Vector硬件接口安装最新的驱动程序
(2)安装XL Driver Library或复制vxlapi.dll和/或vxlapi64.dll到您的工作目录中。
(3)使用Vector Hardware Configuration为您的应用程序分配通道。

2.2.7 CANtact

Linux、Windows和macOS均支持CANtact。要使用CANtact driver作为后端安装python-can,请执行以下操作:
(1)python3 -m pip install "python-can[cantact]"
(2)如果已经安装了python-can,则可以单独安装CANtact后端:

python3 -m pip install cantact

(3)更多相关的文档,请查看cantact.io

2.2.8 CanViewer

当前python-can已经支持通过运行python -m can.viewer 命令显示一个简单的CAN查看器终端应用程序。(类似于CANalyzer的trace)
在Windows上,需要运行如下命令安装库依赖:

python -m pip install "python-can[viewer]"

2.2.9 Installing python-can in development mode

此软件包的“开发版本”安装允许您在本地进行更改,或从Git存储库中获取更新并使用它们,而无需重新安装。下载或克隆源存储库,然后:

python setup.py develop

3、配置

通常,此库与特定的CAN接口一起使用,可以在代码中指定,也可以从配置文件或环境变量中读取。

3.1、代码中指定

can对象暴露了一个rc字典,该字典可用于在从can.interfaces导入之前设置接口和通道。

import can
can.rc['interface'] = 'socketcan'
can.rc['channel'] = 'vcan0'
can.rc['bitrate'] = 500000
from can.interface import Bus

bus = Bus()

您还可以为每个Bus实例指定接口和通道:

import can

bus = can.interface.Bus(bustype='socketcan', channel='vcan0', bitrate=500000)

3.2、配置文件

在Linux系统上,将在以下路径中搜索配置文件:

  1. 〜/ can.conf
  2. /etc/can.conf
  3. $ HOME / .can
  4. $ HOME / .canrc

在Windows系统上,将在以下路径中搜索配置文件:

  1. %USERPROFILE%/can.conf
  2. can.ini(当前工作目录)
  3. %APPDATA%/can.ini

配置文件设置默认接口和通道:

[default]
interface = <the name of the interface to use>
channel = <the channel to use by default>
bitrate = <the bitrate in bits/s to use by default>

该配置还可以包含其他部分(或上下文):

[default]
interface = <the name of the interface to use>
channel = <the channel to use by default>
bitrate = <the bitrate in bits/s to use by default>

[HS]
# All the values from the 'default' section are inherited
channel = <the channel to use>
bitrate = <the bitrate in bits/s to use. i.e. 500000>

[MS]
# All the values from the 'default' section are inherited
channel = <the channel to use>
bitrate = <the bitrate in bits/s to use. i.e. 125000>
from can.interfaces.interface import Bus

hs_bus = Bus(context='HS')
ms_bus = Bus(context='MS')

3.3、环境变量

可以从以下环境变量中获取配置:

  • CAN_INTERFACE
  • CAN_CHANNEL
  • CAN_BITRATE

3.4、接口名称

NameDocumentation
“socketcan”SocketCAN
“kvaser”Kvaser’s CANLIB
“serial”CAN over Serial
“slcan”CAN over Serial / SLCAN
“ixxat”IXXAT Virtual CAN Interface
“pcan”PCAN Basic API
“usb2can”USB2CAN Interface
“nican”NI-CAN
“iscan”isCAN
“neovi”NEOVI Interface
“vector”Vector
“virtual”Virtual
“canalystii”CANalyst-II
“systec”SYSTEC interface

4、库API

主要对象是BusABC和Message。

4.1、Bus

Bus为物理或者虚拟CAN 总线提供了一个包装器。
接口特定实例是通过使用特定接口实例化Bus类来创建的,例如:

vector_bus = can.Bus(interface='vector', ...)

然后,创建的总线能够处理特定于接口的软/硬件交互,同时为用户提供最高层级API。
当前,也可以使用线程安全总线包装器,请参阅Thread safe bus

4.1.1、Transmitting

我们可以调用send()方法并传过去一个Message类型的参数将message发送到CAN总线上,如下所示:

with can.Bus() as bus:
    msg = can.Message(
        arbitration_id=0xC0FFEE,
        data=[0, 25, 0, 1, 3, 1, 4, 1],
        is_extended_id=True
    )
    try:
        bus.send(msg)
        print(f"Message sent on {bus.channel_info}")
    except can.CanError:
        print("Message NOT sent")

周期型信号的发送则通过boradcast manager控制。

4.1.2、Receiving

通过调用recv()方法或者直接在bus上进行迭代可以读取总线上的messages:

with can.Bus() as bus:
    for msg in bus:
        print(msg.data)

此外,我们也可以通过Listener api来接收和处理来自Notifier的消息。

4.8、Utilities

can.detect_available_configs(interfaces=None)

[source]

检测接口当前可以连接的所有配置/通道。
这可能相当耗时。
并非每个平台上的每个接口都可以实现自动配置检测。在这种情况下,此方法不会引发错误,而是返回该接口的空列表。

  • Parameters
interfaces (Union[None, str, Iterable[str]]) 
- None:在所有已知接口中搜索
- string:在字符串名称的接口中搜索
- 在可迭代的接口名称中搜索
  • Return type
    list[dict]
  • Returns
    一个可迭代的dicts,每个dict都适合在can.BusABC的构造函数中使用。

4.9、Notifier

Notifier对象用作总线的消息分发器。

classcan.Notifier(bus, listeners, timeout=1.0, loop=None)

管理can.Message实例向侦听器的分发。

支持多个总线和侦听器。

待续…

 类似资料: