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


Posted in Python onDecember 26, 2019

使用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 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_()

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

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

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

import array
import serial
import threading
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_()

效果如图

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

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

在这里与第四阶段基本相同,需要注意的是,如果收数据直接画图的话,波形会出现问题。所以串口传输数据时使用循环队列(先进先出),数据来之后先进队列,之后再定时器调用函数,出队列,更新图。理论上刷新数据的时间需要大于下位机发送数据的间隔时间,否则队列会越来越大,而且图的刷新不连贯。再就是有一个小问题,因为正弦波有负值,我又没找到很好的把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串口实时显示数据并绘图的例子就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python基于xml parse实现解析cdatasection数据
Sep 30 Python
python中while循环语句用法简单实例
May 07 Python
python查看微信好友是否删除自己
Dec 19 Python
Python中正则表达式详解
May 17 Python
Django实现组合搜索的方法示例
Jan 23 Python
Pycharm2017版本设置启动时默认自动打开项目的方法
Oct 29 Python
python3实现点餐系统
Jan 24 Python
详解Python3中ceil()函数用法
Feb 19 Python
Python3.5文件读与写操作经典实例详解
May 01 Python
python web框架 django wsgi原理解析
Aug 20 Python
python中设置超时跳过,超时退出的方式
Dec 13 Python
用 python 进行微信好友信息分析
Nov 28 Python
简单了解python字符串前面加r,u的含义
Dec 26 #Python
python关于调用函数外的变量实例
Dec 26 #Python
python3 实现调用串口功能
Dec 26 #Python
将python依赖包打包成window下可执行文件bat方式
Dec 26 #Python
python小项目之五子棋游戏
Dec 26 #Python
python自动识别文本编码格式代码
Dec 26 #Python
Python基于pygame实现单机版五子棋对战
Dec 26 #Python
You might like
理解php原理的opcodes(操作码)
2010/10/26 PHP
php使用正则验证中文
2016/04/06 PHP
PDO的安全处理与事物处理方法
2016/10/31 PHP
jquery submit ie6下失效的原因分析及解决方法
2013/11/15 Javascript
jQuery中scrollTop()方法用法实例
2015/01/16 Javascript
基于jQuery实现网页进度显示插件
2015/03/04 Javascript
JavaScript如何动态创建table表格
2020/08/02 Javascript
JavaScript中利用jQuery绑定事件的几种方式小结
2016/03/06 Javascript
JavaScript String 对象常用方法总结
2016/04/28 Javascript
深入剖析JavaScript中的函数currying柯里化
2016/04/29 Javascript
Bootstrap弹出带合法性检查的登录框实例代码【推荐】
2016/06/23 Javascript
js显示动态时间的方法详解
2016/08/20 Javascript
Bootstrap基本插件学习笔记之折叠(22)
2016/12/08 Javascript
Angular路由简单学习
2016/12/26 Javascript
原生javascript实现图片放大镜效果
2017/01/18 Javascript
Vue结合SignalR实现前后端实时消息同步
2017/09/19 Javascript
vue 刷新之后 嵌套路由不变 重新渲染页面的方法
2018/09/13 Javascript
Echart折线图手柄触发事件示例详解
2018/12/16 Javascript
详解js 创建对象的几种方法
2019/03/08 Javascript
js实现web调用摄像头 js截取视频画面
2019/04/21 Javascript
一文了解vue-router之hash模式和history模式
2019/05/31 Javascript
在微信小程序中使用vant的方法
2019/06/07 Javascript
layui添加动态菜单与选项卡
2019/07/26 Javascript
微信小程序用户授权弹窗 拒绝时引导用户重新授权实现
2019/07/29 Javascript
JavaScript装箱及拆箱boxing及unBoxing用法解析
2020/06/15 Javascript
Vue自定义全局弹窗组件操作
2020/08/11 Javascript
[01:46]2020完美世界全国高校联赛秋季赛报名开启
2020/10/15 DOTA
python实现感知器算法(批处理)
2019/01/18 Python
浅析Python3中的对象垃圾收集机制
2019/06/06 Python
python logging日志模块原理及操作解析
2019/10/12 Python
美国时尚孕妇装品牌:A Pea in the Pod
2017/07/16 全球购物
施华洛世奇韩国官网:SWAROVSKI韩国
2018/06/05 全球购物
俄罗斯汽车零件和配件在线商店:CarvilleShop
2019/11/29 全球购物
组织鉴定材料
2014/06/02 职场文书
2016暑期校本培训心得体会
2016/01/08 职场文书
遇事可以测出您的见识与格局
2019/09/16 职场文书