2015-10-28 3 views
1

Я использую webiopi, и в основном я хочу, чтобы при загрузке веб-страницы простаивал цикл простоя, который преследует некоторые светодиоды. Затем, когда кто-то нажимает кнопку на веб-сайте, он останавливает цикл ожидания.Выход из непрерывного цикла в python с помощью webiopi

Вот что я до сих пор:

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. Я не уверен, что мне нужно написать прерывание или многопоточность, но мне просто нужно руководствоваться. Благодаря!

ответ

1

Вы используете однопоточное приложение .. это означает, что после ввода idleLoop() машина (или, по крайней мере, ваша программа) не сможет ничего сделать, включая обработку вашего веб-запроса для выхода из цикла ожидания , потому что он застрял, мигая светодиодами и спал.

Способ справиться с этим, чтобы ваши функции, которые можно запускать и останавливать светодиоды просто установить глобальную переменную, то выход .. например

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 

Это позволит другие задачи, таким как обработка веб-запросы, подлежащая обработке между каждым мерцанием. Во время каждого мигания обработка других вещей будет немного заблокирована .., что делает этот код меньшим, чем идеальный, но он показывает вам правильное направление. В совместной многозадачной среде, такой как эта один, вы никогда не сможете заблокировать цикл, вы должны как можно скорее завершить свою задачу и вернуться. Если вы этого не сделаете, все остальное ждет.

Способ, которым выглядит код: SEEMS, как loop(), является циклом, а ваши макрофункции выполняются независимо друг от друга .. но это не так. Они передают управление друг другу взад и вперед, и только один из них работает одновременно.

В идеале, способ не использовать time.sleep() вообще, но сделать заметку (в переменной) в последний раз, когда вы изменили светодиоды .. и проверить цикл(), чтобы увидеть, как прошло много времени. Если не прошло достаточно времени, ничего не делайте и снова проверьте в следующий раз. По прошествии достаточно времени переверните светодиоды в следующее состояние и сбросьте свой таймер. Это классический способ решения такого рода проблем, который называется подходом «государственной машины».

Когда вы вызываете sleep(), все останавливается, поэтому вы хотите этого избежать.

+0

Спасибо, я знаю, что я сделал это раньше, но я вышел из практики. То, что вы показываете в качестве примера, именно то, что я должен был запомнить. Благодаря! – Photovor

+0

Добро пожаловать. В теории вы могли бы решить эту проблему с помощью реальной многозадачности, но это немного перебор, чтобы просто мигать несколькими светодиодами. –