Implementación del Manipulador GPIO IRQ: Usando Python 3 para Controlar RPi.GPIO

Este código y esta guía tienen la intención de probar la gestión de GPIO IRQ en el ODROID-C1+/C2/XU4/N2. La guía ha sido adaptada partiendo de la página wiki de ODROID https://wiki.odroid.com/odroid-xu4/application_note/gpio/rpi.gpio_irq.

Simplemente tenemos que implementar el manipulador GPIO IRQ con Python 2/3. En esta guía, usaremos Python 3 para programar el manipulador. Sin embargo, antes de empezar, tenemos que instalar RPi.GPIO para ODROID. Consulta la página Wiki https://wiki.odroid.com/odroid-xu4/application_note/gpio/rpi.gpio para las instrucciones de instalación.

Código de muestra

#!/usr/bin/env python3

import sys
import time
import RPi.GPIO as GPIO

# https://wiki.odroid.com/odroid-xu4/application_note/gpio/rpi.gpio#about_bcm_numbering
IRQ_GPIO_PIN = 25
IRQ_EDGE = GPIO.FALLING
count = 0

def handler(channel):
global count

count += 1

def print_status():
global count

print(count)
count = 0

if __name__ == '__main__':
GPIO.setmode(GPIO.BCM)
GPIO.setup(IRQ_GPIO_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.add_event_detect(IRQ_GPIO_PIN, IRQ_EDGE, callback=handler)

print('Press Ctrl-C to exit')
try:
while True:
time.sleep(1)
print_status()
except KeyboardInterrupt:
GPIO.cleanup()
sys.exit(0)
Este es un script modelo muy básico para usar el manipulador GPIO IRQ. Cuenta cuántas interrupciones se solicitan en 1 segundo y muestra el recuento total. Si un usuario presiona Ctrl + C, el script se cerrará.

Hay una función handler () que recibe un parámetro. Este parámetro es necesario ya que la librería lo necesita para registrar internamente la función del manipulador. Esta función aumenta el número de conteo en 1 cuando se recibe una interrupción. La función print_status () muestra el número del conteo e pone la variable de conteo a 0. Si el archivo de script es el principal archivo ejecutado, que significa que es el primer archivo del proyecto Python, RPi.GPIO inicialmente configurado usa GPIO.setmode (). Esta función autoriza al usuario y usa la numeración BCM para seleccionar un pin GPIO.

En GPIO.setup (), el pin GPIO seleccionado está fijado como una fuente de interrupción en este tiempo para usarse de la forma que el usuario pretendía. Deberíamos introducir 3 parámetros, que son el número de pin GPIO en la numeración BCM, la dirección de la señal y el modo pull. Deberíamos fijar la dirección de la señal y el modo pull up para recibir la interrupción GPIO.

Tenemos que añadir una función de manipulador de eventos usando GPIO.add_event_detect (). Esta tiene 3 parámetros, que son el número de pin GPIO en la numeración BCM, el modo edge IRQ y el puntero de la función del manipulador como su nombre. La librería RPi.GPIO registrará el manipulador para el pin GPIO en un bucle interno. Especificamos el modo edge de interrupción para reducir edge utilizando esta función.

Finalmente, hay códigos de gestión de excepciones que detectan interrupciones del teclado (SIGINT). Si se recibe la interrupción, el RPi.GPIO se limpia solo con la función GPIO.cleanup () y el programa se cerrará. Si no se recibe la interrupción, el bucle infinito se ejecuta y llama a print_status () cada 1 segundo, así que podemos limpiar estas largas descripciones.

Funciones

  • def handler(): un manipulador de interrupciones. Aumenta el número de conteo en 1 cuando ocurre la interrupción. Requiere al menos 1 parámetro.
  • def print_status (): muestra el número de conteo actual e inicializa a 0.
  • GPIO.setmode (): Inicia RPi.GPIO con una guía de números pin que debe usarse.
  • GPIO.setup (): fija el pin GPIO como fuente de interrupción. También configura la dirección de la señal y el modo de extracción.
  • GPIO.add_event_detect (): ajusta el mismo pin GPIO que se configuró antes, con el modo edge de interrupción y la función del controlador.
  • Ejecuta la función print_status cada 1 segundo y detecta la interrupción del teclado para cerrar el programa adecuadamente.

Entornos

Para probar su rendimiento de gestión IRQ, utilicé el siguiente conjunto de dispositivos de prueba

  • ODROID C1/C2/XU4/N2
  • Generador de funciones
  • Osciloscopio

Configuré el generador de funciones para generar una onda cuadrada de 1 KHz, y verifiqué esa onda usando un osciloscopio. Cambié la amplitud de cada objetivo a 1.8V o 3.0V cada vez que cambiaba la placa. Luego elegí los pines #22 para la fuente de interrupción y #20 para la puesta a tierra. El pin físico #22 es equivalente al #25 en la numeración BCM. Los tres modelos tienen el mismo factor de forma en el cabezal GPIO. Finalmente, conecté los cables tal y como se muestra en la Figura 1.

Figure 1 - C1+ IRQ test setup
Figura 1 - Configuración de prueba C1 + IRQ

Ejecución

Probemos primero con el C1+. Simplemente ejecute el script sin ningún cambio. Tal como está el script, debería mostrar número en torno a 1000 cada segundo, ya que está configurado para manejar las interrupciones edge descendentes y el generador de funciones está configurado para generar una onda cuadrada de 1 KHz. Para asegurarme, también comprobé la versión actual del kernel:

root@odroid:~# uname -a
Linux odroid 3.10.107-13 #2 SMP PREEMPT Wed Jun 19 02:31:43 -03 2019 armv7l armv7l armv7l GNU/Linux
root@odroid:~# python3 test.py
Press Ctrl-C to exit
1000
1003
1000
1000
1000
1001
1001
987
1001
1001
Éste muestra los números tal y como esperábamos. No podían ser exactamente 1000 en cada momento, porque hay muchos factores [no] previstos que afectan la detección de las interrupciones. Este es el resultado en el ODROID-C2:
root@odroid:~# uname -a
Linux odroid 3.16.68-41 #1 SMP PREEMPT Tue Jun 18 15:06:16 -03 2019 aarch64 aarch64 aarch64 GNU/Linux
root@odroid:~# python3 test.py
Press Ctrl-C to exit
981
993
993
984
985
996
977
995
1001
981
El siguiente resultado es del ODROID-XU4, que usa el pin #26 para la fuente de interrupción y el #28 para la puesta a tierra:
root@odroid:~# uname -a
Linux odroid 4.14.120-160 #1 SMP PREEMPT Fri May 17 01:18:14 -03 2019 armv7l armv7l armv7l GNU/Linux
root@odroid:~# python3 test.py
Press Ctrl-C to exit
1005
1007
1014
1005
1008
1003
1005
1001
1005
1004
Finalmente, así es como se ve en el ODROID-N2
root@odroid:~# uname -a
Linux odroid 4.9.182-31 #1 SMP PREEMPT Tue Jun 18 14:45:56 -03 2019 aarch64 aarch64 aarch64 GNU/Linux
root@odroid:~# python3 test.py
Press Ctrl-C to exit
1000
1002
1002
1003
1000
1000
1000
999
1000
1000
Todos los modelos funcionan bien en la gestión de GPIO IRQ con RPi.GPIO. Ten en cuenta que el número que se muestra en el rango de error aceptable no tiene importancia, ya que cambia continuamente.

Configurar el tipo de Edge GPIO IRQ

También podemos cambiar el tipo de detección edge del pin. Hay tres tipos de edge:

  • Falling
  • Rising
  • Both

Esto se puede cambiar cuando configuras el manipulador GPIO IRQ en el código utilizando la función GPIO.add_event_detect (). Estos se definen respectivamente como:

GPIO.FALLING
GPIO.RISING
GPIO.BOTH
Si deseas detectar utilizando el modo both-edge, reemplaza el valor IRQ_EDGE existente en la línea #9 por el siguiente:
# From
IRQ_EDGE = GPIO.FALLING

# To
IRQ_EDGE = GPIO.BOTH
Aquí tienes una prueba para verificar si funciona. Con C1+, el script modificado produce una onda cuadrada de 1 KHz.
root@odroid:~# python3 test.py
Press Ctrl-C to exit
1994
1997
1994
1998
1999
1980
2002
2001
2001
2002
Muestra aproximadamente 2000 porque el controlador reacciona para ambos momentos de edge, lo que significa que funciona sin problemas.

Referencias https://sourceforge.net/projects/raspberry-gpio-python/

Be the first to comment

Leave a Reply