Arduino y Real-Time-Clock (RTC) DS1302
El chip DS1302 contiene un reloj / calendario en tiempo real con 31 bytes de RAM estática. Se comunica con un microprocesador a través de una interfaz serial simple. El RTC DS1302 proporciona información sobre segundos, minutos, horas, día, fecha, mes y año. La fecha de fin de mes se ajusta automáticamente para los meses con menos de 31 días, incluidas las correcciones para el año bisiesto. El reloj funciona en formato de 24 o de 12 horas con un indicador AM / PM. El DS1302 opera con un voltaje que va desde 2.0V a 5.5V.
La interfaz del DS1302 se simplifica mediante el uso de comunicación en serie síncrona y solo se requieren tres cables para comunicarse con el reloj / RAM: CLK, DATA, RST. Los datos se pueden transferir hacia y desde el reloj / RAM 1 byte a la vez o en una ráfaga de hasta 31 bytes. El DS1302 está diseñado para funcionar con muy baja potencia y retener datos e información de reloj en menos de 1 µW.
El DS1302 es el sucesor del DS1202. Además de las funciones básicas de cronometraje del DS1202, el DS1302 tiene las características adicionales de pines de alimentación dual para fuentes de alimentación primarias y de respaldo, cargador de goteo programable para VCC1 y siete bytes adicionales de memoria de bloc de notas.
En el siguiente ejemplo vamos a utilizar el RTC (Real Time Clock / Reloj en Tiempo Real) DS1302, el cual es un cronómetro muy económico y poderoso, cumple con la mayoría de las necesidades básicas y avanzadas para almacenar logs o consultar la hora en nuestros proyectos.
El material que vamos a utilizar es:
- RTC DS1302 (Con batería CR2023)
- 5 cables
- Librería ArduinoRTClibrary-master
- Arduino (UNO en mi caso)
El esquemático es el siguiente:
NOTA: Algunos fabricantes utilizan distintos nombres para cada puerto, los dos casos más comunes son los siguientes y van conectados de la siguiente manera a Arduino, la primera opción es:
- CLK a PIN 6
- DAT a PIN 7
- RST a PIN 8
La segunda opción es:
- SCLK a PIN 6
- I/O a PIN 7
- CE a PIN 8
Al momento de cablear, podemos encontrar que algunos fabricantes utilizan nombres distintos para cada puerto, verificar cual corresponde a nuestro RTC.
Pasemos al código, lo primero que tenemos que contemplar, es incluir la librería virtuabotixRTC.h la cual podemos descargar desde aquí.
#include <virtuabotixRTC.h> //Libreria // CLK -> 6, DAT -> 7, RST -> 8 // SCLK -> 6, I/O -> 7, CE -> 8 virtuabotixRTC myRTC(6, 7, 8); // Si cambiamos los PIN de conexión, debemos cambiar aquí tambien void setup() { Serial.begin(9600); // Para ajustar la fecha y hora, debemos utilizar el siguiente formato: // segundos, minutos, horas, dia de la semana, numero de día, mes y año myRTC.setDS1302Time(00, 45, 15, 7, 9, 2, 2019); // SS, MM, HH, DW, DD, MM, YYYY /* después de ajustar la hora la linea de arriba se debe comentar o eliminar * para que la fecha y hora quede grabada */ // La configuración de fecha y hora ha sido ajustada } void loop() { // Esta función actualiza las variables para obtener resultados actuales myRTC.updateTime(); // Se imprime el resultado en el Monitor Serial Serial.print("Fecha y hora actual: "); Serial.print(myRTC.dayofmonth); // Se puede cambiar entre día y mes si se utiliza el sistema Americano Serial.print("/"); Serial.print(myRTC.month); Serial.print("/"); Serial.print(myRTC.year); Serial.print(" "); Serial.print(myRTC.hours); Serial.print(":"); Serial.print(myRTC.minutes); Serial.print(":"); Serial.println(myRTC.seconds); // Un pequeño delay para no repetir y leer más facil delay(1000); }
Debemos poner atención en la función myRTC.setDS1302Time(); ya que una vez el código con la configuración de fecha y hora correcta esté cargado a nuestro Arduino, debemos volver a cargar el script pero esta vez eliminando o comentando la linea donde va la función myRTC.setDS1302Time();
Si no volvemos a subir el script con la función borrada o en comentario, cada que encendamos o se reinicie el Arduino se reconfigurará con la fecha y hora que quedó configurada la primera vez que cargamos el script, en el caso del script que puse arriba al no eliminar o comentar la función myRTC.setDS1302Time(); cada que se reinicie o encienda el Arduino la fecha y hora iniciará en “9/2/2019 17:17:0”
// Para ajustar la fecha y hora, debemos utilizar el siguiente formato: // segundos, minutos, horas, dia de la semana, numero de día, mes y año myRTC.setDS1302Time(00, 17, 17, 7, 9, 2, 2019); // SS, MM, HH, DW, DD, MM, YYYY /* después de ajustar la hora la linea de arriba se debe comentar o eliminar * para que la fecha y hora quede grabada */ // La configuración de fecha y hora ha sido ajustada
En resumen; se carga a Arduino el script que contiene la fecha y hora configurada, enseguida se vuelve a cargar el script con la función myRTC.setDS1302Time(); eliminada o en comentario.
De esta forma ya queda configurado nuestro modulo RTC DS1302
Sí queremos leer más sobre la librería podemos consultar la página del autor
El código fuente se encuentra en el siguiente link
Very good! Keep going! 🙂
Muchas Gracias!
hola, esa librería esta incompleta a mi no me funciona, gracias
Hola Fernando. ¿Que error te muestra? Saludos
hola, tengo una duda, cdo ajusto la horA DEL reloj, el año trabaja bien miemtras q este en el rango por encima de 2000 y por debajo de 3000, si envio 1960 coge otro numero.. usted dira y para q te hace falta q este en otr rango.. ok si puede conteste a este email reirm2010@yandex.com ok, muchas gracias
Hola disculpa estoy haciendo un proyecto el cuál incluye el DS1302, el problema es que al desconectar y conectar se me pierde la fecha y la hora, se me reinicia a como lo tenía configurado, he probado como tu dices de comentar o borrar la función pero no se me guarda :C ayuda porfaaa
Después de comentar la línea de configuración, vuelves a subir el sketch al Arduino?
Configuro el set time a la hora que corresponde, lo subo el programa a arduino, inmediatamente comento al lado o arriba y vuelvo a subir el programa, he probado así y a tener dos sketch el bueno con el set correspondiente y el otro comentando listo para subir para guardado
Pudiste arreglar ese detalle?
Comparte tus dos sketch, para analizarlos.
Como puedo poner formato 12hrs??
Dentro del archivo virtuabotixRTC.cpp en la linea 653 debes cambiar el 0 por un 1
rtc.h24.hour_12_24 = 0; // 0 for 24 hour format
Saludos
Muchas gracias por el tutorial, muy amable en compartir conocimiento, ¡Saludos!
Gracias por tu comentario Benicio. En lo que pueda ayudarles, con gusto. ¡Saludos!
Muchas gracias por el tutorial, tengo una consultilla jejeje los minutos, días, meses, etc cuando son inferiores a 10 no muestra dos cifras, quedándose en 1 y no en 01 por ejemplo, el año se muestra con 4 cifras también y me gustaría que mostrara las dos últimas solamente, ¿alguna sugerencia? jeje gracias de antemano!
¿Que tal Raúl? No tengo el proyecto a la mano, para revisarlo, pero recuerdo que dentro del archivo virtuabotixRTC.cpp vienen las configuraciones para ajustar eso que requieres. Échale un ojo al archivo y verás que encuentras la solución. En la primera oportunidad que tenga lo voy a revisar y te comparto que número de linea son las que tienes que modificar.
Saludos!
Muchísimas gracias, si que he mirado el archivo pero no encuentro la manera jeje, como explicaste a otra persona anteriormente si que identifico bien lo de cambiar a 12h o 24h que es cambiar el bit de 0 a 1 o viceversa, pero para que salgan los dos dígitos “01” en vez de “1” en las horas, minutos y demás no lo veo.
uint8_t Hour:4; // 4-bits to hold low decimal digits 0-9 //| |
uint8_t Hour10:2; // 2-bits to hold high decimal digits 0-2 //| |
uint8_t reserved2:1; //| |
uint8_t hour_12_24:1; // 1-bit to set 0 for 24 hour format //| |
***************************************************************
rtc.h24.Hour = bin2bcd_l( hours); //| |
rtc.h24.Hour10 = bin2bcd_h( hours); //| |
rtc.h24.hour_12_24 = 0; // 0 for 24 hour format //| |
Te pego eso por si te sirve de algo jaja
Sé que no es la mejor manera o la manera correcta, pero si te sirve de algo puedes agregar algo así:
DateTime now = RTC.now();
Serial.print(now.day(), DEC);
Serial.print(‘.’);
if(now.month<10)
Serial.print('0'):
Serial.print(now.month(), DEC);
Serial.print('.');
Serial.print(now.year(), DEC);
if(now.hour<10)
Serial.print('0'):
Serial.print(' ');
Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.print(':');
Serial.print(now.second(), DEC);
Serial.println();
PD. Voy a buscar el proyecto para revisar y encontrar una solución mas apropiada. Saludos!
Muchas gracias Pablo, probaré así a ver que tal queda 🙂
He seguido mirando y con otros modelos y otras librerías si que te viene claro como ponerlo con los dos dígitos, en este no veo la manera jeje debería de haberla pero no soy capaz de encontrarla. Un saludo.
Gracias por el código pero no me sirve porque estoy utilizando un lcd 16×2 como salida y se me montan los 0 con el número ya que no se desplaza el solo una a la derecha, si pongo para que se desplace al final queda un código enorme jejeje
Intenta aplicar un lcd.clear() antes de cada impresión en el LCD, es decir antes de todo el lcd.print.
Compárteme tu código y lo revisamos, te voy a enviar un email.
Ok, te lo envié por correo.
Un saludo!
Al final lo solucioné de esta otra manera, tampoco está muy bien pero funciona xD
if (myRTC.hours > 0 && myRTC.hours 0 && myRTC.minutes 0 && myRTC.month <= 9) {
lcd.setCursor(9, 0);
lcd.print(0);
lcd.setCursor(10, 0);
lcd.print(myRTC.month);
}
else {
lcd.setCursor(9, 0);
lcd.print(myRTC.month);
}
Gracias Pablo,
Me ha servido enormemente tus observaciones, sigue adelante, y gracias por compartir.
Hola como andas, te escribo para ver si me podes ayudar por favor, la cuestion es que estoy queriendo programar el encendido de una salida digital (Pin 13) mediante un RTC DS1302 y tengo la librería virtuboatixRTC, pero no estoy pudiendo encontrarle la vuelta
¿Pero que es lo que no encuentras?
Hola.
No me funciona. La hora no se actualiza. Me nuestra constantemente la fecha y hora que se ha asignado.
Parece como si la parte de updateTime() no funcionase.
¿Ya probaste comentando la linea que asigna la hora?
// Para ajustar la fecha y hora, debemos utilizar el siguiente formato:
// segundos, minutos, horas, dia de la semana, numero de día, mes y año
myRTC.setDS1302Time(00, 45, 15, 7, 9, 2, 2019); // SS, MM, HH, DW, DD, MM, YYYY
/* después de ajustar la hora la linea de arriba se debe comentar o eliminar para que la fecha y hora quede grabada
¿Ya probaste comentando la linea que asigna la hora?
// Para ajustar la fecha y hora, debemos utilizar el siguiente formato:
// segundos, minutos, horas, dia de la semana, numero de día, mes y año
myRTC.setDS1302Time(00, 45, 15, 7, 9, 2, 2019); // SS, MM, HH, DW, DD, MM, YYYY
/* después de ajustar la hora la linea de arriba se debe comentar o eliminar para que la fecha y hora quede grabada
hola, mi rtc funcionaba correctamente, pero de un momento a otro la hora no cambia, significa que se dañó? o alguna idea de lo que se puede hacer?
A que te refieres con que la hora no cambia?
Si me sirvió, gracias por el aporte.
Hola ,
A alguien le ha ocurrido que la respuesta del monitor serie es
Current Date / Time: 0/0/2000 0:0:7
No se configura la hora en el reloj.
Alguna idea?
Un saludo
Muchas Gracias, Salusos