runtimewarning raspberry already python events raspberry-pi motion gpio

raspberry - python gpio channel



Raspberry Pi- GPIO Eventos en Python (4)

Estoy usando los pines GPIO en mi Raspberry Pi con un sensor PIR para detectar movimiento. Cuando el sensor detecta movimiento, quiero mover el software a otras funciones.

En este momento, para detectar movimiento, mi programa se ejecuta constantemente en un bucle mientras espera que se detecte el movimiento. Si bien esto funciona en este momento, para usar en el futuro será increíblemente ineficiente y espero mejorar esto asignándolo a un evento.

¿Hay alguna forma de enlazar mi entrada GPIO a un evento que detecte el programa sin ejecutar un ciclo manualmente?

Aquí está mi bucle actual para el movimiento de detección:

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)

El contador y el movimiento de detección se utilizan varias veces para reducir el número de falsos positivos que el sensor detecta.



La biblioteca RPi.GPIO Python ahora admite eventos , que se explican en el párrafo Detecciones de interrupciones y bordes .

Entonces, después de actualizar tu Raspberry Pi con sudo rpi-update para obtener la última versión de la biblioteca, puedes cambiar tu código a:

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

Elegí el método de devoluciones de llamada por hilo porque supongo que su programa hace algunas otras cosas en paralelo para cambiar el valor de var .


Podría ajustar el código GPIO en su propio hilo y hacer que el resto de su programa haga otra cosa mientras el GPIO está esperando la entrada. Echa un vistazo al módulo de enhebrado.

Primero envolvería tu código en una función

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)

Y luego en tu programa principal podrías algo como esto

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

Hay muchas preguntas sobre SO con respecto al enhebrado de python, por lo que es posible que desee desenterrarlas. Tenga en cuenta que también hay muchas cosas que considerar al usar hilos, especialmente en python, que tiene un bloqueo de intérprete global (GIL) que permite que solo se ejecute un proceso a la vez. También puede ser inteligente revisar el módulo de multiprocesamiento con el que se puede enrutar alrededor de la GIL.


kapcom01 da algunas ideas geniales, pero es mejor no dar muchas instrucciones en una interrupción.

Por lo general, coloca un indicador en 1 cuando la devolución de llamada es llamada y realiza el procesamiento en la función principal. De esta manera no hay riesgo de liberar el programa.

Algo como esto:

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