首页 > 解决方案 > tkinter GUI 在绘制 Arduino 的电压时冻结

问题描述

我只是想写一个 GUI 来帮助我测量。现在,我希望能够从我的 Arduino UNO 实时绘制 - 例如 - 电压。可悲的是,这段代码可以正常工作大约 5 秒,之后 tkinter 窗口冻结。令人惊讶的是 v 和 t 列表有效。你能给我一个提示来解决这个问题吗?我只是花几个小时。

from pyfirmata import Arduino, util
import matplotlib
matplotlib.use('TkAgg')
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
from tkinter import *
import time
import threading

board=Arduino('COM3')
iterator = util.Iterator(board)
iterator.start()
Tvl = board.get_pin('a:0:i')

class mclass(threading.Thread):
    def __init__(self,  window):
        threading.Thread.__init__(self)
        self.window = window
        self.box = Entry(window)
        self.button = Button (window, text="check", command=self.plot)
        self.box.pack ()
        self.button.pack()
        self.t=[]
        self.v=[]
        self.fig = Figure(figsize=(6,6))
        self.a = self.fig.add_subplot(111)
        self.a.invert_yaxis()
        self.a.set_title ("Estimation Grid", fontsize=16)
        self.a.set_ylabel("Y", fontsize=14)
        self.a.set_xlabel("X", fontsize=14)

        self.canvas = FigureCanvasTkAgg(self.fig, master=self.window)
        self.canvas.get_tk_widget().pack(side=BOTTOM, fill=BOTH, expand=False)


    def plot (self):
        global t,v
        clock=time.perf_counter()
        while time.perf_counter()-clock<=float(self.box.get()):
            self.v.append(Tvl.read())
            self.t.append(time.perf_counter()-clock)
            if len(self.v)>=25:
                del self.v[0]
                del self.t[0]
            self.a.clear()
            self.a.plot(self.t,self.v)
            self.canvas.draw()


window= Tk()
t= mclass(window)
t.start()
window.mainloop()

标签: user-interfacetkinterplotarduino

解决方案


我感谢您的意见。最后 patthoyts 提示效果很好。我会很感兴趣为什么在这种情况下while循环不起作用。

在新的稳定代码之下,添加了更多功能。

谢谢和问候彼得鲁多

from pyfirmata import Arduino, util
import matplotlib
matplotlib.use('TkAgg')
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
from tkinter import *
import time
import threading

board=Arduino('COM3')
iterator = util.Iterator(board)
iterator.start()
Tvl = board.get_pin('a:0:i')

class mclass(threading.Thread):
    def __init__(self,  window):
        threading.Thread.__init__(self)
        self.window = window
        self.box = Entry(window)
        self.box.pack ()
        self.button = Button (window, text="check", command=self.plot)
        self.button.pack()
        self.button2 = Button(window,text="stop", command=self.start_stop)
        self.button2.pack()
        self.w=Scale(window, from_=0, to=10000)
        self.w.pack()
        self.w2=Scale(window, from_=0, to=100000)
        self.w2.pack()
        self.t=[]
        self.v=[]
        self.ss=True
        self.fig = Figure(figsize=(6,6))
        self.a = self.fig.add_subplot(111)
        self.a.invert_yaxis()
        self.a.set_title ("Estimation Grid", fontsize=16)
        self.a.set_ylabel("Y", fontsize=14)
        self.a.set_xlabel("X", fontsize=14)
        self.canvas = FigureCanvasTkAgg(self.fig, master=self.window)
        self.canvas.get_tk_widget().pack(side=BOTTOM, fill=BOTH, expand=False)


    def plot (self):
        window.after(10, self.plot)
        if self.ss==True:
            self.v.append(Tvl.read())
            self.t.append(time.perf_counter())
            if self.t[0]<self.t[len(self.t)-1]-0.0001*self.w2.get():
                del self.v[0]
                del self.t[0]
            self.a.clear()
                self.a.set_ylim(Tvl.read()-0.0001*self.w.get(),Tvl.read()+0.0001*self.w.get())
            self.a.set_xlim(self.t[len(self.t)-1]-0.001*self.w2.get()+1,time.perf_counter())
            self.a.plot(self.t,self.v)
            self.canvas.draw()

    def start_stop(self):
        if self.ss==True:
            self.ss=False
        else:
            self.ss=True




window= Tk()
t= mclass(window)
t.start()
window.mainloop() 

推荐阅读