张宁的个人博客

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

Python-can库 ①快速了解入门

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

什么是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
发表评论