基于Python的CAN卡数据显示工具

文章介绍了如何使用Python与ControlCAN.dll库进行CAN卡设备的初始化,设置波特率,以及实现数据的接收和处理。作者展示了通过ctypes模块加载动态链接库并操作结构体,进行设备打开、配置和数据解析的过程。
摘要由CSDN通过智能技术生成
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是一种具有广泛用途的高级编程语言。在许多应用中,需要实时读取串口数据。串口通信是一种非常常见的通信方式,它可用于连接外部设备,如传感器、执行器、调制解调器等。这里将讨论如何使用Python进行实时读取串口数据。 要实现Python实时读取串口数据,首先需要安装PySerial。该可以实现串行通信,并提供了强大的API,支持读写串口数据。为了使用它,需要在Python环境中使用pip install pyserial命令将其安装。 接下来,就可以使用Python代码从串口读取实时数据。以下是一些示例代码: import serial ser = serial.Serial('COM1', 9600, timeout=1) while True: data = ser.readline() if data: print(data) 这段代码使用serial模块打开串口“COM1”,波特率为9600,超时时间为1秒。然后在一个无限循环中,使用readline()方法读取串口的数据。如果读到数据,就将其打印出来。 除了使用serial模块,还可以使用其他Python来实现串口通信,如PyQtSerialPort、python-can等。这些都可以实现实时读取串口数据的功能,只需要选择适合自己需求的即可。 总的来说,Python是一种易于学习和使用的编程语言,并且有许多可以扩展其功能。实时读取串口数据是一个很常见的需求,也是Python在工业、控制、物联网等领域中的一种应用。使用PySerial工具进行实时读取串口数据是实现该需求的一种常见方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值