Arduino en Español – Parte 6 – Modulo RTC DS1302

En este capítulo vamos a controlar un Modulo RTC DS1302 (Reloj de tiempo real), que es básicamente un chip que nos permitirá consultar la fecha y hora.

Gracias a que lleva una pila CR2032, seguirá manteniéndola aunque no este conectado.

EL DS1302 funciona por I2C pero en este caso vamos a conectar todos sus pines a pines digitales de nuestro Arduino y no a los pines I2C de la placa (aunque sea poco frecuente), ya que vamos a usar la librería de Makuna que hace un I2C mediante Software.

Esquema de conexionado

Esquema de conexionado DS1302

En el esquema de conexionado podemos identificar varios componentes.

El módulo RTC DS1302 marcado con el número 1 (el color amarillo de la placa es relativo) con 5 pines ordenados de izquierda a derecha tenemos los siguientes pines:

Cable Rojo (VCC) y Negro (GND) que son los cables de tensión y van +5V y GND respectivamente.

Los otros 3 cables de color Azul (CLK o SCLK) que es el reloj de I2C que va al pin digital 5 de Arduino, el Verde (DAT o IO) que es el pin de datos de I2C irá conectado al pin digital 4 de Arduino y para terminar, el cable Naranja (RST o CE) que es el reset, irá conectado al pin 3 digital de Arduino.

La pantalla LCD 2004A marcado con el número 2 que usaremos junto a su modulo de I2C para una conexión mas simple, que será opcional y que empleare para poder visualizar las fecha y hora sin necesidad de usar el monitor serie de Arduino.

Ejemplo de código con Arduino

#include <LiquidCrystal_I2C.h>

//Constructor sin control de backlight (retroiluminacion)
//LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
//Constructor con control de backlight (retroiluminacion)
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

#include <ThreeWire.h>
#include <RtcDS1302.h>

// CONNECTIONS:
// DS1302 CLK/SCLK --> 5
// DS1302 DAT/IO --> 4
// DS1302 RST/CE --> 2
// DS1302 VCC --> 3.3v - 5v
// DS1302 GND --> GND

ThreeWire myWire(4,5,3); // IO, SCLK, CE
RtcDS1302<ThreeWire> Rtc(myWire);

bool blink = false;

void setup() {
  // put your setup code here, to run once:

  Serial.begin(57600);

  Serial.print("compiled: ");
  Serial.print(__DATE__);
  Serial.println(__TIME__);

  lcd.begin(20, 4);
  lcd.backlight();

  Rtc.Begin();

  RtcDateTime compiled = RtcDateTime(__DATE__, __TIME__);
  printDateTime(compiled);
  Serial.println();

  if (Rtc.GetIsWriteProtected())
  {
    Serial.println("RTC was write protected, enabling writing now");
    Rtc.SetIsWriteProtected(false);
  }

  if (!Rtc.GetIsRunning())
  {
    Serial.println("RTC was not actively running, starting now");
    Rtc.SetIsRunning(true);
  }

  RtcDateTime now = Rtc.GetDateTime();
  if (now < compiled) 
  {
      Serial.println("RTC is older than compile time!  (Updating DateTime)");
      Rtc.SetDateTime(compiled);
  }
  else if (now > compiled) 
  {
      Serial.println("RTC is newer than compile time. (this is expected)");
  }
  else if (now == compiled) 
  {
      Serial.println("RTC is the same as compile time! (not expected but all is fine)");
  }

}

void loop() {
  // put your main code here, to run repeatedly:

  RtcDateTime now = Rtc.GetDateTime();
  printDateTime(now);

  if (!now.IsValid())
    {
        // Common Causes:
        //    1) the battery on the device is low or even missing and the power line was disconnected
        Serial.println("RTC lost confidence in the DateTime!");
    }

    if(blink)
    {
      lcd.setCursor(11,3);
      lcd.print("1.50 EUR");
      blink = false;
    }
    else
    {
      lcd.setCursor(11,3);
      lcd.print("        ");
      blink = true;
    }

    delay(1000);

}

#define countof(a) (sizeof(a) / sizeof(a[0]))

void printDateTime(const RtcDateTime& dt)
{
    char datestring[20];

    snprintf_P(datestring, 
            countof(datestring),
            PSTR("%02u/%02u/%04u %02u:%02u:%02u"),
            dt.Month(),
            dt.Day(),
            dt.Year(),
            dt.Hour(),
            dt.Minute(),
            dt.Second() );
    Serial.print(datestring);
}

Analizando el Sketch, para controlar el DS1302 usaremos la librería RTC Lib by Makuna.

Ahora procedemos a importar la librería al Sketch.

Una vez importada, la inicializamos usando su constructor RtcDS1302 Rtc(myWire), el parámetro myWire es un objeto de la clase ThreeWire que debemos crear antes, donde simplemente especificamos los pines a usar ThreeWire myWire(4,5,3); // CLK/SCLK, DAT/IO, RST/CE

Lo mas probable esque el DS1302 no tenga la fecha y hora bien, para ello en el setup creamos un objeto RtcDateTime compiled = RtcDateTime(__DATE__, __TIME__); en donde __DATE__ y __TIME__ son 2 palabras “especiales” que Arduino traducirá al compilar con la fecha y la hora del sistema donde estamos compilándolo (Recordamos que el Arduino NO dispone de un chip de Fecha y Hora interno).

Tras ello, obtenemos la Fecha y Hora actual del DS1302 con RtcDateTime now = Rtc.GetDateTime() y comparamos con if (now < compiled) si la fecha del DS1302 esta mas atrasada que la que acabamos de compilar en Arduino, y de ser así, la ajustamos con Rtc.SetDateTime(compiled).

Ahora, en el loop vamos a mostrar la fecha y hora tanto por monitor serie como por el LCD 2004A, para ello, volvemos a obtener la fecha y hora del DS1302 usando RtcDateTime now = Rtc.GetDateTime() y llamamos a la función printDateTime(now) pasándole como parámetro este objeto (la función esta definida al final del sketch).

Y por último, comprobamos si la fecha y hora es válida usando if (!now.IsValid()) y de no ser así, mostramos un mensaje por monitor serie para avisar de que algo pasa. Normalmente, que el DS1302 esta desconectado o no tiene pila.

Descarga el código de ejemplo: Tutorial de Arduino en Español – Parte 6 – Modulo RTC DS1302 (Reloj en tiempo real) – Fecha y Hora

Para mas tutoriales de Arduino visita https://www.electrimaticayt.com/category/arduino/

Deja un comentario