python串⼝数据绘图_使⽤Python串⼝实时显⽰数据并绘图的
例⼦
使⽤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 = ad()可以读⼀个字符
data = ad(20) 是读20个字符
data = adline() 是读⼀⾏,以/n结束,要是没有/n就⼀直读,阻塞。
data = adlines()和adlines()都需要设置超时时间
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 = adline()
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逐点画波形图')
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')
python怎么读取串口数据
p.setTitle('y = sin(x)')#表格的名字
curve = p.plot()#绘制⼀个图形
idx = 0
def plotData():
global idx#内部作⽤域想改变外部域变量
tmp = np.sin(np.pi / 50 * idx)
if len(data)
data.append(tmp)
else:
data[:-1] = data[1:]#前移
data[-1] = tmp
curve.setData(data)
idx += 1
timer = pg.QtCore.QTimer()
t(plotData)#定时调⽤plotData函数
timer.start(50)#多少ms调⽤⼀次
<_()
四、通过多线程实现串⼝数据的实时绘图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_adline(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逐点画波形图')
data = array.array('i') # 可动态改变数组的⼤⼩,double型数组historyLength = 200 # 横坐标长度
a = 0
s(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()
t(plotData) # 定时刷新数据显⽰
timer.start(50) # 多少ms调⽤⼀次
<_()
效果如图
五、与下位机通讯实现波形实时监测
在这⾥与第四阶段基本相同,需要注意的是,如果收数据直接画图的话,波形会出现问题。所以串⼝传输数据时使⽤循环队列(先进先出),数据来之后先进队列,之后再定时器调⽤函数,出队列,更新图。理论上刷新数据的时间需要⼤于下位机发送数据的间隔时间,否则队列会越来越⼤,⽽且图的刷新不连贯。再就是有⼀个⼩问题,因为正弦波有负值,我⼜没到很好的把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_adline(1),byteorder='little') # 格式转换
if(dat>>7):
dat =256-dat
dat =0-dat
q.put(dat)
def plotData():
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论