import ctypes
from ctypes import *
import numpy as np
from PyQt5 import QtGui
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QTextEdit
from PyQt5.QtCore import QTimer
class VCI_BOARD_INFO(Structure):
_fields_ = [("hw_Version",c_ushort),
("fw_Version", c_ushort),
("dr_Version", c_ushort),
("in_Version", c_ushort),
("irq_Num", c_ushort),
("can_Num", c_byte),
("str_Serial_Num", c_char*20),
("str_hw_Type", c_char*40),
("Reserved", c_ushort*4)]
class VCI_INIT_CONFIG(Structure):
_fields_ = [("AccCode",c_ulong),
("AccMask",c_ulong),
("Reserved",c_ulong),
("Filter",c_char),
("Timing0",c_char),
("Timing1",c_char),
("Mode",c_char)]
class VCI_CAN_OBJ(Structure):
_fields_ = [("ID",c_uint),
("TimeStamp", c_uint),
("TimeFlag", c_byte),
("SendType", c_byte),
("RemoteFlag", c_byte),
("ExternFlag", c_byte),
("DataLen", c_byte),
("Data", c_byte*8),
("Reserved", c_byte*3)]
class CAN_CARD_Init():
def __init__(self,baudRate):
self.nDeviceType = 3
self.nDeviceInd = 0
self.nReserved = 0
self.nCanId = 0
self.can_status = 0
self.vco = VCI_CAN_OBJ()
self.card= ctypes.cdll.LoadLibrary('./ControlCAN.dll')#这里的参数是文件路径
# %% 波特率设置
# %%---- TIM0='00';TIM1='14'; 1000Kbps
# %%---- TIM0='00';TIM1='16'; 800Kbps
# %%---- TIM0='00';TIM1='1C'; 500Kbps
self.vic = VCI_INIT_CONFIG()
self.vic.AccCode = int('00000000',16)# 验收码
self.vic.AccMask = int('FFFFFFFF',16)# 屏蔽码
if(baudRate==500):
self.vic.Timing0 = int('00',16)
self.vic.Timing1 = int('1C',16)
# print("BaudRate 500K")
elif(baudRate==1000):
self.vic.Timing0 = int('00',16)
self.vic.Timing1 = int('14',16)
# print("BaudRate 1000K")
open_status = self.card.VCI_OpenDevice(self.nDeviceType,self.nDeviceInd,self.nReserved)
if open_status==0:
# print("can open failed, please try again!")
self.can_status = 1
else:
self.can_status = 2
# print("can open success!")
can_init_status = self.card.VCI_InitCAN(self.nDeviceType,self.nDeviceInd,self.nCanId, byref(self.vic))
can_start_status = self.card.VCI_StartCAN(self.nDeviceType,self.nDeviceInd,self.nCanId)
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.baudRate = 500
self.can_card = CAN_CARD_Init(self.baudRate)
# 开启编辑器
self.text_edit = QTextEdit(self)
self.setCentralWidget(self.text_edit)
self.setGeometry(800, 300, 700, 400)
# 设置字体
self.text_edit.setStyleSheet("background:black")
self.setWindowIcon(QtGui.QIcon("./20.png"))
self.text_edit.setTextColor(QtGui.QColor(255, 255, 255))
self.text_edit.setFontFamily("幼圆") # 设置字体
self.text_edit.setFontPointSize(30) # 设置字体大小
self.text_edit.setReadOnly(True)
self.setWindowTitle('Tool')
if (self.can_card.can_status == 1):
self.text_edit.setFontPointSize(15) # 设置字体大小
self.text_edit.setText("can open failed, please try again!")
else:
self.text_edit.setFontPointSize(15) # 设置字体大小
self.text_edit.setText("can open success, no data!")
self.timer = QTimer(self)
self.timer.timeout.connect(self.refresh_text)
# 每10ms秒刷新一次
self.timer.start(50)
# 展示页面
self.show()
def refresh_text(self):
global can_status
dataBuf = np.array([0, 0, 0, 0, 0, 0, 0, 0], dtype = np.uint8)
# dataBuf = [0, 0, 0, 0, 0, 0, 0, 0]
# dataBuf = [0, 0, 0, 0, 0, 0, 0, 0]
rev_num = self.can_card.card.VCI_GetReceiveNum(self.can_card.nDeviceType, self.can_card.nDeviceInd, self.can_card.nCanId)
while rev_num != 0:
can_rev_status = self.can_card.card.VCI_Receive(self.can_card.nDeviceType, self.can_card.nDeviceInd, self.can_card.nCanId, byref(self.can_card.vco), 1, 10) #每次接收1包数据,超时10ms
# self.can_card.vco.ID = 0x258
if self.can_card.vco.ID == 0x258:
dataBuf[0] = self.can_card.vco.Data[0]
dataBuf[1] = self.can_card.vco.Data[1]
dataBuf[2] = self.can_card.vco.Data[2]
dataBuf[3] = self.can_card.vco.Data[3]
dataBuf[4] = self.can_card.vco.Data[4]
dataBuf[5] = self.can_card.vco.Data[5]
dataBuf[6] = self.can_card.vco.Data[6]
dataBuf[7] = self.can_card.vco.Data[7]
self.text_edit.setFontPointSize(30) # 设置字体大小
self.text_edit.setText("电池电压: %s.%s V" % (dataBuf[0],'{:02x}'.format(dataBuf[1])))
head = "CANID = 0x258:"
baudRate = "CAN总线波特率: 500K"
dataStr = ""
for i in range(0,8):
temp = '{:02x}'.format(dataBuf[i])
dataStr = dataStr + temp + " "
# print(dataStr)
self.text_edit.append("\n")
self.text_edit.append(head)
self.text_edit.append(dataStr)
self.text_edit.append("\n")
self.text_edit.append(baudRate)
#获取最新的缓存个数
rev_num = self.can_card.card.VCI_GetReceiveNum(self.can_card.nDeviceType, self.can_card.nDeviceInd, self.can_card.nCanId)
if __name__ == '__main__':
app = QApplication(sys.argv)
main_window = MainWindow()
sys.exit(app.exec_())
基于Python的CAN卡数据显示工具
文章介绍了如何使用Python与ControlCAN.dll库进行CAN卡设备的初始化,设置波特率,以及实现数据的接收和处理。作者展示了通过ctypes模块加载动态链接库并操作结构体,进行设备打开、配置和数据解析的过程。
摘要由CSDN通过智能技术生成