使用Python串口实时显示数据并绘图的例子
使用pyserial进行串口传输
一、安装pyserial以及基本用法
在cmd下输入命令pipinstallpyserial
注:升级pip后会出现"‘E:\Anaconda3\Scripts\pip-script.py'isnotpresent."错误
使用easy_installpip命令就能解决,换一条重新能执行安装的命令
常用方法:
ser=serial.Serial(0)是打开第一个串口
printser.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:字符间隔超时
二、最基本的串口代码
importserial
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("opensuccess")
#向端口些数据字符串必须译码
ser.write("hello".encode())
while(True):
line=ser.readline()
if(line):
print(line)
line=0
else:
print("openfailed")
ser.close()#关闭端口
)
三、pyqtgraph的使用
pipinstallpyqtgraph#显示波形的界面
pipinstallPyQt5#界面要Qt的支持
pyqtgraph是Python平台上一种功能强大的2D/3D绘图库,相对于matplotlib库,由于内部实现方式上,使用了高速计算的numpy信号处理库以及Qt的GraphicsView框架,因此,它在大数据量的数字处理和快速显示方面有着巨大的优势,它适合于需要快速绘图更新、视频或实时交互性的操作场合。另外,它不仅为各种数据提供了快速可交互式的图形显示,同时也提供了用于快速开发应用程序的各种小工具,如属性树、流程图等小部件,在数学、科学和工程领域都有着广泛的应用。
importpyqtgraphaspg
importnumpyasnp
importarray
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
defplotData():
globalidx#内部作用域想改变外部域变量
tmp=np.sin(np.pi/50*idx)
iflen(data)
四、通过多线程实现串口数据的实时绘图importpyqtgraphaspg
主要是开了一个线程去处理串口剩下的和上面内容一样就不过多解释了直接上代码
importarray
importserial
importthreading
importnumpyasnp
importtime
i=0
defSerial():
while(True):
n=mSerial.inWaiting()
if(n):
ifdata!="":
dat=int.from_bytes(mSerial.readline(1),byteorder='little')#格式转换
n=0
globali;
ifi
效果如图
五、与下位机通讯实现波形实时监测
在这里与第四阶段基本相同,需要注意的是,如果收数据直接画图的话,波形会出现问题。所以串口传输数据时使用循环队列(先进先出),数据来之后先进队列,之后再定时器调用函数,出队列,更新图。理论上刷新数据的时间需要大于下位机发送数据的间隔时间,否则队列会越来越大,而且图的刷新不连贯。再就是有一个小问题,因为正弦波有负值,我又没找到很好的把Byte转为char的方法,所以只能手动代码处理,先转成int类型,再把第八位(符号位)清零,得到绝对值。然后再取负,得到我们需要的数据。但发现Python无法进行移位操作,python是int类型是无精度类型,不会发生溢出而进行截取的情况,所以只能先转为二进制在移位,太麻烦,直接通过减去一个数的方法来实现了。然后直接上代码吧
importpyqtgraphaspg
importarray
importserial
importthreading
importnumpyasnp
fromqueueimportQueue
importtime
i=0
q=Queue(maxsize=0)
defSerial():
globali;
globalq;
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)
defplotData():
globali;
ifi>2;
print("opensuccess")
#向端口些数据字符串必须译码
mSerial.write("hello".encode())
mSerial.flushInput()#清空缓冲区
else:
print("openfailed")
serial.close()#关闭端口
th1=threading.Thread(target=Serial)
th1.start()
timer=pg.QtCore.QTimer()
timer.timeout.connect(plotData)#定时刷新数据显示
timer.start(1)#多少ms调用一次
app.exec_()
以上这篇使用Python串口实时显示数据并绘图的例子就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。