首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >通过webiopi退出python中的连续循环

通过webiopi退出python中的连续循环
EN

Stack Overflow用户
提问于 2015-10-28 20:20:55
回答 1查看 513关注 0票数 1

我使用的是webiopi,我基本上想要的是,当网页加载时,一个空闲的循环会运行一些LED。然后,当某人按下网站上的一个按钮,它将停止空闲循环。

到目前为止,我的情况如下:

代码语言:javascript
复制
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。我不确定我是否需要写一个中断,或者多线程,但我只是需要一些指导。谢谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-10-28 21:00:29

您在一个单线程应用程序中。这意味着一旦您输入idleLoop(),机器(或者至少是您的程序)不能做任何其他事情,包括处理您的web请求以退出空闲循环,因为它被困在闪烁LED和休眠状态。

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

blink_enabled = Trueblink_enabled = False.

类似于:

代码语言:javascript
复制
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到下一个状态,并重置您的计时器。这是解决这类问题的经典方法。称为“状态机”方法。

当你打电话给睡眠()时,一切都停止了,所以你要避免这样做。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33400886

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档