I am trying to write a real-time serial data reading and ploting APP, which read data from a arduino UNO board. But there is a problem that after more 10000 dataponits readout, the ploting presents a huge delay. I don't know why.
Below is my code:
import re
import sys
import time
import serial
import threading
import numpy as np
import pyqtgraph as pg
from queue import Queue
from pyqtgraph.Qt import QtCore, QtWidgets
class MyApp(QtWidgets.QWidget):
def __init__(self):
QtWidgets.QWidget.__init__(self)
## Creating the Widgets and Layouts
self.plot_widget = pg.PlotWidget()
self.layout = QtWidgets.QVBoxLayout()
self.sbutton = QtWidgets.QPushButton("Start / Continue")
self.ebutton = QtWidgets.QPushButton("Stop")
self.timer = pg.QtCore.QTimer()
self.scroll = QtWidgets.QScrollBar(QtCore.Qt.Horizontal)
## Creating the variables and constants
self.stop_thread = False
self.data_x = [0]
self.data_y = [0]
self.data_z = [0]
self.vsize = 500
self.psize = 300000000
self.mag_x = Queue(maxsize=0)
self.mag_y = Queue(maxsize=0)
self.mag_z = Queue(maxsize=0)
self.Labelstyles = {"color": "black", "font-size": "30px", "font-weight": "bold"}
self.plot_widget.addLegend(labelTextSize ='30px')
self.plot_item_x = self.plot_widget.plot(self.data_x, pen=pg.mkPen('#89D99D', width=4), name='Bx')
self.plot_item_y = self.plot_widget.plot(self.data_y, pen=pg.mkPen('#FA7F08', width=4), name='By')
self.plot_item_z = self.plot_widget.plot(self.data_z, pen=pg.mkPen('#F24405', width=4), name='Bz')
## Building the Widget
self.setLayout(self.layout)
self.layout.addWidget(self.sbutton)
self.layout.addWidget(self.ebutton)
self.layout.addWidget(self.plot_widget)
self.layout.addWidget(self.scroll)
## Changing some properties of the widgets
self.plot_widget.setYRange(-3000, 3000)
self.plot_widget.setFixedSize(1500, 800)
self.plot_widget.setBackground('w')
self.plot_widget.showGrid(x=True, y=True, alpha=0.5)
self.plot_widget.setLabel('left', 'Magnetic Intensity (mT)', bold=True, **self.Labelstyles)
self.plot_widget.setLabel('bottom', 'Counts', bold=True, **self.Labelstyles)
self.plot_widget.setMouseEnabled(x=False, y=False)
self.ebutton.setEnabled(False)
self.scroll.setEnabled(False)
self.scroll.setMaximum(self.vsize)
self.scroll.setMinimum(0)
self.scroll.setValue(self.vsize)
self.plot_widget.setXRange(0, self.vsize)
## Coneccting the signals
self.mSerial = serial.Serial('COM6', 2000000)
self.sbutton.clicked.connect(self.start)
self.ebutton.clicked.connect(self.stop)
self.timer.timeout.connect(self.update)
self.scroll.valueChanged.connect(self.upd_scroll)
self.th1 = threading.Thread(target=self.serial, daemon=True)
def upd_scroll(self):
xmax = np.ceil(len(self.data_x) * (self.scroll.value() / self.scroll.maximum()))-2
xmin = (xmax-self.vsize)
self.plot_widget.setXRange(xmin, xmax)
def update(self):
self.data_x.append(self.mag_x.get())
self.data_y.append(self.mag_y.get())
self.data_z.append(self.mag_z.get())
num = len(self.data_x)
if num <= self.psize:
self.plot_item_x.setData(self.data_x)
self.plot_item_y.setData(self.data_y)
self.plot_item_z.setData(self.data_z)
else:
self.plot_item_x.setData(self.data_x[-self.psize:])
self.plot_item_y.setData(self.data_y[-self.psize:])
self.plot_item_z.setData(self.data_z[-self.psize:])
if num == self.vsize:
self.scroll.setEnabled(True)
if num > self.vsize:
self.upd_scroll()
def start(self):
self.sbutton.setEnabled(False)
self.ebutton.setEnabled(True)
self.timer.start()
self.stop_thread = False
window.mSerial.flushInput()
if not self.th1.is_alive():
self.th1 = threading.Thread(target=self.serial, daemon=True)
self.th1.start()
def stop(self):
self.sbutton.setEnabled(True)
self.ebutton.setEnabled(False)
self.timer.stop()
self.stop_thread = True
self.th1.join()
self.upd_scroll()
def closeEvent(self, event):
self.timer.stop()
event.accept()
def serial(self):
while not self.stop_thread:
ret = b''
n = self.mSerial.inWaiting()
if(n):
ret = self.mSerial.readline()
if len(ret):
data_get = ret.decode('UTF-8')
pattern = re.compile(r"[+-]?\d+(?:\.\d+)?")
data_all = pattern.findall(data_get)
for j in range(len(data_all)):
if j==0:
self.mag_x.put(float(data_all[j]))
if j==1:
self.mag_y.put(float(data_all[j]))
if j==2:
self.mag_z.put(float(data_all[j]))
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
window = MyApp()
window.show()
#access serial port
if (window.mSerial.isOpen()):
print("open success")
window.mSerial.flushInput() #clear the input buffer
else:
print("open failed")
serial.close()
sys.exit(app.exec_())
I've double-checked my code, and my computer has enough memory capacity to do this. Also, I have checked my communication interface, so this should not be a hardware problem. Please help me out.