张宁的个人博客

莫道君行早,更有早行人。

Python-can库 ①快速了解入门

张宁的个人博客/发布时间:2023-05-18/分类:软件&硬件/ 浏览量:12769

什么是Python-can 和 安装方法

Python-can为Python第三方库,主要用于:(翻译自官方文档介绍,全部介绍见:python-can 4.4.2 documentation

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

2. python-can 可以在任何 Python 运行的地方运行; 从 CAN 的高功率计算机到 USB 设备,再到运行 linux 的低功率设备,例如 BeagleBone 或 RaspberryPi。

更具体地说,该库的一些示例用途:

  • 被动记录 CAN 总线上发生的情况。 例如,使用 OBD-II 端口监控商用车辆。

  • 测试通过 CAN 交互的硬件。 在现代汽车、摩托车、船只甚至轮椅中发现的模块已经使用这个库从 Python 中测试了组件。

  • 在回路中对新的硬件模块或软件算法进行原型设计。 轻松与现有总线交互。

  • 创建虚拟模块以原型 CAN 总线通信。

使用pip安装Python-can库(使用了清华的国内镜像源,加速下载):

$ pip install python-can -i https://pypi.tuna.tsinghua.edu.cn/simple


简单案例

Python-can可以实现硬件CAN总线数据的读取、发送,以及虚拟CAN总线数据的读取、发送。

1. 虚拟CAN总线

import can

def send_one():  #发送数据函数
    #实例化两个虚拟CAN总线Bus,分别用于发送数据和接收数据
    with can.interface.Bus('test', interface='virtual') as bus1, can.interface.Bus('test', interface='virtual') as bus2:
        #实例化Message信号,arbitration_id为消息标识符,data为发送的数据
        msg1 = can.Message(arbitration_id=0xabcde, data=[1,2,3])

        try:
            bus1.send(msg1)                                     #bus1发送消息msg1
            msg2 = bus2.recv()                                  #bus2接收消息,并存储在msg2

            bus2.send(msg1)
            msg3 = bus1.recv()
            print("发送成功","\n",msg1,"\n",msg2,"\n",msg3)
        except can.CanError:
            print("通信失败")

        #assert msg1 == msg2
        assert msg1.arbitration_id == msg2.arbitration_id       #比对两个消息标识符是否一致
        assert msg1.data == msg2.data                           #比对两个消息
        assert msg1.timestamp != msg2.timestamp                 #比对两个消息时间戳是否一致

if __name__ == "__main__":
    send_one()
    print(__name__)

运行结果如下:

发送成功 
 Timestamp:        0.000000    ID: 000abcde    X Rx          DL:  3    01 02 03 
 Timestamp: 1723955392.890515    ID: 000abcde    X Rx          DL:  3    01 02 03         Channel: test 
 Timestamp: 1723955392.892515    ID: 000abcde    X Rx          DL:  3    01 02 03         Channel: test
__main__

2. 硬件CAN总线

请确保CAN盒已经正确连接,确认使用的是CAN还是CANFD,并基于波特率调整下方代码中的参数。

import time
import can
from can.bit_timing import BitTimingFd

def send_fd_test():
    #首先基于CAN协议设置波特率,此处设置的为CANFD数据的波特率参数
    timingFD = BitTimingFd(
        f_clock=24000000,  #时钟频率
        nom_brp=3,         #仲裁场分频系数
        nom_tseg1=13,      #仲裁场TSeg1
        nom_tseg2=2,       #仲裁场TSeg2
        nom_sjw=1,         #仲裁场同步跳变宽度
        data_brp=2,        #数据场分频系数
        data_tseg1=4,     #数据场TSeg1
        data_tseg2=1,      #数据场TSeg2
        data_sjw=1         #数据场同步跳变宽度
    )

    bus1 = can.interface.Bus(channel='PCAN_USBBUS1',interface='pcan',fd=True,timing=timingFD)
    msg1 = can.Message(timestamp=0,arbitration_id=0x124,data=[1,0,15,0,1,3,1,4,9,8,8,9,10,11,12,12,15],is_extended_id=False, is_fd=True)

    for i in range(5):
        print(msg1)
        bus1.send(msg1)
        time.sleep(0.1)

其中一些参数的含义,会在后续章节中介绍。

文章关键词
Python
Python-can
CAN
CANFD
发表评论