2016-03-13 50 views
0

我正在開發一個python代碼,我的計算機正在使用串行通信讀取正在傳輸的數據,我的程序以圖形格式顯示了這些數據。在更新圖表後每0.1秒收到一次新數據。在Tkinter GUI中使用動畫圖形python

的代碼是:

import matplotlib 
matplotlib.use("TkAgg") 
from matplotlib import * 
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg 
from matplotlib.figure import Figure 
import matplotlib.animation as animation 
from random import * 
from Serial import * 
import Tkinter as tk 
import ttk 
import xlwt 
import serial 

COMPORT = "COM7" 
BUAD = 115200 

def init(): 
    connected = False 
    global ser 
    global COMPORT, BUAD 
    ser = serial.Serial(COMPORT, BUAD) 
    while not connected: 
     serin = ser.read() 
     connected = True 

def TransmitCommand(Command): 
    SCommand = Command + 'y' 
    ser.write(SCommand) 

def TransmitData(Data): 
    SData = str(Data) + 'y' 
    ser.write(SData) 

def ClosePort(): 
    ser.close() 

def RecieveData(): 
    return ser.readline() 


################################################################################ 
############################ Graph1 ####################################### 
################################################################################ 
F1 = Figure(figsize=(15,8), dpi=80) 
rc("font", size = 10) 
Figure 
a1 = F1.add_subplot(111) 
tList = [] 
xList = [] 
yList = [] 
zList = [] 
fList = [] 
xfList = [] 
yfList = [] 
zfList = [] 
fxList = [] 
fyList = [] 
fzList = [] 
t = 0.00 
t1 = 0 
x = 0 
y = 0 
z = 0 
ex = 0 
ey = 0 
ez = 0 
r1 = 0 
r2 = 0 
r3 = 0 
l = 0 
txp = 0 
typ = 0 
tzp = 0 
global fx1, fy1, fz1 
fx1 = 0.00000 
fy1 = 0.00000 
fz1 = 0.00000 

PPS1 = 1 

def Play1(): 
    global PPS1 
    TransmitCommand('SendData') 
    #print 'Done' 
    PPS1 = 0 
def Pause1(): 
    global PPS1 
    TransmitCommand('StopData') 
    PPS1 = 1 
def Stop1(): 
    global PPS1 
    TransmitCommand('StopData') 
    PPS1 = 2 
def Extract1(): 
    pass 
def Save1(): 
    pass 


def SaveGraph1(): 
    pass 

def animate1(i): 
    global l, ex, ey, ez, t, x, y, z, tList, xList, yList, zList, r1, r2, r3 
    global fx1, fy1, fz1, txp, typ, tzp, xt, yt, zt 

    if(PPS1 == 0): 
     tList.append(t) 
     xList.append(x) 
     yList.append(y) 
     zList.append(z) 

     t = int(RecieveData()) 
     x = int(RecieveData()) 
     if(l == 0): 
      x = (x*0.707)/300 
     else: 
      x = ex - (x*0.707)/300 
     if(x > 0): 
      if(xList[l-1] == 0)|(xList[l-1] < 0): 
       fx1 = (1.0/(t - txp))*1000 
       txp = t 
       r1 = 1 
     y = int(RecieveData()) 
     if(l == 0): 
      y = (y*0.707)/300 
     else: 
      y = ey - (y*0.707)/300 
     if(y > 0): 
      if(yList[l-1] == 0)|(yList[l-1] < 0): 
       fy1 = (1.0/(t - typ))*1000 
       typ = t 
       r2 = 1 
     z = int(RecieveData()) 
     if(l == 0): 
      z = (z*0.707)/300 
     else: 
      z = ez - (z*0.707)/300 
     if(z > 0): 
      if(zList[l-1] == 0)|(zList[l-1] < 0): 
       fz1 = (1.0/(t - tzp))*1000 
       tzp = t 
       r3 = 1 

     if(l == 0): 
      ex = x 
      ey = y 
      ez = z 

     l = l+1 

    if(PPS1 == 2):  
     tList = [] 
     xList = [] 
     yList = [] 
     zList = [] 
     t = 0 
     x = 0 
     y = 0 
     z = 0  

    a1.clear() 
    a1.plot(tList, xList, label = "ax") 
    a1.plot(tList, yList, 'r', label = "ay") 
    a1.plot(tList, zList, 'g', label = "az") 
    a1.set_ylim(-1,1) 
    a1.set_xlabel("Time (ms)") 
    a1.set_ylabel("Acceleration (g)") 
    a1.legend() 

def GenerateGraph1(Master): 
    dataPlot = FigureCanvasTkAgg(F1, master=Master) 
    dataPlot.show() 
    dataPlot.get_tk_widget() 

    display1 = tk.Canvas(Master, width=100, height=400, bg ="white") 
    display1.pack(side = 'right') 
    button1 = tk.Button(display1, text='Play', command=Play1, font='Times 12', bd=5, 
           height = 2, width = 10, anchor = 'w').grid(row = 0, column = 0) 
    button2 = tk.Button(display1, text='Pause', command=Pause1, font='Times 12', bd=5, 
           height = 2, width = 10, anchor = 'w').grid(row = 1, column = 0) 
    button3 = tk.Button(display1, text='Stop', command=Stop1, font='Times 12', bd=5, 
           height = 2, width = 10, anchor = 'w').grid(row = 2, column = 0) 
    button4 = tk.Button(display1, text='Extract Data', command=Extract1, font='Times 12', bd=5, 
           height = 2, width = 10, anchor = 'w').grid(row = 3, column = 0) 
    button5 = tk.Button(display1, text='Save Data', command=Save1, font='Times 12', bd=5, 
           height = 2, width = 10, anchor = 'w').grid(row = 4, column = 0) 
    button5 = tk.Button(display1, text='Save Graph', command=SaveGraph1, font='Times 12', bd=5, 
           height = 2, width = 10, anchor = 'w').grid(row = 5, column = 0) 
    button5 = tk.Button(display1, text='Send Mail', command=Save1, font='Times 12', bd=5, 
           height = 2, width = 10, anchor = 'w').grid(row = 6, column = 0) 
    toolbar = NavigationToolbar2TkAgg(dataPlot, Master) 
    toolbar.update() 
    dataPlot._tkcanvas.pack() 

def show_frame(): 
    frame = GenerateGraph(Graph) 
    frame.tkraise() 

Main = tk.Tk() 
init() 
n = ttk.Notebook(Main, width= 800, height = 400) 
n.grid(row=6,column=0, columnspan=9) 
n.columnconfigure(0, weight=1) 
n.rowconfigure(6, weight=1)  

f1 = ttk.Frame(n); 
n.add(f1, text='Acceleration vs Time') 
GenerateGraph1(f1) 
ani1 = animation.FuncAnimation(F1, animate1, interval=100) 
mainloop() 

Arduino的代碼是:

int toggle1 = 0; 
boolean Graph = 0; 
int x = 0; 
int y = 0; 
int z = 0; 
int i = 0; 

const int groundpin = 18;    // analog input pin 4 -- ground 
const int powerpin = 19;    // analog input pin 5 -- voltage 
const int xpin = A3;     // x-axis of the accelerometer 
const int ypin = A2;     // y-axis 
const int zpin = A1;     // z-axis (only on 3-axis models) 

#include <elapsedMillis.h> 
elapsedMillis timeElapsed; 

void Acceleration(){ 
    Serial.print(timeElapsed); 
    Serial.print("\n"); 
    Serial.print(analogRead(xpin)); 
    Serial.print("\n"); 
    Serial.print(analogRead(ypin)); 
    Serial.print("\n"); 
    Serial.print(analogRead(zpin)); 
    Serial.print("\n"); 
    } 

void setup() 
{ 
    Serial.begin(115200); 
    pinMode(8, OUTPUT); 
    pinMode(9, OUTPUT); 
    pinMode(xpin, INPUT); 
    pinMode(ypin, INPUT); 
    pinMode(zpin, INPUT); 
    Serial.write('1'); 

    noInterrupts();   // disable all interrupts 
    TCCR1A = 0; 
    TCCR1B = 0; 
    TCNT1 = 0; 

    OCR1A = 25000;   // compare match register 16MHz/64/10Hz 
    TCCR1B |= (1 << WGM12); // CTC mode 
    TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt 
    interrupts();    // enable all interrupts 
    TCCR1B |= (1 << CS10); 
    TCCR1B |= (1 << CS11); 

    pinMode(groundpin, OUTPUT); 
    pinMode(powerpin, OUTPUT); 
    digitalWrite(groundpin, LOW); 
    digitalWrite(powerpin, HIGH); 
} 

ISR(TIMER1_COMPA_vect){ 
    if(Graph == 1){ 
    Acceleration(); 
}} 

void loop() { 
    String brightness, recieve, r1; 
    int b1, b2, ledPin; 

    while(Serial.available() == 0) {} 
    recieve = Serial.readStringUntil('y'); 
    r1 = recieve + "t"; 
    if(recieve == "SendData"){Graph = 1;} 
    if(recieve == "StopData"){Graph = 0;timeElapsed = 0;} 
    if(recieve == "motor1"){ 
    ledPin = 8; 
    while(Serial.available() == 0){} 
    brightness = Serial.readStringUntil('y'); 
    b1 = brightness.toInt(); 
    analogWrite(ledPin, b1);} 
    if(recieve == "motor2"){ 
    ledPin = 9; 
    while(Serial.available() == 0){} 
    brightness = Serial.readStringUntil('y'); 
    b1 = brightness.toInt(); 
    analogWrite(ledPin, b1);} 
    } 
    } 

我從振動傳感器採集數據。我使用秒錶來計算振動實際開始的時間與圖表開始顯示數據變化的時間之間的差異。對於第一組數據,時差爲5秒,對於數據組2,差值爲1分10秒,對於第三組爲2分鐘。效果變得更加明顯,因爲我添加了第二張圖和我的其餘GUI。我需要這個軟件能夠運行幾個小時,這意味着我的GUI可能無法響應,而且我也需要這些數據是實時的。造成這種情況的原因是什麼?如何解決?在圖形用戶界面中顯示實時數據可能有更好的方式,因爲我是python的新手,我不知道。

+0

這裏有太多的代碼。一般來說動畫你應該更新現有的藝術家,而不是每次都創建新的藝術家。你可能想用cap deques而不是列表。 – tacaswell

回答

0

這個簡單的動畫示例將每秒繪製一個新的紅點,該方法應該比您所做的更穩定;我已經運行4個月以上的應用程序,地塊曾這樣一分鐘:

import matplotlib.pyplot as plt 
import random 
import time 
plt.ion() 

x = 0 
while x<100: 
    y = random.random() 
    plt.plot(x,y,marker='.',c='red') 
    x+=1 
    time.sleep(1) 
    plt.tight_layout() 
    plt.show() 
    plt.pause(0.1) 

你說你需要它是「實時」的,但它可能是你的代碼的執行時間服用比獲得新數據的0.1秒更長。每10個數據點更新圖表可能是最好的;或者我正在做...每分鐘一次。