首頁 > 軟體

PyQt5+serial模組實現一個串列埠小工具

2023-01-14 14:01:30

串列埠簡述

非同步序列是指UART(Universal Asynchronous Receiver/Transmitter),通用非同步接收/傳送。UART是一個並行輸入成為序列輸出的晶片,通常整合在主機板上。UART包含TTL電平的串列埠和RS232電平的串列埠。 TTL電平是3.3V的,而RS232是負邏輯電平,它定義+5+12V為低電平,而-12-5V為高電平,MDS2710、MDS SD4、EL805等是RS232介面,EL806有TTL介面。

序列介面按電氣標準及協定來分包括RS-232-C、RS-422、RS485等。RS-232-C、RS-422與RS-485標準只對介面的電氣特性做出規定,不涉及接外掛、電纜或協定。

1.RS-232

也稱標準串列埠,最常用的一種序列通訊介面。它是在1970年由美國電子工業協會(EIA)聯合貝爾系統、資料機廠家及計算機終端生產廠家共同制定的用於序列通訊的標準。它的全名是“ [1] 資料終端裝置(DTE)和資料通訊裝置(DCE)之間序列二進位制資料交換介面的技術標準”。傳統的RS-232-C介面標準有22根線,採用標準25芯D型插頭座(DB25),後來使用簡化為9芯D型插座(DB9),現在應用中25芯插頭座已很少採用。
RS-232採取不平衡傳輸方式,即所謂單端通訊。由於其傳送電平與接收電平的差僅為2V至3V左右,所以其共模抑制能力差,再加上雙絞線上的分佈電容,其傳送距離最大為約15米,最高速率為20kb/s。RS-232是為對等(即只用一對收、發裝置)通訊而設計的,其驅動器負載為3~7kΩ。所以RS-232適合本地裝置之間的通訊。 [2]

2.RS-422

標準全稱是“平衡電壓數位介面電路的電氣特性”,它定義了介面電路的特性。典型的RS-422是四線介面。實際上還有一根訊號地線,共5根線。其DB9聯結器引腳定義。由於接收器採用高輸入阻抗和傳送驅動器比RS232更強的驅動能力,故允許在相同傳輸線上連線多個接收節點,最多可接10個節點。即一個主裝置(Master),其餘為從裝置(Slave),從裝置之間不能通訊,所以RS-422支援點對多的雙向通訊。接收器輸入阻抗為4k,故發端最大負載能力是10×4k+100Ω(終接電阻)。RS-422四線介面由於採用單獨的傳送和接收通道,因此不必控制資料方向,各裝置之間任何必須的訊號交換均可以按軟體方式(XON/XOFF握手)或硬體方式(一對單獨的雙絞線)實現。

RS-422的最大傳輸距離為1219米,最大傳輸速率為10Mb/s。其平衡雙絞線的長度與傳輸速率成反比,在100kb/s速率以下,才可能達到最大傳輸距離。只有在很短的距離下才能獲得最高速率傳輸。一般100米長的雙絞線上所能獲得的最大傳輸速率僅為1Mb/s。

3.RS-485

是從RS-422基礎上發展而來的,所以RS-485許多電氣規定與RS-422相仿。如都採用平衡傳輸方式、都需要在傳輸線上接終接電阻等。RS-485可以採用二線與四線方式,二線制可實現真正的多點雙向通訊,而採用四線連線時,與RS-422一樣只能實現點對多的通訊,即只能有一個主(Master)裝置,其餘為從裝置,但它比RS-422有改進,無論四線還是二線連線方式匯流排上可多接到32個裝置。

RS-485與RS-422的不同還在於其共模輸出電壓是不同的,RS-485是-7V至+12V之間,而RS-422在-7V至+7V之間,RS-485接收器最小輸入阻抗為12kΩ、RS-422是4kΩ;由於RS-485滿足所有RS-422的規範,所以RS-485的驅動器可以在RS-422網路中應用。

RS-485與RS-422一樣,其最大傳輸距離約為1219米,最大傳輸速率為10Mb/s。平衡雙絞線的長度與傳輸速率成反比,在100kb/s速率以下,才可能使用規定最長的電纜長度。只有在很短的距離下才能獲得最高速率傳輸。一般100米長雙絞線最大傳輸速率僅為1Mb/s。

注:以上內容摘自百度百科。

引腳定義:

  • RX(Receive Data):接收資料
  • TX(Transmit Data):傳送資料
  • CTS(Clear To Send): 清除傳送
  • RTS(Request To Send):請求傳送
  • DTR(Data Terminal Ready):資料終端準備好
  • DSR(Data Set Ready):資料準備好

如果UART只有RX、TX兩個訊號,要流控的話只能是軟流控;

如果有RX,TX,CTS,RTS 四個訊號,則多半是支援硬流控的UART;

如果有 RX,TX,CTS ,RTS ,DTR,DSR 六個訊號的話,RS232標準的可能性比較大。

serial模組

引數

方法

使用模板

1.初始化埠無指定引數

mSerial = serial.Serial()
mSerial.port = ‘COM9'
mSerial.baudrate = 115200
'''其它埠引數'''
m.Serial.open() # 開啟埠
mSerial.isOpen()
mSerial.read()
mSerial.write(b'hello world')

2.初始化埠指定埠號和波特率

mSerial = serial.Serial(‘COM9', 115200)
mSerial.isOpen()
mSerial.read()
mSerial.write(b'hello world')

3.初始化埠指定所有引數

mSerial = serial.Serial(port=‘COM9', baudrate=115200, bytesize=8, parity=‘N', stopbits=1, timeout=100, xonxoff=False, rtscts=False, dsrdtr=False)
mSerial.isOpen()
mSerial.read()
mSerial.write(b'hello world')

串列埠工具範例

主程式程式碼

import sys
import serial
import serial.tools.list_ports

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

from ui_comport import Ui_MainWindow

class ComPortWindow(QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None) -> None:
        super(ComPortWindow, self).__init__(parent)
        self.setupUi(self)

        self.setWindowTitle('串列埠小工具')
        self.setWindowIcon(QIcon('./images/iconCOM9.png'))

        self.mSerial = serial.Serial()
        self.ScanComPort() # 掃描一次串列埠埠
        self.OnPortChanged()
 
        self.comboBox_Baudrate.setCurrentText("115200") # 設定預設波特率
        self.comboBox_ByteSize.setCurrentText("8")      # 設定預設資料位
        
        self.BtnScanPort.clicked.connect(self.ScanComPort)
        self.BtnOpenPort.clicked.connect(self.OpenComPort)
        self.BtnClosePort.clicked.connect(self.CloseComPort)
        self.BtnSendData.clicked.connect(self.SendData)
        self.BtnClearRecv.clicked.connect(self.ClearRecvText)
        self.BtnClearSend.clicked.connect(self.ClearSendText)
        self.comboBox_ComPort.currentIndexChanged.connect(self.OnPortChanged)

        # 串列埠接收資料定時器
        self.recvTimer = QTimer(self)
        self.recvTimer.timeout.connect(self.RecvData)

    def ClearRecvText(self):
        self.textBrowserRecvArea.clear()

    def ClearSendText(self):
        self.lineEdit_SendData.clear()

    def OnPortChanged(self):
        if len(self.portDict) > 0:
            self.label_CurrentPortName.setText(self.portDict[self.comboBox_ComPort.currentText()])

    def ScanComPort(self):
        self.portDict = {}
        self.comboBox_ComPort.clear()
        portList = list(serial.tools.list_ports.comports())
        for port in portList:
            self.portDict["%s" % port[0]] = "%s" % port[1]
            self.comboBox_ComPort.addItem(port[0])
        if len(self.portDict) == 0:
            QMessageBox.critical(self, "警告", "未找到串列埠", QMessageBox.Cancel, QMessageBox.Cancel)
        pass

    def OpenComPort(self):
        # 設定埠號
        self.mSerial.port = self.comboBox_ComPort.currentText()

        # 設定波特率
        self.mSerial.baudrate = int(self.comboBox_Baudrate.currentText())

        # 資料位設定
        bytesize = self.comboBox_ByteSize.currentText()
        if "5" == bytesize:
            self.mSerial.bytesize = serial.FIVEBITS
        elif "6" == bytesize:
            self.mSerial.bytesize = serial.SIXBITS
        elif "7" == bytesize:
            self.mSerial.bytesize = serial.SEVENBITS
        elif "8" == bytesize:
            self.mSerial.bytesize = serial.EIGHTBITS

        # 停止位設定
        stopbitsItems = [serial.STOPBITS_ONE, serial.STOPBITS_ONE_POINT_FIVE, serial.STOPBITS_TWO]
        self.mSerial.stopbits = stopbitsItems[self.comboBox_Stopbits.currentIndex()]

        # 校驗位設定
        parityItmes = [serial.PARITY_NONE, 
                    serial.PARITY_ODD,
                    serial.PARITY_EVEN,
                    serial.PARITY_MARK,
                    serial.PARITY_SPACE,
                    serial.PARITY_NAMES]
        self.mSerial.parity = parityItmes[self.comboBox_Parity.currentIndex()]
        
        stopbitsItems = [serial.STOPBITS_ONE, serial.STOPBITS_ONE_POINT_FIVE, serial.STOPBITS_TWO]
        self.mSerial.stopbits = stopbitsItems[self.comboBox_Stopbits.currentIndex()]           # 停止為[]

        flowctrl = self.comboBox_FlowCtrl.currentText()
        if 'None' == flowctrl:
            self.mSerial.xonxoff = False            # 軟體流控       
            self.mSerial.rtscts = False             # 硬體流控
            self.mSerial.dsrdtr = False             # 硬體流控
        elif 'XON/XOFF' == flowctrl:
            self.mSerial.xonxoff = True            # 軟體流控       
            self.mSerial.rtscts = False             # 硬體流控
            self.mSerial.dsrdtr = False             # 硬體流控          
        elif 'RTS/CTS' == flowctrl:
            self.mSerial.xonxoff = False            # 軟體流控       
            self.mSerial.rtscts = True             # 硬體流控
            self.mSerial.dsrdtr = False             # 硬體流控

        # 超時時間
        self.mSerial.timeout = 100

        if self.mSerial.isOpen():
            QMessageBox.warning(self, "警告", "串列埠已開啟", QMessageBox.Cancel, QMessageBox.Cancel)
        else:
            try:
                self.BtnOpenPort.setEnabled(False)
                self.mSerial.open()
                self.mSerial.flushInput()
                self.mSerial.flushOutput()
                self.recvTimer.start(20)
            except:
                QMessageBox.critical(self, "警告", "串列埠開啟失敗", QMessageBox.Cancel, QMessageBox.Cancel)
                self.BtnOpenPort.setEnabled(True)
        
        # 列印埠資訊
        print(self.mSerial)

    def CloseComPort(self):
        self.recvTimer.stop()
        if self.mSerial.isOpen():
            self.BtnOpenPort.setEnabled(True)
            self.mSerial.flushInput()
            self.mSerial.flushOutput()
            self.mSerial.close()            
        pass
    
    def SendData(self):
        if self.mSerial.isOpen():
            sendtext = self.lineEdit_SendData.text()
            sendtext = sendtext + 'rn'
            self.mSerial.write(sendtext.encode("utf-8"))
            print("send data:", sendtext)
        else:
            QMessageBox.warning(self, "警告", "串列埠未開啟,請先開啟串列埠", QMessageBox.Cancel, QMessageBox.Cancel)

    def RecvData(self):
        dataheader = b'$$:' # 資料框頭, 原始資料框格式 '$$:10,11,12'

        try:
            num = self.mSerial.inWaiting()
        except:
            self.CloseComPort()

        if num > 0:
            try:
                self.data = self.mSerial.readline(1024)
                # 讀取一行資料 新增到資料接收顯示區
                if self.data.endswith("n".encode("utf-8")):
                    self.textBrowserRecvArea.append(self.data.decode("utf-8"))

                # 解析資料項,資料框以 b'$$:' 開頭,多個資料引數之間以 ‘,' 分割, 資料框以'rn'結束 
                if self.data.decode('UTF-8').startswith(dataheader.decode('UTF-8')):
                    rawdata = self.data[len(dataheader) : len(self.data)-2]
                    data = rawdata.split(b',')
                    print(int(data[0]), int(data[1]), int(data[2]))
            except:
                pass


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

QtDesigner UI介面設計:

QtDesigner UI檔案 comport.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>1135</width>
    <height>713</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <widget class="QGroupBox" name="groupBox_ComSettings">
    <property name="geometry">
     <rect>
      <x>10</x>
      <y>20</y>
      <width>221</width>
      <height>471</height>
     </rect>
    </property>
    <property name="title">
     <string>串列埠設定</string>
    </property>
    <widget class="QWidget" name="horizontalLayoutWidget">
     <property name="geometry">
      <rect>
       <x>10</x>
       <y>400</y>
       <width>201</width>
       <height>51</height>
      </rect>
     </property>
     <layout class="QHBoxLayout" name="horizontalLayout">
      <item>
       <widget class="QPushButton" name="BtnOpenPort">
        <property name="text">
         <string>開啟串列埠</string>
        </property>
       </widget>
      </item>
      <item>
       <widget class="QPushButton" name="BtnClosePort">
        <property name="text">
         <string>關閉串列埠</string>
        </property>
       </widget>
      </item>
     </layout>
    </widget>
    <widget class="QWidget" name="horizontalLayoutWidget_2">
     <property name="geometry">
      <rect>
       <x>10</x>
       <y>350</y>
       <width>201</width>
       <height>51</height>
      </rect>
     </property>
     <layout class="QHBoxLayout" name="horizontalLayout_8">
      <item>
       <widget class="QPushButton" name="BtnScanPort">
        <property name="text">
         <string>掃描埠</string>
        </property>
       </widget>
      </item>
     </layout>
    </widget>
    <widget class="QLabel" name="label_CurrentPortName">
     <property name="geometry">
      <rect>
       <x>10</x>
       <y>20</y>
       <width>201</width>
       <height>31</height>
      </rect>
     </property>
     <property name="text">
      <string/>
     </property>
    </widget>
    <widget class="QWidget" name="layoutWidget">
     <property name="geometry">
      <rect>
       <x>10</x>
       <y>60</y>
       <width>201</width>
       <height>281</height>
      </rect>
     </property>
     <layout class="QVBoxLayout" name="verticalLayout">
      <item>
       <layout class="QHBoxLayout" name="horizontalLayout_2">
        <item>
         <widget class="QLabel" name="label_ComPort">
          <property name="maximumSize">
           <size>
            <width>60</width>
            <height>16777215</height>
           </size>
          </property>
          <property name="text">
           <string>串  口</string>
          </property>
         </widget>
        </item>
        <item>
         <widget class="QComboBox" name="comboBox_ComPort">
          <property name="editable">
           <bool>false</bool>
          </property>
         </widget>
        </item>
       </layout>
      </item>
      <item>
       <layout class="QHBoxLayout" name="horizontalLayout_3">
        <item>
         <widget class="QLabel" name="label_Baudrate">
          <property name="maximumSize">
           <size>
            <width>60</width>
            <height>16777215</height>
           </size>
          </property>
          <property name="text">
           <string>波特率</string>
          </property>
         </widget>
        </item>
        <item>
         <widget class="QComboBox" name="comboBox_Baudrate">
          <property name="editable">
           <bool>true</bool>
          </property>
          <property name="currentText">
           <string>115200</string>
          </property>
          <property name="currentIndex">
           <number>8</number>
          </property>
          <item>
           <property name="text">
            <string>2400</string>
           </property>
          </item>
          <item>
           <property name="text">
            <string>4800</string>
           </property>
          </item>
          <item>
           <property name="text">
            <string>9600</string>
           </property>
          </item>
          <item>
           <property name="text">
            <string>14400</string>
           </property>
          </item>
          <item>
           <property name="text">
            <string>19200</string>
           </property>
          </item>
          <item>
           <property name="text">
            <string>38400</string>
           </property>
          </item>
          <item>
           <property name="text">
            <string>56000</string>
           </property>
          </item>
          <item>
           <property name="text">
            <string>57600</string>
           </property>
          </item>
          <item>
           <property name="text">
            <string>115200</string>
           </property>
          </item>
          <item>
           <property name="text">
            <string>128000</string>
           </property>
          </item>
          <item>
           <property name="text">
            <string>256000</string>
           </property>
          </item>
          <item>
           <property name="text">
            <string>230400</string>
           </property>
          </item>
          <item>
           <property name="text">
            <string>1000000</string>
           </property>
          </item>
          <item>
           <property name="text">
            <string>2000000</string>
           </property>
          </item>
          <item>
           <property name="text">
            <string>3000000</string>
           </property>
          </item>
         </widget>
        </item>
       </layout>
      </item>
      <item>
       <layout class="QHBoxLayout" name="horizontalLayout_4">
        <item>
         <widget class="QLabel" name="label_ByteSize">
          <property name="maximumSize">
           <size>
            <width>60</width>
            <height>16777215</height>
           </size>
          </property>
          <property name="text">
           <string>資料位</string>
          </property>
         </widget>
        </item>
        <item>
         <widget class="QComboBox" name="comboBox_ByteSize">
          <property name="editable">
           <bool>false</bool>
          </property>
          <property name="currentText">
           <string>8</string>
          </property>
          <property name="currentIndex">
           <number>3</number>
          </property>
          <item>
           <property name="text">
            <string>5</string>
           </property>
          </item>
          <item>
           <property name="text">
            <string>6</string>
           </property>
          </item>
          <item>
           <property name="text">
            <string>7</string>
           </property>
          </item>
          <item>
           <property name="text">
            <string>8</string>
           </property>
          </item>
         </widget>
        </item>
       </layout>
      </item>
      <item>
       <layout class="QHBoxLayout" name="horizontalLayout_6">
        <item>
         <widget class="QLabel" name="label_Stopbits">
          <property name="maximumSize">
           <size>
            <width>60</width>
            <height>16777215</height>
           </size>
          </property>
          <property name="text">
           <string>停止位</string>
          </property>
         </widget>
        </item>
        <item>
         <widget class="QComboBox" name="comboBox_Stopbits">
          <item>
           <property name="text">
            <string>1</string>
           </property>
          </item>
          <item>
           <property name="text">
            <string>1.5</string>
           </property>
          </item>
          <item>
           <property name="text">
            <string>2</string>
           </property>
          </item>
         </widget>
        </item>
       </layout>
      </item>
      <item>
       <layout class="QHBoxLayout" name="horizontalLayout_5">
        <item>
         <widget class="QLabel" name="label_Parity">
          <property name="maximumSize">
           <size>
            <width>60</width>
            <height>16777215</height>
           </size>
          </property>
          <property name="text">
           <string>校驗位</string>
          </property>
         </widget>
        </item>
        <item>
         <widget class="QComboBox" name="comboBox_Parity">
          <item>
           <property name="text">
            <string>None</string>
           </property>
          </item>
          <item>
           <property name="text">
            <string>Odd</string>
           </property>
          </item>
          <item>
           <property name="text">
            <string>Even</string>
           </property>
          </item>
          <item>
           <property name="text">
            <string>Mark</string>
           </property>
          </item>
          <item>
           <property name="text">
            <string>Space</string>
           </property>
          </item>
         </widget>
        </item>
       </layout>
      </item>
      <item>
       <layout class="QHBoxLayout" name="horizontalLayout_7">
        <item>
         <widget class="QLabel" name="label_CTS">
          <property name="maximumSize">
           <size>
            <width>60</width>
            <height>16777215</height>
           </size>
          </property>
          <property name="text">
           <string>流  控</string>
          </property>
         </widget>
        </item>
        <item>
         <widget class="QComboBox" name="comboBox_FlowCtrl">
          <item>
           <property name="text">
            <string>None</string>
           </property>
          </item>
          <item>
           <property name="text">
            <string>RTS/CTS</string>
           </property>
          </item>
          <item>
           <property name="text">
            <string>XON/XOFF</string>
           </property>
          </item>
         </widget>
        </item>
       </layout>
      </item>
     </layout>
    </widget>
   </widget>
   <widget class="QGroupBox" name="groupBox">
    <property name="geometry">
     <rect>
      <x>250</x>
      <y>20</y>
      <width>871</width>
      <height>471</height>
     </rect>
    </property>
    <property name="title">
     <string>接收區</string>
    </property>
    <widget class="QTextBrowser" name="textBrowserRecvArea">
     <property name="geometry">
      <rect>
       <x>10</x>
       <y>20</y>
       <width>851</width>
       <height>441</height>
      </rect>
     </property>
    </widget>
   </widget>
   <widget class="QGroupBox" name="groupBox_2">
    <property name="geometry">
     <rect>
      <x>250</x>
      <y>500</y>
      <width>871</width>
      <height>161</height>
     </rect>
    </property>
    <property name="title">
     <string>傳送區</string>
    </property>
    <widget class="QLineEdit" name="lineEdit_SendData">
     <property name="geometry">
      <rect>
       <x>10</x>
       <y>20</y>
       <width>851</width>
       <height>51</height>
      </rect>
     </property>
    </widget>
    <widget class="QPushButton" name="BtnSendData">
     <property name="geometry">
      <rect>
       <x>10</x>
       <y>80</y>
       <width>71</width>
       <height>71</height>
      </rect>
     </property>
     <property name="text">
      <string>傳送資料</string>
     </property>
    </widget>
   </widget>
   <widget class="QGroupBox" name="groupBox_3">
    <property name="geometry">
     <rect>
      <x>10</x>
      <y>500</y>
      <width>221</width>
      <height>161</height>
     </rect>
    </property>
    <property name="title">
     <string>收/發控制</string>
    </property>
    <widget class="QPushButton" name="BtnClearRecv">
     <property name="geometry">
      <rect>
       <x>10</x>
       <y>20</y>
       <width>201</width>
       <height>61</height>
      </rect>
     </property>
     <property name="text">
      <string>清空接收區</string>
     </property>
    </widget>
    <widget class="QPushButton" name="BtnClearSend">
     <property name="geometry">
      <rect>
       <x>10</x>
       <y>90</y>
       <width>201</width>
       <height>61</height>
      </rect>
     </property>
     <property name="text">
      <string>清空傳送區</string>
     </property>
    </widget>
   </widget>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>1135</width>
     <height>26</height>
    </rect>
   </property>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
 </widget>
 <resources/>
 <connections/>
</ui>

comport.ui檔案編譯生成的ui_comport.py

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'd:projectpython串列埠工具串列埠收發工具comport.ui'
#
# Created by: PyQt5 UI code generator 5.15.7
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.


from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(1135, 713)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.groupBox_ComSettings = QtWidgets.QGroupBox(self.centralwidget)
        self.groupBox_ComSettings.setGeometry(QtCore.QRect(10, 20, 221, 471))
        self.groupBox_ComSettings.setObjectName("groupBox_ComSettings")
        self.horizontalLayoutWidget = QtWidgets.QWidget(self.groupBox_ComSettings)
        self.horizontalLayoutWidget.setGeometry(QtCore.QRect(10, 400, 201, 51))
        self.horizontalLayoutWidget.setObjectName("horizontalLayoutWidget")
        self.horizontalLayout = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget)
        self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.BtnOpenPort = QtWidgets.QPushButton(self.horizontalLayoutWidget)
        self.BtnOpenPort.setObjectName("BtnOpenPort")
        self.horizontalLayout.addWidget(self.BtnOpenPort)
        self.BtnClosePort = QtWidgets.QPushButton(self.horizontalLayoutWidget)
        self.BtnClosePort.setObjectName("BtnClosePort")
        self.horizontalLayout.addWidget(self.BtnClosePort)
        self.horizontalLayoutWidget_2 = QtWidgets.QWidget(self.groupBox_ComSettings)
        self.horizontalLayoutWidget_2.setGeometry(QtCore.QRect(10, 350, 201, 51))
        self.horizontalLayoutWidget_2.setObjectName("horizontalLayoutWidget_2")
        self.horizontalLayout_8 = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget_2)
        self.horizontalLayout_8.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout_8.setObjectName("horizontalLayout_8")
        self.BtnScanPort = QtWidgets.QPushButton(self.horizontalLayoutWidget_2)
        self.BtnScanPort.setObjectName("BtnScanPort")
        self.horizontalLayout_8.addWidget(self.BtnScanPort)
        self.label_CurrentPortName = QtWidgets.QLabel(self.groupBox_ComSettings)
        self.label_CurrentPortName.setGeometry(QtCore.QRect(10, 20, 201, 31))
        self.label_CurrentPortName.setText("")
        self.label_CurrentPortName.setObjectName("label_CurrentPortName")
        self.layoutWidget = QtWidgets.QWidget(self.groupBox_ComSettings)
        self.layoutWidget.setGeometry(QtCore.QRect(10, 60, 201, 281))
        self.layoutWidget.setObjectName("layoutWidget")
        self.verticalLayout = QtWidgets.QVBoxLayout(self.layoutWidget)
        self.verticalLayout.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout.setObjectName("verticalLayout")
        self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
        self.label_ComPort = QtWidgets.QLabel(self.layoutWidget)
        self.label_ComPort.setMaximumSize(QtCore.QSize(60, 16777215))
        self.label_ComPort.setObjectName("label_ComPort")
        self.horizontalLayout_2.addWidget(self.label_ComPort)
        self.comboBox_ComPort = QtWidgets.QComboBox(self.layoutWidget)
        self.comboBox_ComPort.setEditable(False)
        self.comboBox_ComPort.setObjectName("comboBox_ComPort")
        self.horizontalLayout_2.addWidget(self.comboBox_ComPort)
        self.verticalLayout.addLayout(self.horizontalLayout_2)
        self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_3.setObjectName("horizontalLayout_3")
        self.label_Baudrate = QtWidgets.QLabel(self.layoutWidget)
        self.label_Baudrate.setMaximumSize(QtCore.QSize(60, 16777215))
        self.label_Baudrate.setObjectName("label_Baudrate")
        self.horizontalLayout_3.addWidget(self.label_Baudrate)
        self.comboBox_Baudrate = QtWidgets.QComboBox(self.layoutWidget)
        self.comboBox_Baudrate.setEditable(True)
        self.comboBox_Baudrate.setObjectName("comboBox_Baudrate")
        self.comboBox_Baudrate.addItem("")
        self.comboBox_Baudrate.addItem("")
        self.comboBox_Baudrate.addItem("")
        self.comboBox_Baudrate.addItem("")
        self.comboBox_Baudrate.addItem("")
        self.comboBox_Baudrate.addItem("")
        self.comboBox_Baudrate.addItem("")
        self.comboBox_Baudrate.addItem("")
        self.comboBox_Baudrate.addItem("")
        self.comboBox_Baudrate.addItem("")
        self.comboBox_Baudrate.addItem("")
        self.comboBox_Baudrate.addItem("")
        self.comboBox_Baudrate.addItem("")
        self.comboBox_Baudrate.addItem("")
        self.comboBox_Baudrate.addItem("")
        self.horizontalLayout_3.addWidget(self.comboBox_Baudrate)
        self.verticalLayout.addLayout(self.horizontalLayout_3)
        self.horizontalLayout_4 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_4.setObjectName("horizontalLayout_4")
        self.label_ByteSize = QtWidgets.QLabel(self.layoutWidget)
        self.label_ByteSize.setMaximumSize(QtCore.QSize(60, 16777215))
        self.label_ByteSize.setObjectName("label_ByteSize")
        self.horizontalLayout_4.addWidget(self.label_ByteSize)
        self.comboBox_ByteSize = QtWidgets.QComboBox(self.layoutWidget)
        self.comboBox_ByteSize.setEditable(False)
        self.comboBox_ByteSize.setObjectName("comboBox_ByteSize")
        self.comboBox_ByteSize.addItem("")
        self.comboBox_ByteSize.addItem("")
        self.comboBox_ByteSize.addItem("")
        self.comboBox_ByteSize.addItem("")
        self.horizontalLayout_4.addWidget(self.comboBox_ByteSize)
        self.verticalLayout.addLayout(self.horizontalLayout_4)
        self.horizontalLayout_6 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_6.setObjectName("horizontalLayout_6")
        self.label_Stopbits = QtWidgets.QLabel(self.layoutWidget)
        self.label_Stopbits.setMaximumSize(QtCore.QSize(60, 16777215))
        self.label_Stopbits.setObjectName("label_Stopbits")
        self.horizontalLayout_6.addWidget(self.label_Stopbits)
        self.comboBox_Stopbits = QtWidgets.QComboBox(self.layoutWidget)
        self.comboBox_Stopbits.setObjectName("comboBox_Stopbits")
        self.comboBox_Stopbits.addItem("")
        self.comboBox_Stopbits.addItem("")
        self.comboBox_Stopbits.addItem("")
        self.horizontalLayout_6.addWidget(self.comboBox_Stopbits)
        self.verticalLayout.addLayout(self.horizontalLayout_6)
        self.horizontalLayout_5 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_5.setObjectName("horizontalLayout_5")
        self.label_Parity = QtWidgets.QLabel(self.layoutWidget)
        self.label_Parity.setMaximumSize(QtCore.QSize(60, 16777215))
        self.label_Parity.setObjectName("label_Parity")
        self.horizontalLayout_5.addWidget(self.label_Parity)
        self.comboBox_Parity = QtWidgets.QComboBox(self.layoutWidget)
        self.comboBox_Parity.setObjectName("comboBox_Parity")
        self.comboBox_Parity.addItem("")
        self.comboBox_Parity.addItem("")
        self.comboBox_Parity.addItem("")
        self.comboBox_Parity.addItem("")
        self.comboBox_Parity.addItem("")
        self.horizontalLayout_5.addWidget(self.comboBox_Parity)
        self.verticalLayout.addLayout(self.horizontalLayout_5)
        self.horizontalLayout_7 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_7.setObjectName("horizontalLayout_7")
        self.label_CTS = QtWidgets.QLabel(self.layoutWidget)
        self.label_CTS.setMaximumSize(QtCore.QSize(60, 16777215))
        self.label_CTS.setObjectName("label_CTS")
        self.horizontalLayout_7.addWidget(self.label_CTS)
        self.comboBox_FlowCtrl = QtWidgets.QComboBox(self.layoutWidget)
        self.comboBox_FlowCtrl.setObjectName("comboBox_FlowCtrl")
        self.comboBox_FlowCtrl.addItem("")
        self.comboBox_FlowCtrl.addItem("")
        self.comboBox_FlowCtrl.addItem("")
        self.horizontalLayout_7.addWidget(self.comboBox_FlowCtrl)
        self.verticalLayout.addLayout(self.horizontalLayout_7)
        self.groupBox = QtWidgets.QGroupBox(self.centralwidget)
        self.groupBox.setGeometry(QtCore.QRect(250, 20, 871, 471))
        self.groupBox.setObjectName("groupBox")
        self.textBrowserRecvArea = QtWidgets.QTextBrowser(self.groupBox)
        self.textBrowserRecvArea.setGeometry(QtCore.QRect(10, 20, 851, 441))
        self.textBrowserRecvArea.setObjectName("textBrowserRecvArea")
        self.groupBox_2 = QtWidgets.QGroupBox(self.centralwidget)
        self.groupBox_2.setGeometry(QtCore.QRect(250, 500, 871, 161))
        self.groupBox_2.setObjectName("groupBox_2")
        self.lineEdit_SendData = QtWidgets.QLineEdit(self.groupBox_2)
        self.lineEdit_SendData.setGeometry(QtCore.QRect(10, 20, 851, 51))
        self.lineEdit_SendData.setObjectName("lineEdit_SendData")
        self.BtnSendData = QtWidgets.QPushButton(self.groupBox_2)
        self.BtnSendData.setGeometry(QtCore.QRect(10, 80, 71, 71))
        self.BtnSendData.setObjectName("BtnSendData")
        self.groupBox_3 = QtWidgets.QGroupBox(self.centralwidget)
        self.groupBox_3.setGeometry(QtCore.QRect(10, 500, 221, 161))
        self.groupBox_3.setObjectName("groupBox_3")
        self.BtnClearRecv = QtWidgets.QPushButton(self.groupBox_3)
        self.BtnClearRecv.setGeometry(QtCore.QRect(10, 20, 201, 61))
        self.BtnClearRecv.setObjectName("BtnClearRecv")
        self.BtnClearSend = QtWidgets.QPushButton(self.groupBox_3)
        self.BtnClearSend.setGeometry(QtCore.QRect(10, 90, 201, 61))
        self.BtnClearSend.setObjectName("BtnClearSend")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 1135, 26))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        self.comboBox_Baudrate.setCurrentIndex(8)
        self.comboBox_ByteSize.setCurrentIndex(3)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.groupBox_ComSettings.setTitle(_translate("MainWindow", "串列埠設定"))
        self.BtnOpenPort.setText(_translate("MainWindow", "開啟串列埠"))
        self.BtnClosePort.setText(_translate("MainWindow", "關閉串列埠"))
        self.BtnScanPort.setText(_translate("MainWindow", "掃描埠"))
        self.label_ComPort.setText(_translate("MainWindow", "串  口"))
        self.label_Baudrate.setText(_translate("MainWindow", "波特率"))
        self.comboBox_Baudrate.setCurrentText(_translate("MainWindow", "115200"))
        self.comboBox_Baudrate.setItemText(0, _translate("MainWindow", "2400"))
        self.comboBox_Baudrate.setItemText(1, _translate("MainWindow", "4800"))
        self.comboBox_Baudrate.setItemText(2, _translate("MainWindow", "9600"))
        self.comboBox_Baudrate.setItemText(3, _translate("MainWindow", "14400"))
        self.comboBox_Baudrate.setItemText(4, _translate("MainWindow", "19200"))
        self.comboBox_Baudrate.setItemText(5, _translate("MainWindow", "38400"))
        self.comboBox_Baudrate.setItemText(6, _translate("MainWindow", "56000"))
        self.comboBox_Baudrate.setItemText(7, _translate("MainWindow", "57600"))
        self.comboBox_Baudrate.setItemText(8, _translate("MainWindow", "115200"))
        self.comboBox_Baudrate.setItemText(9, _translate("MainWindow", "128000"))
        self.comboBox_Baudrate.setItemText(10, _translate("MainWindow", "256000"))
        self.comboBox_Baudrate.setItemText(11, _translate("MainWindow", "230400"))
        self.comboBox_Baudrate.setItemText(12, _translate("MainWindow", "1000000"))
        self.comboBox_Baudrate.setItemText(13, _translate("MainWindow", "2000000"))
        self.comboBox_Baudrate.setItemText(14, _translate("MainWindow", "3000000"))
        self.label_ByteSize.setText(_translate("MainWindow", "資料位"))
        self.comboBox_ByteSize.setCurrentText(_translate("MainWindow", "8"))
        self.comboBox_ByteSize.setItemText(0, _translate("MainWindow", "5"))
        self.comboBox_ByteSize.setItemText(1, _translate("MainWindow", "6"))
        self.comboBox_ByteSize.setItemText(2, _translate("MainWindow", "7"))
        self.comboBox_ByteSize.setItemText(3, _translate("MainWindow", "8"))
        self.label_Stopbits.setText(_translate("MainWindow", "停止位"))
        self.comboBox_Stopbits.setItemText(0, _translate("MainWindow", "1"))
        self.comboBox_Stopbits.setItemText(1, _translate("MainWindow", "1.5"))
        self.comboBox_Stopbits.setItemText(2, _translate("MainWindow", "2"))
        self.label_Parity.setText(_translate("MainWindow", "校驗位"))
        self.comboBox_Parity.setItemText(0, _translate("MainWindow", "None"))
        self.comboBox_Parity.setItemText(1, _translate("MainWindow", "Odd"))
        self.comboBox_Parity.setItemText(2, _translate("MainWindow", "Even"))
        self.comboBox_Parity.setItemText(3, _translate("MainWindow", "Mark"))
        self.comboBox_Parity.setItemText(4, _translate("MainWindow", "Space"))
        self.label_CTS.setText(_translate("MainWindow", "流  控"))
        self.comboBox_FlowCtrl.setItemText(0, _translate("MainWindow", "None"))
        self.comboBox_FlowCtrl.setItemText(1, _translate("MainWindow", "RTS/CTS"))
        self.comboBox_FlowCtrl.setItemText(2, _translate("MainWindow", "XON/XOFF"))
        self.groupBox.setTitle(_translate("MainWindow", "接收區"))
        self.groupBox_2.setTitle(_translate("MainWindow", "傳送區"))
        self.BtnSendData.setText(_translate("MainWindow", "傳送資料"))
        self.groupBox_3.setTitle(_translate("MainWindow", "收/發控制"))
        self.BtnClearRecv.setText(_translate("MainWindow", "清空接收區"))
        self.BtnClearSend.setText(_translate("MainWindow", "清空傳送區"))

COM9接到了樹莓派Pico(Raspberry Pi Pico)的串列埠上,串列埠小工具傳送的資料會通過樹莓派Pico接收後再轉發給串列埠小工具

Raspberry Pi Pico程式碼

from machine import Pin,UART
import utime
uart0 = UART(0, baudrate=115200, bits=8, parity=None, stop=1, tx=Pin(16), rx=Pin(17), )
#uart0.deinit()
txData = b'hello worldrn'
rxData = bytes()

while True:
    while uart0.any() > 0:
        rxData = uart0.readline()
        uart0.write(rxData)
        print(rxData.decode('utf-8'))        
    utime.sleep(0.2)

以上就是PyQt5+serial模組實現一個串列埠小工具的詳細內容,更多關於PyQt5 serial串列埠工具的資料請關注it145.com其它相關文章!


IT145.com E-mail:sddin#qq.com