通过 webiopi 退出 python 中的连续循环
Exiting a continuous loop in python via webiopi
我正在使用 webiopi,我基本上想要发生的是当网页加载时,一个空闲循环追逐一些 LED 运行s。然后,当有人按下网站上的按钮时,它会停止空闲循环。
这是我目前的情况:
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,我连接了一个按钮来发送停止循环的命令,我可以看到它通过 POST,但是在我在PI上调试window,只看到进入了idleLoop,却没有进入stopLoop。我不确定我是否必须编写中断或多线程,但我只需要一些指导。谢谢!
您在单线程应用程序中..这意味着一旦您进入 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
这将允许在每次闪烁之间处理其他任务,例如处理网络请求。在每次眨眼期间,其他事情的处理将被阻止一点点......这使得这段代码不太理想......但它向您展示了正确的方向。在这样的协作多任务环境中一,你永远不能阻塞循环,你必须尽快完成你的任务并且return。如果你不这样做,其他一切都在等待。
从代码的外观来看,它看起来像 loop() 正在循环,并且您的宏函数正在彼此独立执行..但事实并非如此。它们相互来回传递控制权,一次只有一个运行。
理想的做法是根本不使用 time.sleep(),而是记下(在变量中)您上次更换 LED 的时间……并检查 loop()看看过去了多少时间.. 如果时间不够,什么也不做,下次再检查。一旦经过足够的时间,将 LED 翻转到下一个状态并重置计时器。这是解决此类问题的经典方法。称为 'state machine' 方法。
当你调用 sleep() 时一切都会停止,所以你想避免这种情况。
我正在使用 webiopi,我基本上想要发生的是当网页加载时,一个空闲循环追逐一些 LED 运行s。然后,当有人按下网站上的按钮时,它会停止空闲循环。
这是我目前的情况:
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,我连接了一个按钮来发送停止循环的命令,我可以看到它通过 POST,但是在我在PI上调试window,只看到进入了idleLoop,却没有进入stopLoop。我不确定我是否必须编写中断或多线程,但我只需要一些指导。谢谢!
您在单线程应用程序中..这意味着一旦您进入 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
这将允许在每次闪烁之间处理其他任务,例如处理网络请求。在每次眨眼期间,其他事情的处理将被阻止一点点......这使得这段代码不太理想......但它向您展示了正确的方向。在这样的协作多任务环境中一,你永远不能阻塞循环,你必须尽快完成你的任务并且return。如果你不这样做,其他一切都在等待。
从代码的外观来看,它看起来像 loop() 正在循环,并且您的宏函数正在彼此独立执行..但事实并非如此。它们相互来回传递控制权,一次只有一个运行。
理想的做法是根本不使用 time.sleep(),而是记下(在变量中)您上次更换 LED 的时间……并检查 loop()看看过去了多少时间.. 如果时间不够,什么也不做,下次再检查。一旦经过足够的时间,将 LED 翻转到下一个状态并重置计时器。这是解决此类问题的经典方法。称为 'state machine' 方法。
当你调用 sleep() 时一切都会停止,所以你想避免这种情况。