I am a goat cheese producer and I would like to automatize some process in the cheese making workshop.
for example acquiring temperature and humidity in a room and turning on an air extractor if the humidity climb over a predefined value.
or for example apply an heating ramp to the temperature inside the milk tank…
I would like all these command on a panel, similar to labview.
I will work with an arduino and python.
I need some help with tkinter and specifically designing and interface that start a temperature acquisition when the user press a button and stop the acquisition if the button is pressed again.
There is no trouble in my arduino software, when “51” is sent to the arduino, it returns the value tdsT were tds is a string and T the value of the temperature.
I wrote a python script that do the job without the GUI :
#####################IMPORT##############################
import serial
import time
arduino = serial.Serial(port ='/dev/ttyACM0',baudrate = 9600, timeout = .1)
def Lecture():#def de update GUI
time.sleep(1)
data = arduino.readline()
data = data.decode('utf-8')
return data
while 1:
arduino.write(bytes('51','utf-8'))
time.sleep(1)
Data = Lecture()
# print(Data)
while Data[0:3]!="tds":
arduino.write(bytes('51','utf-8'))
time.sleep(0.5)
Data = Lecture()
Data = float(Data[3:8])
print(Data)
Then I tried to Implement this code in a tkinter GUI but after several attempts I could not code to obtain what I wanted :
#####################IMPORT##############################
from tkinter import *
import serial
import time
import threading
#####################Initialisation##############################
arduino = serial.Serial(port ='/dev/ttyACM0',baudrate = 9600, timeout = .1)
incrTemps = 10#secondes
#####################Initialisation#######
global is_on
#temp
is_on = False
#####################interface##############################
root = Tk()
#####################fonctions##############################
def Lecture():#def de update GUI
time.sleep(1)
data = arduino.readline()
data = data.decode('utf-8')
return data
def Switch():
global is_on
if is_on:
button.config(image = off)
is_on = False
else:
button.config(image = on)
is_on = True
while is_on:
arduino.write(bytes('51','utf-8'))
time.sleep(incrTemps)
Data = Lecture()
while Data[0:3]!="tds":
arduino.write(bytes('51','utf-8'))
time.sleep(0.5)
Data = Lecture()
Data = float(Data[3:8])
print(Data)
#####################boutons##############################
on = PhotoImage(file = "switch-on.png")
off = PhotoImage(file = "switch-off.png")
button = Button(root, image = on, bd = 0,command = Switch)
button.pack(pady = 50)
root.mainloop()
This script display a GUI, I clik on the button, the temperature is acquired and displayed in my Ubuntu console but the GUI is stuck in the infinite loop (while 1: ….) and I can not clik again on the button to stop it.
I have a problem with the tkinter structure, can you help me please.
Thank you per advance
0
You have while is_on:
but, is_on
never gets set to False
in the loop and since you are blocking the main GUI thread, even pressing the button again won’t work because it is blocked.
You can use after
to run a function without blocking the main GUI. But since you don’t modify the GUI while you are setting the temp, you can use a thread.
# Thread function to set the tds. Runs in the background.
def set_tds():
# Loop until is_on is set to False by the button press.
while is_on:
arduino.write(bytes('51','utf-8'))
Data = Lecture()
if Data[0:3] == "tds":
# Success. Just print.
print(Data)
time.sleep(incrTemps)
thread = None
def Switch():
global is_on
if is_on:
button.config(image = off)
is_on = False
else:
button.config(image = on)
is_on = True
# Start the thread.
thread = Thread(target = set_tds)
thread.start() # Does not block
The main issue here, is that the thread is blocked for 10 seconds during sleep
. So, it won’t see if you set is_on = False
until the sleep is over. You can use an event instead of sleep
: Python time.sleep() vs event.wait()
1