Arduino y las interrupciones (Parte I)

Introduccion

Pues nada como dice el titulo, comenzaremos con un pequeño post de lo que es Arduino y sus interrupciones, realmente estoy pensando en hacer post con cosas un tanto "complicadas" utilizando la tarjeta Arduino, el porque, pues porque quiero y ya (ja ja ja como un buen show de comedia) en fin, primero lo primero, este blog no esta enfocado en empezar de lo básico como prender y apagar leds o tener converciones analogico-digitales (Existen muchos post en internet, un mar de informacion diria yo) no! aqui vamos a las carnitas a proyectos un poco mas complejos (segun verdad porque igual lo que ando pensado hacer existen muchos post jar jar jaaaaaar) y pues bueno basta de mucho blah blah blah y empecemos, ahora si (por fin!!).

Arduino

¿Que es?

Es una plataforma código abierto (Open-Source) basadas en hardware y software. (Esperaban mas pues no). Esto es lo que es Arduino en pocas palabras.

Características:

- Microcontrolador ATmega328
- Voltaje de entrada de 6 a 12 [V]
- 14 Pines de entrada y salida digital (de los cuales 6 se pueden usar tambien como generadores de señal PWM)
- 6 Entradas analógicas.

Interrupciones

¿Que es una interrupción? (Pues yo ni se la verdad pero les tratare de explicar lo mejor posible)

Básicamente es una señal que interrumpe la actividad normal de nuestro micro controlador y existen tres tipos de interrupción:

1.- Un evento realizado por hardware (De la cual partiremos).

2.- Un evento programado  (Uso de timers, estas son interesantes y hasta la fecha en lo personal solo las eh ocupado con los PIC).

3.- Por software (Este se los debo no lo manejo por el momento, si encuentro información mas detallada con gusto se las compartiré).

¿Como funciona una interrupción por hardware?



Supongan el siguiente ejemplo, ustedes están tranquilamente leyendo y de repente comienza a llover y tienen ropa tendida en el patio de su casa, que es lo que hacen, de manera inmediata suspenden su lectura y meten de manera veloz su ropa, terminando esto, siguen tranquilamente con su lectura, bingo!! eso es una interrupción.

Ahora nos trasladaremos al mundo de la electrónica, cuando algo interrumpe la ejecución normal de nuestro programa, este de manera inmediata suspende la actividad llevada a cabo (de manera ordenada para regresar al punto de interrupción) saltando a ejecutar la funcion que en este punto se denominara Interrupt Service Handler o ISH, cuando la ISH termiana, el proceso vuelve de manera tranquila al punto donde se quedo y sigue con lo que estaba haciendo, como si no hubiese pasado nada.
(Imaginense a los pinguinos de Madagascar diciendo tu nos has visto nada en este punto).

Bueno y a todo esto, por que la interrupción, que mi Arduino no es lo suficientemente veloz como para saber en que punto hacer y no hacer las cosas, acaso me estas diciendo que no sirve o que pasa aqui...

La respuesta es simple, de pende, jar jar jaaar, claro, todo va a depender de lo que estemos haciendo, el como lo estemos haciendo y el para que lo estemos haciendo, nuestros Arduino son veloces no lo negare pero, una señal electrónica es mucho mas veloz todavía, eh aquí el por que en muchas ocasiones el uso de los delay no conviene mucho, lamento reventarles la burbuja pero no son muy eficientes en algunas ocasiones... pero como dije antes, todo va a depender de lo que estemos haciendo.

Bueno mucha teoría hasta este punto, lo se a mi tampoco me gusta mucho pero venga, tienen que saber como funciona esto si no como van a saber aplicar el concepto y en donde.

Interrupciones, su funcionamiento en Arduino y el primer ejemplo

Llegados a este punto comenzare con lo que sigue, como puedo usarlas en mi Arduino, como mencione al principio de esta entrada (creo que lo hice no estoy muy seguro)  solo usaremos un Arduino UNO, por tanto tienen que tener en cuenta que:

En la placa Arduino UNO, NANO, MINI, y otros basados en el chip 328 solo se puede hacer uso de estas funciones por los pines 2 y 3, un poco limitadas pero bueno para lo que vamos a hacer va de sobra.

Para hacer llamado de esta funcion puede ser:

  1. LOW: Cuando se tenga un 0 logico.
  2. CHANGE: Cuando se tenga un cambio de 0 a 1 o de 1 a 0.
  3. RISING: Por flanco de subida, cuando pase de 0 a 1.
  4. FALLING: Por flanco de bajada, cuando pase de 1 a 0.
Como vamos a mandar llamar a nuestra función:

  (digitalPinToInterrupt(pin), ISR, mode); 

digitalPinToInterrupt(pin): En que pin se realizo la interrupcion.
ISR: "Interrup Service Rutine" el modo de la interrupcion.
mode: El modo en que sera utilizada (LOW, CHANGE, RISING, FALLING).



Y bueno como siempre, ahora viene un ejemplo, este es sencillo, es el prender y apagar un led pero por interrupciones.

Esquema eléctrico:


Funcionamiento:





Programa:

//Definimos el pin que ensendera y apagara cada que presionemos un boton
#define led 10   
//Definimos el pin donde sera la interrupcion que es el pin dos
const int interrupcion = 2;
//Definimos unavariable de tipo entero volatile
volatile int estado = LOW;

void setup() {
  
  //Definimos el pin llamado led como salida
  pinMode(led, OUTPUT);
  //Definimo el pin de la interrupcion como entrada
  pinMode(interrupcion, INPUT);
  //Mandamos llamar la funcion de interrupcion y que esta sea cada que existe un cambio
  //de 0 logico (0 volts) a un 1 logico (5 volts)
  attachInterrupt(digitalPinToInterrupt(interrupcion), parpadeo, CHANGE);
  //Inicio de comunicacion serie con Arduino
  Serial.begin(9600);
}

//Creamos la funcion llamada parpadeo
void parpadeo(){

  //Cada que exista un cambio en el pin lo negara
  // es decir cuando se tenga un 0 logico tendremos un 1 logico y viceversa
  estado = !estado;

}

void loop() {
  
  //Escribiremos de manera digital lo que se tenga en la funcion por interrupcion
  //Si tiene un 0 logico el led estar apagado, si tiene un uno logico encendera el led
  //y asi de manera infinita.
  digitalWrite(led, estado);
  //Funcion para mandar datos cada que se hace una interrupcion
  Serial.println(estado);

}

Si cargaron el programa tal cual, verán que prende el led, pero tiene un tipo de parpadeo extraño, asi que para corregir eso se agregara un control anti rebote controlado por tiempo, y el código se los dejo por acá:

//Definimos el pin que ensendera y apagara cada que presionemos un boton
#define led 10   
//Definimos el pin donde sera la interrupcion que es el pin dos
const int interrupcion = 2;
//Definimos unavariable de tipo entero volatile
volatile int estado = LOW;
//Extra, opcion para control "Anti rebote" con tiempo
unsigned long T = 0;

void setup() {
  
  //Definimos el pin llamado led como salida
  pinMode(led, OUTPUT);
  //Definimo el pin de la interrupcion como entrada
  pinMode(interrupcion, INPUT);
  //Mandamos llamar la funcion de interrupcion y que esta sea cada que existe un cambio
  //de 0 logico (0 volts) a un 1 logico (5 volts)
  attachInterrupt(digitalPinToInterrupt(interrupcion), parpadeo, CHANGE);
  //Inicio de comunicacion serie con Arduino
  Serial.begin(9600);

}

//Creamos la funcion llamada parpadeo
void parpadeo(){
  //Control de tiempo cuando sea 0 + 250 milisegundos se vera si existe
  //algun cambio de lo contrario se quedara igual.
  if(millis() > T + 250){
  //Cada que exista un cambio en el pin lo negara
  // es decir cuando se tenga un 0 logico tendremos un 1 logico y viceversa
  estado = !estado;
  T = millis();
  }
}

void loop() {

  //Escribiremos de manera digital lo que se tenga en la funcion por interrupcion
  //Si tiene un 0 logico el led estar apagado, si tiene un uno logico encendera el led
  //y asi de manera infinita.
  digitalWrite(led, estado);
  //Funcion para mandar datos cada que se hace una interrupcion
  Serial.println(estado);

}

Conclusiones

Como se observa se pueden realizar interrupciones y aprovecharlas para realizar otras funciones que este llevando nuestro Arduino.

Se puede llevar a cabo una instrucción con un tiempo de retardo con la función de interrupción de Arduino, no obstante, no debemos sobrecargar dichas instrucciones porque se puede llegar a tener fallos en la misma, algún error de lectura por decir algo.

Esto es algo que va en serio, no debe llevar a cabo cálculos muy complejos con las interrupciones, comunicación serie, I2C y SPI.

Las variables de las ISR si se dieron cuenta, en este programa se hizo volátil, pero, ¿porque?

Las variables "Volatile" indican que dicha variable tiene que ser consultada antes de ser usada porque pudo haber sido modificada de manera ajena al flujo natural del programa (bingo!!! esto es lo que hace una interrupción, modifica el flujo del programa al ser interrumpido osea una interrupción del programa).
para mas referencias entren en este link:
Les advierto esta en ingles, osea ya se jodieron!

Así que hasta aquí el post, espero que les sirva de algo, y espero que sigan leyendo el blog para mas proyectos, cualquier duda, ya saben comentario saludos!.









Comentarios

Entradas populares de este blog

Arduino y las Interrupciones parte III (Medir RPM con Arduino)

RPM, Arduino y un Display LCD

LABview y Arduino