我使用的是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。我不确定是否必须编写中断或多线程,但我只需要一些指导。谢谢!
答案 0 :(得分:1)
您处于单线程应用程序中...这意味着一旦您进入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请求。在每次眨眼期间,其他事情的处理将被阻止一点......这使得这不是理想的代码位...但它向您展示了正确的方向。在这样的合作多任务环境中一,你永远不能阻止循环,你必须尽快完成你的任务并返回。如果你不这样做,其他一切都会等待。
代码的样子,它像循环一样SEEMS循环,你的宏函数彼此独立地执行..但事实并非如此。他们正在相互传递控制权,一次只能运行其中一个。
理想情况下,执行此操作的方法是不要使用time.sleep(),而是要记录(在变量中)上次更改LED&..并检查循环()看看已经过了多少时间..如果没有足够的时间过去,什么都不做,下次再检查一下。一旦经过足够的时间,将LED翻转到下一个状态并重置计时器。这是解决这类问题的经典方法......被称为“状态机”'方法
当你打电话给sleep()时,一切都会停止,所以你想避免这种情况。