我使用的是webiopi,我基本上想要的是,当网页加载时,一个空闲的循环会运行一些LED。然后,当某人按下网站上的一个按钮,它将停止空闲循环。
到目前为止,我的情况如下:
import webiopi
import time
GPIO = webiopi.GPIO
LIGHT1 = 2
LIGHT2 = 3
LIGHT3 = 4
def setup():
GPIO.setFunction(LIGHT1, GPIO.OUT)
GPIO.setFunction(LIGHT2, GPIO.OUT)
GPIO.setFunction(LIGHT3, GPIO.OUT)
a=0
def loop():
webiopi.sleep(1)
@webiopi.macro
def stopLoop():
print("Stopping Loop");
global a
a = 1
return a
@webiopi.macro
def idleLoop():
print("Entering idleLoop");
while (a==0):
GPIO.digitalWrite(LIGHT1, GPIO.HIGH)
time.sleep(0.05)
GPIO.digitalWrite(LIGHT2, GPIO.HIGH)
GPIO.digitalWrite(LIGHT1, GPIO.LOW)
time.sleep(0.05)
GPIO.digitalWrite(LIGHT3, GPIO.HIGH)
GPIO.digitalWrite(LIGHT2, GPIO.LOW)
time.sleep(0.05)所以,我可以让它运行idleLoop,我有一个按钮连接起来发送stopLoop的命令,我可以看到它通过POST,但是在PI上的调试窗口中,我只看到它进入idleLoop,但它从未进入stopLoop。我不确定我是否需要写一个中断,或者多线程,但我只是需要一些指导。谢谢!
发布于 2015-10-28 21:00:29
您在一个单线程应用程序中。这意味着一旦您输入idleLoop(),机器(或者至少是您的程序)不能做任何其他事情,包括处理您的web请求以退出空闲循环,因为它被困在闪烁LED和休眠状态。
处理这个问题的方法是让启动和停止LED的函数只设置一个全局变量,然后退出。例如
blink_enabled = True或blink_enabled = False.
类似于:
blink_enabled = False
def loop():
webiopi.sleep(1)
if blink_enabled:
blink_once()
def blink_once():
GPIO.digitalWrite(LIGHT1, GPIO.HIGH)
time.sleep(0.05)
GPIO.digitalWrite(LIGHT2, GPIO.HIGH)
GPIO.digitalWrite(LIGHT1, GPIO.LOW)
time.sleep(0.05)
GPIO.digitalWrite(LIGHT3, GPIO.HIGH)
GPIO.digitalWrite(LIGHT2, GPIO.LOW)
time.sleep(0.05)
@webiopi.macro
def stopLoop():
blink_enabled = False
@webiopi.macro
def idleLoop():
blink_enabled = True这将允许在每次眨眼之间处理其他任务,例如处理web请求。在每眨眼之间,其他事物的处理就会被阻塞一点点。这使得这不是一个理想的代码..。但它给你指明了前进的正确方向。在这样的协作多任务环境中,您永远不能阻止循环,您必须尽快完成任务并返回。如果你不这样做,其他一切都在等着你。
按照代码的样子,循环()似乎是循环的,宏函数是相互独立地执行的。但事实并非如此。它们之间互相传递控制权,每次只有一个在运行。
理想情况下,这样做的方法是根本不使用time.sleep(),而是(在变量中)记录上次更改LED的时间。并签入循环()以查看已经过去了多少时间。如果没有足够的时间过去,什么也不做,下次再检查一次。一旦足够的时间过去,翻转LED到下一个状态,并重置您的计时器。这是解决这类问题的经典方法。称为“状态机”方法。
当你打电话给睡眠()时,一切都停止了,所以你要避免这样做。
https://stackoverflow.com/questions/33400886
复制相似问题