发表评论
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总线数据的读取、发送。
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__
请确保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)
其中一些参数的含义,会在后续章节中介绍。