我有一个运行Flask框架的Raspberry Pi来创建一个非常特定于应用程序的http服务器。在Pi服务器上执行特定页面的HTTP GET会触发GPIO操作(例如:检查是否按下按钮,LED亮起,LED熄灭等)。因为我将轮询 / status 页面以查看按钮是否以250毫秒间隔按下,我不希望轮询 / unlock 页面使用timer.sleep( 0.25)关闭继电器250ms。
我想设置一个动作,当被叫时,将等待250ms,关闭LED然后悄悄地离开。我尝试了线程和sched。线程工作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
我也尝试了sched,它对我不起作用,虽然可能是因为我从内到外编程,边做边学:
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 :(得分: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之前已定义如下:
GREEN = 24
# Use GPIO pin numbers
GPIO.setmode(GPIO.BCM)
GPIO.setup(GREEN, GPIO.OUT)
像魅力一样。