使用 python-tkinter 和 arduino 的监控和数据采集系统

问题描述 投票:0回答:1

我是一名山羊奶酪生产商,我想实现奶酪制作车间的一些流程自动化。

例如,获取房间内的温度和湿度,并在湿度超过预定值时打开抽气机。

或者例如对奶罐内的温度应用加热斜坡...

我希望所有这些命令都在面板上,类似于labview。

我将使用 arduino 和 python。

我需要 tkinter 的一些帮助,并专门设计和界面,当用户按下按钮时启动温度采集,并在再次按下按钮时停止采集。

我的arduino软件没有问题,当“51”发送到arduino时,它返回值tdsT,tds是一个字符串,T是温度值。

我写了一个 python 脚本,无需 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)

然后我尝试在 tkinter GUI 中实现此代码,但经过几次尝试后我无法编码来获得我想要的东西:

#####################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()

此脚本显示一个 GUI,我点击按钮,温度被获取并显示在我的 Ubuntu 控制台中,但 GUI 陷入无限循环(while 1: ....),我无法再次点击按钮阻止它。

我对 tkinter 结构有疑问,你能帮我吗?

提前谢谢您

python tkinter arduino
1个回答
0
投票

你有

while is_on:
,但是,
is_on
永远不会在循环中设置为
False
,并且由于你阻塞了主GUI线程,即使再次按下按钮也不会起作用,因为它被阻塞了。

您可以使用

after
来运行函数,而不会阻塞主 GUI。但由于您在设置温度时不修改 GUI,因此可以使用线程。

# Thread function to set the tds. Runs in the background.
def set_tds():
    while is_on:
        arduino.write(bytes('51','utf-8'))
        Data = Lecture()
        if Data[0:3] == "tds":
            # Success. Just print and done
            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()

这里的主要问题是线程在

sleep
期间被阻塞了 10 秒。因此,在睡眠结束之前,它不会查看您是否设置了
is_on = False
。您可以使用 and event 代替 sleep:Python time.sleep() vs event.wait()

© www.soinside.com 2019 - 2024. All rights reserved.