2013-04-22 9 views
19

Ich verwende die GPIO-Pins auf meinem Raspberry Pi mit einem PIR-Sensor, um Bewegung zu erkennen. Wenn der Sensor eine Bewegung erkennt, möchte ich die Software auf andere Funktionen verschieben.Raspberry Pi- GPIO Ereignisse in Python

Im Moment, um Bewegungen zu erkennen, läuft mein Programm ständig in einer Schleife, während es darauf wartet, dass Bewegung erkannt wird. Während dies im Moment funktioniert, wird dies für die Zukunft unglaublich ineffizient sein und ich hoffe, dass ich dies verbessern kann, indem ich es einer Veranstaltung zuweise.

Gibt es eine Möglichkeit, meine GPIO-Eingabe an ein Ereignis zu binden, das vom Programm erkannt wird, ohne eine Schleife manuell auszuführen.

Hier ist meine Stromschleife für die Detektion motion:

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) 

Der Zähler und zum Erfassen Bewegung mehrfach verwendet wird, um die Zahl der Fehlalarme zu reduzieren, dass der Sensor aufnimmt.

Antwort

1

Sie könnten den GPIO-Code in einen eigenen Thread einbinden und den Rest Ihres Programms etwas anderes machen lassen, während das GPIO auf Eingabe wartet. Schauen Sie sich die threading module

Zuerst habe ich den Code in eine Funktion wickeln würde

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) 

Und dann in Ihrem Hauptprogramm könnte man diese so etwas wie

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

Es gibt viele Fragen auf SO in Bezug auf Python-Threading, also möchten Sie sie vielleicht ausgraben. Bitte beachten Sie, dass es bei der Verwendung von Threads auch viele Dinge zu beachten gibt, besonders in Python mit einer globalen Interpreter-Sperre (GIL), die nur einen Prozess gleichzeitig ausführen lässt. Es könnte auch schlau sein, die multiprocessing module zu überprüfen, mit der man die GIL routen kann.

+1

Würde diese Methode mit einer GUI arbeiten? Ich möchte die Bewegungsdetektorklasse aufrufen, die diese Schleife von meiner GUI aus ausführt, aber mit der Schleife stürzt sie nur die GUI ab. Wenn ich dies mit dem Thread verwende, führt dies dazu, dass die Bewegungserkennungsschleife im Hintergrund ausgeführt wird, während die GUI auf die zugehörige Eingabe wartet? – Stefoth

+1

@Stefoth das ist so ziemlich wie GUI-Programmierung funktioniert. Ihre GUI wird in ihrem eigenen Thread ausgeführt und der Bewegungserkennungscode wird in ihrem eigenen ausgeführt. – msvalkon

26

Die RPi.GPIO Python-Bibliothek lesen unterstützt jetzt Events, die im Interrupts and Edge detection Absatz erläutert werden.

So nach mit sudo rpi-update Ihre Raspberry Pi Aktualisierung der neuesten Version der Bibliothek zu erhalten, können Sie den Code ändern:

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 

wählte ich die Threaded callbacks Methode, weil ich, dass Ihr Programm nehme ein paar andere Dinge tut parallel, um den Wert von var zu ändern.