Reloj Tiempo real I2C DS1307 Rtc

El Reloj de tiempo real DS1307 es un integrado de MAxim/Dallas, este dispositivo permite almacenar la hora y fecha de igual forma como lo hace un reloj de pulcera, para su uso disponemos de distintas librerias pero la mas usada es TimeLib.h, la cual nos permite consulta y modificar la hora y fecha almacenada en el chip.

Aun asi y sabiendo que tenemos disponibles librerias que nos hacen el trabajo mas facil pasaremos por el trauma(jejeje) de trabajar sin la librearia.

Ejemplo: (Primero las conexiones)

 

Necesitaremos soldar los pines a la placa antes.

Codigo de seteo de hora y fecha, precaución cada vez que ejecutemos se configurara la misma hora ingresada en el codigo.

 

/**
* Ejemplo para arduino de escritura de fecha y hora al DS1307 en el
* modulo TinyRTC. Este ejemplo pone a tiempo el reloj con los datos
* provistos en la funcion setup.
*/
#include <Wire.h>

// Declaracion de las variables para almacenar informacion de tiempo
uint8_t second, minute, hour, wday, day, month, year;

/**
* Inicio del sketch: Este codigo se ejecuta al conectar el arduino
*/
void setup() {
// NOTA: Estas instrucciones se requieren para alimentar directamente el
// chip RTC desde los pines A3 Y A2 (colocar directamente el modulo sobre
// la tarjeta arduino, sin la necesidad de cablear en Arduino UNO).
// Si no se quiere hacer esto, se pueden eliminar o comentar sin problemas
pinMode(A3, OUTPUT);
digitalWrite(A3, HIGH);
pinMode(A2, OUTPUT);
digitalWrite(A2, LOW);

// Configurar la comunicacion a 9600 baudios
Serial.begin(9600);

// Preparar la librería Wire (I2C)
Wire.begin();

// Imprimir encabezado a la terminal
Serial.println(«—————————————————-«);
Serial.println(» EJEMPLO ESCRITURA DE DS1307 EN TINYRTC CON ARDUINO «);
Serial.println(«—————————————————-«);

// Inicializar las variables con el tiempo a cargar en el modulo RTC
second = 0;
minute = 58;
hour = 23;
wday = 4;
day = 15;
month = 2;
year = 17;
}

/**
* Ciclo principàl del sketch: Escribir informacion de fecha y hora una sola vez
*/
void loop() {
// Escribir hora y fecha al RTC
write_ds1307();

// Imprimimos la fecha y hora
Serial.println(«Poner a tiempo el DS1307 en Tiny RTC:»);
print_time();

// Ciclo infinito, no hacemos nada mas
for (;;);
}

/**
* Esta funcion establece la cominicación con el DS1307 y lee los registros
* de fecha y hora. Entrega la informacion horaria en las variables globales
* declaradas al principio del sketch.
*/
bool write_ds1307()
{
// Iniciar el intercambio de información con el DS1307 (0x68)
Wire.beginTransmission(0x68);
// Escribir la dirección del registro segundero
Wire.write(0x00);
// Escribir valores en los registros, nos aseguramos que el bit clock halt
// Del registro del segundero este desactivado
Wire.write(bin2bcd(second & 0x7F));
Wire.write(bin2bcd(minute));
Wire.write(bin2bcd(hour));
Wire.write(bin2bcd(wday));
Wire.write(bin2bcd(day));
Wire.write(bin2bcd(month));
Wire.write(bin2bcd(year));
// Terminamos la escritura y verificamos si el DS1307 respondio
// Si la escritura se llevo a cabo el metodo endTransmission retorna 0
if (Wire.endTransmission() != 0)
return false;
}

/**
* Convierte un numero binario a BCD
*/
uint8_t bin2bcd(uint8_t bin)
{
return (bin / 10 * 16) + (bin % 10);
}

/**
* Imprime la fecha y hora al monitor serial de arduino
*/
void print_time()
{
Serial.print(«Fecha: «);
Serial.print(day);
Serial.print(‘/’);
Serial.print(month);
Serial.print(‘/’);
Serial.print(year);

Serial.print(»  Hora: «);
Serial.print(hour);
Serial.print(‘:’);
Serial.print(minute);
Serial.print(‘:’);
Serial.print(second);

Serial.println();
}

 

Ahora podemos consultar la hora  con el siguiente codigo :

 

/**
*
* Ejemplo para arduino de lectura de fecha y hora al DS1307 en el
* modulo TinyRTC. Este ejemplo envia al monitor serial la fecha y la hora
* almacenada en el RTC cada segundo.
*/
#include <Wire.h>

// Declaracion de las variables para almacenar informacion de tiempo
uint8_t second, minute, hour, wday, day, month, year, ctrl;

/**
* Inicio del sketck: Este codigo se ejecuta al conectar el arduino
*/
void setup() {
// NOTA: Estas instrucciones se requieren para alimentar directamente el
// chip RTC desde los pines A3 Y A2 (colocar directamente el modulo sobre
// la tarjeta arduino, sin la necesidad de cablear en Arduino UNO).
// Si no se quiere hacer esto, se pueden eliminar o comentar sin problemas
pinMode(A3, OUTPUT);
digitalWrite(A3, HIGH);
pinMode(A2, OUTPUT);
digitalWrite(A2, LOW);

// Configurar la comunicacion a 9600 baudios
Serial.begin(9600);

// Preparar la librería Wire (I2C)
Wire.begin();

// Imprimir encabezado a la terminal
Serial.println(«—————————————————-«);
Serial.println(«EJEMPLO LECTURA DE RTC DS1307 EN TINYRTC CON ARDUINO»);
Serial.println(«—————————————————-«);
}

/**
* Ciclo principàl del sketch: Leer y mostrar la hora y fecha cada segundo
*/
void loop() {
// Esperar 1 segundo
delay(1000);

// Leer los registros del RTC
if (read_ds1307()) {
// Mostrar la fecha y hora
print_time();
} else {
// No se puede leer desde le DS1307 (NACK en I2C)
Serial.println(«No se detecta el DS1307, revisar conexiones»);
}
}

/**
* Esta funcion establece la cominicación con el DS1307 y lee los registros
* de fecha y hora. Entrega la informacion horaria en las variables globales
* declaradas al principio del sketch.
*/
bool read_ds1307()
{
// Iniciar el intercambio de información con el DS1307 (0xD0)
Wire.beginTransmission(0x68);

// Escribir la dirección del segundero
Wire.write(0x00);

// Terminamos la escritura y verificamos si el DS1307 respondio
// Si la escritura se llevo a cabo el metodo endTransmission retorna 0
if(Wire.endTransmission() != 0)
return false;

// Si el DS1307 esta presente, comenzar la lectura de 8 bytes
Wire.requestFrom(0x68, 8);

// Recibimos el byte del registro 0x00 y lo convertimos a binario
second = bcd2bin(Wire.read());
minute = bcd2bin(Wire.read()); // Continuamos recibiendo cada uno de los registros
hour = bcd2bin(Wire.read());
wday = bcd2bin(Wire.read());
day = bcd2bin(Wire.read());
month = bcd2bin(Wire.read());
year = bcd2bin(Wire.read());

// Recibir los datos del registro de control en la dirección 0x07
ctrl = Wire.read();
}

/**
* Esta función convierte un número BCD a binario. Al dividir el número guardado
* en el parametro BCD entre 16 y multiplicar por 10 se convierten las decenas
* y al obtener el módulo 16 obtenemos las unidades. Ambas cantidades se suman
* para obtener el valor binario.
*/
uint8_t bcd2bin(uint8_t bcd)
{
// Convertir decenas y luego unidades a un numero binario
return (bcd / 16 * 10) + (bcd % 16);
}

/**
* Imprime la fecha y hora al monitor serial de arduino
*/
void print_time()
{
Serial.print(«Fecha: «);
Serial.print(day);
Serial.print(‘/’);
Serial.print(month);
Serial.print(‘/’);
Serial.print(year);

Serial.print(»  Hora: «);
Serial.print(hour);
Serial.print(‘:’);
Serial.print(minute);
Serial.print(‘:’);
Serial.print(second);

Serial.println();
}

 

Ocupando la libreria TimeLib.h

Link descargas necesarias.

Time.h

DS1307RTC

 

/*
* TimeRTC.pde
* example code illustrating Time library with Real Time Clock.
*
*/

#include <TimeLib.h>
#include <Wire.h>
#include <DS1307RTC.h>  // a basic DS1307 library that returns time as a time_t

void setup()  {
Serial.begin(9600);
while (!Serial) ; // wait until Arduino Serial Monitor opens
setSyncProvider(RTC.get);   // the function to get the time from the RTC
if(timeStatus()!= timeSet)
Serial.println(«Unable to sync with the RTC»);
else
Serial.println(«RTC has set the system time»);
}

void loop()
{
if (timeStatus() == timeSet) {
digitalClockDisplay();
} else {
Serial.println(«The time has not been set.  Please run the Time»);
Serial.println(«TimeRTCSet example, or DS1307RTC SetTime example.»);
Serial.println();
delay(4000);
}
delay(1000);
}

void digitalClockDisplay(){
// digital clock display of the time
Serial.print(hour());
printDigits(minute());
printDigits(second());
Serial.print(» «);
Serial.print(day());
Serial.print(» «);
Serial.print(month());
Serial.print(» «);
Serial.print(year());
Serial.println();
}

void printDigits(int digits){
// utility function for digital clock display: prints preceding colon and leading 0
Serial.print(«:»);
if(digits < 10)
Serial.print(‘0’);
Serial.print(digits);
}