ESP32 & Interrupciones Externas

La diferencia entre una interrupción programada y otra externa es que el temporizador que dispara la alarma a intervalos programados es sustituido por un botón conectado a un pin. Entre otras posibilidades.

Precisamente este es el sentido de las interrupciones, poder hacer otras cosas mientras no suceda el evento, pero cuando ese evento externo esté presente, que ejecute rápidamente el código asociado y en función de nuestras necesidades esa interrupción podra ser rápida para que vuelva al trabajo original o tan larga como para interrumpir el tiempo que se defina en el codigo del manejo de ese disparo.

Si ya hemos comprendido bien como se producen las interrupciones programadas, lo que expongo a continuación será mas fácil de entender con un sketch completo que de nuevo utilizará un servo para no perder el concepto.

Antes de seguir un aviso:

NO DEBEMOS DEJAR EL “VOID LOOP ” VACIO DE SUCESOS, POR EJEMPLO PUEDE OCURRIR QUE ESTE LAZO PRINCIPAL SOLO CONTENGA EL MANEJO DE LA INTERRUPCIÓN,LO QUE IMPLICA QUE CUANDO CARGUEMOS EL CODIGO,EL LAZO NO EJECUTARÁ NADA HASTA QUE LLEGUE EL DISPARO QUE PONGA EN MARCHA LA INTERRUPCIÓN, Y LO QUE OBSERVARAS ES QUE LA PLACA SE RESETEARA APROX. CADA 4 O 5 SEGUNDOS. SE SOLUCIONA METIENDO UN DELAY DE 10 msg (void(10))

EJERCICIO:

Contamos con un servo conectado a la GPIO 15, cuya función indefinida es barrer un sector de 0-90 y 90-0.

Lo que queremos es generar una alarma en la GPIO 27, de forma que cada vez que dicho pin pase a nivel LOW, el mismo servopase a barrer el sector completo 0-180 y 180-0 a la misma velocidad anterior. Pero queremos que esto ocurra a los 10 segundos de activada la alarma. Ademas quiero monitorizar el evento en el monitor serie.

Hemos conectado un pulsador en la GPIO 27 en pull up, con su resistencia física. Cuando este pase a nivel GND (falling) la función ISR cambiará el valor de la variable goblal volatil “trigger”, y cuando el servo llegue de vuelta a 0 grados se parará durante 10 segundos y comenzara a girar a 180 grados y vuelta a 0, la variable trigger pasar de nuevo a “false”, el servo seguira con su código principal y preparado para recibir otra interrupción. El efecto es el mismo que reconocer el disparo de la interrupción pero no ejecutarla hasta que el lazo principal le deje un hueco, o finalizar la secuencia de lo que estaba haciendo. Soy un poco pesado con esto, porque cuando empecé a estudiar este tema, creí entender que una interrupción paraba en el acto la ejecución de un codigo, y eso no es así.

#include <Servo.h>

Servo servo_15;  // create servo object to control a servo

long t1 = 0;
int pos15;
const int Sensor = 27;

volatile boolean trigger = false;
int t;

void IRAM_ATTR isr() {

  trigger = true;
 
}

void setup() {
  Serial.begin(115200);
  servo_15.attach(15);
  pos15 = 0;
  servo_15.write(pos15);

  pinMode(Sensor, INPUT);
  

  attachInterrupt(digitalPinToInterrupt(Sensor), isr, FALLING);

}

void loop() {
for (pos15 = 0; pos15 <= 90; pos15 += 1) {
        // in steps of 1 degree
        servo_15.write(pos15);
        delay(28);
      }
      for (pos15 = 90; pos15 >= 0; pos15 -= 1) {
        servo_15.write(pos15);
        delay(28);
      }
 

  if (trigger == true  ) { //  decir if (trigger) es igual que if (trigger = true)
   Serial.println("Alerta se ha detectado una alarma");
   delay(100);
        Serial.println("servo barrera 180 grados en 10 segundos");
    for (t=0;t<=10;t+=1){
    Serial.println(t);
    delay(1000);
    }
      for (pos15 = 0; pos15 <= 180; pos15 += 1) {
        // in steps of 1 degree
        servo_15.write(pos15);
        delay(28);
      }
      for (pos15 = 180; pos15 >= 0; pos15 -= 1) {
        servo_15.write(pos15);
        delay(28);
      }

      trigger = false;
    }
}

Cinco constantes están predefinidas como valores válidos:

LOWLos disparadores interrumpen cuando el pin está LOW
HIGHLos disparadores interrumpen cuando el pin es HIGH
CHANGELos disparadores interrumpen cuando el pin cambia de valor, de HIGH a LOW o LOW a HIGH
FALLINGLos disparadores interrumpen cuando el pin va de HIGH a LOW
RISINGLos disparadores interrumpen cuando el pin va de LOW a HIGH

El problema de rebote o bouncing producido por el hardware, esto es, el mismo boton que se conecta al pin para ponerlo a nivel bajo, causa ruido que hace que el disparo se repita muchas veces, se puede evitar con un condensador de 1 microf en paralelo con el boton o también se puede arreglar introduciendo mas códigos y puedes consultar este enlace donde te lo aclararán mejor:

https://github.com/thomasfredericks/Bounce2

En mi ejemplo no se produce rebote, quizas por la configuración del código.

Como parar los disparos:

detachInterrupt(digitalPinToInterrupt(pin));

Basta con poner “detachInterrupt(digitalPinToInterrupt(Sensor));” al final del manejo de la interrupción para que solo se produzca una vez la interrupción. Pero si lo colocamos al principio del lazo principal,ya no se producira ninguna vez el disparo.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Translate »