【python上位机开发】5、串口相关的功能

一、环境安装

    串口相关的功能是这次上位机的核心也是基础,所以第五章先总结一下这部分吧。

    安装串口相关的库函数,pip install pyserial  或者直接软件包里面安装即可,版本任意,不过最好新一些。(我这边使用的是3.5版本)

pip install pyserial

二、逻辑分析

     为了保证我们串口工具的正常使用,我们需要做到:

        1、如果有新的串口接入pc,我们要做及时的更新

        2、要获取电脑已连接的串口名称

        3、串口打开/关闭

        4、串口接收数据

        5、串口发送数据

  以上这些就是我们要去实现的串口相关的功能,接下来针对每一项功能去做实现,写对应的功能代码。

三、更新串口号和获取已经连接的串口名称

       为了使得整体逻辑更清晰,会按照逻辑顺序的序号编写。

       1、创建一个串口类(class serial_class)

  

class serial_class

       2、定义构造函数,实例化一个py.serial类,定义一个列表,用于存放串口号。

class serial_class:
    def __init__(self):
        self.Serial_Next_Port_Number = []
        self.serial = serial.Serial()

       3、扫描当前的串口号

    def serial_port_scan():
        serial_port_list = list(serial.tools.list_ports.comports())
        now_port = []
        for number in  serial_port_list:
            now_port.append(number.device)
        return now_port

      4、判断串口是否变化,执行相关的函数,如果串口一致,就执行pass语句。若不一致,且串口是打开状态,说明串口被拔掉了,则弹窗提示,并且对应的按钮使能。

   def serial_is_change(self):
       now_port = self.con.serial_class.serial_port_scan()  # 获取当前的串口号
       if now_port == self.con.serial_class.Serial_Next_Port_Number: # 如果两个列表一致,说明串口没有发生改变,不做处理,执行pass语句
           pass
       else:
         try:
          if self.con.serial_class.Serial_Next_Port_Number != now_port and self.con.serial_class.serial.is_open:
            QMessageBox.information(self,"错误","串口已拔出",QMessageBox.Yes,QMessageBox.Yes) # 如果是打开的情况下拔出串口,则弹出警告弹窗
            self.con.serial_class.serial.close() # 承上逻辑,关闭串口
            self.con.ui.ui.close_uart_pushButton.setEnabled(True) # 且“关闭按钮”使能
            self.con.ui.ui.open_uart_pushButton.setEnabled(True)# “打开按钮”使能
         except Exception as error:
           print(error)
         finally:
           self.con.ui.ui.uart_number_comboBox.clear() # 清空串口号显示
           self.con.ui.ui.uart_number_comboBox.addItems(now_port) # 重新载入新的串口号
           self.con.serial_class.Serial_Next_Port_Number = now_port # 将获取到的串口号载入为最新
           self.con.ui.ui.baud_comboBox.setEnabled(True) # 波特率显示框使能
           self.con.ui.ui.stop_bit_comboBox.setEnabled(True) # 停止位显示使能
           self.con.ui.ui.check_bit_comboBox.setEnabled(True)# 校验位显示使能
           self.con.ui.ui.uart_number_comboBox.setEnabled(True)# 串口号显示使能
           self.con.ui.ui.data_bit_comboBox.setEnabled(True) # 数据位显示使能

    5、保持持续执行。如果是按照从上到下的代码执行顺序,对应的函数只执行一次,我们需要在程序启动的时候,一直的去扫描,持续的监控。这时候就需要用到一个定时器,定时的去执行我们的检测函数,保证每一次的串口变化都可以及时的更新。(ps:定时器在主控制类定义和实例化哦)

self.timer.timeout.connect(self.serial_con.serial_is_change)

 四、串口打开/关闭

     串口的打开需要我们定义,串口号、波特率、校验位、数据位、停止位。我们可以从ui页面的combox的数据中获取

那我们要怎么去获取这些方框内的值呢?利用以下方法:

ui.ui.uart_number_comboBox.currentText()

QT的comboBox有一个currenText()方法,就是获取里面的值。

所以这个功能的实现为:

  1、获取对应comboBox里面的值

  2、将1中获取的值,给serial打开的所需数据赋值

  3、实例化对应的类,最后串口即可打开成功

  4、串口关闭的话,使用close()方法

(ps:下面的函数是打开串口的槽函数,会涉及到其他功能点,看不懂的可以先不管,看上半部分的逻辑即可)

    @Slot()
    def pushbutton_serial_open_slot(self):
        stop_bit = (1, 1.5, 2)
        check_bit = ('N', 'O', 'E')  # 'N' 无校验 'O' 奇校验 'E'偶校验
        choice_serial_port_number = self.con.ui.ui.uart_number_comboBox.currentText()
        choice_serial_baud_rate = int(self.con.ui.ui.baud_comboBox.currentText())
        choice_serial_data_bit = int(self.con.ui.ui.data_bit_comboBox.currentText())
        choice_serial_check_bit = self.con.ui.ui.check_bit_comboBox.currentIndex()
        choice_serial_stop_bit = self.con.ui.ui.stop_bit_comboBox.currentIndex()
        try:
            self.con.serial_class.serial = serial.Serial(port=choice_serial_port_number,
                                                     baudrate=choice_serial_baud_rate,
                                                     bytesize=choice_serial_data_bit,
                                                     parity=check_bit[choice_serial_check_bit],
                                                     stopbits=stop_bit[choice_serial_stop_bit])
            if self.con.serial_class.serial.is_open:
                self.con.ui.ui.uart_number_comboBox.setEnabled(False)
                self.con.ui.ui.baud_comboBox.setEnabled(False)
                self.con.ui.ui.data_bit_comboBox.setEnabled(False)
                self.con.ui.ui.check_bit_comboBox.setEnabled(False)
                self.con.ui.ui.stop_bit_comboBox.setEnabled(False)
                self.con.ui.ui.open_uart_pushButton.setEnabled(False)
                self.con.ui.ui.close_uart_pushButton.setEnabled(True)
                self.con.ui.ui.pushButton.setEnabled(True)
                self.con.ui.ui.checkBox.setEnabled(False)
                QMessageBox.information(self, "小赖提示", self.con.serial_class.serial.name + "打开成功" , QMessageBox.Ok, QMessageBox.Ok)
        except Exception as error:
            if "拒绝访问" in str(error):
                QMessageBox.information(self, "小赖提示", "串口拒绝访问", QMessageBox.Yes, QMessageBox.Yes)
            else:
                QMessageBox.information(self, "小赖提示", "打开失败", QMessageBox.Yes, QMessageBox.Yes)
            self.con.ui.ui.open_uart_pushButton.setEnabled(True)
            print(error)
        if self.con.serial_class.serial.is_open and (not self.Serial_Open_state):  # 串口打开成功
            self.con.serial_con.Serial_Data_RX_Thread.start() 
            self.Serial_Open_state = True 

五、串口接收数据

  调用串口的read相关的方法,这里使用readline,读取整行数据(详情在后续的接收数据槽函数当中详细解答)

六、串口发送数据

   调用串口的write方法,写入数据(详细在后续的发送数据槽函数当中详细解答)

七、结束语

  串口相关的功能就到这边了,后续还会继续更新,其中的一些部分也有借鉴网上一些大佬的思路,若有一些错误的地方,烦请指正。

  未完待续。。。。。

作者:重生之我在厦门做测试

物联沃分享整理
物联沃-IOTWORD物联网 » 【python上位机开发】5、串口相关的功能

发表回复