Python 利用PyQt5写一个简易的串口助手

本文介绍了一位开发者如何使用Python和PyQt5从零开始创建一个简易的串口助手的过程,包括设置串口参数、发送与接收数据、界面布局及信号触发等功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

       学习单片机,STM32好长时间了,也做了一些项目,一直想利用上位机实现电脑与单片机之间的传输数据,利用串口助手是最直接的通信方式,但串口助手不适合做上位机,如果会写串口助手的软件,基本能写自己写一个上位机,历时一个月,终于写出一个简易的串口助手,笔者自己写的软件,有些Bug,分享出来,仅供参考,欢迎大家一起学习与讨论。

       目标:利用Python语言写一个简易的串口助手

       环境:Win10,  python语言, PyQt5, Pycharm

       思路:先做出主体,慢慢优化与添加其他的功能,在串口助手设计中主体是获取串口ID号,设置波特率,发送数据,接收数据,添加界面布局,信号触发等操作。

       一、设置串口ID号

        建议制作第一版串口助手,可以先选定固定串口和波特率进行设计,在笔者设计时,固定一个串口为COM4,波特率为9600设计,设置参考代码如下:

 self.t = serial.Serial('com4', 9600)
 port = self.t.portstr
 print(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)   #打开串口COM4
            port = self.t.portstr     #返回但端口号
            self.portnameEdit.setText(port)   #显示在界面上
            self.flag_open=1
        except 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.youkuaiyun.com/download/scx2006114/11579725

                                              

                                         图1                                                                                                  图2                

参考资料链接:

   1.发送和接收数据:https://blog.youkuaiyun.com/xiaoeleis/article/details/81484872

   2.页面布局:https://blog.youkuaiyun.com/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_ports

class CO2UI(QWidget):

    def __init__(self):
        super(CO2UI, self).__init__()
        self.initUI()
        global flag_open     #标志位,判断串口是否打开
        self.flag_open = 0
    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("C02上位机")
    def messageUI(self):
        '''提示信息'''
        QMessageBox.critical(self, " ", "串口打开失败,请选择正确的串口")
    def Check_serial(self):
        '''检测串口是否被打开'''
        try:
            self.t = serial.Serial('com4', 9600)   #打开串口COM4
            port = self.t.portstr     #返回但端口号
            self.portnameEdit.setText(port)   #显示在界面上
            self.flag_open=1
        except 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_())

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

远去的星光

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值