Reloj de Tiempo Real Con Arduino y DS3231
Reloj de Tiempo Real Con Arduino y DS3231
Reloj de Tiempo Real Con Arduino y DS3231
En este tutorial vamos a aprender a utilizar el módulo DS3231, un Reloj de Tiempo Real (RTC)
de alta precisión.
Con ayuda de un Arduino Nano y una pantalla lcd 16×2 vamos a realizar un sencillo reloj que
muestre la hora y fecha.
Características DS3231
El módulo DS3231 cuenta con excelentes características, integra un cristal oscilador
compensado por temperatura que ayuda a mantener la precisión del reloj en +-2 minutos por
año en temperaturas con rango de -40°C a +85°C.
El reloj puede operar en formato de 24 o 12 horas con indicador AM/PM, incluye dos alarmas
programables y una señal cuadrada programable.
Emplea interfaz I2C, así que es posible utilizar el módulo RTC con cualquier microcontrolador
que cuente con esta comunicación.
Pines DS3231
En el modo transmisor el RTC envía la información de los registros que almacenan la hora y
fecha al dispositivo maestro.
Registros de configuración
Los registros que almacenan la información del RTC comienzan en la dirección 00H y terminan
en 12H, en este tutorial vamos a acceder a las direcciones 00h – 06h que son las
correspondientes a hora y fecha.
Circuito de conexión
Programación
Para configurar la fecha y hora en nuestro módulo DS3231 usamos la función:
5.- Programar nuevamente el Arduino para evitar que se reinicie la fecha por algún reset.
Programa principal
// variables
int seconds, minutes, hours, day, date, month, year;
String weekDay;
void setup()
{
Wire.begin();
// set up the LCD's number of columns and rows:
lcd.begin(16, 2);
// to set hour and date use the following steps
// 1.- Uncomment the instruction
// 2.- Set time and date
// 3.- Upload the sketch
// 4.- Comment and upload again to prevent a reset time
// setDate(seconds(0-59), minutes(0-59), hours(0-23), day(1-7), date(0-31), month(1-12), year(0-99))
//setDate(00, 6, 18, 06, 26, 02, 16);
}
void loop()
{
lcd.clear();
if(date<10)
lcd.print("0");
lcd.print(date);
lcd.print("/");
if(month<10)
lcd.print("0");
lcd.print(month);
lcd.print("/20");
lcd.print(year);
lcd.setCursor(4,1);
lcd.print(hours);
lcd.print(":");
if(minutes<10)
lcd.print("0");
lcd.print(minutes);
lcd.print(":");
if(seconds<10)
lcd.print("0");
lcd.print(seconds);
delay(1000);
}
void getDate()
{
// Send request to DS3231 to receive the date
Wire.beginTransmission(DS3231_I2C_ADDRESS);
Wire.write(0x00); // start at register 00h (seconds)
Wire.endTransmission();
Wire.requestFrom(DS3231_I2C_ADDRESS, 7); // Request 7 bytes (00h - 006h)
while(Wire.available())
{
seconds = Wire.read();
minutes = Wire.read();
hours = Wire.read();
day = Wire.read();
date = Wire.read();
month = Wire.read();
year = Wire.read();
// convert BCD to decimal
seconds = (((seconds >> 4) * 10) + (seconds & B00001111));
minutes = (((minutes >> 4) * 10) + (minutes & B00001111));
hours = ((((hours & B00110000) >> 4) * 10) + (hours & B00001111));
day = (day & B00000111);
month = ((((month & B00010000) >> 4) * 10) + (month & B00001111));
date = ((((date & B00110000)>> 4) * 10) + (date & B00001111));
year = (((year >> 4) * 10) + (year & B00001111));
}
switch (day) {
case 1:
weekDay = "Sun";
break;
case 2:
weekDay = "Mon";
break;
case 3:
weekDay = "Tue";
break;
case 4:
weekDay = "Wed";
break;
case 5:
weekDay = "Thu";
break;
case 6:
weekDay = "Fri";
break;
default: break;
}
}
void setDate(byte seconds, byte minutes, byte hours, byte day, byte date, byte month, byte year)
{
// convert DEC to BCD
seconds = (seconds % 10) + ((seconds / 10) << 4);
minutes = (minutes % 10) + ((minutes / 10) << 4);
hours = (hours % 10) + ((hours / 10) << 4);
date = (date % 10) + ((date / 10) << 4);
month = (month % 10) + ((month / 10) << 4);
year = (year % 10) + ((year / 10) << 4);
Wire.beginTransmission(DS3231_I2C_ADDRESS);
Wire.write(0x00);
Wire.write(seconds);
Wire.write(minutes);
Wire.write(hours);
Wire.write(day);
Wire.write(date);
Wire.write(month);
Wire.write(year);
Wire.endTransmission();
}