高质量编码--Python开发串口读取程序

2023-03-06 16:33:22 浏览数 (1)

下图是一款多功能声级计,是采用数字信号处理技术的新一代噪声测量仪器,它支持将实时测量的数据通过串口输出。

通过Serial Port Utility串口调试助手可以看到通过串口输出的声音测量数据的为固定格式的文本。

代码语言:javascript复制
Name:DATA_0001	
2023-02-27 10:31:00
Stat.-One    Tm=00h00m59s
R: 20dB~132dB Ts=00h01m00s
Model:AWA6228 	 Serial:10340396
Calibrate@2022-09-29 13:41:05 Lx=-28.6dB
Statistics: A F
Leq,T= 19.5dB SEL  = 37.2dB
Lmax = 36.9dB Lmin = 15.7dB
L 5  = 22.8dB L10  = 20.2dB
L50  = 17.6dB L90  = 16.2dB
L95  = 16.0dB SD   =  2.4dB

使用Python语言通过串口协议连接该仪器,解析字节流数据,实时显示仪器测量结果。使用tkinter来开发UI界面,pyserial来读写串口,正则表达式提取数据。代码如下:

代码语言:python代码运行次数:0复制
# -*- coding:utf-8 -*-
import tkinter as tk
import tkinter.ttk as ttk
from tkinter import font
import serial
import serial.tools.list_ports as list_ports
import timer
import threading
import re
title="""欢迎使用"""
dateRe=re.compile("n(?P<date>[d-] )s(?P<time>[d:]*)")
dataRe=re.compile("([a-zA-Z] [w,]*s*)[=:]s*?([dw.-~] )")
fields=['Lx', 'Leq,T', 'SEL', 'Lmax', 'Lmin','L5', 'L10', 'L50', 'L90','L95','SD']
 
class Frame(tk.Frame):
    def __init__(self, master):
     
        tk.Frame.__init__(self, master)
        self.master = master
        self.grid()
       
        
        cbx_port = ttk.Combobox(self)
        self.cbx_port=cbx_port
        
        cbx_port.grid(row=0, column=0)

        btn_port=tk.Button(self, text="刷新串口列表",  command=self.get_ports)
        btn_port.grid(row=0,column=1)


        btn_read=tk.Button(self, text="读取数据",  command=self.read_data)
        btn_read.grid(row=0,column=2)
        self.btn_read=btn_read
        
        
        btn_pause=tk.Button(self, text="停止读取",state='disabled',  command=self.pause_data)
        btn_pause.grid(row=0,column=3)
        self.btn_pause=btn_pause
        
        label_info = tk.Label(self,text=title,font='courier 20 bold',justify='center')
        label_info.grid(row=1, column=0,columnspan=4)
        self.label_info=label_info
        self.get_ports()
    def get_ports(self):
        while self.cbx_port.get():
            self.cbx_port.delete(0)
        
        for i,port in enumerate(list_ports.comports()):
            self.cbx_port.insert(i,port.name)

    def pause_data(self):
        
        timer.kill_timer(self.timer)
        global ser
        ser.close()
        self.btn_pause.config(state='disabled')
        self.btn_pause.update()
        self.btn_read.config(state='normal')
        self.btn_read.update()
 
    def read_data(self):
        port_name=self.cbx_port.get()
        if not port_name:
            return 
        global ser
        ser=serial.Serial(port_name,baudrate=115200,timeout=1)
     
        self.btn_pause.config(state='normal')
        self.btn_pause.update()

        self.btn_read.config(state='disabled')
        self.btn_read.update()
                                                 
        self.timer=timer.set_timer(2000,self.receive_data)

    def receive_data(self,j,k):    
        while True:
            data=ser.read(400)
            if(not data):
                break    
            text=data.decode(errors='ignore')
            text=text.replace('L 5','L5')
            print(text)
            date=dateRe.search(text)
            print('date',date)
            data=dataRe.findall(text)
            data=[[i.strip() for i in j] for j in data if j[0].strip() in fields]
            print(data)
            if(date and data):            
                text1="时间:{date} {time}".format(**date.groupdict())
                text2=''.join([("{0}:{1}" ('n' if i%2==0 else 't')).format(*item) for (i,item) in enumerate(data) ])
                self.label_info.config(text=text1 'n' text2)
                self.label_info.update()
        
if __name__ == "__main__":
    
    root = tk.Tk() 
    root.title("噪声读取程序!")
   
    frame = Frame(root)
    root.geometry('600x400')
    root.maxsize(600,400)
    
    frame.mainloop()

效果如下:

0 人点赞