Python uses PyQt5 to write a simple serial assistant

Keywords: Python Pycharm

STM32 has been studying SCM for a long time, and has also done some projects. It has always wanted to use PC to transmit data between PC and SCM. Using serial assistant is the most direct way of communication, but serial assistant is not suitable for PC. If you can write the software of serial assistant, you can write one by yourself. Upper computer, lasted a month, finally wrote a simple serial assistant, the author's own software, some Bug, to share, for reference only, welcome to learn and discuss together.

Objectives: Write a simple serial assistant in Python

Environment: Win10, python, PyQt5, Pycharm

Thought: Make the main body first, optimize and add other functions slowly. In the design of serial assistant, the main body is to obtain serial ID number, set baud rate, send and receive data, add interface layout, signal trigger and other operations.

Setting serial ID number

It is suggested that the first edition of serial assistant be made. Fixed serial port and baud rate can be selected to design first. When the author designs, a serial port is fixed as COM4 and baud rate is 9600. The reference codes are as follows:

 self.t = serial.Serial('com4', 9600)
 port = self.t.portstr
 print(port)

In this way, the serial port is simply set to COM4 when the serial port is opened, the baud rate is 9600, and COM4 is the computer port used by the author. Later ports and baud rates become optional

Sending and receiving data

The sending data type can be divided into string sending and hexadecimal sending. The way of sending data is input sending. In this paper, string sending is realized first, and then hexadecimal sending is realized later. Similarly, the received data can be received by strings first, and then transmitted by hexadecimal system. The reference code is as follows:

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()    #Open Serial Port
    def port_close(self):
        self.port.close()
    def send_data(self):
        data = input("Please enter the data to be sent (non-Chinese) and receive the data at the same time.: ")
        n = self.port.write(data.encode())    #send data
        print(n)
    def read_data(self):          #receive data
        while True:    
            self.message = self.port.readline()  #receive data
            print(self.message)

serialPort = "COM4"  # serial port
baudRate = 9600  # baud rate

if __name__ == '__main__':
    mSerial = SerialPort(serialPort, baudRate)
    t1 = threading.Thread(target=mSerial.read_data)
    t1.start()
    while True:
        time.sleep(1)
        mSerial.send_data()

3. Joining the Interface Layout

Using PyQt5 library to build the interface, using grid layout management QGridLayout in the interface layout, the code is as follows:

 def initUI(self):
        grid = QGridLayout()

        self.portname = QLabel("Port number")   #add controls
        self.datanumber = QLabel("Send data bits:")
        self.datasender = QLabel("Send data:")
        self.datareview = QLabel("Receiving data:")
        self.button = QPushButton("Send out")
        self.open_button = QPushButton("open")
        self.portnameEdit = QLineEdit()
        self.datanumberEdit = QLineEdit()
        self.datasenderEdit = QLineEdit()
        self.datareviewEdit = QLineEdit()

        grid.addWidget(self.portname, 1, 0)  #Location of add controls
        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)    #layout

        self.button.clicked.connect(self.Cosender)    #Connect the "Send" button with the signal slot
        self.open_button.clicked.connect(self.Check_serial)    #Associate the Open button with the signal slot
        self.setGeometry(300,300,200,200)  #Setting Form Size
        self.setWindowTitle("Serial Port Assistant")    

IV. Adding Trigger Signal

In the layout management above, two buttons, Open and Send, are added. Two buttons need to be added to the signal slot. After compiling the signal slot code, the button and the signal slot are correlated. The signal slot code is as follows:

    def messageUI(self):
        '''Prompt Serial Port Open Status Information'''
        QMessageBox.critical(self, "error", "Serial Port Failed to Open, Please Select the Right Serial Port")  #Pop-up message
    def Check_serial(self):
        '''Detecting whether the serial port is opened'''
        try:
            self.t = serial.Serial('com4', 9600)   #Open COM4 Serial Port
            port = self.t.portstr     #Return but port number
            self.portnameEdit.setText(port)   #Display on the interface
            self.flag_open=1
        except serial.serialutil.SerialException:   #Failed to open, output prompt information
            self.messageUI()      #Tips
    def Cosender(self):
        '''"Send button, signal slot'''
        if self.flag_open==1:    #Serial port is opened
            self.str_input = self.datasenderEdit.text()   #Return the sending text above
            n = self.t.write((self.str_input+'\n').encode())
            self.datanumberEdit.setText(str(n-1))     #Write data digit box
            self.datasenderEdit.setText(str(self.str_input))    #Write to send box
            time.sleep(1)  # sleep() and inWaiting() are best used in pairs
            num = self.t.inWaiting()  #Get the length of the received data
            if num:
                self.receivemessage = self.t.read(num) #Read and receive data
                print(self.receivemessage)
                self.datareviewEdit.setText(str(self.receivemessage)[2:-1])  #Write to receive box

        else:    #Serial Port Failed to Open
            self.messageUI()

The code of the associated button and the signal slot is as follows:

 self.button.clicked.connect(self.Cosender)    #Connect the "Send" button with the signal slot
 self.open_button.clicked.connect(self.Check_serial)    #Associate the Open button with the signal slot

This is accomplished by making a basic and easy serial assistant. If there are any shortcomings, please give more advice. Later, a serial port is added to the development. The baud rate is optional. There are strings and hexadecimal designs for sending and receiving data. Interested readers can download the source code by themselves. Source code link:

Reference link:

1. Sending and receiving data: https://blog.csdn.net/xiaoeleis/article/details/81484872

2. Page layout: https://blog.csdn.net/zhulove86/article/details/52563298

The complete code is as follows:

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     #Flag bit to determine whether the serial port is open
        self.flag_open = 0
    def initUI(self):
        grid = QGridLayout()

        self.portname = QLabel("Port number")
        self.datanumber = QLabel("Send data bits:")
        self.datasender = QLabel("Send data:")
        self.datareview = QLabel("Receiving data:")
        self.button = QPushButton("Send out")
        self.open_button = QPushButton("open")
        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 Upper computer")
    def messageUI(self):
        '''Tips'''
        QMessageBox.critical(self, " ", "Serial Port Failed to Open, Please Select the Right Serial Port")
    def Check_serial(self):
        '''Detecting whether the serial port is opened'''
        try:
            self.t = serial.Serial('com4', 9600)   #Open COM4 Serial Port
            port = self.t.portstr     #Return but port number
            self.portnameEdit.setText(port)   #Display on the interface
            self.flag_open=1
        except serial.serialutil.SerialException:   #Failed to open, output prompt information
            self.messageUI()      #Tips

    def Cosender(self):
        if self.flag_open==1:
            if self.flag_open == 1:  # Serial port is opened
                self.str_input = self.datasenderEdit.text()  # Return the sending text above
                n = self.t.write((self.str_input + '\n').encode())
                self.datanumberEdit.setText(str(n - 1))  # Write data digit box
                self.datasenderEdit.setText(str(self.str_input))  # Write to send box
                time.sleep(1)  # sleep() and inWaiting() are best used in pairs
                num = self.t.inWaiting()  # Get the length of the received data
                if num:
                    self.receivemessage = self.t.read(num)  # Read and receive data
                    print(self.receivemessage)
                    self.datareviewEdit.setText(str(self.receivemessage)[2:-3])  # Write to receive box
        else:
            self.messageUI()


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

 

Posted by non_zero on Mon, 19 Aug 2019 00:45:16 -0700