Saltar al contenido
Control Automático Educación

Timer Arduino

Hola controleros y controleras en el día de hoy vamos a aprender a usar el famoso TIMER de ARDUINO que nos dará la posibilidad de programar tareas en tiempos exactos en nuestro proyecto de automatización.

Antes de comenzar, te hago la invitación para que veas nuestro CURSO GRATIS DE ARDUINO.

Timer en Arduino

Es indudable que realizar una medición de tiempo precisa en un proyecto autónomo es de suma importancia por lo que todo aquel que esté aprendiendo a utilizar el Arduino, deberá entender como trabajar con los temporizadores o TIMERS del ARDUINO.

El Timer Arduino está fuertemente relacionado con lo que vimos en la entrada pasada, de las Interrupciones con Arduino (timer arduino interrupt), y esto es dado a que como ya lo anticipábamos en ese post, los timers serán ejecutados por medio de una interrupción para atender alguna tarea en especifica.

Interrupción Arduino

Si ya has usado la instrucción delay del Arduino sabes que dicha instrucción nos permite temporizar, sin embargo, el problema de esa función es que BLOQUEA el Arduino y debemos esperar hasta que el tiempo del delay transcurra para poder continuar con el programa y esto en muchos casos es INVIABLE.

delay Arduino

La ventaja de los timers de Arduino es justamente esa, que podremos temporizar el tiempo, cuando simultáneamente estamos realizando otra tarea con la placa de desarrollo.

En resumen, el Timer del Arduino es un Temporizador que se programa en el Arduino que se dispara en un tiempo predeterminado. Y en cada momento que este temporizador se dispara, el Arduino ejecuta una función de Interrupción. Por ejemplo, se puede programar un timer que se dispare a cada segundo, o a cada 3 segundos y así sucesivamente, para que el Arduino cumpla una tarea específica.

Timer Arduino

Modos de Timers

Cuando hablamos de Timer en Arduino, podemos pensar en 2 modos de funcionamiento en los cuales se puede aplicar esta importante característica.

Entonces el timer lo podemos usar en:

  1. Una señal PWM: Es la señal que podemos controlar en los pines del Arduino con el símbolo (~), la cual vamos a abordar en detalle en otra entrada del sitio web.
  2. CTC (Clear timer on compare match): Esta es la opción que vamos a usar el día de hoy y simplemente como su nombre lo indica, el sistema contabiliza un tiempo dentro de un contador y cuando este contador alcanza el valor del registro de los timers, se ejecuta la interrupción del Arduino.

A continuación se muestra los modos que pueden ser configurados en los registros del microcontrolador. Sin embargo, si tu vas a utilizar librerías para la configuración será mucho más facil de alplicarlo.

Tipos de Timers

Dado que el timer es un recurso del microcontrolador del Arduino podremos realizar el conteo de tiempo sin la necesidad de ningún hardware externo.

Cada placa de Arduino posee un cristal de cuarzo, por ejemplo, para el caso del Arduino UNO, MEGA, Pro Mini tenemos un cristal de cuarzo de 16MHz. Ese cristal es el encargado de darle los tiempos de ejecución (ticks) del programa interno del Arduino.

Cristal Cuarzo Arduino UNO - Timer Arduino

El Timer se vale de ese cristal, donde teóricamente podríamos ejecutar una interrupción cada 1/16.000.000 segundos o lo que se conoce como 1 tick. Cada instrucción consume  “x” ciclos de reloj, entonces tenemos que  dividir este ciclo por la frecuencia de  dicho reloj. La mayoría de las instrucciones consumen un ciclo; por eso se considera que la arquitectura AVR da (casi) 1MIPS por Mhz.

Sólo los saltos y algunas instrucciones de 16 bits necesitan más ciclos; eso es algo que pasa en todas las arquitecturas

Sin embargo, para ejecutar las instrucciones propias del Arduino, muchas veces consumimos más de 1 tick. Los Timers disponibles en Arduino poseen un registro el cual nos dice cuántos ticks son necesarios para disparar el timer.

Dependiendo de la placa de Arduino que poseas, tendrás disponible para tus proyectos los siguientes Timers

Timer 0 Arduino

Es de 8bits. Usado para las funciones delay(), millis(), micros(). Es conveniente NO modificar este TIMER para evitar alterar estas funciones que son muy comunes en nuestros códigos

Timer 1 Arduino

Es de 16 bits. Usado por la librería Servo en Arduino Uno (Timer5 para Arduino Mega). Se usa principalmente para el control de Servos, sin embargo, si no estas controlado servos, puedes usar este timer 1 arduino libremente.

Timer 2 Arduino

Es de 8 bits. Usado en la función tone(). Si no usas este módulo, puedes emplear el timer 2 Arduino libremente para temporizar otra aplicación.

Timer 3, 4, 5 Arduino Mega

solo disponibles en los Mega. Todos de 16bits. Muy utilizados principalmente para el control de Servos, sin embargo también eres libre de usarlos como te convenga.

Prescaler y Registros de Comparación

Como ya lo detallamos anteriormente por causa del cristal de 16MHz los temporizadores pueden incrementar sus contadores a 16MHz, cada tick del contador representa 1 / 16,000,000 de segundo (~ 63ns), por lo que un contador, por ejemplo, tardará un incremento de10 en 625ns (muy rápido)

Vemos que la velocidad del contador a 16MHz es demasiado rápida. Y dado que el Timer0 y el timer2 son temporizadores de 8 bits, significa que pueden almacenar un valor de contador máximo de 255. El Timer1 es un temporizador de 16 bits, lo que significa que puede almacenar un valor de contador máximo de 65535. Una vez que un contador alcanza su máximo valor, este volverá a cero. (Esto se llama desbordamiento).

Esto significa que a 16MHz, incluso si configuramos el registro de comparación de comparación con el valor máximo del contador, se producirán interrupciones cada 256 / 16,000,000 segundos (~ 16us) para los contadores de 8 bits, y cada 65,536 / 16,000,000 (~ 4 ms) segundos para el Contador de 16 bits. Claramente, esto continua siendo muy rápido, y estar interrumpiendo el programa constantemente no tiene mucho sentido.

Para controlar la velocidad del incremento del temporizador utilizamos el prescaler el cual establece la veloidad de temporización con la siguiente ecuación:

(velocidad del temporizador (Hz)) = (velocidad del reloj Arduino (16MHz)) / prescaler

Por lo tanto, un prescaler de 1 incrementará el contador a 16MHz, un preescaler de 8 lo incrementará a 2MHz, un preescaler de 64 = 250kHz, y así sucesivamente.

El prescaler puede ser igual a 1, 8, 64, 256 y 1024.

Prescaler Arduino

La frecuencia de interrupción viene dado por la siguiente ecuación:

frecuencia de interrupción (Hz) = (velocidad de reloj Arduino 16,000,000Hz) / (preescaler * (registro de comparación + 1))

el +1 está ahí porque el registro de comparación está indexado a cero

Al reorganizar la ecuación anterior, se puede resolver el valor de registro de comparación que le dará la frecuencia de interrupción deseada:

Registro de comparación = [16,000,000Hz / (preescalador * frecuencia de interrupción deseada)] – 1

recuerde que cuando usa los temporizadores 0 y 2, este número debe ser menor que 256 y menor que 65536 para el temporizador1

así que si deseas una interrupción a cada segundo (frecuencia de 1Hz):

Registro de comparación = [16,000,000 / (preescaler * 1)] -1

con un prescaler de 1024 obtienes:

Registro de comparación = [16,000,000 / (1024 * 1)] -1= 15,624

desde 256 <15,624 <65,536, debe usar el TIMER1 para esta interrupción.

Registros del TIMER

Internamente, el microcontrolador del Arduino es manejado por diferentes registros. La gran ventaja de Arduino es que muchas veces nosotros como usuarios, no tenemos que entrar en detalle como configurar estos registros internos, ya que la propia interfaz de Arduino hace toda la configuración por nosotros. Sin embargo, en aplicaciones como el Timer, si no empleamos librerías, deberemos optar por modificar estos registros manualmente. Los registros de temporizador más importantes son:

Comparadores

Utilizados para comparar el estado del contador del timer, con el resultado de la configuración establecida mediante el pre-escalador (si es que lo usamos…) con el fin de ejecutar una acción si la comparación resulta en una igualdad.

Configuración de timers

Comenzaremos estableciendo el modo CTC para poder activar las interrupciones cada que ocurra un desbordamiento del TIMER. Esto sucede cuando el registro contador (TCNTn) coincida con el valor del registro de comparación de salida (OCRnA/B).

Los registros deben ser vistos en el propio datasheet del microcontrolador que estamos usando, por eso deben tener cuidado y ver cada hoja de datos. La ventaja que nos da Arduino IDE es que nos entrega ya definidos los registros correspondientes a nuestra placa.

La configuración de timers se hacen dentro de setup() del Sketch siempre desactivando las interrupciones antes de comenzar a configurar el/los timer/s y re-activarlas al final.

La configuración del código de la interrupción se predefine con la función:

y la interrupción la configuraremos usando las constantes pre-configuradas para cada placa que para nuestro caso será TIMERn_COMPA_vect

Finalmente, los registros que usaremos son:

TCCRnA/B

Registros de control para poder configurar el timer en modo CTC y el pre-escalador.

Timer0/2 (Arduino UNO y Mega 2560)

  • TCCRnA debe estar todo en 0 excepto por el bit WGM01 que debe estar en 1 para configurar el modo CTC.
  • TCCRnB debe estar todo en 0 excepto los bits que vayamos a usar en 1 para nuestro pre-escalador, si es que usaremos uno.

Timer1 (Arduino UNO y Mega 2560), Timer3/4/5 (Arduino Mega 2560)

  • TCCRnA debe estar todo en 0 para nuestro uso

  • TCCRnB debe estar todo en 0 excepto por el bit WGMn2 que debe estar en 1 para configurar el modo CTC y los bits del pre-escalador que necesitemos si es que usaremos uno

TCNTn

Registro contador. Por lo general lo inicializaremos en 0 al comenzar.

OCRnA

Registro comparador de salida. Luego de definir nuestro pre-escalador, este registro lo usaremos con un valor específico para que las interrupciones ocurran cuando el valor del contador (TCNTn) coincida con éste registro.

TIMSKn

Registro de configuración de interrupción. En nuestro caso lo usaremos con todos los bits en 0 menos el bit OCIEnA que deberá estar en 1 para indicarle a nuestro timer que usaremos el registro OCRnA para comparar.

Modo normal con interrupción por desbordamiento
 

El siguiente ejemplo muestra cómo parpadear el LED en el pin 13 de la placa Arduino UNO a intervalos de 1 segundo y usando la interrupción de desbordamiento del temporizador:

 

En este ejemplo, el temporizador se configuró en modo normal, con los pines OC1A y OC1B desconectados (TCCR1A = 0). Se seleccionó Prescaler de 1024 a través del registro TCCR1B. Para que el temporizador se desborde cada segundo, es necesario comenzar su valor con la diferencia entre su valor máximo (65536) y el período deseado. El período se calcula teniendo en cuenta la frecuencia del oscilador y el prescaler seleccionado, además de la frecuencia de interrupción deseada. Finalmente, la interrupción del TIMER1 se habilitó a través del bit T0IE1 del registro TIMSK1. El parpadeo del LED se realiza en la rutina de interrupción donde es necesario volver a cargar el temporizador para el conteo correcto.

Interrupción del modo CTC en comparación

El siguiente ejemplo muestra cómo parpadear el LED usando el modo CTC y generando interrupción en comparación:

 

En este ejemplo, se utiliza el modo CTC, por lo que el valor del conteo del temporizador se compara constantemente con el registro OCR1A. Para el funcionamiento, se seleccionó el modo CTC, el bit WGM12 = 1 y el prescaler establecido en 1024. El valor de comparación se cargó en el registro OCR1A y finalmente se habilitó la interrupción de comparación. El LED se invierte en la rutina de interrupción, aquí no es necesario restablecer el temporizador con un valor, porque el modo CTC restablece el temporizador cuando se alcanza el valor de comparación.

Librería Arduino TimerOne

Esta librería puede ser descargada directamente del repositorio de Arduino junto con su documentación (Arduino Timer Library). Para eso abra el Sketch del Arduino, y en la propia pestaña Sketch (parte superior) diríjase a  “Include Library” y luego a “manage Libraries”, y aquí busque por TimerOne e instale.

Librerias de Arduino - TIMER

Actualmente Arduino NO tiene una librería OFICIAL para el manejo de TIMERs debido a que estos TIMERs son usados por funciones base del arduino, como el delay, millis, micros, servo, etc. Tal y como lo detallamos en el apartado anterior. Por lo tanto, si comenzamos a modificar el timer 1 de Arduino, no podremos usar la librería Servo, pues esta presentaría inconsistencias.

SINTAXIS

Veamos como utilizar esta libería para el uso primordial de temporización, en una entrada futura, la analizaremos para el manejo de la señal PWM.

Para comenzar procedemos llamando la librería

Esto va a crear automáticamente dentro del código un objeto llamado Timer1, el cual procedemos a configurar con las siguientes instrucciones.

La instrucción Timer1.inizialize de Arduino inicializa el timer con el valor de period, este valor es el tiempo en el que queremos que se dispare el temporizador y debe ser escrito en microsegundos.

Activa la función especifica que será ejecutada como interrupción, cada que el TIMER se dispare. Similar a como lo vimos en la entrada pasada.

Desactiva la función de interrupción que se ejecuta cada que el TIMER se dispara.

Lee el tiempo transcurrido desde la última transferencia en microsegundos.

A continuación veremos ejemplos del timerone arduino.

TimerOne Ejemplo

Una de las aplicaciones a ser utilizadas con los timers es realizar con Arduino un Temporizador o un contador de tiempo. Por lo tanto en el siguiente ejemplo haremos un temporizador con Arduino usando la librería timerone. El resultado lo visualizaremos en un LCD 20×4 con Arduino.

En este ejemplo veremos un temporizador Arduino con LCD

TimerOne

Eso es todo por la entrada del dia de hoy, espero les haya gustado y hayan aprendido algo nuevo. Si te ha servido el contenido de esta entrada, de los videos y los códigos de implementación y deseas apoyar mi trabajo invitandome a un café super barato, puedes hacerlo en el siguiente link:

👉 Invitar a Sergio a un Café ☕️

Que esten muy bien, nos vemos en la siguiente entrada.

Summary
Como usar el Timer en Arduino
Article Name
Como usar el Timer en Arduino
Description
Existen várias formas de usar el Timer en Arduino. Una de ellas es modificando directamente los registros del microcontrolador. O la más fácil es a través de librerías como el TimerOne, donde simplemente la inicializas "Timer1.initialize(period);" y posteriormente activando la interrupción "Timer1.attachInterrupt( ISR_Callback) ;"
Author
Publisher Name
Control Automático Educación
Publisher Logo