新手:又一个非阻塞延迟:没有睡眠延迟LED开启()

问题描述:

我有一个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而无错误的任务(或执行其他任何操作)?

在朋友的帮助下,答案比我预想的要简单: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) 

奇迹般有效。