Python 利用PyQt5写一个简易的串口助手
? ? ? ?學習單片機,STM32好長時間了,也做了一些項目,一直想利用上位機實現電腦與單片機之間的傳輸數據,利用串口助手是最直接的通信方式,但串口助手不適合做上位機,如果會寫串口助手的軟件,基本能寫自己寫一個上位機,歷時一個月,終于寫出一個簡易的串口助手,筆者自己寫的軟件,有些Bug,分享出來,僅供參考,歡迎大家一起學習與討論。
? ? ? ?目標:利用Python語言寫一個簡易的串口助手
? ? ? ?環境:Win10,? python語言, PyQt5, Pycharm
? ? ? ?思路:先做出主體,慢慢優化與添加其他的功能,在串口助手設計中主體是獲取串口ID號,設置波特率,發送數據,接收數據,添加界面布局,信號觸發等操作。
? ? ? ?一、設置串口ID號
? ? ? ? 建議制作第一版串口助手,可以先選定固定串口和波特率進行設計,在筆者設計時,固定一個串口為COM4,波特率為9600設計,設置參考代碼如下:
self.t = serial.Serial('com4', 9600)port = self.t.portstrprint(port)這樣就簡單將串口設置為打開串口時為COM4,波特率為9600,COM4是筆者所用的電腦端口。后續將端口和波特率變為可選擇
? ? ? ? 二、發送數據和接收數據
? ? ? ?發送數據類型簡單可分為字符串發送和十六進制發送,發送數據方式是輸入發送,在本文中先實現字符串發送,后續再實現十六進制發送。同理,接收數據也可先實現字符串接收,后續再實現十六進制發送。參考代碼如下:
import serial import time import threading class SerialPort:message = ''def __init__(self, port, buand):super(SerialPort, self).__init__()self.port = serial.Serial(port, buand)self.port.close()if not self.port.isOpen():self.port.open()def port_open(self):if not self.port.isOpen():self.port.open() #打開串口def port_close(self):self.port.close()def send_data(self):data = input("請輸入要發送的數據(非中文)并同時接收數據: ")n = self.port.write(data.encode()) #發送數據print(n)def read_data(self): #接收數據while True: self.message = self.port.readline() #接收數據print(self.message)serialPort = "COM4" # 串口 baudRate = 9600 # 波特率if __name__ == '__main__':mSerial = SerialPort(serialPort, baudRate)t1 = threading.Thread(target=mSerial.read_data)t1.start()while True:time.sleep(1)mSerial.send_data()?三、加入界面布局
? ? ? ?利用PyQt5庫搭建界面,在界面布局中使用網格布局管理QGridLayout,代碼如下:
def initUI(self):grid = QGridLayout()self.portname = QLabel("端口號") #添加控件self.datanumber = QLabel("發送數據位數:")self.datasender = QLabel("發送數據:")self.datareview = QLabel("接收數據:")self.button = QPushButton("發送")self.open_button = QPushButton("打開")self.portnameEdit = QLineEdit()self.datanumberEdit = QLineEdit()self.datasenderEdit = QLineEdit()self.datareviewEdit = QLineEdit()grid.addWidget(self.portname, 1, 0) #添加控件的位置grid.addWidget(self.portnameEdit, 1, 1)grid.addWidget(self.datanumber, 2, 0)grid.addWidget(self.datanumberEdit, 2, 1)grid.addWidget(self.datasender, 3, 0,)grid.addWidget(self.datasenderEdit, 3, 1, 1, 6)grid.addWidget(self.datareview, 4, 0)grid.addWidget(self.datareviewEdit, 4, 1, 1, 6)grid.addWidget(self.button, 5, 3)grid.addWidget(self.open_button, 5, 1)self.setLayout(grid) #布局self.button.clicked.connect(self.Cosender) #關聯"發送"按鈕與信號槽self.open_button.clicked.connect(self.Check_serial) #關聯“打開”按鈕與信號槽self.setGeometry(300,300,200,200) #設置窗體大小self.setWindowTitle("串口助手")四、加入觸發信號
? ? ? ?在上面的布局管理中,加入了“打開”和“發送”兩個按鈕。需要給兩個按鈕加入信號槽。編寫好信號槽代碼后再關聯按鈕與信號槽。信號槽代碼如下:
def messageUI(self):'''提示串口打開狀況信息'''QMessageBox.critical(self, "錯誤", "串口打開失敗,請選擇正確的串口") #彈出提示信息def Check_serial(self):'''檢測串口是否被打開'''try:self.t = serial.Serial('com4', 9600) #打開串口COM4port = self.t.portstr #返回但端口號self.portnameEdit.setText(port) #顯示在界面上self.flag_open=1except serial.serialutil.SerialException: #打開失敗,輸出提示信息self.messageUI() #提示信息def Cosender(self):'''“發送”按鈕,信號槽'''if self.flag_open==1: #串口被打開self.str_input = self.datasenderEdit.text() #返回上面的發送文字n = self.t.write((self.str_input+'\n').encode())self.datanumberEdit.setText(str(n-1)) #寫入數據位數框self.datasenderEdit.setText(str(self.str_input)) #寫入發送框time.sleep(1) # sleep() 與 inWaiting() 最好配對使用num = self.t.inWaiting() #獲取接收到的數據長度if num:self.receivemessage = self.t.read(num) #讀取接收數據print(self.receivemessage)self.datareviewEdit.setText(str(self.receivemessage)[2:-1]) #寫入接收框else: #串口打開失敗self.messageUI()? ? ?關聯按鈕與信號槽的代碼如下:
self.button.clicked.connect(self.Cosender) #關聯"發送"按鈕與信號槽self.open_button.clicked.connect(self.Check_serial) #關聯“打開”按鈕與信號槽? ?這樣制作一個基本的簡易串口助手完成。如有不足之處請多多指教。效果如圖1所示。后面在開發加入了串口,波特率可供選擇性,發送和接收數據有字符串和十六進制等設計,效果如圖2所示,有興趣的讀者可以自行下載源代。源代碼鏈接:
https://download.csdn.net/download/scx2006114/11579725
? ? ? ? ? ? ? ? ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?圖1? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 圖2? ? ? ? ? ? ????
參考資料鏈接:
? ?1.發送和接收數據:https://blog.csdn.net/xiaoeleis/article/details/81484872
? ?2.頁面布局:https://blog.csdn.net/zhulove86/article/details/52563298
完整代碼如下:
import sys from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QLineEdit, \QGridLayout, QLabel, QMessageBox, QComboBox, \QCheckBox import serial import time import serial.tools.list_portsclass CO2UI(QWidget):def __init__(self):super(CO2UI, self).__init__()self.initUI()global flag_open #標志位,判斷串口是否打開self.flag_open = 0def initUI(self):grid = QGridLayout()self.portname = QLabel("端口號")self.datanumber = QLabel("發送數據位數:")self.datasender = QLabel("發送數據:")self.datareview = QLabel("接收數據:")self.button = QPushButton("發送")self.open_button = QPushButton("打開")self.portnameEdit = QLineEdit()self.datanumberEdit = QLineEdit()self.datasenderEdit = QLineEdit()self.datareviewEdit = QLineEdit()grid.addWidget(self.portname, 1, 0)grid.addWidget(self.portnameEdit, 1, 1)grid.addWidget(self.datanumber, 2, 0)grid.addWidget(self.datanumberEdit, 2, 1)grid.addWidget(self.datasender, 3, 0,)grid.addWidget(self.datasenderEdit, 3, 1, 1, 6)grid.addWidget(self.datareview, 4, 0)grid.addWidget(self.datareviewEdit, 4, 1, 1, 6)grid.addWidget(self.button, 5, 3)grid.addWidget(self.open_button, 5, 1)self.setLayout(grid)self.button.clicked.connect(self.Cosender)self.open_button.clicked.connect(self.Check_serial)self.setGeometry(300,300,200,200)self.setWindowTitle("C02上位機")def messageUI(self):'''提示信息'''QMessageBox.critical(self, " ", "串口打開失敗,請選擇正確的串口")def Check_serial(self):'''檢測串口是否被打開'''try:self.t = serial.Serial('com4', 9600) #打開串口COM4port = self.t.portstr #返回但端口號self.portnameEdit.setText(port) #顯示在界面上self.flag_open=1except serial.serialutil.SerialException: #打開失敗,輸出提示信息self.messageUI() #提示信息def Cosender(self):if self.flag_open==1:if self.flag_open == 1: # 串口被打開self.str_input = self.datasenderEdit.text() # 返回上面的發送文字n = self.t.write((self.str_input + '\n').encode())self.datanumberEdit.setText(str(n - 1)) # 寫入數據位數框self.datasenderEdit.setText(str(self.str_input)) # 寫入發送框time.sleep(1) # sleep() 與 inWaiting() 最好配對使用num = self.t.inWaiting() # 獲取接收到的數據長度if num:self.receivemessage = self.t.read(num) # 讀取接收數據print(self.receivemessage)self.datareviewEdit.setText(str(self.receivemessage)[2:-3]) # 寫入接收框else:self.messageUI()if __name__ == "__main__":app = QApplication(sys.argv)test = CO2UI()test.show()sys.exit(app.exec_())?
總結
以上是生活随笔為你收集整理的Python 利用PyQt5写一个简易的串口助手的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 免安装mysql8.0
- 下一篇: Python将PDF转成图片—PyMuP