发表评论
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)
其中一些参数的含义,会在后续章节中介绍。