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.
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 981El 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 1004Finalmente, 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 1000Todos 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.BOTHSi 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.BOTHAquí 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 2002Muestra 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