python-can使用总结

python-can的使用总结

简介

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

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

使用

1、首先导入库

import can

2、实例化Canalyst, PeakCAN

def SetChannel():
    global bus_instance
    print("实例化pcan")
    bus_instance = can.interface.Bus(bustype='pcan', channel='PCAN_USBBUS1',bitrate=500000)
def SetChannel_can(ChannelNumber):
    global bus_instance
    print("实例化can")
    print(ChannelNumber)
    bus_instance = can.interface.Bus(bustype='canalystii', channel=ChannelNumber, bitrate=500000)

3、发送报文

def SendMessage(canMessage):
    bus_instance.send(canMessage, 0.1)
can_data_list = [0, 0, 0, 0, 0, 0, 0, 0]
can_message = can.Message(arbitration_id=SendID, data=can_data_list, is_extended_id=False)
SendMessage(can_message)
can.message(timestamp=0.0,                     //时间戳
			arbitration_id=0,                  //报文id
			is_extended_id=True,               //是否为扩展帧
			is_remote_frame=False,             //是否为远程帧
			is_error_frame=False,              //是否为错误帧
			channel=None,                      //通道
			dlc=None,                          //dlc大小
			data=None,                         //数据
			is_fd=False,                       //是否为canfd
			is_rx=True,                        //是否为接收帧
			bitrate_switch=False,              //比特率开关
			error_state_indicator=False,       
		 	check=False)                       

4、接收报文(rcvId换成自己的报文id,如0x123)

def recv_message(rcvId):
    recv_id = 0x123
    can_filter = [{"can_id": recv_id, "can_mask": 0xFFFFFFFF}]
    bus_instance.set_filters(can_filter)
    # state = bus_instance.status()
    # print("pcan总线状态:", state)

    message = bus_instance.recv(0.001)
    return message

报文数据在message的data中

message = recv_message(RcvID)
recv_can_data = message.data
# recv_can_data[0]...

另一种处理数据的方法

message = recv_message(RcvID)
recv_can_msg = str(message).split()
can_id = recv_can_msg[3]			# eg:'00000123',注意id的格式
can_data0 = recv_can_msg[7]			# eg:'ff'
can_data1 = recv_can_msg[8]
can_data2 = recv_can_msg[9]
can_data3 = recv_can_msg[10]
can_data4 = recv_can_msg[11]
can_data5 = recv_can_msg[12]
can_data6 = recv_can_msg[13]
can_data7 = recv_can_msg[14]

can_data0 = int(can_data0,16)		# eg:255即0xff

5、清空缓存区

# 丢弃可能在输出缓冲区排队的每一条信息
def resetTxBuffer():
    bus_instance.flush_tx_buffer()

6、pcan清空缓存区接收到的报文不对的话要重置总线

# 重置总线
def resetBus():
    bus_instance.reset()

7、pcan切换芯片后再次实例化报错初始化失败时需要关闭总线

# 关闭总线
def shutdownBus():
    bus_instance.shutdown()

补充:
使用cantools库,根据dbc解析数据
1、导入库

import cantools

2、加载dbc文件

# 加载DBC文件
db = cantools.db.load_file('path_to_your_dbc_file.dbc')

3、发送数据时根据dbc编码消息

# 发送消息
def send_message(message_id, data):
    # 根据DBC文件编码数据
    encoded_data = db.encode_message(message_id, data)	# 字节类型
    msg = can.Message(arbitration_id=message_id, data=encoded_data, is_extended_id=False)
    bus.send(msg)
   
# 发送示例
data_to_send = {'SignalName1': value1, 'SignalName2': value2}  # 根据DBC文件和需要发送的信号进行替换
send_message(0x123, data_to_send)  # 0x123是要发送的消息ID

4、接收数据时根据dbc解码消息

# 接收并解码消息
def receive_and_decode():
    message = bus.recv()  # 阻塞等待接收消息
    decoded_message = db.decode_message(message.arbitration_id, message.data)	# 参数:can_id, can_data(字节类型)
    print(decoded_message)
    
# 接收并解码示例
receive_and_decode()
  • 29
    点赞
  • 104
    收藏
    觉得还不错? 一键收藏
  • 12
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值