侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

使用Python串口实时显示数据并绘图的例子

Python  /  管理员 发布于 7年前   198

使用pyserial进行串口传输

一、安装pyserial以及基本用法

在cmd下输入命令pip install pyserial

注:升级pip后会出现 "‘E:\Anaconda3\Scripts\pip-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() 是读一行,以/n结束,要是没有/n就一直读,阻塞。

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:字符间隔超时

二、最基本的串口代码

import serialportx="COM5"bps=9600timex=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=0else: print("open failed")ser.close()#关闭端口)

三、pyqtgraph的使用

pip install pyqtgraph#显示波形的界面

pip install PyQt5#界面要Qt的支持

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

import pyqtgraph as pgimport numpy as npimport arrayapp = pg.mkQApp()#建立appwin = 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 = 0def 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 += 1timer = pg.QtCore.QTimer()timer.timeout.connect(plotData)#定时调用plotData函数timer.start(50)#多少ms调用一次app.exec_()

四、通过多线程实现串口数据的实时绘图import pyqtgraph as pg

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

import arrayimport serialimport threadingimport numpy as npimport timei = 0def 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] = datdef 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 pgimport arrayimport serialimport threadingimport numpy as npfrom queue import Queueimport timei = 0q = 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串口实时显示数据并绘图的例子就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。


  • 上一条:
    python 串口读取+存储+输出处理实例
    下一条:
    简单了解python字符串前面加r,u的含义
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 在python语言中Flask框架的学习及简单功能示例(0个评论)
    • 在Python语言中实现GUI全屏倒计时代码示例(0个评论)
    • Python + zipfile库实现zip文件解压自动化脚本示例(0个评论)
    • python爬虫BeautifulSoup快速抓取网站图片(1个评论)
    • vscode 配置 python3开发环境的方法(0个评论)
    • 近期文章
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • 在go + gin中gorm实现指定搜索/区间搜索分页列表功能接口实例(0个评论)
    • 在go语言中实现IP/CIDR的ip和netmask互转及IP段形式互转及ip是否存在IP/CIDR(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2018-04
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2022-01
    • 2023-07
    • 2023-10
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客