• 用Python串口实时显示数据并绘图pyqtgraph


    https://blog.csdn.net/RNG_uzi_/article/details/96736432

    其他方法如 Processing   SerialChart

    http://www.starlino.com/serialchart

    https://github.com/starlino/serialchart

    用Python串口实时显示数据并绘图

    使用pyserial进行串口传输

    一、安装pyserial以及基本用法

    在cmd下输入命令pip install pyserial
    注:升级pip后会出现 "‘E:Anaconda3Scriptspip-script.py’ is not present."错误
    使用 easy_install pip命令就能解决,换一条重新能执行安装的命令

    常用方法:
    ser = serial.Serial(0) 是打开第一个串口
    print ser.portstr 能看到第一个串口的标识,windows下是COM1
    ser.write(“hello") 就是往串口里面写数据
    ser.close() 就是关闭ser表示的串口
    ser.open() 会打开这个串口
    ser = serial.Serial(‘COM1’, 115200) 来设置波特率,当然还有专门的函数
    data = ser.read()可以读一个字符
    data = ser.read(20) 是读20个字符
    data = ser.readline() 是读一行,以 结束,要是没有 就一直读,阻塞。
    data = ser.readlines()ser.xreadlines()都需要设置超时时间
    ser.baudrate = 9600 设置波特率
    ser 来查看当前串口的状态
    ser.isOpen() 看看这个串口是否已经被打开

    串行口的属性:
    name:设备名字
    portstr:已废弃,用name代替
    port:读或者写端口
    baudrate:波特率
    bytesize:字节大小
    parity:校验位
    stopbits:停止位
    timeout:读超时设置
    writeTimeout:写超时
    xonxoff:软件流控
    rtscts:硬件流控
    dsrdtr:硬件流控
    interCharTimeout:字符间隔超时

    注意:使用开发板printf函数,以 结束。使用serial.readline()进行读取数据,使用decode对其进行编码,编码之后使用split(’ ')[i]函数进行读取某个字节。

    二、最基本的串口代码

    import serial
    portx="COM5"
    bps=9600
    timex=5
    #串口执行到这已经打开 再用open命令会报错
    ser = serial.Serial(portx, int(bps), timeout=1, parity=serial.PARITY_NONE,stopbits=1)
    if (ser.isOpen()):
        print("open success")
         # 向端口些数据 字符串必须译码
        ser.write("hello".encode()) 
        while (True):
            line = ser.readline()  
            if(line):
                print(line)
                line=0
    else:
    	print("open failed")
    ser.close()#关闭端口
    

    三、pyqtgraph的使用

    pip install pyqtgraph#显示波形的界面
    pip install PyQt5#界面要Qt的支持

    pyqtgraph是Python平台上一种功能强大的2D/3D绘图库,相对于matplotlib库,由于内部实现方式上,使用了高速计算的numpy信号处理库以及Qt的GraphicsView框架,因此,它在大数据量的数字处理和快速显示方面有着巨大的优势,它适合于需要快速绘图更新、视频或实时交互性的操作场合。另外,它不仅为各种数据提供了快速可交互式的图形显示,同时也提供了用于快速开发应用程序的各种小工具,如属性树、流程图等小部件,在数学、科学和工程领域都有着广泛的应用。

    import pyqtgraph as pg
    import numpy as np
    import array
    
    app = pg.mkQApp()#建立app
    win = pg.GraphicsWindow()#建立窗口
    win.setWindowTitle(u'pyqtgraph逐点画波形图')
    win.resize(800, 500)#小窗口大小
    
    data = array.array('d') #可动态改变数组的大小,double型数组
    historyLength = 100#横坐标长度
    p = win.addPlot()#把图p加入到窗口中
    p.showGrid(x=True, y=True)#把X和Y的表格打开
    p.setRange(xRange=[0,historyLength], yRange=[-1.2, 1.2], padding=0)
    p.setLabel(axis='left', text='y / V')#靠左
    p.setLabel(axis='bottom', text='x / point')
    p.setTitle('y = sin(x)')#表格的名字
    curve = p.plot()#绘制一个图形
    idx = 0
    def plotData():
        global idx#内部作用域想改变外部域变量
        tmp = np.sin(np.pi / 50 * idx)
        if len(data)<historyLength:
            data.append(tmp)
        else:
            data[:-1] = data[1:]#前移
            data[-1] = tmp
        curve.setData(data)
        idx += 1
    
    timer = pg.QtCore.QTimer()
    timer.timeout.connect(plotData)#定时调用plotData函数
    timer.start(50)#多少ms调用一次
    
    app.exec_()
    

    在这里插入图片描述
    四、通过多线程实现串口数据的实时绘图import pyqtgraph as pg

    主要是开了一个线程去处理串口 剩下的和上面内容一样 就不过多解释了 直接上代码

    import array
    import serial
    import threading
    import pyqtgraph as pg import numpy as np import time i = 0 def Serial(): while(True): n = mSerial.inWaiting() if(n): if data!=" ": dat = int.from_bytes(mSerial.readline(1),byteorder='little') # 格式转换 n=0 global i; if i < historyLength: data[i] = dat i = i+1 else: data[:-1] = data[1:] data[i-1] = dat def plotData(): curve.setData(data) if __name__ == "__main__": app = pg.mkQApp() # 建立app win = pg.GraphicsWindow() # 建立窗口 win.setWindowTitle(u'pyqtgraph逐点画波形图') win.resize(800, 500) # 小窗口大小 data = array.array('i') # 可动态改变数组的大小,double型数组 historyLength = 200 # 横坐标长度 a = 0 data=np.zeros(historyLength).__array__('d')#把数组长度定下来 p = win.addPlot() # 把图p加入到窗口中 p.showGrid(x=True, y=True) # 把X和Y的表格打开 p.setRange(xRange=[0, historyLength], yRange=[0, 255], padding=0) p.setLabel(axis='left', text='y / V') # 靠左 p.setLabel(axis='bottom', text='x / point') p.setTitle('semg') # 表格的名字 curve = p.plot() # 绘制一个图形 curve.setData(data) portx = 'COM24' bps = 19200 # 串口执行到这已经打开 再用open命令会报错 mSerial = serial.Serial(portx, int(bps)) if (mSerial.isOpen()): print("open success") mSerial.write("hello".encode()) # 向端口些数据 字符串必须译码 mSerial.flushInput() # 清空缓冲区 else: print("open failed") serial.close() # 关闭端口 th1 = threading.Thread(target=Serial)#目标函数一定不能带()被这个BUG搞了好久 th1.start() timer = pg.QtCore.QTimer() timer.timeout.connect(plotData) # 定时刷新数据显示 timer.start(50) # 多少ms调用一次 app.exec_()

    效果如图

    在这里插入图片描述

    五、与下位机通讯实现波形实时监测

    在这里与第四阶段基本相同,需要注意的是,如果收数据直接画图的话,波形会出现问题。所以串口传输数据时使用循环队列(先进先出),数据来之后先进队列,之后再定时器调用函数,出队列,更新图。理论上刷新数据的时间需要大于下位机发送数据的间隔时间,否则队列会越来越大,而且图的刷新不连贯。再就是有一个小问题,因为正弦波有负值,我又没找到很好的把Byte转为char的方法,所以只能手动代码处理,先转成int类型,再把第八位(符号位)清零,得到绝对值。然后再取负,得到我们需要的数据。但发现Python无法进行移位操作,python是int类型是无精度类型,不会发生溢出而进行截取的情况,所以只能先转为二进制在移位,太麻烦,直接通过减去一个数的方法来实现了。然后直接上代码吧

    import pyqtgraph as pg
    import array
    import serial
    import threading
    import numpy as np
    from queue import Queue
    import time
    
    
    i = 0
    q = Queue(maxsize=0)
    def Serial():
        global i;
        global q;
        while(True):
            n = mSerial.inWaiting()
            if(n):
                dat = int.from_bytes(mSerial.readline(1),byteorder='little')  # 格式转换
                if(dat>>7):
                    dat =256-dat
                    dat =0-dat
                q.put(dat)
    
    def plotData():
        global i;
        if i < historyLength:
            data[i] = q.get()
            i = i+1
        else:
            data[:-1] = data[1:]
            data[i-1] = q.get()
        curve.setData(data)
    
    
    if __name__ == "__main__":
        app = pg.mkQApp()  # 建立app
        win = pg.GraphicsWindow()  # 建立窗口
        win.setWindowTitle(u'pyqtgraph逐点画波形图')
        win.resize(800, 500)  # 小窗口大小
        data = array.array('i')  # 可动态改变数组的大小,double型数组
        historyLength = 100  # 横坐标长度
        a = 0
        data=np.zeros(historyLength).__array__('d')#把数组长度定下来
        p = win.addPlot()  # 把图p加入到窗口中
        p.showGrid(x=True, y=True)  # 把X和Y的表格打开
        p.setRange(xRange=[0, historyLength], yRange=[-50, 50], padding=0)
        p.setLabel(axis='left', text='y / V')  # 靠左
        p.setLabel(axis='bottom', text='x / point')
        p.setTitle('semg')  # 表格的名字
        curve = p.plot()  # 绘制一个图形
        curve.setData(data)
        portx = 'COM25'
        bps = 19200
        # 串口执行到这已经打开 再用open命令会报错
        mSerial = serial.Serial(portx, int(bps))
        if (mSerial.isOpen()):
            dat = 0xff;
            dat >> 2;
            print("open success")
            # 向端口些数据 字符串必须译码
            mSerial.write("hello".encode())
            mSerial.flushInput()  # 清空缓冲区
        else:
            print("open failed")
            serial.close()  # 关闭端口
        th1 = threading.Thread(target=Serial)
        th1.start()
        timer = pg.QtCore.QTimer()
        timer.timeout.connect(plotData)  # 定时刷新数据显示
        timer.start(1)  # 多少ms调用一次
        app.exec_()
    

    Python+pyqtgraph数据可视化:自定义坐标轴信息

    方法1

    其原则是,直接使用pyqtgraph库提供的轴项类AxisItem,定义它的一个实例对象,调用该类的setTicks函数设置横坐标轴的字符信息,代码如下:
    在这里插入图片描述
    代码简要说明如下:

    1、第14-16行,产生波形的x、y数据及对应的x轴的字符信息列表

    2、第20行,将x数值及字对应字符组成一个元组的列表

    3、第25-26行,创建轴项类AxisItem的实例对象strAxis,并调用setTicks函数设置横坐标的字符信息

    4、第29-30行,使用strAxis创建绘图对象并绘制波形图

    方法2

    其原则是,以pyqtgraph库提供的轴项类AxisItem作为基类,在程序中创建一个自定义的轴项类,类中重定义函数tickStrings来实现横坐标刻度的的字符信息显示,代码如下:
    在这里插入图片描述
    代码简要说明如下:

    1、第13-29行,以pyqtgraph库提供的AxisItem作为基类自定义了一个轴项类MyStringAxis,在类中重定义tickStrings函数,实现横坐标刻度的的字符信息显示

    2、第33-35行,产生波形的x、y数据及对应的x轴的字符信息列表

    3、第39行,将x数值及字对应字符组成一个元组的列表

    4、第42-44行,创建自定义类MyStringAxis的实例对象strAxis,用其创建绘图对象并绘制波形图

    Python+pyqtgraph数据可视化之多条曲线绘制方法

    pyqtgraph是Python平台上一种功能强大的2D/3D绘图库,相对于matplotlib库,由于其在内部实现方式上,使用了高速计算的numpy信号处理库以及Qt的GraphicsView框架,因此它在大数据量的处理及快速显示方面有着天然的优势,非常适合于需要快速绘图更新、视频或实时交互性的操作场合,在数学、科学和工程领域都有着广泛的应用。

    对于多条曲线的快速绘制方式,有两种方案可供选择,一种是将多条曲线合并显示在一幅绘图区域上,另一种方案是将多条曲线显示在不同的绘图区域上,对于这两种绘制方案,下面通过例子来演示在Python语言中使用pyqtgraph库编程实现的方法。

    方案1:将多条曲线合并显示在一幅绘图区域
    程序的运行效果如下图所示:
    在这里插入图片描述
    例子在图形的一幅绘图区域上显示了3条曲线,分别为正弦曲线、余弦曲线及sinc函数曲线。
    主要实现代码如下:
    在这里插入图片描述
    代码主要部分说明如下:

    1、第13行,创建应用程序实例app

    2、第15-17行,创建一个图形显示窗口win,设置窗口属性,如窗口标题、窗口大小等

    3、第19-22行,使用numpy库产生3条曲线即正弦曲线、余弦曲线及sinc函数曲线的x、y数据

    4、第24行,在win上添加一个绘图区域对象p,参数中设置了X、Y轴label及图形标题等

    5、第25-27行,在p上分别添加3条不同颜色的曲线

    6、第28-29行,设置绘图区域的网格及坐标轴范围属性

    7、第31行,使用app.exec_()函数运行实例,进入消息循环

    方案2:将多条曲线显示在不同的绘图区域
    程序的运行效果如下图所示:
    在这里插入图片描述
    对于上面的正弦曲线、余弦曲线及sinc函数曲线分别显示在了图形的3个绘图区域上。
    主要实现代码如下:
    在这里插入图片描述
    代码主要部分说明如下:

    1、第13-22行,和上例完全相同

    2、第24-27行,在win上分别添加了3个绘图区域对象p1、p2、p3,其中,第26行,说明在绘图区域的下一行创建p3,第27行的参数“colspan=2”说明p3占的列宽为2列

    3、第29-32行,在for循环中分别在3个绘图区域对象上绘制不同的曲线,并设置绘图区域的网格及坐标轴范围等属性

    4、第34行,使用app.exec_()函数运行实例,进入消息循环

    备注
    在第2种方案中创建绘图区域对象p时,也可以在参数中直接指定p处于的位置及行宽、列宽等信息,如将上面例子中第26、27行合并写为如下代码也是等价的。

    欢迎加关注,共同交流。

    感谢前辈:
    https://blog.csdn.net/up1012/article/details/81010312
    http://www.360doc.com/content/18/1007/18/29771970_792744060.shtml

  • 相关阅读:
    js原型链
    charles重放攻击2
    charles攻击重放测试网页
    js逆向基础知识
    js重放攻击
    js逆向之 中间人攻击-js注入
    修改jadx默认内存
    frida-ida hook操作
    关于ios 9系统完全越狱frida安装不上的的问题
    IDA 静态调试和动态调试
  • 原文地址:https://www.cnblogs.com/sinferwu/p/14149592.html
Copyright © 2020-2023  润新知