2013-04-22 18 views
19

Sto usando i pin GPIO sul mio Raspberry Pi con un sensore PIR per rilevare il movimento. Quando il sensore rileva il movimento, desidero spostare il software su altre funzioni.Raspberry Pi- GPIO Events in Python

Al momento, per rilevare il movimento, il mio programma è costantemente in esecuzione in un ciclo mentre è in attesa del rilevamento del movimento. Mentre questo funziona al momento, per l'uso in futuro questo sarà incredibilmente inefficiente e spero di migliorare su questo assegnandolo ad un evento.

C'è un modo per associare il mio ingresso GPIO a un evento rilevato dal programma senza eseguire manualmente un ciclo.

Ecco il mio anello di corrente per rilevamento di movimento:

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) 

Il contatore e rilevare i tempi di movimento multipla è utilizzato per ridurre il numero di falsi positivi che il sensore raccoglie.

risposta

1

È possibile avvolgere il codice GPIO nella propria thread e fare in modo che il resto del programma esegua qualcos'altro mentre GPIO è in attesa di input. Controlla la threading module

Prima avevo avvolgere il codice in una funzione

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) 

E poi nel programma principale si potrebbe qualcosa di simile

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

Ci sono un sacco di domande su SO riguardo il threading di Python, quindi potresti volerli scavare. Si noti che ci sono anche molte cose da considerare quando si usano i thread, specialmente in python che ha un lock dell'interprete globale (GIL) che consente l'esecuzione di un solo processo alla volta. Potrebbe anche essere intelligente controllare lo multiprocessing module con il quale è possibile orientarsi attorno a GIL.

+1

Questo metodo funziona con una GUI? Quello che voglio fare è chiamare la classe del rilevatore di movimento che questo loop stia girando dalla mia GUI, ma con il loop si blocca solo la GUI. Se lo uso con il thread, causerà il loop del motion detection in background mentre la GUI ascolta l'input ad esso associato? – Stefoth

+1

@Stefoth questo è più o meno come funziona la programmazione GUI. La GUI verrà eseguita nel proprio thread e il codice di rilevamento del movimento verrà eseguito autonomamente. – msvalkon

26

Il biblioteca RPi.GPIO Python ora supporta Eventi, che sono spiegate nel paragrafo Interrupts and Edge detection.

Così, dopo l'aggiornamento del Raspberry Pi con sudo rpi-update per ottenere l'ultima versione della libreria, è possibile modificare il codice per:

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 

ho scelto il metodo Threaded callbacks perché suppongo che il programma fa alcune altre cose in parallelo per modificare il valore di var.