使用超声波传感器检查距离的功能冻结tkin

2024-10-01 13:43:51 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试使用python和超声波传感器来测量距离,然后每秒用距离值更新一个tkinter标签。但是,我遇到了问题;它将运行一段时间,从几秒钟到几分钟,然后冻结。你知道吗

这是我的密码:

from tkinter import *
import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BCM)
GPIO_TRIGGER_X = 4
GPIO_ECHO_X = 27
GPIO.setup(GPIO_TRIGGER_X, GPIO.OUT)
GPIO.setup(GPIO_ECHO_X, GPIO.IN)

def distanceX():

    GPIO.output(GPIO_TRIGGER_X, True)
    time.sleep(0.0001)
    GPIO.output(GPIO_TRIGGER_X, False)

    StartTime = time.time()
    StopTime = time.time()

    while GPIO.input(GPIO_ECHO_X) == 0:
        StartTime = time.time()

    while GPIO.input(GPIO_ECHO_X) == 1:
        StopTime = time.time()

    TimeElapsed = StopTime - StartTime
    distance = (TimeElapsed * 34300) / 2

    return distance

def updateDistance():
        dX = distanceX()
        print(dX)
        lengthValue.configure(text=dX)
        root.after(1000, updateDistance)

root = Tk()

root.geometry("200x100")
root.tk_setPalette(background="white", foreground="black")

lengthName = Label(root, text = "Length:")
lengthValue = Label(root, text="start")

lengthName.grid(row=1, column=1)
lengthValue.grid(row=1, column=2)

updateDistance() 
root.mainloop()

我试过在单独的脚本中单独运行distanceX(),只是打印出值,效果很好。我还尝试过在没有distanceX()的情况下运行脚本,如下所示:

dX = 0

def updateDistance():
        global dX
        print(dX)
        lengthValue.configure(text=dX)
        dX += 1
        root.after(1000, updateDistance)

…这也很好。你知道吗

有什么想法吗? 如果我遗漏了任何需要的信息,请提前道歉,这是我第一次尝试python和tkinter。。。你知道吗


Tags: textimportechogpiotimetkinterdefroot
2条回答

Tkinter是单螺纹的。函数distanceX中的while循环阻塞主线程,直到它接收到一个真值并继续处理函数的其余部分。这就是为什么你会经历冰冻。你知道吗

尝试运行以下命令:

from tkinter import *
import time

root = Tk()
flag = True

def something():
    global flag
    while flag:
        print ("Hello World")
        time.sleep(1)

def set_flag():
    global flag
    flag = False

something()
root.after(2000,set_flag)
root.mainloop()

你会看到你的Tk窗口甚至不会弹出,因为While循环阻塞了主线程。你知道吗

要解决这个问题,需要执行distanceX()函数。比如:

from tkinter import *
import threading, time

root = Tk()
flag = True

def something():
    global flag
    while flag:
        print ("Hello world")
        time.sleep(1)

def set_flag():
    global flag
    flag = False

t = threading.Thread(target=something)
t.start()
root.after(2000,set_flag)
root.mainloop()

您可以在here中阅读更多关于线程的内容。你知道吗

原来问题实际上是distanceX()中的两个while循环。两个都加了一个超时,一切正常。工作代码:

from tkinter import *
import RPi.GPIO as GPIO
import threading, time

GPIO.setmode(GPIO.BCM)
GPIO_TRIGGER_X = 4
GPIO_ECHO_X = 27
GPIO.setup(GPIO_TRIGGER_X, GPIO.OUT)
GPIO.setup(GPIO_ECHO_X, GPIO.IN)

def distanceX():

    while True:
         timeout = time.time() + 0.1
         GPIO.output(GPIO_TRIGGER_X, True)
         time.sleep(0.0001)
         GPIO.output(GPIO_TRIGGER_X, False)

         StartTime = time.time()
         StopTime = time.time()

         while GPIO.input(GPIO_ECHO_X) == 0:
            StartTime = time.time()
            if time.time() > timeout:
                break

         while GPIO.input(GPIO_ECHO_X) == 1:
            StopTime = time.time()
            if time.time() > timeout:
                break

         TimeElapsed = StopTime - StartTime
         distance = (TimeElapsed * 34300) / 2

         print(distance)
         lengthValue.configure(text=distance)

         time.sleep(1)

def check():
    print("All good")


root = Tk()

root.geometry("200x100")
root.tk_setPalette(background="white", foreground="black")

lengthName = Label(root, text = "Length:")
lengthValue = Label(root, text="start")
button = Button(root, text="Check", command=check)

lengthName.grid(row=1, column=1)
lengthValue.grid(row=1, column=2)
button.grid(row=2, column=1)

t1 = threading.Thread(target=distanceX)
t1.start()
root.mainloop()

相关问题 更多 >