使用 python 的带有覆盆子的简单存在检测器

a trivial Presence detector with raspberry using python

我想使用 raspberry pi 构建一个存在检测器,以判断房间内是否有人。

到目前为止,原理非常简单和基本:我使用pir检测器来检测运动。在这第一步之后,我想使用一个 led(例如),如果房间满了,它会是红色的;如果房间空闲,它会是绿色的。我不知道在那之后我能做什么,但我想先成功。 使用网络,我编写了这个程序(有效):

import RPi.GPIO as GPIO
import time
import urllib

GPIO.setmode(GPIO.BCM)

GPIO_PIR = 7

GPIO.setup(GPIO_PIR,GPIO.IN)

Current_State  = 0
Previous_State = 0

try:
    print "Attente detection..."
    while GPIO.input(GPIO_PIR)==1:
        Current_State = 0
    print " Pret"

    while True :

        Current_State = GPIO.input(GPIO_PIR)

        if Current_State==1 and Previous_State==0:
            print " Mouvement detecte !"
            time.sleep(5)
            Previous_State=1
        elif Current_State==0 and Previous_State==1:
            print " Pret "
            Previous_State=0

            time.sleep(1)

except KeyboardInterrupt:
    print " Quit"
GPIO.cleanup()

我现在想做的是有一条包含房间状态的消息,所以这条消息可以是"room full"或"room empty"。

例如,如果检测到移动(终端将打印 "movement detected" 并在 5 秒后 "ready for detection"),则消息应为 "room full"。如果 10 秒后未检测到任何移动,消息将切换为 "room empty" 等

就是这样!我知道在 python 中做到这一点非常简单和基本(这不是覆盆子问题),但我并不真正熟悉 python 并且我不知道如何将它与所有人一起使用这个 "if" 和 "while" 的块。 你能帮我解决一下吗,谢谢

你太接近了!

让我们先跳到正确的地方。在您的第二个 while True 块中,您的代码已经 sleeps (等待)一个时间间隔 在继续之前。这是一些注释和格式更正:

while True:

    # this reads from your GPIO to set a variable
    Current_State = GPIO.input(GPIO_PIR)

    # if it detected motion or if there wasn't motion last time we checked..
    if Current_State==1 and Previous_State==0:
        print " Mouvement detecte !"

        # wait five seconds so we're not checking as fast as the cpu
        # will allow!
        time.sleep(5)
        Previous_State=1

    # this block has the same logic as above, but in reverse!
    elif Current_State==0 and Previous_State==1:
        # if we don't detect motion on gpio, print ready
        # this is where we need to keep track of how many times we didn't
        # detect motion.
        print " Pret "
        Previous_State=0

        time.sleep(1)

现在,让我们完成这项工作。您可能不想要第一个 while GPIO.input(GPIO_PIR)==1: 块,因为它只会阻塞线程,设置 Current_State,即使我们稍后重新定义它(这也可能会阻止您的程序到达实际While True: 完成我们工作的循环。

这是实现您想要的逻辑的清理版本的样子:

import RPi.GPIO as GPIO
import time
import urllib

GPIO.setmode(GPIO.BCM)
GPIO_PIR = 7
GPIO.setup(GPIO_PIR,GPIO.IN)

Previous_State = 0
Pret_Counter = 0
pret_message = None

try:
    # this will only print the first time.
    print "Attente detection..."

    # this loop will continuously run
    while True:

        Current_State = GPIO.input(GPIO_PIR)

        # if we have a message, print it!
        if pret_message:
            print pret_message

        if Current_State and Previous_State==0:
            print "Mouvement detecte!"
            time.sleep(5)
            Previous_State=1
            # Someone moved.  reset detection counter.
            Pret_Counter = 0

        elif Pret_Counter > 9:
            # if we've been empty for 10 seconds,
            # don't bother incrementing our counter
            pret_message = "Room empty"

        elif Current_State==0 and Previous_State:
            print "Pret"
            Pret_Counter += 1
            Previous_State=0
            time.sleep(1)

except KeyboardInterrupt:
    print "Quit"
GPIO.cleanup()

我手头没有 raspberry pi 来测试 GPIO 或 pir 检测器的行为,但这应该可以解决问题。

此外,您可能想稍微调整一下阈值——就像您现在的代码一样,您每 5 秒只检查一次运动。如果两次都没有检测到运动,则您将房间标记为空。我建议对你的新空逻辑使用类似的技巧——每 2 秒检查一次,也许 10 次(有时会议很无聊,人们会小睡一会儿),然后再决定它是空的。

作为旁注,您应该通过 Python 教程,例如官方 Python 2 version if you want to keep learning an old version, or the Python 3 版本来了解 Python 编程的当前状态。