问题
I am reading datas from serial port using an STM32 kit. Problem is that I need to use own timestamp for plot ADC datas. That is mean x-axis should be my RTC time(using ms for this) and y-axis is ADC datas. There are programs for plot serial port but as I said I need to set own time for graph. I tried matplotlib for this but it was really slow. Then have used pyqtgraph and this script:
from pyqtgraph.Qt import QtGui, QtCore
import numpy as np
import pyqtgraph as pg
from pyqtgraph.ptime import time
import serial
app = QtGui.QApplication([])
p = pg.plot()
p.setWindowTitle('live plot from serial')
curve = p.plot()
data = [0]
raw=serial.Serial("/dev/ttyACM0",115200)
#raw.open()
def update():
global curve, data
line = raw.readline()
data.append(int(line))
xdata = np.array(data, dtype='float64')
curve.setData(xdata)
app.processEvents()
timer = QtCore.QTimer()
timer.timeout.connect(update)
timer.start(0)
if __name__ == '__main__':
import sys
if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
QtGui.QApplication.instance().exec_()
This is slow too but fast compare with mathplotlib. Now I can't find how split my timestamp and ADC datas for plot like x,y. My datas are spliting with ';'.
Thanks for answers.
Edited:
I changed my code reading speed looking enough for know. But know it is plotting some glitches like timetamp is jumping with forward and come back or very big numbers of x-axis datas. I am monitoring datas on a serial port GUI and I can't find any wrong data. Somethings is coming from Python code, i think. Can I ignore these glitches on plotting program?
Code now:
import numpy as np
import pyqtgraph as pg
import serial
app = pg.Qt.QtGui.QApplication([])
p = pg.plot()
p.setWindowTitle('live plot from serial')
curve = p.plot()
data = [0]
tdata = [0]
temp = [0]
datax = [0]
datay = [0]
temp = 0
now = 0
k = 0
raw=serial.Serial("/dev/ttyACM0",115200, timeout=None)
while p.isVisible():
line = raw.readline().decode('utf-8').strip()
print("raw line:", line)
line = str(line)
print("str line:", line)
line = line.split(':')
print("splitted line:", line)
if len(line) >= 4:
print("line>4:", line)
tdata = line[0]
data = line[1]
print("line[0]; line[1]:", tdata, line)
tdata = int(tdata)
data = int(data)
print("int(tdata)", tdata)
print("int(line)", data)
datax.append(int(tdata))
datay.append(int(data))
xdata = np.array(datax, dtype='float64')
ydata = np.array(datay, dtype='float64')
p.setXRange(tdata-500, tdata+500, padding=0)
curve.setData(xdata, ydata)
# p.setYRange(0 ,data+30, padding=0)
print("now will refresh the plot")
app.processEvents()
else:
print("line<4:", line)
回答1:
Splitting the data
When you use Serial.readline()
the data read will contain the newline character \n
at the end (see Python univeral newlines, could be \r\n\
if you send from Windows).
First decode the bytes received and remove the newline character:
data_string = r.readline().decode('utf-8').strip()
Then split the string at :
data_split = data_string.split(':')
Now data_split
is a list with the entries
[packetCount, databuffer, sec, subsec]
and you can convert them to floats or integers and put them in the Numpy array.
Speed improvement
Serial.readline
might slow down your code. Use something like this https://stackoverflow.com/a/56632812/7919597 .
Also consider shifting the data in a fixed numpy array instead of creating a new one each time with xdata = np.array(data, dtype='float64')
.
See Shift elements in a numpy array
I am using these functions in combination with a Thread
like
import threading
import queue
q = queue.Queue()
thread = threading.Thread(target=read_from_port, args=(serial_port, q))
thread.start()
to read from the serial port.
There is a very helpful example in the PyQtGraph examples:
https://github.com/pyqtgraph/pyqtgraph/blob/develop/examples/scrollingPlots.py
Is shows three different methods for plotting scrolling plots with Numpy arrays.
I ended up using a combination of method 1 and 3, shifting as many places as were read from the serial port in the meantime.
来源:https://stackoverflow.com/questions/59470518/how-to-increase-speed-and-split-data-with-multiple-plots-using-pyqtgraph