2017-07-18 896 views
2

我试图让我的树莓派使用红外传感器检测动作,然后打开LED 5秒钟,同时每隔0.5秒轮询IR传感器。这是到目前为止我的代码,但它等待LED再次检查红外传感器之前关闭...Python:每秒运行一次循环并触发5秒钟功能

import RPi.GPIO as GPIO 
import time 

GPIO.setmode(GPIO.BCM) 
PIR_PIN = 18 
GPIO.setup(PIR_PIN, GPIO.IN) 
LED_PIN = 17 
GPIO.setup(LED_PIN, GPIO.OUT) 
def light(): 
    GPIO.output(LED_PIN, GPIO.input(PIR_PIN)) 
    time.sleep(5) 
    GPIO.output(LED_PIN, False) 
try: 
    while True: 
    if GPIO.input(PIR_PIN): 
     print("Motion Detected!") 
     light() 
    time.sleep(0.5) 
except KeyboardInterrupt: 
    GPIO.cleanup() 
+1

使用多线程 – Benjamin

回答

2

这正是基于代码的正确行为。为了不阻止light() def,你不能有像time.sleep这样的阻塞语句。解决这个问题

一种方法是使用线程:

from threading import Thread 
import RPi.GPIO as GPIO 
import time 

GPIO.setmode(GPIO.BCM) 
PIR_PIN = 18 
GPIO.setup(PIR_PIN, GPIO.IN) 
LED_PIN = 17 
GPIO.setup(LED_PIN, GPIO.OUT) 
def light(): 
    GPIO.output(LED_PIN, GPIO.input(PIR_PIN)) 
    time.sleep(5) 
    GPIO.output(LED_PIN, False) 
try: 
    while True: 
    if GPIO.input(PIR_PIN): 
     print("Motion Detected!") 
     t = Thread(target=light) # Create thread 
     t.start() # Start thread 
    time.sleep(0.5) 
except KeyboardInterrupt: 
    GPIO.cleanup() 

Threading可以让你在你的程序同时运行多个事情。尽管如此,现在又开辟了另一个需要线程同步的蠕虫。

我强烈建议在实现上述代码之前进一步阅读关于使用python的多线程,如果执行不正确,则线程是非常危险的。

+0

看起来不错!我需要在light函数中调用t.stop()吗? –

+1

不,你一旦完成,就完成了。在外部停止线程通常是一个糟糕的主意,你应该让线程运行它的过程并处理自己停止 – Chris

+0

好的 - 工程太棒了!如果在灯亮的情况下再次检测到运动,是否有重新启动线程的方法(或者我猜是睡眠定时器)? –