Raspberry Pi-Python 中的 GPIO 事件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16143842/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Raspberry Pi- GPIO Events in Python
提问by Stefoth
I am using the GPIO pins on my Raspberry Pi with a PIR sensor to detect motion. When the sensor detects motion I want to then move the software onto other functions.
我使用 Raspberry Pi 上的 GPIO 引脚和 PIR 传感器来检测运动。当传感器检测到运动时,我想将软件移动到其他功能上。
At the moment, to detect motion I have my program constantly running in a loop while it is waiting for motion to be detected. While this works at the moment, for use in the future this will be incredibly inefficient and am hoping to improve on this by assigning it to an event.
目前,为了检测运动,我让我的程序在等待检测运动时不断循环运行。虽然这目前有效,但为了将来使用,这将非常低效,我希望通过将其分配给事件来改进这一点。
Is there any way to bind my GPIO input to an event that is detected by the program without manually running a loop.
有什么方法可以将我的 GPIO 输入绑定到程序检测到的事件,而无需手动运行循环。
Here is my current loop for detection motion:
这是我当前用于检测运动的循环:
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)
The counter and detecting motion multiple times is used to reduce the number of false positives that the sensor picks up.
计数器和多次检测运动用于减少传感器拾取的误报数量。
回答by msvalkon
You could wrap the GPIO-code into it's own thread and have the rest of your program do something else while the GPIO is waiting for input. Check out the threading module
您可以将 GPIO 代码包装到它自己的线程中,并在 GPIO 等待输入时让程序的其余部分做其他事情。查看线程模块
First I'd wrap your code into a function
首先,我将您的代码包装成一个函数
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)
And then in your main program you could something like this
然后在你的主程序中你可以像这样
input_thread = threading.Thread(target = wait_input)
input_thread.start()
# do something in the meanwhile
input_thread.join()
There are plenty of questions on SO concerning python threading, so you might want to dig them up. Please note that there are also plenty of things to consider when using threads, especially in python which has a global interpreter lock (GIL) which allows only one process to run at a time. It might also be smart to check out the multiprocessing modulewith which one can route around the GIL.
关于python线程的SO有很多问题,所以你可能想把它们挖出来。请注意,在使用线程时还有很多事情需要考虑,尤其是在具有全局解释器锁 (GIL) 的 python 中,它一次只允许运行一个进程。检查可以绕过 GIL的多处理模块也可能是明智之举。
回答by Nipun Batra
Now the RPi GPIO library has inbuilt interrupt driven GPIO control which can happen in separate thread freeing up resources. You may wish to read the following http://raspi.tv/2013/how-to-use-interrupts-with-python-on-the-raspberry-pi-and-rpi-gpio-part-3
现在 RPi GPIO 库内置了中断驱动的 GPIO 控制,可以在单独的线程中释放资源。您可能希望阅读以下内容http://raspi.tv/2013/how-to-use-interrupts-with-python-on-the-raspberry-pi-and-rpi-gpio-part-3
回答by kapcom01
The RPi.GPIOPython library now supports Events, which are explained in the Interrupts and Edge detectionparagraph.
该RPi.GPIOPython库现在支持活动,这是在解释中断和边缘检测段落。
So after updating your Raspberry Pi with sudo rpi-updateto get the latest version of the library, you can change your code to:
因此,在更新您的 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
I chose the Threaded callbacksmethod because I suppose that your program does some other things in parallel to change the value of var.
我选择了Threaded callbacks方法,因为我认为您的程序并行执行了一些其他操作来更改var.
回答by Lemaitre Cedric
kapcom01 gives some great ideas but it's better to make not make a lot of instructions in the a interrupt.
kapcom01 提供了一些很棒的想法,但最好不要在中断中发出大量指令。
Usually you put a flag to 1 when the callback is call and you make the processing in the main function. In thes manner there is no risk of freesing the programm.
通常在调用回调时将标志设置为 1,并在主函数中进行处理。以这种方式没有释放程序的风险。
Somethings like this :
像这样的东西:
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

