简体   繁体   中英

Plotting in time using PyQtGraph and Pyserial

I am trying to do a real-time plot, using pyqtgraph. I am reading the data, from and arduino, using Pyserial. I tried the matplotlib library before using pyqtgraph, but it did not gave me the speed that i need to plot. So, searching another ways to draw live-data, i met PyQtgraph. I read the docs and a lot of examples, and i have found these two examples:

pltting with sample interval

plotting using pyqt4

Both are drawn as a function of time, which is what i need to do. I have modified each of them to get the data from the Arduino using Pyserial. The prolem is that it still draws very slow.

This is the code (from the second link) i am using:

class TimeAxisItem(pg.AxisItem):
  def __init__(self, *args, **kwargs):
    super(TimeAxisItem, self).__init__(*args, **kwargs)

  def tickStrings(self, values, scale, spacing):
    return [QTime().addMSecs(value).toString('mm:ss') for value in values]

class MyApplication(QtGui.QApplication):
  def __init__(self, *args, **kwargs):
    super(MyApplication, self).__init__(*args, **kwargs)
    self.t = QTime()
    self.t.start()

    self.data = deque(maxlen=20)

    self.win = pg.GraphicsWindow(title="Basic plotting examples")
    self.win.resize(1000,600)

    self.plot = self.win.addPlot(title='Timed data', axisItems={'bottom':  TimeAxisItem(orientation='bottom')})
    self.curve = self.plot.plot()

    self.tmr = QTimer()
    self.tmr.timeout.connect(self.update)
    self.tmr.start(100)

    print "Opening port"
    self.raw=serial.Serial("com4",9600)
    print "Port is open"


  def update(self):
    line = self.raw.read()
    ardString = map(ord, line)
    for number in ardString:
        numb = float(number/77.57)
        print numb
        self.data.append({'x': self.t.elapsed(), 'y': numb})
        x = [item['x'] for item in self.data]
        y = [item['y'] for item in self.data]
        self.curve.setData(x=x, y=y)

def main():
  app = MyApplication(sys.argv)
  sys.exit(app.exec_())

if __name__ == '__main__':
  main()

What can i do to draw faster over time?It seems that i am loosing some data with this code.

Really hope you can help me.

In your update function, try calling

self.curve.clear()

at the very beginning of the function.

What strikes me as slightly off is the timing of what's going on here, rather than the pyqtgraph particulars. Your update method is polling the serial port at 100ms intervals per your QTimer object, so at 9600 baud, your port could generate 9600bps*.1sec = 960 bytes. However, your serial.Serial.read() with no argument defaults to size = 1 per here: http://pyserial.readthedocs.io/en/latest/pyserial_api.html#serial.Serial.read

So it appears as though you are reading only 1 byte every 100ms in your update call of:

line = self.raw.read()

So my guess is you should put something more sensible in the read size, 1024:

line = self.raw.read(1024)

with a timeout specified in the serial.Serial instantiation:

self.raw=serial.Serial("com4",9600,timeout=0)

This way, the read won't block and just return the full amount of data available in the buffer.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM