2013-04-22 22 views
19

Raspberry PiのGPIOピンをPIRセンサーで使用して動きを検出しています。センサーが動きを検出すると、ソフトウェアを他の機能に移動したいと思います。PythonでのRaspberry Pi- GPIOイベント

現在のところ、動きを検出するために、動きが検出されるのを待っている間、私のプログラムは常にループで動作しています。これは現時点では機能しますが、将来的には非常に非効率的で、イベントに割り当てることでこれを改善したいと考えています。

手動でループを実行することなくプログラムで検出されたイベントにGPIO入力をバインドする方法はありますか。

var = 1 
counter = 0 
while var == 1: 
    if GPIO.input(7): 
     counter += 1 
     time.sleep(0.5) 
    else: 
     counter = 0 
     time.sleep(1) 

    if counter >= 3: 
     print "Movement!" 
     captureImage() 
     time.sleep(20) 

カウンタとセンサーが拾うことを偽陽性の数を減らすために使用される運動を複数回検出:

は、ここに私の現在の検出運動のためのループです。

答えて

1

GPIOコードを自分のスレッドにラップして、GPIOが入力を待っている間に残りのプログラムを実行させることができます。あなたのメインプログラムで

def wait_input(): 
    var=1 
    counter = 0 
    while var == 1: 
     if GPIO.input(7): 
      counter += 1 
     time.sleep(0.5) 
     else: 
      counter = 0 
      time.sleep(1) 
     if counter >= 3: 
      print "Movement!" 
      captureImage() 
      time.sleep(20) 

そして、あなたはこの

input_thread = threading.Thread(target = wait_input) 
input_thread.start() 
# do something in the meanwhile 
input_thread.join() 

のようなものSOに質問がたくさんあります可能性があり、私は関数にあなたのコードをラップしたいthreading module

ファーストをチェックしてくださいPythonのスレッディングに関して、あなたはそれらを掘り出したいかもしれません。スレッドを使用するときには、特に一度に1つのプロセスしか実行できないようにするグローバルインタプリタロック(GIL)を持つPythonで考慮すべきことがたくさんあることに注意してください。 multiprocessing moduleをGILの周りを回って調べることも賢明かもしれません。

+1

この方法は、GUIと同じように機能しますか?私がしたいのは、このループが自分のGUIから実行されているモーションディテクタクラスを呼び出すことですが、ループを使うとGUIがクラッシュするだけです。これをスレッドで使用すると、GUIが関連する入力をリッスンしている間にモーション検出ループがバックグラウンドで実行されますか? – Stefoth

+1

@StefothこれはGUIプログラミングがどのように機能するかです。あなたのGUIは独自のスレッドで動作し、モーション検出コードはそれ自身で動作します。 – msvalkon

26

RPi.GPIO Pythonライブラリを読み込むしたい場合があり、今Interrupts and Edge detection段落で説明されているイベントをサポートしています。

だから、ライブラリの最新バージョンを取得するsudo rpi-updateであなたのラズベリーパイを更新した後、あなたがあなたのコードを変更することができます。

from time import sleep 
import RPi.GPIO as GPIO 

var=1 
counter = 0 

GPIO.setmode(GPIO.BOARD) 
GPIO.setup(7, GPIO.IN, pull_up_down=GPIO.PUD_DOWN) 

def my_callback(channel): 
    if var == 1: 
     sleep(1.5) # confirm the movement by waiting 1.5 sec 
     if GPIO.input(7): # and check again the input 
      print("Movement!") 
      captureImage() 

      # stop detection for 20 sec 
      GPIO.remove_event_detect(7) 
      sleep(20) 
      GPIO.add_event_detect(7, GPIO.RISING, callback=my_callback, bouncetime=300) 

GPIO.add_event_detect(7, GPIO.RISING, callback=my_callback, bouncetime=300) 

# you can continue doing other stuff here 
while True: 
    pass 

私はあなたのプログラムは、いくつかの他の事をしているとしたので、私はThreaded callbacks方法を選びました並行してvarの値を変更します。

関連する問題