ESP32 - Interrupción de GPIO

En este tutorial, vamos a aprender cómo usar las interrupciones GPIO en el ESP32. Las interrupciones GPIO en el ESP32 permiten un manejo receptivo y eficiente de eventos externos, lo que las hace esenciales para aplicaciones en tiempo real en IoT y sistemas embebidos. Al entender y configurar adecuadamente estas interrupciones, puedes crear proyectos robustos y receptivos que reaccionen de inmediato al entorno.

Interrupción GPIO del ESP32

Hardware Requerido

1×Módulo de Desarrollo ESP32 ESP-WROOM-32
1×Cable USB Tipo-A a Tipo-C (para PC USB-A)
1×Cable USB Tipo-C a Tipo-C (para PC USB-C)
1×Push Button
1×Protoboard
1×Cables Puente
1×(Recomendado) Placa de Expansión de Terminales de Tornillo para ESP32
1×(Recomendado) Breakout Expansion Board for ESP32
1×(Recomendado) Divisor de Alimentación para ESP32

Or you can buy the following kits:

1×DIYables ESP32 Starter Kit (ESP32 included)
1×DIYables Sensor Kit (30 sensors/displays)
1×DIYables Sensor Kit (18 sensors/displays)
Divulgación: Algunos de los enlaces proporcionados en esta sección son enlaces de afiliado de Amazon. Podemos recibir una comisión por las compras realizadas a través de estos enlaces sin costo adicional para usted. Apreciamos su apoyo.

¿Qué es una interrupción GPIO?

Una interrupción de GPIO es una señal que provoca que el procesador detenga su ejecución actual y salte a un fragmento específico de código conocido como la rutina de servicio de interrupción (ISR). Esto permite que el ESP32 maneje tareas de alta prioridad de inmediato, sin necesidad de sondear continuamente los pines GPIO.

Interrupciones en ESP32

El ESP32 admite varios tipos de interrupciones de GPIO:

  • Flanco Ascendente: Se activa cuando el pin GPIO cambia de BAJO a ALTO.
  • Flanco Descendente: Se activa cuando el pin GPIO cambia de ALTO a BAJO.
  • Ambos Flancos: Se activa ante cualquier cambio de estado, ya sea de BAJO a ALTO o de ALTO a BAJO.
  • Nivel Bajo: Se activa cuando el pin GPIO permanece BAJO.
  • Nivel Alto: Se activa cuando el pin GPIO permanece ALTO.

Cómo configurar las interrupciones GPIO en el ESP32

Para configurar una interrupción GPIO en el ESP32, debes seguir estos pasos:

Inicializar el GPIO: Establezca el modo del pin GPIO como entrada o salida según sea necesario. Por ejemplo:

pinMode(GPIO_Pin, INPUT_PULLUP);

Adjuntar la interrupción: Utilice la función attachInterrupt() para vincular el pin GPIO a un ISR.

attachInterrupt(GPIO_Pin, ISR_function, mode);

Esta función acepta tres argumentos:

  • GPIO_Pin: Especifica el pin GPIO que se utilizará como pin de interrupción, indicando qué pin debe monitorear el ESP32.
  • ISR_function: El nombre de la función que se llamará cada vez que ocurra la interrupción.
  • mode: Define la condición que activa la interrupción. Hay cinco constantes predefinidas que se pueden usar:
    • RISING: Dispara cuando el pin pasa de LOW a HIGH (en Borde ascendente).
    • FALLING: Dispara cuando el pin pasa de HIGH a LOW (en Borde descendente).
    • CHANGE: Dispara en cualquier cambio en el estado del pin (en Ambos bordes).
    • HIGH: Dispara cuando el pin está en HIGH (en Nivel Alto).
    • LOW: Dispara cuando el pin está en LOW (en Nivel Bajo).

    Define la función ISR: Escribe la rutina de servicio de interrupción que se ejecutará cuando se active la interrupción.

    La rutina de servicio de interrupciones (ISR) es una función que se invoca cada vez que ocurre una interrupción en el pin GPIO. Su sintaxis se muestra a continuación.

    void IRAM_ATTR ISR_function() { Statements; }

    Vamos a sumergirnos en un ejemplo práctico de usar interrupciones con el pin GPIO del ESP32 conectado a un botón.

Diagrama de Cableado

Diagrama de cableado del ESP32 para un pulsador

This image is created using Fritzing. Click to enlarge image

Si no sabe c\u00f3mo alimentar ESP32 y otros componentes, encuentre instrucciones en el siguiente tutorial: C\u00f3mo alimentar ESP32.

Código de interrupciones de ESP32

#define BUTTON_PIN 21 // The ESP32 pin GPIO21 connected to the button void IRAM_ATTR handleButtonPress(); void setup() { Serial.begin(9600); // Initialize the GPIO pin as an input pinMode(BUTTON_PIN, INPUT_PULLUP); // Attach interrupt to the GPIO pin attachInterrupt(digitalPinToInterrupt(BUTTON_PIN), handleButtonPress, FALLING); } void loop() { // Main code here } // Interrupt Service Routine (ISR) void IRAM_ATTR handleButtonPress() { Serial.println("Button pressed!"); }

En este ejemplo:

  • El BUTTON_PIN está definido como GPIO21.
  • La función pinMode() configura el pin GPIO como una entrada con una resistencia pull-up interna.
  • La función attachInterrupt() adjunta la ISR handleButtonPress al BUTTON_PIN, configurada para activarse en un borde descendente.
  • La función handleButtonPress es la ISR que se ejecuta cuando se presiona el botón.

El código anterior muestra cómo se ve el código de interrupción, pero puede no funcionar en la práctica porque utiliza la función Serial.println(), la cual tarda más en procesarse de lo permitido en una rutina de servicio de interrupción.

Para probar cómo funcionan las interrupciones, consulte el ejemplo de código práctico a continuación:

#define BUTTON_PIN 21 // The ESP32 pin GPIO21 connected to the button volatile bool buttonPressed = false; // use volatile for variable that is accessed from inside and outside ISR void IRAM_ATTR handleButtonPress(); void setup() { Serial.begin(9600); // Initialize the GPIO pin as an input pinMode(BUTTON_PIN, INPUT_PULLUP); // Attach interrupt to the GPIO pin attachInterrupt(digitalPinToInterrupt(BUTTON_PIN), handleButtonPress, FALLING); } void loop() { // Main code here if (buttonPressed) { Serial.println("Button pressed!"); buttonPressed = false; // Reset the flag } // Other code here } // Interrupt Service Routine (ISR) void IRAM_ATTR handleButtonPress() { // Serial.println("Button pressed!"); // do NOT use function that takes long time to execute buttonPressed = true; }

Pasos R\u00e1pidos

  • Si es la primera vez que usas ESP32, consulta cómo configurar el entorno para ESP32 en Arduino IDE.
  • Realiza el cableado como en la imagen de arriba.
  • Conecta la placa ESP32 a tu PC mediante un cable micro USB.
  • Abre Arduino IDE en tu PC.
  • Selecciona la placa ESP32 correcta (p. ej. ESP32 Dev Module) y el puerto COM.
  • Copia el código anterior y ábrelo con Arduino IDE
  • Haz clic en el botón Upload en Arduino IDE para cargar el código al ESP32
  • Presiona el botón varias veces
  • Consulta el resultado en el Monitor Serial
COM6
Send
Button pressed! Button pressed! Button pressed! Button pressed!
Autoscroll Show timestamp
Clear output
9600 baud  
Newline  

Es posible que observe que una sola pulsación de un botón da lugar a múltiples eventos de pulsación que se muestran en el Monitor Serial. Esto no es un problema de interrupciones, sino un problema con el propio botón. Para aprender a solucionarlo, consulte el tutorial ESP32 - Botón - Debounce.

Puedes ver otro ejemplo que utiliza interrupciones en este tutorial ESP32 - Rotary Encoder.

Consideraciones importantes

  • Sin parámetros ni valores de retorno: Una función ISR no puede tener ningún parámetro y no debe devolver nada.
  • Tiempo de ejecución de la ISR: Mantenga el código ISR lo más corto y eficiente posible. Los ISRs largos pueden hacer que el sistema pierda otras interrupciones o degradar el rendimiento general.
  • Concurrencia: Tenga cuidado con los recursos compartidos accedidos dentro de las ISR. Use operaciones atómicas o desactive las interrupciones si es necesario para evitar condiciones de carrera. Específicamente, use la palabra clave volatile para las variables accedidas tanto dentro como fuera de la función ISR.
  • IRAM_ATTR: Coloque el código ISR en IRAM usando el atributo IRAM_ATTR para garantizar que se ejecute rápidamente sin leer desde la memoria flash.

Video Tutorial

Estamos considerando crear tutoriales en video. Si considera que los tutoriales en video son importantes, suscríbase a nuestro canal de YouTube para motivarnos a crear los videos.

Tutoriales Relacionados

※ NUESTROS MENSAJES

  • No dude en compartir el enlace de este tutorial. Sin embargo, por favor no use nuestro contenido en otros sitios web. Hemos invertido mucho esfuerzo y tiempo en crear el contenido, ¡por favor respete nuestro trabajo!