i'm trying to do simple GUI for reflow oven controller. The GUI samples temperature every 1s (now it get it from random function, eventually from arduino). But now every 1s the ram usage increase by aprox 3.5 mb - i guess it something to do with matplot animation, and that its only drawing new images on top of old ones (lines 103- 115) but how to solve this? It runs aprox 385 sec then:
C:\Users\veeti\PycharmProjects\Reflow\venv\Scripts\python.exe C:/Users/veeti/PycharmProjects/Reflow/Main.py Exception in Tkinter callback Traceback (most recent call last): File "C:\Program Files (x86)\python37\lib\tkinter__init__.py", line 1705, in call return self.func(*args) File "C:\Program Files (x86)\python37\lib\tkinter__init__.py", line 749, in callit func(*args) File "C:\Users\veeti\PycharmProjects\Reflow\venv\lib\site-packages\matplotlib\backends_backend_tk.py", line 118, in _on_timer TimerBase._on_timer(self) File "C:\Users\veeti\PycharmProjects\Reflow\venv\lib\site-packages\matplotlib\backend_bases.py", line 1194, in _on_timer ret = func(*args, **kwargs) File "C:\Users\veeti\PycharmProjects\Reflow\venv\lib\site-packages\matplotlib\animation.py", line 1447, in _step still_going = Animation._step(self, *args) File "C:\Users\veeti\PycharmProjects\Reflow\venv\lib\site-packages\matplotlib\animation.py", line 1173, in _step self._draw_next_frame(framedata, self._blit) File "C:\Users\veeti\PycharmProjects\Reflow\venv\lib\site-packages\matplotlib\animation.py", line 1192, in _draw_next_frame self._draw_frame(framedata) File "C:\Users\veeti\PycharmProjects\Reflow\venv\lib\site-packages\matplotlib\animation.py", line 1755, in _draw_frame self._drawn_artists = self._func(framedata, self._args) File "C:/Users/veeti/PycharmProjects/Reflow/Main.py", line 115, in animate canvas.draw() File "C:\Users\veeti\PycharmProjects\Reflow\venv\lib\site-packages\matplotlib\backends\backend_tkagg.py", line 9, in draw super(FigureCanvasTkAgg, self).draw() File "C:\Users\veeti\PycharmProjects\Reflow\venv\lib\site-packages\matplotlib\backends\backend_agg.py", line 386, in draw self.renderer = self.get_renderer(cleared=True) File "C:\Users\veeti\PycharmProjects\Reflow\venv\lib\site-packages\matplotlib\backends\backend_agg.py", line 399, in get_renderer self.renderer = RendererAgg(w, h, self.figure.dpi) File "C:\Users\veeti\PycharmProjects\Reflow\venv\lib\site-packages\matplotlib\backends\backend_agg.py", line 86, in init self._renderer = _RendererAgg(int(width), int(height), dpi) MemoryError: In RendererAgg: Out of memory
also the animation wont turn on without line 124 command "animate(1)" - why so?
import tkinter
import matplotlib.pyplot as plt
import random
import matplotlib.animation as animation
from matplotlib.backends.backend_tkagg import (
FigureCanvasTkAgg)
def exitHandler():
print("at exit handler")
ani.event_source.stop()
root.destroy()
def startButtonClick():
print("start")
def stopButtonClick():
print("stop")
def readTemperature():
return random.randint(0,250)
def updateTimeLabel(time = -99):
timeLabel.config(text= "Time: {}".format (time))
def updateTargetTempLabel(temp = -99) :
targetTempLabel.config(text="Target temp: \n {} ".format (temp))
def updateCurrentTempLabel(temp = -99) :
currentTempLabel.config(text="Current temp: \n {} ".format (temp))
def updateHeaterStatus(temp,target):
if (temp < target):
heaterStatusLabel.config(text="Heater: \n On")
else:
heaterStatusLabel.config(text="Heater: \n Off")
def calculateTarget(time):
global timePoints, tempQuidance, targetTemp
#find current slope and calculate the target temp
for i in range (len(timePoints)):
if (timePoints[i] < time < timePoints[i+1]):
slope = (tempQuidance[i+1] - tempQuidance[i]) / (timePoints[i+1] -timePoints[i])
currentTarget = (time -timePoints[i]) * slope + tempQuidance[i]
return (currentTarget)
def animate(i):
global timePoints,tempQuidance,numberOfPoints,measuredTemp, time
time = time+1
measuredTemp.append(readTemperature())
numberOfPoints.append(len(measuredTemp))
ax.clear()
ax.plot(timePoints,tempQuidance)
ax.plot(numberOfPoints,measuredTemp)
updateTimeLabel(time)
updateTargetTempLabel(calculateTarget(time))
updateCurrentTempLabel(measuredTemp[-1])
updateHeaterStatus(measuredTemp[-1], 100)
canvas = FigureCanvasTkAgg(fig,plotFrame)
canvas.draw()
canvas.get_tk_widget().grid(row=3,column=0,columnspan = 4)
global measuredTemp, numberOfPoints, time, targetTemp
time = 0
measuredTemp=[]
numberOfPoints=[]
targetTemp = 0
#temperature profile
timePoints = [0,300,400,460,500]
tempQuidance =[0,150,150,250,0]
root=tkinter.Tk()
root.title('Reflow oven controller')
root.geometry("1600x800")
controlFrame = tkinter.LabelFrame(root,width = 500, height = 800, borderwidth = 3, padx=5,pady=5)
plotFrame = tkinter.LabelFrame(root,padx=5,pady=5)
controlFrame.grid(row = 0, column = 0 )
controlFrame.grid_propagate(0)
plotFrame.grid(row = 0, column= 1)
timeLabel=tkinter.Label(plotFrame,text = "Time: ")
targetTempLabel = tkinter.Label(plotFrame,text = "Target temp")
currentTempLabel = tkinter.Label(plotFrame,text = "Current temp")
heaterStatusLabel = tkinter.Label(plotFrame,text = "Heater status: \n unknown")
timeLabel.grid(row= 0, column=0)
targetTempLabel.grid(row=0, column= 1)
currentTempLabel.grid(row=0, column= 2)
heaterStatusLabel.grid(row = 0, column = 3)
fig=plt.figure()
ax = fig.add_subplot(1, 1, 1)
startButton = tkinter.Button(controlFrame, text = "Start", command = startButtonClick)
stopButton = tkinter.Button(controlFrame, text="Stop", command = stopButtonClick)
startButton.grid(row = 0,column = 0)
stopButton.grid(row = 0 ,column= 1 )
animate(1)
ani = animation.FuncAnimation(fig, animate, interval=1000) #run animation every 1s, animate func takes care of getting new values and GUI update
root.protocol("WM_DELETE_WINDOW", exitHandler)
root.mainloop()
thx in advance