22

我使用 Raspberry Pi 上的 GPIO 引脚和 PIR 传感器来检测运动。当传感器检测到运动时,我想将软件移动到其他功能上。

目前,为了检测运动,我的程序在等待检测运动时不断循环运行。虽然这目前有效,但对于将来的使用来说,这将是非常低效的,我希望通过将其分配给一个事件来改进这一点。

有什么方法可以将我的 GPIO 输入绑定到程序检测到的事件,而无需手动运行循环。

这是我当前用于检测运动的循环:

var = 1
counter = 0
while var == 1:
    if GPIO.input(7):
        counter += 1
        time.sleep(0.5)
    else:
        counter = 0
        time.sleep(1)

    if counter >= 3:
        print "Movement!"
        captureImage()
        time.sleep(20)

计数器和多次检测运动用于减少传感器拾取的误报数量。

4

4 回答 4

34

RPi.GPIO Python 库现在支持事件,这在中断和边缘检测段落中进行了说明。

因此,在更新您的 Raspberry Pisudo rpi-update以获得最新版本的库后,您可以将代码更改为:

from time import sleep
import RPi.GPIO as GPIO

var=1
counter = 0

GPIO.setmode(GPIO.BOARD)
GPIO.setup(7, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

def my_callback(channel):
    if var == 1:
        sleep(1.5)  # confirm the movement by waiting 1.5 sec 
        if GPIO.input(7): # and check again the input
            print("Movement!")
            captureImage()

            # stop detection for 20 sec
            GPIO.remove_event_detect(7)
            sleep(20)
            GPIO.add_event_detect(7, GPIO.RISING, callback=my_callback, bouncetime=300)

GPIO.add_event_detect(7, GPIO.RISING, callback=my_callback, bouncetime=300)

# you can continue doing other stuff here
while True:
    pass

我选择了Threaded 回调方法,因为我认为您的程序会并行执行一些其他操作来更改var.

于 2013-09-03T15:29:17.980 回答
3

现在 RPi GPIO 库具有内置的中断驱动 GPIO 控制,可以在单独的线程中释放资源。您可能希望阅读以下http://raspi.tv/2013/how-to-use-interrupts-with-python-on-the-raspberry-pi-and-rpi-gpio-part-3

于 2013-06-04T13:59:27.647 回答
1

您可以将 GPIO 代码包装到它自己的线程中,并让程序的其余部分在 GPIO 等待输入时执行其他操作。查看线程模块

首先,我将您的代码包装成一个函数

def wait_input():
    var=1
    counter = 0
    while var == 1:
        if GPIO.input(7):
            counter += 1
        time.sleep(0.5)
        else:
            counter = 0
            time.sleep(1)
        if counter >= 3:
            print "Movement!"
            captureImage()
            time.sleep(20)

然后在你的主程序中你可以这样

input_thread = threading.Thread(target = wait_input)
input_thread.start()
# do something in the meanwhile
input_thread.join()

关于 python 线程的 SO 有很多问题,所以你可能想挖掘它们。请注意,在使用线程时还需要考虑很多事情,尤其是在具有全局解释器锁 (GIL) 的 python 中,它一次只允许一个进程运行。查看可以在 GIL 周围路由的多处理模块也可能是明智的。

于 2013-04-22T09:44:54.753 回答
0

kapcom01 提供了一些很棒的想法,但最好不要在中断中做很多指令。

通常在调用回调时将标志设置为 1,然后在主函数中进行处理。以这种方式,没有释放程序的风险。

像这样的东西:

     from time import sleep
     import RPi.GPIO as GPIO



     def init():
         # make all your initialization here
         flag_callback = False
         # add an interrupt on pin number 7 on rising edge
         GPIO.add_event_detect(7, GPIO.RISING, callback=my_callback, bouncetime=300)


     def my_callback():
         # callback = function which call when a signal rising edge on pin 7
         flag_callback = True


     def process_callback():
         # TODO: make process here
         print('something')


     if __name__ == '__main__':
     # your main function here

     # 1- first call init function
     init()

     # 2- looping infinitely 
     while True:
         #3- test if a callback happen
         if flag_callback is True:
             #4- call a particular function
             process_callback()
             #5- reset flagfor next interrupt
             flag_callback = False
    pass
于 2018-10-03T08:15:23.087 回答