1 安装 python-can 包
安装命令如下:
pip install python-can
安装完成后可用下面命令查看是否安装成功及版本。
pip show python-can
Name: python-can
Version: 4.4.2
Summary: Controller Area Network interface module for Python
Home-page: https://github.com/hardbyte/python-can
Author: python-can contributors
Author-email:
License: LGPL v3
Location: D:\python3\Lib\site-packages
Requires: packaging, pywin32, typing-extensions, wrapt
Required-by:
2 创建 Vector Hardware Application
Vector VN1630A 硬件如下图:
打开控制面板,找到Vector Hardware选项,点击进入配置界面。
当硬件设备VN 1630A未插入电脑时,
插入硬件设备插入时,
创建一个新的 Application.
输入Application Name,然后点击OK即可。例如 创建了一个名为 FctTool 的Application,包含两个CAN通道。
3 分配硬件设备通道给 Application
将 VN1630A 的 channel 1分配给 FctTool 的 CAN 1(下图因为已经分配过了,所以只显示 CAN 2),将 VN1630A 的 channel 2分配给 FctTool 的 CAN 2。
最终如下:
4 编程实现
完整代码如下:
import can
from can.interfaces.vector import VectorBus
def prase_can_msg(msg):
message_str = str(msg)
parts = message_str.split()
# print("parts:", parts)
try:
err_frame = parts.index('E')
# print("Error frame found at index:", err_frame)
return None, None, None
except Exception as e:
# print("Error frame not found:", e)
pass
# 提取Timestamp
timestamp = float(parts[1])
# 提取ID
msg_id = int(parts[3].strip(), 16)
# 提取DLC(数据长度)
dlc_index = parts.index('DL:') + 1
dlc = int(parts[dlc_index].strip())
# 提取数据字段
data_index = parts.index('DL:') + 2
data1 = parts[data_index:data_index+dlc]
data = [int(x, 16) for x in data1]
# 提取Channel
channel_index = parts.index('Channel:') + 1
channel = int(parts[channel_index].strip())
hex_data = ' '.join('0x%02x' % i for i in data)
print("Timestamp channel msg_id dlc data")
print(f"{timestamp:10.6f} {channel:5d} {msg_id:9X} {dlc:6d} {hex_data}")
return msg_id, dlc, data
def detect_device_exist():
# 检测Vector 1603A设备是否存在
device_exist = False
try:
configs = can.detect_available_configs(interfaces=['vector'])
for config in configs:
if config['vector_channel_config'].name == 'VN1630A Channel 1':
device_exist = True
break
except Exception as e:
print("Detect available configs Error:", e)
app_exits = False
try:
app_cfg = VectorBus.get_application_config(app_name='FctTool', app_channel=0)
if app_cfg is not None:
app_exits = True
print("app_cfg:", app_cfg)
except can.interfaces.vector.exceptions.VectorInitializationError as e:
print("Get application config Error:", e)
if device_exist and app_exits:
return True
# 如果没有找到Vector 1603A设备,则返回False
return False
def vector_init():
if not detect_device_exist():
print("Vector 1603A device not found.")
return None
# 创建CAN总线对象,指定Vector 1603A接口
try:
# app_name 要和控制面板 Vector Hardware里面配置的名字一致,这里的 channel 要配置为0, 对应实际的 CAN 1 通道
bus = can.Bus(interface='vector', channel=0, bitrate=500000, app_name="FctTool")
print("bus type:", type(bus))
except Exception as e:
print("Create CAN bus object Error:", e)
try:
return bus
except UnboundLocalError as e:
print("Return CAN bus object Error:", e)
print("Error: CAN bus channel is used by other application.")
return None
else:
print("Other error.")
def vector_send_msg(bus, msg_id, message, dlc):
# 发送CAN消息
msg = can.Message(arbitration_id=msg_id, dlc=dlc, data=message, is_extended_id=False)
bus.send(msg)
def vector_recv_msg(bus):
# 接收CAN消息
msg = bus.recv(timeout=0.1)
if msg is not None:
# 解析CAN消息
msg_id, dlc, data = prase_can_msg(msg)
if msg_id is None:
# print("Error frame received.")
return False, None, None, None
return True, msg_id, dlc, data
else:
return False, None, None, None
def vector_close(bus):
# 关闭CAN总线
bus.shutdown()
if __name__ == '__main__':
bus = vector_init()
if bus is None:
print("CAN bus initialized failed.")
exit(1)
print("CAN bus initialized successfully.")
msg_id = 0x7F1
dlc = 8
message = [0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
vector_send_msg(bus, msg_id, message, dlc)
have_msg, msg_id, dlc, data = vector_recv_msg(bus)
if have_msg:
print("Received message:")
print(f"ID: 0x{msg_id:04X}")
print(f"DL: {dlc}")
print("Data: {data}".format(data=' '.join('0x%02x' % i for i in data)))
vector_close(bus)
创建bus总线对象时需要注意下面这个点,
5 效果演示
Vector VN1630A插入电脑,另一端连接ECU,然后运行python脚本。
app_cfg: (<XL_HardwareType.XL_HWTYPE_VN1630: 57>, 0, 0)
bus type: <class 'can.interfaces.vector.canlib.VectorBus'>
CAN bus initialized successfully.
Timestamp channel msg_id dlc data
1735904698.304546 0 7F2 8 0x1f 0x01 0x02 0x00 0x00 0x00 0x00 0x00
Received message:
ID: 0x07F2
DL: 8
Data: 0x1f 0x01 0x02 0x00 0x00 0x00 0x00 0x00
参考资料:https://python-can.readthedocs.io/en/stable/interfaces/vector.html