Raspberry PiのGPIOピンとPIRセンサーを使用して、動きを検出しています。センサーが動きを検出したら、ソフトウェアを他の機能に移動します。
現時点では、モーションを検出するために、モーションが検出されるのを待っている間、プログラムを常にループで実行しています。これは現時点では機能しますが、将来使用するためには信じられないほど非効率的であり、イベントに割り当てることでこれを改善したいと考えています。
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)
カウンターとモーションの検出を複数回使用して、センサーが検出する誤検知の数を減らします。
RPi.GPIOPythonライブラリはEvents、これは 割り込みとエッジ検出 段落で説明されています。
したがって、Raspberry Piを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
私はあなたのプログラムがvar
の値を変更するために他の何かを並行して行うと思うので Threaded callbacks メソッドを選択しました。
RPi GPIOライブラリには、独立したスレッドで発生する可能性のある割り込み駆動GPIO制御が組み込まれているため、リソースが解放されます。以下を読むことをお勧めします http://raspi.tv/2013/how-to-use-interrupts-with-python-on-the-raspberry-pi-and-rpi-gpio-part-
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 pythonスレッド化についての質問がたくさんあるので、掘り下げてみてください。考慮すべきこともたくさんあることに注意してください。特にpythonでスレッドを使用します。これは、一度に1つのプロセスのみを実行できるグローバルインタープリターロック(GIL)を持ちます。 multiprocessingモジュール を使用してGILを迂回できます。
kapcom01はいくつかの素晴らしいアイデアを提供しますが、割り込みで多くの命令を作成しない方が良いです。
通常、コールバックが呼び出されたときにフラグを1に設定し、メイン関数で処理を行います。この方法では、プログラムを解放するリスクはありません。
このようなもの:
from time import sleep
import RPi.GPIO as GPIO
def init():
# make all your initialization here
flag_callback = False
# add an interrupt on pin number 7 on rising Edge
GPIO.add_event_detect(7, GPIO.RISING, callback=my_callback, bouncetime=300)
def my_callback():
# callback = function which call when a signal rising Edge on pin 7
flag_callback = True
def process_callback():
# TODO: make process here
print('something')
if __name__ == '__main__':
# your main function here
# 1- first call init function
init()
# 2- looping infinitely
while True:
#3- test if a callback happen
if flag_callback is True:
#4- call a particular function
process_callback()
#5- reset flagfor next interrupt
flag_callback = False
pass