使用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数据类型转换函数总结
Mar 11 Python
Python获取网页上图片下载地址的方法
Mar 11 Python
浅谈Python程序与C++程序的联合使用
Apr 07 Python
Python实现把xml或xsl转换为html格式
Apr 08 Python
Python爬取十篇新闻统计TF-IDF
Jan 03 Python
TensorFlow实现AutoEncoder自编码器
Mar 09 Python
Python 移动光标位置的方法
Jan 20 Python
在VS2017中用C#调用python脚本的实现
Jul 31 Python
python内存管理机制原理详解
Aug 12 Python
Python实现多线程/多进程的TCP服务器
Sep 03 Python
DJango的创建和使用详解(默认数据库sqlite3)
Nov 18 Python
Pymysql实现往表中插入数据过程解析
Jun 02 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的特殊设置
2006/10/09 PHP
简单采集了yahoo的一些数据
2007/02/14 PHP
php自动加载机制的深入分析
2013/06/08 PHP
PHP使用Mysqli类库实现完美分页效果的方法
2016/04/07 PHP
PHP 表单提交及处理表单数据详解及实例
2016/12/27 PHP
Extjs ajax同步请求时post方式参数发送方式
2009/08/05 Javascript
IE6 fixed的完美解决方案
2011/03/31 Javascript
js中方法重载如何实现?以及函数的参数问题
2013/08/01 Javascript
js获取客户端操作系统类型的方法【测试可用】
2016/05/27 Javascript
js仿百度音乐全选操作
2017/01/13 Javascript
微信小程序实现聊天对话(文本、图片)功能
2018/07/06 Javascript
简单了解node npm cnpm的具体使用方法
2019/02/27 Javascript
使用ESLint禁止项目导入特定模块的方法步骤
2019/03/04 Javascript
详解如何模拟实现node中的Events模块(通俗易懂版)
2019/04/15 Javascript
mpvue微信小程序开发之实现一个弹幕评论
2019/11/24 Javascript
Vue常用传值方式、父传子、子传父及非父子实例分析
2020/02/24 Javascript
JavaScript隐式类型转换代码实例
2020/05/29 Javascript
[02:34]肉山说——泡妞篇
2014/09/16 DOTA
python 运算符 供重载参考
2009/06/11 Python
Python os模块介绍
2014/11/30 Python
Django 添加静态文件的两种实现方法(必看篇)
2017/07/14 Python
Python在图片中插入大量文字并且自动换行
2019/01/02 Python
Python3.4学习笔记之类型判断,异常处理,终止程序操作小结
2019/03/01 Python
python简单实现矩阵的乘,加,转置和逆运算示例
2019/07/10 Python
python实现修改固定模式的字符串内容操作示例
2019/12/30 Python
Python实现获取当前目录下文件名代码详解
2020/03/10 Python
python爬虫开发之使用Python爬虫库requests多线程抓取猫眼电影TOP100实例
2020/03/10 Python
Python发送邮件封装实现过程详解
2020/05/09 Python
用60行代码实现Python自动抢微信红包
2021/02/04 Python
关于box-sizing的全面理解
2016/07/28 HTML / CSS
ProBikeKit澳大利亚:自行车套件,跑步和铁人三项装备
2016/11/30 全球购物
马来西亚领先的在线礼品店:Giftr
2018/08/23 全球购物
小米乌克兰网上商店:Xiaomi.UA
2019/10/29 全球购物
J2EE面试题
2016/03/14 面试题
小学六一儿童节活动方案
2014/08/27 职场文书
2014院党委领导班子及其成员群众路线对照检查材料思想汇报
2014/10/04 职场文书