2016-11-13 11 views
0

私はPythonとRaspberry Piで始まり、それらを使って物理計算を行っていました。whileループを中断して関数を実行し、ループに戻る方法

私はそれで始まりました:https://www.raspberrypi.org/learning/physical-computing-with-python/とすべてうまくいった。私は(!成功して)交通信号機で遊ぶことを試みたより

https://www.raspberrypi.org/learning/physical-computing-with-python/trafficlights/

ここに私のコード:

from gpiozero import Button, TrafficLights 
from time import sleep 

lights = TrafficLights(25, 8, 7) 

while True: 
    lights.green.on() 
    print("GREEN") 
    sleep(12) 
    lights.green.off() 
    lights.amber.on() 
    print("AMBER") 
    sleep(4) 
    lights.red.on() 
    lights.amber.off() 
    print("RED") 
    sleep(12) 
    lights.amber.on() 
    print("RED & AMBER") 
    sleep(4) 
    lights.red.off() 
    lights.amber.off() 

私は横断歩道のためのボタンを追加しようとしましたより。しかしここに私は問題があります。

ここでコード:

from gpiozero import Button, TrafficLights 
from time import sleep 

button = Button(21) 
lights = TrafficLights(25, 8, 7) 

def pedestrian_crossing(): 
    sleep(4) 
    lights.off() 
    lights.amber.on() 
    print("Pedestrian crossing: AMBER") 
    sleep(4) 
    lights.red.on() 
    lights.amber.off() 
    print("Pedestrian crossing: RED") 
    sleep(12) 
    lights.amber.on() 
    print("Pedestrian crossing: RED & AMBER") 
    sleep(4) 
    lights.red.off() 
    lights.amber.off() 

button.when_pressed = pedestrian_crossing 

while True: 
    lights.green.on() 
    print("GREEN") 
    sleep(12) 
    lights.green.off() 
    lights.amber.on() 
    print("AMBER") 
    sleep(4) 
    lights.red.on() 
    lights.amber.off() 
    print("RED") 
    sleep(12) 
    lights.amber.on() 
    print("RED & AMBER") 
    sleep(4) 
    lights.red.off() 
    lights.amber.off() 

私は、button.wait_for_pressbutton.wait_for_release &(株)を試してみましたが、button.is_pressedは私に最良の結果を与えたものでした。

ボタンを押したときに関数が呼び出されても、ループが継続するという問題があります。では、コードを書き直すにはどうすればいいですか?ボタンを押すとループが停止し、関数が呼び出され、関数内のすべてが実行され、ループに戻ります。

他のボタン属性を持つ別の解決策がありますか?

ありがとうございます!

答えて

0

方法下記のように、代わりに呼び出し約横断歩道機能に直接ボタンを押して、を押し、次にループ

ながらに復帰している場合、ループがpedestrian_crossing関数を呼び出しますしながら、内部で、横断歩道プレストリガーを示すために、変数を設定するときそれは得ることがほとんど〜1Sが遅れる
pedestrian_press = False 
def pedestrian_crossing(): 
    global pedestrian_press 
    pedestrian_press = False # reset press 
    sleep(4) 
    lights.off() 
    lights.amber.on() 
    print("Pedestrian crossing: AMBER") 
    sleep(4) 
    lights.red.on() 
    lights.amber.off() 
    print("Pedestrian crossing: RED") 
    sleep(12) 
    lights.amber.on() 
    print("Pedestrian crossing: RED & AMBER") 
    sleep(4) 
    lights.red.off() 
    lights.amber.off() 

def set_pedestrian_press(): 
    global pedestrian_press 
    pedestrian_press = True 

button.when_pressed = set_pedestrian_press 


def my_sleep(n): 
    # checking for pedestrian press done at 1 sec interval 
    # to make it check at smaller interval 
    # change to range(n*10) then sleep(0.1), for 0.1s interval 
    for i in range(n): 
     sleep(1) 
     if pedestrian_press: # check if pedestrian press 
      pedestrian_crossing() 

while True: 
    lights.green.on() 
    print("GREEN") 
    my_sleep(12) # every second will check for pedestrian_press 
    lights.green.off() 
    lights.amber.on() 
    print("AMBER") 
    my_sleep(4) # every second will check for pedestrian_press 
    lights.red.on() 
    lights.amber.off() 
    print("RED") 
    my_sleep(12) # every second will check for pedestrian_press 
    lights.amber.on() 
    print("RED & AMBER") 
    my_sleep(4) # every second will check for pedestrian_press 
    lights.red.off() 
    lights.amber.off() 
+0

は( 'pedestrian_crossあなたの答え@Skyccのためではなく、変更していただき、ありがとうござい中断作るwhileループで呼び出している毎回のmy_sleepをチェックしますので、

はmy_sleep機能でpedestrian_pressのVARのためにチェックを入れます) 'はループの内側の緑色のライトの後に即座にトリガーされますボタンを押してください。 –

+0

私の間違いは、var名の代わりに関数名を確認して、修正してください。もう一度やり直してください – Skycc

+0

こんにちは@Skycc!今のところ期待通りです。 'if'と歩行者横断プロセスが始まるまでスクリプトを実行するボタンを押します。しかし、ボタンを押して歩行者の横断を開始するとすぐにループを中断する方法はありますか?ボタンを押したときに元のコードで覚えているように、それが発生します。唯一の問題は、ループが止まらないことです。 ;-) とにかくありがとう!!! –

関連する問題