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.

0

There are 0 best solutions below