2017-10-05 105 views
1

我有一個Raspberry Pi運行Flask框架來製作一個非常特定於應用程序的http服務器。在Pi服務器上執行特定頁面的HTTP GET會觸發GPIO操作(例如,檢查按鈕是否被按下,LED是否亮起,LED是否熄滅等)。因爲我將輪詢/狀態頁面以查看按鈕是否以250毫秒的間隔被按下,所以我不希望輪詢該頁面以使用timer.sleep(0.25)關閉250毫秒的繼電器。新手:又一個非阻塞延遲:沒有睡眠延遲LED開啓()

我想設置一個動作,當被調用時,將等待250ms,關閉LED,然後悄然離開。我嘗試了線程和調度。線程工作ONCE並拋出錯誤,當我第二次通過代碼(引發RuntimeError(「線程只能啓動一次」))。

# 
# lots of other defines and includes 
# 
import threading 
# set up function to turn de-energize relay (and Green LED) 
def LED_Off_Wait(): 
    GPIO.output(GREEN, False) 

# set up timed thread 
LED_Off = threading.Timer(0.25, LED_Off_Wait) 

# 
# flask framework page definitions go here 
# 

# unlock page where we energize and de-energize a lock 
@app.route('/unlock') 
def thing_unlock(): 
    GPIO.output(GREEN, True) # energize the relay (and green LED) 
# time.sleep(0.25) # don't want to do this 
# GPIO.output(GREEN, False) #don't want to do this 
    LED_Off.start() # trigger the non-blocking thread to turn off 
        # the GPIO pin in 0.25s 
# more flask stuff... 
    response = make_response(render_template('body.html', response='unlocked')) 
    response.headers['Access-Control-Allow-Origin'] = '*' 
    return response 

我試着章附表以及和它不工作對我來說,雖然它可能是因爲我是從內到外的設計,邊做邊學:

import sched 

def LED_Off(): 
    GPIO.output(GREEN, False) 

# set up scheduled action, as nearly as I can determine from my reading 
LED_ON_Delay = sched.scheduler(time.time, time.sleep) # set up scheduler (no sleep!) 
LED_ON_Delay.enter(1, 1, LED_Off,()) # schedule LED_Off for 0.25s in the future 

# 
# again, more Flask stuff here 
# 

@app.route('/unlock') 
def thing_unlock(): 
    GPIO.output(GREEN, True) 
# time.sleep(0.25) # don't want to do this 
# GPIO.output(GREEN, False) # don't want to do this 
    LED_ON_Delay.run() #trigger "non-blocking sleep" 
    response = make_response(render_template('body.html', response='unlocked')) 
    response.headers['Access-Control-Allow-Origin'] = '*' 
    return response 

# more Flask stuff... 

底線:如何如果我嘗試兩次執行該操作,是否會在一定時間後關閉一個可以關閉GPIO而無錯誤的任務(或執行其他任何操作)?

回答

0

在朋友的幫助下,答案比我預想的要簡單:Lambda函數。首先,import threading然後使用threading.Timer()申報的時間間隔後,將你想要做什麼(關閉LED)的功能:

def LED_Off_Wait(wait_time,IO_port): 
    threading.Timer(wait_time, lambda: GPIO.output(IO_port, False)).start() 

在這種情況下,我需要讓我通過使用它在一個以上的地方延遲時間和它需要採取行動的GPIO引腳。

當我需要關閉LED另一個函數中的延遲之後,我把它稱爲是這樣的:

@app.route('/unlock') 
def prop_unlock(): 
    GPIO.output(GREEN, True) 
    LED_Off_Wait(0.5, GREEN) 
    response = make_response(render_template('body.html', response='unlocked')) 
    response.headers['Access-Control-Allow-Origin'] = '*' 
    return response 

爲了完整,綠色前面已經定義是這樣的:

GREEN = 24 
# Use GPIO pin numbers 
GPIO.setmode(GPIO.BCM) 
GPIO.setup(GREEN, GPIO.OUT) 

奇蹟般有效。