最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

基于PyQt5實(shí)現(xiàn)一個(gè)串口接數(shù)據(jù)波形顯示工具

 更新時(shí)間:2023年01月14日 08:44:39   作者:SongYuLong的博客  
這篇文章主要為大家詳細(xì)介紹了如何利用PyQt5實(shí)現(xiàn)一個(gè)串口接數(shù)據(jù)波形顯示工具,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起了解一下

工具簡(jiǎn)述

基于PyQt5開(kāi)發(fā)UI界面使用QtDesigner設(shè)計(jì),需要使用到serial模塊(串口庫(kù))和pyqtgraph(圖形庫(kù))。上位機(jī)通過(guò)串口接收來(lái)自MCU發(fā)送數(shù)據(jù),解析出每一個(gè)數(shù)據(jù)項(xiàng)并以波形圖的方式顯示。本例程下位機(jī)是Raspberry Pi Pico發(fā)送HMC5883L地磁模塊數(shù)據(jù),數(shù)據(jù)項(xiàng)有x,y,z,h等,數(shù)據(jù)格式’$$:x,y,z,h’。

主程序代碼

import sys
import numpy as np

from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *

import serial
import serial.tools.list_ports
from ui_main import Ui_MainWindow
import pyqtgraph as pg


class AppMainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super(AppMainWindow, self).__init__(parent)
        self.setupUi(self)
        self.setWindowTitle("串口數(shù)據(jù)波形顯示工具")
        self.PosX = 0
        self.dataIndex = 0          # 數(shù)據(jù)列表當(dāng)前索引
        self.dataMaxLength = 10000  # 數(shù)據(jù)列表最大長(zhǎng)度
        self.dataheader = b'$$:'    # 數(shù)據(jù)幀開(kāi)頭
        self.dataX = np.zeros(self.dataMaxLength, dtype=float)
        self.dataY = np.zeros(self.dataMaxLength, dtype=float)
        self.dataZ = np.zeros(self.dataMaxLength, dtype=float)
        self.dataH = np.zeros(self.dataMaxLength, dtype=float)

        self.mSerial = serial.Serial()
        self.ScanComPort()
        self.SelectComPort()
        
        self.btnScanPort.clicked.connect(self.ScanComPort)
        self.btnOpenPort.clicked.connect(self.OpenComPort)
        self.btnClosePort.clicked.connect(self.CloseComPort)
        self.cmbComPort.currentIndexChanged.connect(self.SelectComPort)

        self.mTimer = QTimer()
        self.mTimer.timeout.connect(self.ReceiverPortData)

        self.plotM.setAntialiasing(True)
        # self.plotM.setBackground()
        self.canvasX = self.plotM.plot(self.dataX, pen=pg.mkPen(color='r', width=1))
        self.canvasY = self.plotM.plot(self.dataY, pen=pg.mkPen(color='g', width=1))
        self.canvasZ = self.plotM.plot(self.dataZ, pen=pg.mkPen(color='b', width=1))
        self.canvasH = self.plotM.plot(self.dataH, pen=pg.mkPen(color='y', width=1))

    def ScanComPort(self):
        self.cmbComPort.clear()
        self.portDict = {}
        portlist = list(serial.tools.list_ports.comports())
        for port in portlist:
            self.portDict["%s" % port[0]] = "%s" % port[1]
            self.cmbComPort.addItem(port[0])
        if len(self.portDict) == 0:
            QMessageBox.critical(self, "警告", "未找到串口設(shè)備!", QMessageBox.Cancel, QMessageBox.Cancel)
        pass
    
    def SelectComPort(self):
        if len(self.portDict) > 0 :
            self.labComPortName.setText(self.portDict[self.cmbComPort.currentText()])
        else:
            self.labComPortName.setText("未檢測(cè)到串口設(shè)備!")
        pass

    def OpenComPort(self):
        self.mSerial.port = self.cmbComPort.currentText()
        self.mSerial.baudrate = int(self.cmbBaudrate.currentText())

        if self.mSerial.isOpen():
            QMessageBox.warning(self, "警告", "串口已打開(kāi)", QMessageBox.Cancel, QMessageBox.Cancel)
        else:
            try:
                self.btnOpenPort.setEnabled(False)
                self.mSerial.open()
                self.mSerial.flushInput()
                self.mSerial.flushOutput()
                self.mTimer.start(1)
            except:
                QMessageBox.critical(self, "警告", "串口打開(kāi)失?。?, QMessageBox.Cancel, QMessageBox.Cancel)
                self.btnOpenPort.setEnabled(True)
        print(self.mSerial)
        pass

    def CloseComPort(self):
        self.mTimer.stop()
        if self.mSerial.isOpen():
            self.btnOpenPort.setEnabled(True)
            self.mSerial.flushInput()
            self.mSerial.flushOutput()
            self.mSerial.close()
        pass

    def ReceiverPortData(self):
        '''
        接收串口數(shù)據(jù),并解析出每一個(gè)數(shù)據(jù)項(xiàng)更新到波形圖
        數(shù)據(jù)幀格式'$$:95.68,195.04,-184.0\r\n'
        每個(gè)數(shù)據(jù)幀以b'$$:'開(kāi)頭,每個(gè)數(shù)據(jù)項(xiàng)以','分割
        '''
        try:
            n = self.mSerial.inWaiting()
        except:
            self.CloseComPort()

        if n > 0:
            # 端口緩存內(nèi)有數(shù)據(jù)
            try:
                self.recvdata = self.mSerial.readline(1024) # 讀取一行數(shù)據(jù)最大長(zhǎng)度1024字節(jié)

                if self.recvdata.decode('UTF-8').startswith(self.dataheader.decode('UTF-8')):
                    rawdata = self.recvdata[len(self.dataheader) : len(self.recvdata) - 2]
                    data = rawdata.split(b',')
                    # print(rawdata)
                    
                    if self.dataIndex < self.dataMaxLength:
                        # 接收到的數(shù)據(jù)長(zhǎng)度小于最大數(shù)據(jù)緩存長(zhǎng)度,直接按索引賦值,索引自增1
                        # print(rawdata, rawdata[0], rawdata[1], rawdata[2], self.dataX[self.dataIndex], self.dataY[self.dataIndex], self.dataZ[self.dataIndex])
                        self.dataX[self.dataIndex] = float(data[0])
                        self.dataY[self.dataIndex] = float(data[1])
                        self.dataZ[self.dataIndex] = float(data[2])
                        self.dataH[self.dataIndex] = float(data[3])
                        self.dataIndex = self.dataIndex + 1
                    else:
                        # 寄收到的數(shù)據(jù)長(zhǎng)度大于或等于最大數(shù)據(jù)緩存長(zhǎng)度,丟棄最前一個(gè)數(shù)據(jù)新數(shù)據(jù)添加到數(shù)據(jù)列尾
                        self.dataX[:-1] = self.dataX[1:]
                        self.dataY[:-1] = self.dataY[1:]
                        self.dataZ[:-1] = self.dataZ[1:]
                        self.dataH[:-1] = self.dataH[1:]

                        self.dataX[self.dataIndex - 1] = float(data[0])
                        self.dataY[self.dataIndex - 1] = float(data[1])
                        self.dataZ[self.dataIndex - 1] = float(data[2])
                        self.dataH[self.dataIndex - 1] = float(data[3])
                    
                    # 更新波形數(shù)據(jù)
                    self.canvasX.setData(self.dataX)
                    self.canvasY.setData(self.dataY)
                    self.canvasZ.setData(self.dataZ)
                    self.canvasH.setData(self.dataH)

                    # self.canvasX.setPos(self.PosX, 0)
                    # self.canvasY.setPos(self.PosX, 0)
                    # self.canvasZ.setPos(self.PosX, 0)
            except:
                pass
        pass

    def SendPortData(self):
        pass


if __name__ == "__main__":
    app = QApplication(sys.argv)
    win = AppMainWindow()
    win.show()
    sys.exit(app.exec_())

Qt Designer設(shè)計(jì)UI界面

程序運(yùn)行效果

到此這篇關(guān)于基于PyQt5實(shí)現(xiàn)一個(gè)串口接數(shù)據(jù)波形顯示工具的文章就介紹到這了,更多相關(guān)PyQt5數(shù)據(jù)波形顯示工具內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Python函數(shù)高級(jí)(命名空間、作用域、裝飾器)

    Python函數(shù)高級(jí)(命名空間、作用域、裝飾器)

    這篇文章介紹了Python函數(shù)的高級(jí)用法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-05-05
  • 機(jī)器學(xué)習(xí)、深度學(xué)習(xí)和神經(jīng)網(wǎng)絡(luò)之間的區(qū)別和聯(lián)系

    機(jī)器學(xué)習(xí)、深度學(xué)習(xí)和神經(jīng)網(wǎng)絡(luò)之間的區(qū)別和聯(lián)系

    機(jī)器學(xué)習(xí)>神經(jīng)網(wǎng)絡(luò)>深度學(xué)習(xí)≈深度神經(jīng)網(wǎng)絡(luò),機(jī)器學(xué)習(xí)包括了神經(jīng)網(wǎng)絡(luò)在內(nèi)的許多算法,而神經(jīng)網(wǎng)絡(luò)又可以分為淺度神經(jīng)網(wǎng)絡(luò)和深度神經(jīng)網(wǎng)絡(luò),深度學(xué)習(xí)是使用了深度神經(jīng)網(wǎng)絡(luò)的技術(shù),雖然機(jī)器學(xué)習(xí)、深度學(xué)習(xí)和神經(jīng)網(wǎng)絡(luò)是不同的,但在構(gòu)建復(fù)雜系統(tǒng)時(shí),許多相關(guān)概念是混合在一起的
    2024-02-02
  • 一文教會(huì)你用Python實(shí)現(xiàn)pdf轉(zhuǎn)word

    一文教會(huì)你用Python實(shí)現(xiàn)pdf轉(zhuǎn)word

    python實(shí)現(xiàn)pdf轉(zhuǎn)word,支持中英文轉(zhuǎn)換,轉(zhuǎn)換精度高,可以達(dá)到使用效果,下面這篇文章主要給大家介紹了關(guān)于用Python實(shí)現(xiàn)pdf轉(zhuǎn)word的相關(guān)資料,需要的朋友可以參考下
    2023-01-01
  • Tensorflow中使用tfrecord方式讀取數(shù)據(jù)的方法

    Tensorflow中使用tfrecord方式讀取數(shù)據(jù)的方法

    這篇文章主要介紹了Tensorflow中使用tfrecord方式讀取數(shù)據(jù)的方法,適用于數(shù)據(jù)較多時(shí),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-06-06
  • Python中非常實(shí)用的Math模塊函數(shù)教程詳解

    Python中非常實(shí)用的Math模塊函數(shù)教程詳解

    Math模塊中,有很多基礎(chǔ)的數(shù)學(xué)知識(shí),我們必須要掌握的,例如:指數(shù)、對(duì)數(shù)、三角或冪函數(shù)等。因此,特意借著這篇文章,為大家講解一些該庫(kù)
    2021-10-10
  • 動(dòng)態(tài)設(shè)置django的model field的默認(rèn)值操作步驟

    動(dòng)態(tài)設(shè)置django的model field的默認(rèn)值操作步驟

    這篇文章主要介紹了動(dòng)態(tài)設(shè)置django的model field的默認(rèn)值操作步驟,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-03-03
  • Django中使用session保持用戶登陸連接的例子

    Django中使用session保持用戶登陸連接的例子

    今天小編就為大家分享一篇Django中使用session保持用戶登陸連接的例子,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-08-08
  • Python調(diào)用Redis的示例代碼

    Python調(diào)用Redis的示例代碼

    這篇文章主要介紹了Python調(diào)用Redis的示例代碼,幫助大家更好的理解和學(xué)習(xí)python,感興趣的朋友可以了解下
    2020-11-11
  • python3中@dataclass的實(shí)現(xiàn)示例

    python3中@dataclass的實(shí)現(xiàn)示例

    @dataclass?是 Python 3.7 引入的一個(gè)裝飾器,用于方便地定義符合數(shù)據(jù)類(lèi)協(xié)議的類(lèi),本文主要介紹了python3中@dataclass的實(shí)現(xiàn)示例,感興趣的可以了解一下
    2024-02-02
  • python標(biāo)準(zhǔn)庫(kù) datetime的astimezone設(shè)置時(shí)區(qū)遇到的坑及解決

    python標(biāo)準(zhǔn)庫(kù) datetime的astimezone設(shè)置時(shí)區(qū)遇到的坑及解決

    這篇文章主要介紹了python標(biāo)準(zhǔn)庫(kù) datetime的astimezone設(shè)置時(shí)區(qū)遇到的坑及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-09-09

最新評(píng)論

夏津县| 阳原县| 清流县| 东至县| 梅州市| 兴隆县| 白城市| 青州市| 达孜县| 岳普湖县| 富源县| 离岛区| 东阿县| 明光市| 保山市| 呼伦贝尔市| 车险| 高碑店市| 齐河县| 博爱县| 红桥区| 临海市| 启东市| 介休市| 鹿邑县| 德兴市| 新邵县| 搜索| 嘉荫县| 仪征市| 河南省| 青川县| 武冈市| 尉氏县| 临沂市| 伊通| 巴彦县| 洪洞县| 定襄县| 玉龙| 瑞金市|