1

我正在使用 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。我不确定是否必须编写中断或多线程,但我只需要一些指导。谢谢!

4

1 回答 1

1

你在一个单线程应用程序中......这意味着一旦你进入 idleLoop(),机器(或者,至少,你的程序)不能做任何其他事情,包括处理你的 web 请求以退出空闲循环,因为它是卡住闪烁你的 LED 和睡觉。

处理这个问题的方法是让你的函数启动和停止 LED 只设置一个全局变量然后退出.. 例如

blink_enabled = Trueblink_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 请求。在每次眨眼期间,其他事情的处理都会被阻塞一点点......这使得这段代码不太理想......但它向您展示了前进的正确方向。在这样的协作多任务环境中一,你永远不能阻塞循环,你必须尽快完成你的任务并返回。如果你不这样做,其他一切都在等待。

代码的外观看起来像 loop() 是循环的,并且您的宏函数彼此独立执行..但事实并非如此。它们相互之间来回传递控制权,一次只有一个运行。

理想情况下,这样做的方法是根本不使用 time.sleep(),而是记下(在变量中)您上次更改 LED 的时间.. 并检查 loop() 以查看已经过去了多少时间..如果没有足够的时间过去,什么也不做,下次再检查。一旦经过足够的时间,将 LED 翻转到下一个状态并重置计时器。这是解决此类问题的经典方法……称为“状态机”方法。

当你调用 sleep() 时,一切都会停止,所以你想避免这种情况。

于 2015-10-28T21:00:29.333 回答