我为我的覆盆子pi制作了一个蜂鸣器程序。我希望程序是为了安全:如果我的门打开时间过长(我的门有一个磁传感器),蜂鸣器会发出嗡嗡声。一旦门关闭,蜂鸣器就会停止。但是,我注意到蜂鸣器在蜂鸣器响起之前有一段延迟(time.sleep(10))。似乎我的代码在它停止之前循环if语句。我希望我的蜂鸣器在门关闭后立即停止。有人可以帮我解决我的代码吗?
import time
import RPi.GPIO as gpio
buzzer = 11
door = 3
gpio.setmode(gpio.BOARD)
gpio.setwarnings(False)
gpio.setup(buzzer, gpio.OUT)
gpio.setup(door, gpio.IN, pull_up_down=gpio.PUD_UP)
while True:
if gpio.output(door):
time.sleep(10)
gpio.output(buzzer, True)
else:
gpio.output(buzzer, False)
gpio.cleanup()
答案 0 :(得分:3)
如果你想要一个相当简单的答案,最好让一些跟踪器每秒更新一次。
seconds_open = 0
while True:
if gpio.output(door):
seconds_open += 1
if seconds_open == 10:
gpio.output(buzzer, True)
else:
gpio.output(buzzer, False)
seconds_open = 0
time.sleep(1)
注意:关闭门时,蜂鸣器将在第二个标记处关闭,因此可能会稍微延迟。您可以通过更改睡眠的增量和持续时间来提高准确性。或者您可以使用线程来使用Gyppo的答案。编辑:Gyppo指出,如果您决定使用浮点睡眠/计数器,您需要将if语句更改为:
if seconds_open >= 10:
答案 1 :(得分:1)
我不认为sleep
声明正在做你想要的。此刻,一旦你打开门,sleep
计时器开始,10秒后蜂鸣器开火(即使你已关门)。 Python逐行遍历您的代码,并且不会进展到gpio.output(buzzer, True)
(然后回到循环的开始),直到它等待10秒。在那个10s期间,Python没有做任何其他事情,sleep
是一个'阻塞'功能。
可能值得研究threading,其中有一个名为Timer
的“非阻塞”睡眠。你可以有像
while True:
if door_is_open:
Timer(10.0, buzz_if_still_open).start()
你还得到了:
def buzz_if_still_open():
if door_is_still_open:
buzz()
使用threading
的{{1}},Python将继续愉快地继续围绕主Timer
循环,并且函数while True
将在10秒后运行。
(如果您快速关上门然后将其打开,此代码仍然会响起,修复后留给读者练习:P)
答案 2 :(得分:1)
您可以尝试使用多个while
循环:
while True:
if gpio.output(door):
time.sleep(10)
if gpio.output(door):
gpio.output(buzzer, True)
while True:
if not gpio.output(door):
gpio.output(buzzer, False)
break
else:
gpio.output(buzzer, False)
else:
gpio.output(buzzer, False)
这通过测试门是否打开等待10秒来起作用。如果它仍然打开,蜂鸣器会熄灭,然后它会进入一个循环,直到门关闭,它会从环路中断开。
编辑:
添加了else
语句作为可能的修复