如果在Pi中用于蜂鸣器系统的else语句

时间:2017-07-11 18:06:52

标签: python raspberry-pi

我为我的覆盆子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()

3 个答案:

答案 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语句作为可能的修复