python串口数据实时图有很大的滞后

时间:2016-10-27 12:11:07

标签: python matplotlib

我正在尝试从串口读取并使用matplot在图表中绘制数据。 以下是我的代码: 我看到由于情节,存在巨大的滞后(队列中的数据达到10000字节)因此我看不到实时情节。如果我做错了什么,请你帮帮我。

<

import serial # import Serial Library
   import numpy  # Import numpy
   import matplotlib.pyplot as plt 

   Accelerometer= []
   COM_read = serial.Serial('COM5', 9600, timeout=None,parity='N',stopbits=1,rtscts=0) #Creating our serial object name
plt.ion() #Tell matplotlib you want interactive mode to plot live data
cnt=0
COM_read.flushInput()
COM_read.flushOutput()
def makeFig(): #Create a function that makes our desired plot

    plt.title('My Live Streaming Sensor Data')      #Plot the title
    plt.grid(True)                                  #Turn the grid on
    plt.ylabel('Acc in g')                          #Set ylabels
    plt.plot(Accelerometer, 'ro-', label='Accelerometer g') #plot the temperature
    plt.legend(loc='upper left')                    #plot the legend
    plt.ylim(15000,30000)                           #Set limits of second y axis- adjust to readings you are getting


print "came through"
while True: # While loop that loops forever
    print COM_read.inWaiting()
    while (COM_read.inWaiting()==0): #Wait here until there is data
            pass #do nothing
    s  = COM_read.readline() #read the line of text from the serial port
    decx = int(s[0:4],16)
    decy = int(s[5:9],16)
    decz = int(s[10:14],16)
    if decx > 32768:
          decx = decx - 65536;
    if decy > 32768:
         decy = decy - 65536;
    if decz > 32768:
         decz = decz - 65536;
    #print decx,decy,decz
    res = ((decx*decx) + (decy*decy) + (decz*decz))**(1.0/2.0)




    Accelerometer.append(res)                     #Build our Accelerometer array by appending temp readings

    drawnow(makeFig)                       #Call drawnow to update our live graph
    plt.pause(.000001)                     #Pause Briefly. Important to keep drawnow from crashing

    cnt=cnt+1
    if(cnt>50):                            #If you have 50 or more points, delete the first one from the array
        Accelerometer.pop(0)               #This allows us to just see the last 50 data points

> ----------------根据Dr.John的建议,代码编写如下-----

import serial
import matplotlib
import threading, time
import pylab
import matplotlib.pyplot as plt
import matplotlib.animation as anim

    class MAIN:
    #ser =0;
    def __init__(self):
        self.res = 0.0
        self.ser = serial.Serial('COM5', 9600, timeout=None,parity='N',stopbits=1,rtscts=0)
        self.ser.flushInput()
        elf.ser.flushOutput()
        c = self.ser.read(1);
        while(c != '\n'):
            =self.ser.read(1)
    return

    def acquire_data(self):
        s = self.ser.readline()
        decx = int(s[0:4],16)
        decy = int(s[5:9],16)
        decz = int(s[10:14],16)
        if decx > 32768:
            decx = decx - 65536;
        if decy > 32768:
            decy = decy - 65536;
        if decz > 32768:
            decz = decz - 65536;


    self.res = ((decx*decx) + (decy*decy) + (decz*decz))**(1.0/2.0)
    print self.res
    return

ex = MAIN()
threading.Timer(2,ex.acquire_data).start() #starts function acquire_data every 2 sec and resets self.res with 0.5Hz
fig, ax = plt.subplots()
ax.plot(time.time(), self.res, 'o-')
print "closed"

1 个答案:

答案 0 :(得分:1)

在大多数情况下,真正的循环是一个坏主意。

在大多数情况下,非OO编程是一个坏主意。

在大多数情况下(滞后),将绘图数据附加到列表是一个坏主意。

使用

在定义的时间开始数据采集
import threading, time
threading.Timer(2, acquire_data).start() #starts function acquire_data every 2 sec and resets self.res with 0.5Hz

然后代替while循环,请为自己的利益定义基于类的函数:

class MAIN:
 def __init__(self):
    self.res = 0

 def acquire_data(self):
    ....
    return self.res

并用

绘图
fig, ax = plt.subplots()
ax.plot(time.time(), self.res, 'o-')

迎接眼镜蛇博士