it-swarm.com.de

Himbeer-PiGIO-Ereignisse in Python

Ich verwende die GPIO-Pins an meinem Raspberry Pi mit einem PIR-Sensor, um Bewegungen zu erkennen. Wenn der Sensor eine Bewegung erkennt, möchte ich die Software auf andere Funktionen übertragen.

Momentan läuft mein Programm zur Erkennung von Bewegungen ständig in einer Schleife, während es darauf wartet, dass Bewegung erkannt wird. Während dies im Moment funktioniert, ist dies für die zukünftige Verwendung unglaublich ineffizient und hofft, dies zu verbessern, indem es einer Veranstaltung zugewiesen wird.

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 aktuelle Schleife für die Erkennungsbewegung:

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 das mehrmalige Erkennen von Bewegungen werden verwendet, um die Anzahl der Fehlalarme zu reduzieren, die der Sensor aufnimmt.

19
Stefoth

Die Python-Bibliothek RPi.GPIO unterstützt jetzt Events, die im Abschnitt Interrupts und Kantenerkennung erläutert werden.

Nachdem Sie Ihr Raspberry Pi mit Sudo rpi-update aktualisiert haben, um die neueste Version der Bibliothek zu erhalten, können Sie Ihren Code folgendermaßen ä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

Ich habe die Threaded Callbacks -Methode gewählt, weil ich glaube, dass Ihr Programm einige andere Aktionen parallel ausführt, um den Wert von var zu ändern.

30
kapcom01

Die RPi-GPIO-Bibliothek verfügt nun über eine Interrupt-gesteuerte GPIO-Steuerung, die in separaten Threads auftreten kann, die Ressourcen freigeben. Sie können die folgenden http://raspi.tv/2013/how-to-use-interrupts lesen -mit-python-on-the-himbeer-pi-und-rpi-gpio-part-3

3
Nipun Batra

Sie können den GPIO-Code in einen eigenen Thread einbinden und den Rest Ihres Programms etwas anderes tun lassen, während der GPIO auf Eingaben wartet. Schauen Sie sich das Threading-Modul an

Zuerst würde ich Ihren Code in eine Funktion einbinden

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 könnten Sie in Ihrem Hauptprogramm so etwas machen

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

Zu SO gibt es eine Menge Fragen zum Python-Threading. Bitte beachten Sie, dass bei der Verwendung von Threads auch einiges zu beachten ist. Dies gilt insbesondere für Python, das über eine globale Interpretersperre (GIL) verfügt, die jeweils nur einen Prozess ausführen kann. Es kann auch sinnvoll sein, das Multiprocessing-Modul auszuprobieren , mit dem man die GIL umleiten kann.

1
msvalkon

kapcom01 gibt einige großartige Ideen, aber es ist besser, nicht viele Anweisungen in einem Interrupt zu machen.

Normalerweise setzen Sie ein Flag auf 1, wenn der Rückruf aufgerufen wird, und Sie nehmen die Verarbeitung in der Hauptfunktion vor. Auf diese Weise besteht keine Gefahr, dass das Programm freigegeben wird.

Etwas wie dieses:

     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 __== '__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
0
Lemaitre Cedric