Módulo RTC DS1307 con Arduino


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.

Materiales necesarios

  • 1 Arduino. (comprar Arduino MEGA)
  • Módulo RTC DS1307. (comprar RTC DS1307)
  • Cables. (comprar cables)

RTC DS1307 06Mó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.

RTC DS1307 09
Esquema eléctrico Arduino Mega.

RTC DS1307 08
Esquema gráfico Arduino Mega.

RTC DS1307 04
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.
}

RTC DS1307 05
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.
}

RTC DS1307 07
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.

Descargar Sketch


5 comentarios en «Módulo RTC DS1307 con Arduino»

  1. 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(" ");

    Responder
  2. 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.

    Responder

Deja un comentario