En este segundo tutorial sobre Arduino les enseñaremos a usar un modulo RTC (Real Time Clock) mediante el bus I2C. Usaremos una librería que nos facilitará la comunicación entre este modulo y Arduino. El módulo que emplearemos es el Tiny RTC I2C que incorpora un reloj de tiempo real DS1307, una batería para memorizar los datos y una pequeña memoria EEPROM 24C32.
Arduino incorpora sus propios temporizadores, uno de ellos es millis(). Muchos usuarios se preguntaran para que usar un modulo externo temporizador, la respuesta es sencilla, los temporizadores de Arduino son contadores que cuando se inician empiezan desde 0, por ejemplo millis() se inicia una vez conectemos la alimentación de Arduino, es el contador encargado de indicar cuanto tiempo lleva encendido Arduino, y una vez se pierde la alimentación, este valor desaparece.
Podemos entender entonces, que para algunos proyectos que necesitemos usar el tiempo como variable, estos contadores no nos servirían y necesitaríamos un RTC externo que posea una batería para almacenar los datos.
Índice de Contenido
Materiales necesarios
- 1 Arduino. (comprar Arduino MEGA)
- Módulo RTC DS1307. (comprar RTC DS1307)
- Cables. (comprar cables)
Módulo Tiny RTC I2C.
Esquemas y montaje
Comenzaremos conectando el modulo a nuestra placa Arduino, es sencillo de conectar ya que usa una comunicación I2C.
Esquema eléctrico Arduino Mega.
Esquema gráfico Arduino Mega.
Una vez conectado, tendremos que añadir la librería RTClib a la IDE de Arduino. La descargaremos y descomprimiremos en C:/diretorio arduino/libraries
Esta librería se apoya en la librería Wire para la comunicación I2C, por lo que tendremos que hacer referencia a ella he incluirla en nuestro código. No os preocupeis, la librería Wire ya viene por defecto añadida a la IDE. RTClib es compatible con cualquier modulo RTC que usel el chip DS1307.
Código para configurar el módulo RTC DS1307
#include <Wire.h> #include "RTClib.h" RTC_DS1307 RTC; void setup () { Wire.begin(); // Inicia el puerto I2C RTC.begin(); // Inicia la comunicación con el RTC RTC.adjust(DateTime(__DATE__, __TIME__)); // Establece la fecha y hora (Comentar una vez establecida la hora) Serial.begin(9600); // Establece la velocidad de datos del puerto serie } void loop () { }
Descripción del código
RTC.adjust(DateTime(__DATE__, __TIME__));
Esta función establecerá la fecha y hora en nuestro reloj DS1307. La fecha y hora usada para cargarla en nuestro modulo, será la fecha de creación del archivo .hex generado al compilar el sketch.
Código para mostrar fecha y hora
Una vez cargado el código anterior en nuestro Arduino, ya debería estar configurada la fecha y hora en el módulo RTC. Para mostrar la fecha y hora actual usaremos el código siguiente.
#include <Wire.h> #include "RTClib.h" RTC_DS1307 RTC; void setup () { Wire.begin(); // Inicia el puerto I2C RTC.begin(); // Inicia la comunicación con el RTC //RTC.adjust(DateTime(__DATE__, __TIME__)); // Establece la fecha y hora (Comentar una vez establecida la hora) Serial.begin(9600); // Establece la velocidad de datos del puerto serie } void loop(){ DateTime now = RTC.now(); // Obtiene la fecha y hora del RTC Serial.print(now.year(), DEC); // Año Serial.print('/'); Serial.print(now.month(), DEC); // Mes Serial.print('/'); Serial.print(now.day(), DEC); // Dia Serial.print(' '); Serial.print(now.hour(), DEC); // Horas Serial.print(':'); Serial.print(now.minute(), DEC); // Minutos Serial.print(':'); Serial.print(now.second(), DEC); // Segundos Serial.println(); delay(1000); // La información se actualiza cada 1 seg. }
Si todo es correcto veremos la fecha actual como se muestra en la imagen.
Podremos comprobar que desconectando la alimentación, y no la batería, la fecha y hora seguirá siendo la correcta.
La librería RTClib tiene una función que merece la pena mencionar, esta función es dayOfWeek() Es una función que devuelve el valor del día de la semana, es decir, si es lunes retornara un 1, si es martes un 2, si es miércoles un 3 y así sucesivamente. En el siguiente código vemos como se usa:
Código para mostrar el día de la semana
#include <Wire.h> #include "RTClib.h" RTC_DS1307 RTC; void setup () { Wire.begin(); // Inicia el puerto I2C RTC.begin(); // Inicia la comunicación con el RTC //RTC.adjust(DateTime(__DATE__, __TIME__)); // Establece la fecha y hora (Comentar una vez establecida la hora) Serial.begin(9600); // Establece la velocidad de datos del puerto serie } void loop () { DateTime now = RTC.now(); Serial.print("Dia de la semana: "); Serial.println(now.dayOfWeek(), DEC); // L(1), M(2), X(3), J(4), V(5), S(6), D(7) delay(1000); // La información se actualiza cada 1 seg. }
Resultado final.
Solución de errores
Numerosos usuarios nos han comentado alguno de los problemas que han tenido a la hora de usar este módulo. Estas son las recomendaciones a seguir para resolverlos.
- Se muestra la fecha 2000/1/1 0:0:0
Este resultado se debe a que la batería del reloj está agotada o esta se ha quitado con anterioridad. Sustituya la batería por una nueva o coloque la batería y configure la fecha de nuevo. - Se muestra la fecha 2165/165/165 165:165:85
Se debe a un fallo de conexión o algún otro fallo interno producido por la manipulación del módulo mientras que esta alimentado. Comprueba las conexiones, desconectar el módulo de Vcc, quitar la pila y volver a conectar Vcc. Desconectar nuevamente Vcc poner la pila y volver a conectar Vcc.
Intenta no manipular el modulo mientras está conectado a Vcc, ya sea de Arduino u otra fuente de alimentación externa.
excelente y funcional pero como le pongo ceros a la izquierda ya que marca 13:1:1 en lugar de 13:01:01
saludos
if (RTC.hour < 10) // correct hour if necessary
{Serial.print("0"); Serial.print(RTC.hour, DEC);}
else
{Serial.print(RTC.hour, DEC); }
Serial.print(":");
if (RTC.minute < 10) // correct minute if necessary
{Serial.print("0");
Serial.print(RTC.minute, DEC); }
else
{Serial.print(RTC.minute, DEC); }
Serial.print(":");
if (RTC.second < 10) // correct second if necessary
{Serial.print("0"); Serial.print(RTC.second, DEC); }
else
{Serial.print(RTC.second, DEC);}
Serial.print(" ");
if (RTC.day < 10) // correct date if necessary
{Serial.print("0"); Serial.print(RTC.day, DEC);}
else
{Serial.print(RTC.day, DEC); }
Serial.print("-");
if (RTC.month < 10) // correct month if necessary
{Serial.print("0"); Serial.print(RTC.month, DEC); }
else
{Serial.print(RTC.month, DEC);}
Serial.print("-");
Serial.print(RTC.year, DEC); // Year need not to be changed
Serial.println(" ");
Excelente tutorial, ya me funciona perfectamente en el monitor serial y en una pantalla lcd 16 x 2.
Necesito implementar un RTC pero con display 7 segmentos, sólo las horas y los minutos.
Cómo sería la forma? Yo lo hice pero sin RTC y cuando se corta la energía la hora se pierde y toca volver a ajustar la hora.
Men me da error en la compilacion
Disculpa, para configurar con la hora de la pc, sabrias como hacerlo??
Gracias!!
Saludos!!