通过webiopi在python中退出连续循环 [英] Exiting a continuous loop in python via webiopi

查看:100
本文介绍了通过webiopi在python中退出连续循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用webiopi,我基本上希望发生的是,在加载网页时,运行了一个追逐某些LED的空闲循环.然后,当有人按下网站上的按钮时,它将停止空闲循环.

I'm using webiopi, and what I basically want to happen is that when the webpage loads, an idle loop which chases some LEDs runs. Then, when someone presses a button on the website, it will stop the idle loop.

这是我到目前为止所拥有的:

Here's what I have so far:

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

So, I can get it to run the idleLoop, and I have a button hooked up to send the command for stopLoop, and I can see that it goes via POST, however in my debugging window on the PI, I just see it enter idleLoop, but it never enters stopLoop. I'm not sure if I have to write an interrupt, or multithreading, but I just need some guidance. Thanks!

推荐答案

您在一个单线程应用程序中..这意味着一旦您输入idleLoop(),机器(或至少是您的程序)就无法执行其他任何事情,包括处理您的Web请求以退出空闲循环,因为该请求一直使您的LED闪烁并进入睡眠状态.

You're in a single threaded application.. which means that once you enter idleLoop(), the machine (or, at least, your program) cannot do anything else, including process your web request to exit the idle loop, because it is stuck blinking your LEDs and sleeping.

处理此问题的方法是让您的功能来启动和停止LED,而只需设置一个全局变量然后退出即可.例如

The way to handle this is to have your functions that start and stop the LEDs merely set a global variable then exit.. eg

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请求.在每次闪烁期间,其他内容的处理都会被阻塞一点..这使它成为不太理想的代码..但是它向您显示了正确的方向.在这样的协作多任务环境中一,您永远无法阻止循环,必须尽快完成任务并返回.如果您不这样做,其他所有内容都会等待.

This will allow other tasks, such as handling web requests, to be processed between each blink. During each blink, processing of other things will be blocked for a little bit.. which makes this a less-than-ideal bit of code.. but it shows you the right direction to head in. In a cooperative multitasked environment such as this one, you can never block the loop, you must finish your task as soon as possible and return. If you don't, everything else waits.

代码的外观看起来像loop()循环一样,并且您的宏函数彼此独立执行..事实并非如此.他们正在相互之间来回传递控制,一次只能运行其中一个.

The way the code looks, it SEEMS like loop() is looping and your macro functions are executing independently of each other.. but that is not the case. They are passing control back and forth to each other and only one of them runs at a time.

理想的方法是完全不使用time.sleep(),而是记下(上一次更改)LED的时间(在变量中).然后检查loop()以查看有多少时间过去了..如果时间还不够,请什么也不做,下次再检查.一旦经过了足够的时间,将LED翻转到下一个状态并重置计时器.这是解决此类问题的经典方法.称为状态机"方法.

Ideally the way to do this is to not use time.sleep() at all, but to make note (in a variable) of the last time you changed the LED's.. and check in loop() to see how much time has passed.. if not enough time has passed, do nothing and check again next time. Once enough time has passed, flip the LEDs to the next state and reset your timer. That's the classic way to solve this kind of problem.. called a 'state machine' approach.

当您调用sleep()时,所有操作都会停止,因此您要避免这种情况.

When you call sleep() everything stops, so you want to avoid that.

这篇关于通过webiopi在python中退出连续循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆