【Python实战系列】串口实时接收数据并基于pyqtgraph绘图

0、前言

  串口数据图形化调试助手,这乍一听起来貌似还挺阔以的样子。那究竟是啥子呢?且听慢慢道来。事情的缘由是当前在做的一个项目中,在调试Mag(地磁)相关的Sensor。获取Mag的原始数据之后,首先要做的就是判断原始数据的质量如何,及是否是我们想要的数据,不仅要看数据是否在相应状况下处于合理的范围内,且数据的变化是否符合规律,所以呢需要一个能将原始数据实时绘制成图的工具。OK,那么来列举一下需求:

  1. 串口通讯:串口打印是嵌入式开发时重要的调试手段,所以此处数据也通过串口传输给上位机;
  2. 实时图表:将串口输出的数据实时绘图;
  3. 至少能够同时绘制更新三组数据(x轴、y轴、z轴)数据。

1、相关库的安装

pip install pyserial  	#python 串口库
pip install pyqtgraph	#安装pyqtgraph	
pip install PyQt5		#安装python QT

在这里插入图片描述

2、实战实例

#!/usr/bin/env python
#-*-coding:utf-8 -*-
import os
import sys
import time
import signal
import string
import pyqtgraph as pg
import array
import serial
import threading
import numpy as np
from queue import Queue
import re

i = 0
q_mag_x = Queue(maxsize=0)
q_mag_y = Queue(maxsize=0)
q_mag_z = Queue(maxsize=0)
curve_num = 0;

def Serial():
    global i;
    global q_mag_x;
    global q_mag_y;
    global q_mag_z;
    ret = b''
    while(True):
        n = mSerial.inWaiting()
        if(n):
            ret = mSerial.readline()
            print(ret)
            if len(ret):
                data_get = ret.decode('UTF-8')
                pattern = re.compile(r"[+-]?\d+(?:\.\d+)?")   # find the num
                data_all = pattern.findall(data_get)
                print(data_all)
                for j in range(len(data_all)):
                    if j==0:
                        q_mag_x.put(data_all[j])
                    if j==1:
                        q_mag_y.put(data_all[j])
                    if j==2:
                        q_mag_z.put(data_all[j])

def plotData():
    global i;
    if i < historyLength:
        data_x[i] = q_mag_x.get()
        if curve_num >= 2:
            data_y[i] = q_mag_y.get()
        if curve_num >= 3:
            data_z[i] = q_mag_z.get()
        i = i+1
    else:
        data_x[:-1] = data_x[1:]
        data_x[i-1] = q_mag_x.get()
        if curve_num >= 2:
            data_y[:-1] = data_y[1:]
            data_y[i-1] = q_mag_y.get()
        if curve_num >= 3:
            data_z[:-1] = data_z[1:]
            data_z[i-1] = q_mag_z.get()

    curve1.setData(data_x)
    curve2.setData(data_y)
    curve3.setData(data_z)

def sig_handler(signum, frame):
    sys.exit(0)

if __name__ == "__main__":
    curve_num = 3
    
    signal.signal(signal.SIGINT, sig_handler)
    signal.signal(signal.SIGTERM, sig_handler)
    app = pg.mkQApp()           # App Setup
    win = pg.GraphicsWindow()   # Window Setup
    win.setWindowTitle(u'pyqtgraph chart tool')
    win.resize(900, 600)        #window size
    data_x = array.array('i')
    data_y = array.array('i')
    data_z = array.array('i')
    historyLength = 160 

    data_x = np.zeros(historyLength).__array__('d')
    data_y = np.zeros(historyLength).__array__('d')
    data_z = np.zeros(historyLength).__array__('d')
    p = win.addPlot() 
    p.showGrid(x=True, y=True)
    p.setRange(xRange=[0, historyLength], yRange=[-1000, 1000], padding=0)
    p.setLabel(axis='left',     text='y-mag')
    p.setLabel(axis='bottom',   text='x-time')
    p.setTitle('Serial Chart')
    curve1 = p.plot(data_x, pen='r')
    curve2 = p.plot(data_y, pen='g')
    curve3 = p.plot(data_z, pen='b')
    
    portx = 'COM1'
    bps = 115200
    mSerial = serial.Serial(portx, int(bps))
    if (mSerial.isOpen()):
        print("open success")
        mSerial.flushInput()
    else:
        print("open failed")
        serial.close()
    
    #Serial data receive thread
    th1 = threading.Thread(target=Serial)
    th1.setDaemon(True)
    th1.start()
    
    #plot timer define
    timer = pg.QtCore.QTimer()
    timer.timeout.connect(plotData)
    timer.start(10)
    app.exec_()

3、实例演示

在这里插入图片描述

4、后记

  之后有时间的话还是希望能够继续完善这个东东,以后也能再能把这玩意当成真正的调试工具来用!
在这里插入图片描述


参考传送门:

  1. pyqtgraph官网:https://www.pyqtgraph.org/
  2. 博客: 用Python串口实时显示数据并绘图

猜你喜欢

转载自blog.csdn.net/qq_33475105/article/details/119121331