2017-01-23 175 views
0

私は、ボタンを押したときにLCDディスプレイに情報が表示されるように、Pythonでいくつかのコードを書いています。これは私のコードの一部です:Pythonでメインスレッドを一時停止する

GPIO.setmode(GPIO.BCM) 
GPIO.setup(18, GPIO.IN, pull_up_down=GPIO.PUD_UP) 

def action1(self): 
    temp = "15" 
    lcd.clear() 
    lcd.message(" Temp. Est.: \n" + " " + temp + " " + chr(223) + "C") 
    time.sleep(5.0) 
    lcd.clear 

GPIO.add_event_detect(18, GPIO.RISING,callback=action1, bouncetime=800) 

while True: 
date = datetime.now().strftime('%m-%d-%Y %H:%M') 
lcd.message(date) 
time.sleep(5.0) 
lcd.clear() 

このコードが動作しているが、私はボタンを押したときに、それは(それは私がボタンを押したときに依存して)再び、私に時間と温度を温度を示しています。私は "GPIO.add_event_detect"コールバック関数の2番目のスレッドを実行し、メインスレッドを一時停止しないことを読んだ。私は、ボタンを押した後、ボタンを押すたびにLCD上にとどまり、私の場合は時間の経過とともにコードが下から始まることを望みます。 どうすればいいですか?ありがとうございました!

+1

ボタンを押す時間をキャプチャし、あとでボタンが押されすぎるのを無視することで、自分自身でデバウンスすることができます。この質問への回答http://raspberrypi.stackexchange.com/questions/8544/gpio-interrupt-debounceが役に立ちます。 –

+0

表示される値はどのくらい速く切り替わりますか?あなたのボタンはおそらくバウンスしています。あなたはこれを読むことができます:https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/robot/buttons_and_switches/ –

+0

あなたは私が間違っているか、間違ってしまったかもしれませんが、ここでの問題はボタンの繰り返しを繰り返すことではありません。問題は、常に表示したいコードがwhileループにあり、GPIO.add_event_detectで開いた別のスレッドとメインスレッド内のコードが交互に表示されることです。 – antonioag

答えて

0

マルチスレッドには直感的な驚きがたくさんあります。それらを避けるために、私はむしろ2つの異なるスレッドからディスプレイを更新することを避けたいと思います。

代わりに、私はむしろハンドラスレッドからメッセージを送信するか、少なくともそれから共有フラグを更新しました。

メインループの実行速度が向上し、更新(ラフスケッチ)に反応するであろう:

desired_state = None # the shared flag, updated from key press handler. 
current_state = 'show_date' # what we used to display 
TICK = 0.1 # we check the state every 100 ms. 
MAX_TICKS = 50 # we display a value for up to 5 seconds. 
ticks_elapsed = 0 
while True: 
    if desired_state != current_state: 
    # State changed, start displaying a new thing. 
    current_state = desired_state 
    ticks_elapsed = 0 
    if desired_state == 'show_date': 
     put_date_on_lcd() 
    elif desired_state == 'show_temp': 
     put_temp_on_lcd() 
    elif desired_state == 'blank': 
     clear_lcd() 
    else: # unknown state, we have an error in the program. 
     signal_error('What? %s' % desired_state) 
    # Advance the clock. 
    time.sleep(TICK) 
    ticks_elapsed += 1 
    if ticks_elapsed >= MAX_TICKS: 
    # Switch display to either date or blank. 
    desired_state = 'show_date' if current_state == 'blank' else 'blank' 
    ticks_elapsed = 0 

は免責事項:私はこのコードをテストしていません。

+0

ありがとうございます。とにかく、GPIO.add_event_detectで別のスレッドを開いたときに、メインスレッドのプロセスを一時停止/中断したいのですが、別のスレッドによる二重のLCDの更新を避けるためです。私はそれを得ることができません – antonioag

+0

さて、シグナルハンドラスレッドで "メインスレッドを停止"フラグを更新し、メインスレッドのフラグ状態をスリープ/スリープしますか?ただし、任意の場所でメインスレッドを_interruptすることはできませんが、特定の場所で待機させるだけです。プリエンプティブなのではなく、協調的なマルチタスキングの一種。 – 9000

関連する問題