2017-07-18 189 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

好的 - 工程太棒了!如果在燈亮的情況下再次檢測到運動,是否有重新啓動線程的方法(或者我猜是睡眠定時器)? –