Encuentra información referente a la programación, electrónica y mucho más, la página está pensada para compartir contenido educativo relevante coadyuvando a su aprendizaje diario.
Timer con Arduino o interrupciones internas

El manejo de un timer o también llamado interrupciones internas con Arduino es un tema muy útil que nos ayudara a realizar proyectos que necesiten medir el tiempo con mayor precisión y realizar alguna tarea específica, como sábenos Arduino no tiene una librería oficial para el manejo de timers, aunque si existe librerias de terceros que nos ayuda al manejo de estos.

Al no tener la suficiente información sobre los timers en la página web oficial de Arduino, estamos obligados a hacer uso de los datasheet de los microcontroladores que usan las tarjetas de desarrollo de Arduino, para poder recabar información sobre el manejo correcto de estos timers o temporizadores.

Un timer es ejecutado internamente en el microcontrolador generando una señal cuadrada que es determinada por la frecuencia que trabaja el microcontrolador.

Como ya dijimos cada placa de Arduino presenta sus propias características por lo cual debemos diferenciar uno de otro en el caso de Arduino UNO que es una de las tarjetas más usadas tiene 3 timers para su manejo y además trabaja con un cristal de cuarzo  de 16MHZ, en el caso un Arduino MEGA tiene 6 timers, estos datos son muy útiles para empezar trabajar con los timers.

Modos de operación de los timers en Arduino

Según el datashet del microcontrolador Atmega328p que esta presente en la placa Arduino UNO nos dice que existen 4 modos de funcionamientos y son:

Modo normal.- Es el modo más simple de operar, la dirección de conteo siempre se incrementa y cuando llega a desbordarse llegando a su valor máximo de 8 bits se reinicia el conteo.

Modo CTC (Clear Timer on Compare Match). – En este modo el contador se borra y se reinicia a cero cuando el valor de TCNTn es igual al valor de OCRnA, esto nos ayuda a contar los eventos externos.

Modo PWM rápido (Fast PWM).- Con este modo podemos trabajar con una onda PWM de alta frecuencia, en este modo el contador cuenta desde abajo hasta arriba, el contador se incrementa hasta que el valor del contador es igual al valor de arriba (OCRnA) y se borra en el siguiente ciclo.

Modo PWM de fase correcta (Phase Correct PWM Mode).- Gracias a este modo podemos trabajar con una onda PWM de alta resolución y está basada en una doble pendiente, este contador cuenta desde abajo hasta arriba y luego de arriba hacia abajo,este modo de doble pendiente son muy utilizados para aplicaciones de control de motores.

Tipos de Timers en Arduino

En la documentación provista por Arduino en sus sitio web no existe la suficiente información sobre el manejo de Timers, esto lo podemos solucionar accediendo a las hojas de datos de los microcontroladores que Arduino usa en sus placas, esto hace que el tratamiento no sea siempre igual en todas las placas de Arduino, por lo cual debemos tomar en cuenta que siempre existirá diferencias entre un microcontrolador y otro.

Los microcontroladores Atmega168 y Atmega328 cuentan con 3 Timers pero claro no son los únicos que usamos entre otros microcontroladores muy usados podemos citar el Atmega1280 y Atmega2560 que tienen 6 Timers para poder desarrollar nuestros proyectos.

Timer0.- Este Timer tiene un tamaño de 8 bits por lo cual podemos trabajar hasta un valor máximo de 255, este temporizador o Timer es usada para el buen funcionamiento de las funciones delay(), millis(), y micros().

Timer1.- Este Timer o temporizado es de 16 bits esto nos dice que podemos trabajar con valores de hasta 65535, este Timer es referenciado en la librería <Servo.h> para manejar servos, esto hace que si estamos usando esta librería para manejar servos y modificamos el funcionamiento del Timer1 posiblemente no funcione de forma correcta nuestro proyecto con servos.

Timer2.- Este Timer es de 8 bits, Arduino lo usa para reproducir sonidos mediante ondas cuadradas con la función tone(), esto es muy útil cuando deseamos realizar algún proyecto sonoro, pero si no vamos a usar la función tone(), este Timer puede ser modificado para satisfacer nuestro requerimientos.     

Timer3, 4 ,5.- Estos Timers están presentes en los microcontroladores Atmega1280 y Atmega2560, son de 16 bits por lo cual podemos trabajar con valores de hasta 65535.

Prescaler en los timers en Arduino

Cuando hablamos de Timer o temporizador siempre lo relacionamos con un prescaler, un prescaler no es más que un circuito capaz de reducir aquella señal de alta frecuencia a una de menor frecuencia mediante un divisor, su principal función es regular el tiempo a una velocidad óptima para nuestro proyecto.

El prescaler trabaja con 1, 8, 64, 256 y 1024  

Arduino Uno tiene un cristal de cuarzo de 16MHz que trabaja directamente con el microcontrolador Atmega128P, esto implica que las interrupciones serian cada 4.1ms con un timer de 16 bits, si trabajamos con un timer de 8 bits seria 15.94µs, esto generaría una interrupción demasiada rápida y no sería muy práctico.

Prescaler de un timer con arduino

Para poder trabajar con tiempos más largos debemos utilizar un prescaler para ampliar el tiempo para este caso usaremos el modo CTC (Clear Timer on Compare Match) que consiste en realizar una comparación y hacer el desbordamiento del registro, si queremos hacer el calculo del valor de comparación y almacenarlo en el registro OCRnA, a continuación haremos el cálculo para hacer una interrupción por timer cada 1 segundo.

Calculo del periodo del prescaler

Si el resultado sobrepasa los 255 esto utilizaremos el Timer1 ya que admite hasta un valor de 65535 y está dentro el rango permitido, los Timer 0 y 2 solo admiten hasta un máximo de 255, lo primero que debemos hacer, es obtener la frecuencia mínima requerida y guardarlo en registro TCCRnB, gracias a esto el prescaler se habilitara para trabajar con ella, como ya sabemos solo podemos trabajar con prescaler de 1, 8, 32, 64, 256 y 1024, el microcontrolador Atmega128P utiliza la siguiente formula, en caso de usar otro debe consultar su hoja de datos.

Donde OCRnx sera igual a 0 para obtener la máxima frecuencia posible y N es el prescaler, con esto podemos ya podemos empezar a realizar nuestros cálculos.

En este caso obtendremos la máxima frecuencia con el prescaler de 1024 y si creemos que es óptimo para nuestro proyecto, procedemos a habilitar este prescaler en el registro TCCRnB.

Esto nos genera un periodo de 0.0000128 segundos.

Con este periodo de tiempo tendremos una interrupción por desbordamiento cada 32.64ms.

Como vemos aun es pequeño el tiempo pero podemos utilizar un acumulador para almacenar un valor en cada interrupción por desbordamiento, necesitaríamos alrededor de 30 ciclos para llegar lo más cerca de un segundo (0.03264s * 30 = 0.9792s), esta sería una solución en caso que deseemos trabajar con un Timer de 8 bits.

Configuración de Timers en Arduino

Hasta ahora ya sabemos cómo obtener los tiempos para el Timer que deseamos usar, pero es hora de configurar en nuestro código y para esto necesitamos básicamente 4 instrucciones, TCCRnA/B, TCNTn, OCRnA y TIMSKn.

TCCRnA/B.- Es un registro para configurar el modo de funcionamiento del Timer.

TCNTN.- Es el registro  contador.

OCRnA.- Es un registro que lo usamos para realizar la comparación de los valores ya mencionados anteriormente y así realizar el desbordamiento y realizar las interrupciones.

TIMSKn.- Este registro es usado para configurar nuestra interrupción.

Funcion ISR(interrupcion)

Esta función es usada para realizar subrutinas que se ejecutaran en cada interrupción de nuestro Timer, y según la hoja de datos, el vector de interrupciones del microcontrolador Atmega328P existe 10 posibles interrupciones para trabajar con el Timer.

Ejemplo un Timer con Arduino pero sin el uso de librerías

El ejemplo consiste en encender 4 led de forma secuencial y apagarlos de forma secuencial, cada led se encenderá tras pasar un segundo y se apagara cada segundo.

Materiales

  • 1 Arduino Uno
  • 4 led
  • 4 Resistencias de 220 o 330 ohmios
  • Cables para la conexión

Diagrama de conexión

Diagrama del ejemplo de interrupciones internas o timer con Arduino

Código

/* AUTOR: CREATIVIDAD CODIFICADA
 *  www.creatividadcodificada.com
 *  NOMBRE DEL PROYECTO: Encendido de Leds con Timers
*/
volatile unsigned int contador = 8;
void setup()
{
//configuramos nuestro pines de salida para los leds
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);
   
  //deshabilitamos las interrupciones
  noInterrupts();

// configuracion de del Timer1 de 16 bits en modo CTC y prescales de 1024
  TCCR1A = 0;                 
  TCCR1B = 0; 
  TCCR1B |= (1 << WGM12)|(1<<CS10)|(1 << CS12);

//Inicializamos el contador               
  TCNT1  = 0;

// configuramos nuestro registro de comparacion para 1 segundo
  OCR1A = 15624;

//configuramos el desbordamiento             
  TIMSK1 |= (1 << OCIE1A);  

// habiltamos nuestras interrupciones
  interrupts();
}
  void loop()
  {
  //.....
  }
  void encenderLed(byte led)
  {
    digitalWrite(led, !digitalRead(led));
    }
  ISR(TIMER1_COMPA_vect)          
  {
    encenderLed(contador);
    contador++;
    if(contador>11)contador = 8;
  }

2 comentarios sobre: “Timer con Arduino o interrupciones internas

¿Que te parecio el artículo?

Su dirección de email no sera publicado. Los campos obligatorios están marcados con *.

¿Qué hacemos con tus datos?

Creatividad Codificada como responsable tratará tus datos con la finalidad de gestionar tu participación en nuestro blog informativo. Puedes acceder, rectificar y suprimir tus datos, así como ejercer otros derechos consultando la información adicional y detallada sobre protección de datos en nuestra Política de Privacidad