Maximizing serial communication speed for live plotting data from Teensy 3.2 using Python

后端 未结 1 1546
难免孤独
难免孤独 2020-12-21 16:53

I\'m trying to plot data as quickly as possible with Python (PyQtGraph) received from a Teensy 3.2 which is sending analog data over a serial communication. The code can suf

相关标签:
1条回答
  • 2020-12-21 17:39

    As M.R. suggested above you'd be probably better off if you pack more data before sending it through instead of sending a two-byte packet at a time.

    But the horrible performance you see has more to do with the way you read data on your computer. If you read just two bytes from your serial port and attach them to the plot the overhead you end up with is huge.

    If you instead process as many bytes as you have available on your RX buffer you can get almost real-time performance.

    Just change your update function:

    def update():
    
        global curve, ptr, Xm    
    
        if ser.inWaiting() > 0                         # Check for data not for an open port
            b1 = ser.read(ser.inWaiting())             # Read all data available at once
            if len(b1) % 2 != 0:                       # Odd length, drop 1 byte
                b1 = b1[:-1]
            data_type = dtype(uint16)
            data_int = fromstring(b1, dtype=data_type) # Convert bytes to numpy array
            data_int = data_int.byteswap()             # Swap bytes for big endian
            Xm = append(Xm, data_int)              
            ptr += len(data_int)                              
            Xm[:-len(data_int)] = Xm[len(data_int):]   # Scroll plot
            curve.setData(Xm[(len(Xm)-windowWidth):])                     
            curve.setPos(ptr,0)                   
            QtGui.QApplication.processEvents()   
    

    After toying a bit with the idea of iterating the bytes two at a time I thought it should be possible to do it with numpy, and coincidentally I found this question, which is very similar to yours. So credit goes there for the numpy solution.

    Unfortunately, the battery of my portable scope died so I could not test the code above properly. But I think a good solution should be workable from there.

    I did not check the Teensy code in detail, but at a quick glance, I think the timer for the interrupt you're using to give the tempo for the ADC might be a bit too tight. You forgot to consider the start and stop bits that travel with each data byte and you are not accounting for the time it takes to get the AD conversion done (I guess that should be very small, maybe 10 microseconds). All things considered, I think you might need to increase the heartbeat to be sure you're not introducing irregular sampling times. It should be possible to get much faster sampling rates with the Teensy, but to do that you need to use a completely different approach. A nice topic for another question I guess...

    0 讨论(0)
提交回复
热议问题