Micropython: Interrupciones externas en el ESP8266

El uso de interrupciones es una técnica habitual en los circuitos con microcontroladores para atender eventos rápidos que de otra manera podrían pasar desapercibidos. En este artículo veremos los recursos que nos ofrece Micropython para atender interrupciones externas en el caso específico de una placa con el ESP8266.

Interrupciones

Las interrupciones nos proveen de un método eficaz para responder rápidamente a un evento que requiere de nuestra atención de manera inmediata, o que se produce esporádicamente o dura un intervalo de tiempo muy pequeño. En un microcontrolador existen varias fuentes de interrupciones. Algunas son internas, como un timer que llega a un determinado valor, el conversor A/D que finaliza una conversión o un módulo de comunicaciones que recibió un dato desde un puerto. Otras en cambio son externas, como las que se producen cuando se activan determinados pines de Entrada/Salida (GPIO).

Cuando se produce una interrupción, se altera el flujo normal del programa y la ejecución salta a la llamada Rutina de Atención de Interrupciones (ISR, Interrupt Service Routine) o Controlador de interrupciones (Interrupt handler) donde debemos atender al evento que la produjo lo mas rápido posible y volver a retomar el flujo normal.

En esta ocasión nos centraremos sólo en las interrupciones externas y veremos como manejarlas en un ESP8266.

Pines

Todos los pines de E/S del ESP8266 pueden generar interrupciones externas menos GPIO16

Interrupciones en Micropython

Micropython incluye los mecanismos para manejar interrupciones externas en el módulo machine, que ya vimos cuando analizamos el manejo de las entradas y salidas. De hecho, utilizaremos la misma clase Pin que en esa oportunidad. Por lo tanto, lo primero que debemos hacer es importar esta clase en nuestro código:

from machine import Pin

El método que vamos a emplear es irq, que acepta los siguientes parámetros:

irq (trigger=condicion, handler=callback)

trigger: Especifica en que condiciones se dispara la interrupción externa:

Pin.IRQ_FALLING: El disparo se produce en el flanco de bajada (cuando el pin cambia de 1 a 0)

Pin.IRQ_RISING: El disparo se produce en el flanco de subida (cuando el pin cambia de 0 a 1)

Estas dos condiciones se pueden combinar con la función “OR” para que el disparo se produzca en ambos flancos (ascendente O descendente).

handler: Es la función que atiende a la interrupción (a una función que se pasa como parámetro de otra función, como en este caso se le denomina “callback”). Esta función tiene un único parámetro de entrada que es el número de pin que disparó la interrupción.

Ejemplo con D1 mini

En este ejemplo vamos a conectar una tecla a la entrada D1 de una placa D1 mini para generar interrupciones y veremos como funciona el programa. Tal vez necesites repasar cómo configurar los pines de GPIO en este artículo anterior.

Conexión a la entrada D1

El programa es el siguiente:

from machine import Pin

#Mapeo de GPIO de D1 Mini
D0 = 16
D1 = 5
D2 = 4
D3 = 0
D4 = 2
D5 = 14
D6 = 12
D7 = 13
D8 = 15

def AtiendeInterrupcion (pin):
     print ("Interrumpe el pin: ", pin)

Boton1 = Pin (D1, Pin.IN, pull=Pin.PULL_UP)  #Tecla en D1
Boton1.irq (trigger=Pin.IRQ_FALLING, handler=AtiendeInterrupcion)

while (True):
     pass

Analicemos el código: Comenzamos importando la clase Pin del módulo machine.

Luego, se definen como constantes todos los pines de E/S de la D1 Mini con su correspondiente pin físico. Es una buena costumbre incluir estas definiciones al principio de cada programa, según el tipo de placa que usemos, para no tener que estar consultando la correspondencia (mapeo) entre la denominación del pin (Dx) y su número físico en una imagen o tabla. Estas definiciones pueden guardarse en un archivo “.py” aparte e importarse como un módulo mas.

Seguidamente se define la función AtiendeInterrupcion que se ejecutará cada vez que se dispare una interrupción externa. Le llega como parámetro el número de pin y lo único que hace en este ejemplo es precisamente imprimir ese valor.

A continuación encontramos la definición del pin Boton1, que se corresponde con el pin D1, que es una entrada con el PULL UP activado.

Luego, empleando el método irq activamos la generación de interrupciones en ese pin (Boton1) y especificamos que las mismas se dispararán en el flanco de bajada e indicamos cual es la función que las atiende.

Finalmente, en el bucle principal no hacemos nada.

La ejecución del programa nos muestra una impresión en la consola cada vez que se pulsa la tecla, ya que tal como está conectada eso hace que la entrada pase de 1 (valor establecido por el PULL UP) a 0 (GND a través de la tecla).

Salida del programa de ejemplo

Conclusión

En este artículo vimos las generalidades de las interrupciones externas y como atenderlas en un ESP8266, en futuras publicaciones veremos ejemplos prácticos para aprovechar esta funcionalidad. Cualquier duda o sugerencia pueden dejarla en la sección de comentarios.

Deja un comentario

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

Habilitar notificaciones OK No, gracias