El DS1307  de Maxim/Dallas es un circuito integrado reloj en tiempo real (RTC) capaz de almacenar y llevar la cuenta de la fecha y hora de manera autónoma, además disponemos de unos cuantos bytes de memoria RAM no volátil (NVRAM) para almacenar datos arbitrarios. En esta entrada, exploraremos las ventajas y operaciones básicas del circuito DS1307 instalado en el módulo TinyRTC, también explicaremos su funcionamiento en conjunto con una placa arduino para aquellas aplicaciones que requieren un control preciso del tiempo.

El módulo Tiny RTC, además de todo el circuito de soporte para el DS1307, incluye también una memoria EEPROM I2C para almacenar datos en ella y un zócalo para soldar de manera opcional un sensor de temperatura DS18B20 (one-wire),  sin embargo en esta ocasión trataremos únicamente el uso del DS1307; el uso de la memoria EEPROM y el sensor quedarán de tarea para el lector.

El arduino posee un CPU bastante poderoso, y sin embargo aún así es incapaz de mantener la hora correctamente a largo plazo, debido a los microsegundos que se atrasan (o adelantan) al dividir la frecuencia del reloj principal para dar con el segundo exacto. Por esta razón tanto el arduino como nuestra PC requieren de un circuito integrado especializado que incluye un oscilador a cristal de cuarzo. Dicho oscilador genera una frecuencia estable y divisible mediante hardware digital para lograr el segundo exacto. Este circuito integrado especializado normalmente también tiene la capacidad de funcionar en un modo de bajo consumo que permite alimentarlo con una batería pequeña (del tipo que llevan los relojes).

Conceptos básicos.

Para entender como funciona el circuito DS1307 y el programa que corre en la tarjeta Arduino debemos conocer algunos conceptos clave:

  • RTC o Reloj en Tiempo Real – Es un circuito electrónico especializado cuya función es mantener la hora y fecha actual en un sistema informático (ya sea con microcontrolador u otro tipo de CPU). Se caracteríza por tener un bajo consumo de energía y también normalmente su propia fuente de alimentación auxiliar. Al recurrir a este tipo de circuitos integrados es de esperar que se obtenga una mejor precisión en la cuenta del tiempo. Un ejemplo de dispositivos que incluyen relojes en tiempo real son las computadoras personales (PC).
  • Bus I2C o TWI – Es el protocolo de comunicación físico mediante el cual se comunican el Arduino y el módulo RTC DS1307. El bus cuenta con dos lineas: de datos y de reloj, ambas del tipo colector abierto (o drenador abierto). Por lo que se requieren resistencias pull-up (Rpu en el esquemático) para generar un estado lógico alto. Más abajo en esta página se muestra una conexión básica del DS1307 con un microcontrolador a través del bus I2C.
  • Decimal codificado en binario – Es un estándar de datos en el cual los dígitos decimales se representan mediante secuencias de 4 bits. Esto es así por que con 4 bits se pueden representar todos los dígitos decimales del 0 al 9. En un byte en memoria se pueden almacenar números decimales del 0 al 99. En el DS1307 los datos de fecha y hora están codificados en BCD y veremos más adelante la forma de convertir de BCD a binario. A continuación se muestran los dígitos decimales y sus equivalentes en BCD.equivalencia_BCD

Recomendamos ampliar nuestra lectura sobre estos temas para poder comprender como funciona el reloj en tiempo real DS1307 y poder solucionar cualquier problema durante las prácticas que realicemos.

Funcionamiento interno y registros del DS1307

  • Para la comunicación a través de I2C, el DS1307 requiere de dos resistencias pull-up en los pines SDA y SCL. Si vamos a utilizar el pin SQW/OUT, este también requiere una resistencia pull-up para funcionar correctamente.
  • El DS1307 requiere un cristal de 32.768 Khz, este valor viene dado por el hecho de que 2^15 = 32,768. Esto quiere decir que la frecuencia es divisible binariamente para generar un segundo exacto. El cristal ya se incluye si compramos algún módulo con el DS1307.
  • El DS1307 requiere dos fuentes de alimentación: Por una parte, requiere alimentación de 5 volts que opera mientras el circuito esta encendido y funcionando y otra fuente de poder que proviene de una batería de litio (tipo reloj) que mantiene funcionando el reloj/calendario mientras la alimentación principal NO esta disponible. El cambio entre ambas fuentes de alimentación es gestionado por el DS1307 de manera automática.ds1307_conexion_con_microcontrolador
  • Disponemos de un pin de salida que puede ser configurado para que el RTC entregue una onda cuadrada con una frecuencia configurable, las frecuencias disponibles se muestran en la siguiente tabla y se configuran mediante los bits RS1, RS0 y SQWE de registro de control, si se usa este pin hay que agregar una resistencia pull-up, ya que es del tipo “Open drain”:ds1307_squarewave_output
  • Los registros del DS1307 almacenan la fecha y la hora en formato BCD. La dirección de cada registro y la información almacenada en cada uno se muestra en la siguiente tabla:ds1307_mapa_de_registros
  • El funcionaliento del chip se controla mediante el bit 7 del registro del segundero (0x00) y el registro de control (0x07): El bit CH del segundero detiene el reloj cuando esta en alto (así se entregan los módulos de fábrica) y en este modo NO se lleva el conteo de tiempo por que el oscilador esta detenido. ES MUY IMPORTANTE PONER A 0 ESTE BIT PARA QUE EL RTC FUNCIONE (ver código de ejemplo). El registro de control maneja la funcionalidad del pin de salida de onda cuadrada.ds1307_registro_de_control
  • A partir de la dirección 0x08 disponemos de memoria RAM no volátil (NVRAM) cuyo contenido no se borra con la pérdida de energía, este segmento de memoria funciona de manera similar a una memoria EEPROM, solo que no existen limitaciones en cuanto al numero de escrituras.

Materiales necesarios.

Para las prácticas vamos a requerir el siguiente material, que pueden encontrar en nuestra tienda virtual:

Conexión del TinyRTC al Arduino

El módulo TinyRTC requiere las siguientes conexiones con la tarjeta Arduino. Nótese que el pin “DS” del módulo TinyRTC no se utiliza, corresponde al sensor de temperatura 1-wire que no se encuentra instalado de fábrica. Solamente son indispensables las lineas SDA, SCL y la alimentación de 5 volts:

ds1307 con arduino. Tinyrtc diagrama de conexion

Para montar el circuito de prueba, podemos auxiliarnos de un protoboard, de manera opcional. También es válido usar solamente cables.El circuito armado nos quedó de la siguiente forma:

tutorial_ds1307_con_arduino_01

Ejemplo de lectura DS1307 sin librería

Con la información que tenemos hasta ahora, ya podemos darnos una idea de como estructurar el sketch para leer y escribir el RTC DS1307. Utilizaremos la librería “Wire.h” que se incluye instalada de serie con el ambiente arduino para manejar la comunicación I2C entre el DS1307 y el Arduino. Presentamos dos “sketches” o programas. En el primero realizaremos la escritura o puesta a tiempo del módulo RTC y en el segundo, realizaremos la lectura y muestra de la información de fecha y hora que ya hemos almacenado. En estos ejemplos NO estamos utilizando ninguna librería específica para el DS1307, solamente utilizamos la librería “Wire.h” de arduino para hablar con dispositivos a través del bus I2C.

¿Como poner a tiempo el DS1307?

El siguiente código permite escribir una fecha arbitraria en el RTC y ponerlo a funcionar. Hay que configurar una fecha y hora válidos (actual) dentro de la función setup, donde se inicializan los valores de variables que contienen información horaria. Hay que aclarar que se trata de un ejemplo minimalista que será fácil de entender para los principiantes.

El resultado de ejecutar el sketch anterior en el DS1307 debe ser como el siguiente:

poner_a_tiempo_ds1307_con_arduinoEste programa no genera salida adicional a la terminal serial, ya que solamente pone a tiempo el reloj. Una vez puesto a tiempo ya  podemos usar la información almacenada con nuestro siguiente sketch o para la aplicación que estamos desarrollando. Recomendamos ejecutar este sketch solamente una vez, ya que siempre que se resetea o conecta la tarjeta este reestablecerá la misma fecha y hora programadas, es necesario cargar el sketch de lectura de inmediato y evitar reiniciar la tarjeta con este sketch cargado.

¿Como leer la fecha y hora del DS1307?

El siguiente sketch lee la información de fecha y hora del DS1307 y la muestra en la terminal (monitor serial).

El resultado de este programa es  el siguiente, deberemos ver la fecha y la hora en el monitor serial, esta debe conservarse aunque desconectemos el cable USB o la alimentación principal del Arduino.

leer_tiempo_ds1307_con_arduino

Librería de Arduino para el DS1307

La librería para el DS1307 encapsula el código anterior en una clase cuyos métodos podemos llamar para obtener la fecha y hora o poner a tiempo el reloj. Usando una librería, nuestro programa principal puede reducirse bastante, además de que queda más legible y elegante. En el ejemplo siguiente vamos a ver como realizar la operación de lectura, pero esta vez haciendo uso de la librería DS1307RTC.

Para que el siguiente código funcione, es necesario descargar e instalar dos librerías en nuestro entorno de arduino:

  • Librería DS1307RTC – Esta librería permite leer y escribir el reloj DS1307
  • Librería TimeLib – Permite realizar operaciones de fecha y hora en formato unix (solo se usa para compilar la libreria DS1307RTC, no forma parte de los ejemplos).

En la carpeta de ejemplos de la librería DS1307RTC podemos encontrar también el ejemplo para poner a tiempo el reloj con una fecha y hora arbitrarias.

El resultado de ejecutar el ejemplo anterior debe ser similar al siguiente:

monitor_serial_ds1307_01

Programación de un horario con Arduino

En esta entrada te enseñamos lo básico sobre el funcionamiento del reloj en tiempo real DS1307. Sin embargo hasta ahora solo puedes leer o escribir la fecha / hora. Si deseas aprender a realizar acciones concretas en una fecha y hora determinadas, será necesario que continues estudiando nuestro siguiente tutorial que trata el tema de la programación de eventos y horarios con el Arduino y un RTC. Puedes encontrar el tutorial avanzado del RTC en el siguiente enlace:

Con este tutorial puedes realizar el control de cargas de corriente alterna, como lámparas y ventiladores, aunque en realidad puedes controlar muchas otras cosas a través de las librerías disponibles para arduino. Te invitamos a continuar aprendiendo sobre el tema.

Conclusión

En este tutorial aprendimos como manipular los registros del DS1307 para ponerlo a tiempo y para realizar la lectura de la fecha y hora. Aprendimos que es posible accesar al DS1307 mediante librerías especializadas o de forma manual mediante la librería “wire.h” sin necesidad de instalar ninguna otra librería. La forma final en la que el usuario accede a los datos del RTC depende de sus preferencias y del proyecto en el que se trabaja. El DS1307 es un ejemplo muy bueno de como podernos comunicarnos con cualquier dispositivo usando el bus I2C, por lo que siempre podemos utilizar este código como base para cualquier dispositivo que  posee interfaz I2C.