RTC – Real Time Clock DS1302, 1307 e 3231

No artigo de hoje vamos falar sobre os relógios de tempo real, ou como são conhecidos, os RTCs – Real Time Clocks. Vamos explicar os três principais modelos utilizados em aplicações com Arduino: RTC DS1302, RTC DS1307 e RTC3231. Também terá um projeto, no qual iremos usar o RTC DS1307 para enviar informações de data e hora para um LCD, ou seja, vamos fazer um relógio digital.

Introdução

Os RTCs são pequenos dispositivos eletrónicos usados para incorporar dados de data e hora a dispositivos eletrónicos. Os RTCs utilizam cristais de quartzo e circuitos auxiliados integrados em um chip para medir o tempo. Praticamente todos os dispositivos que necessitam de controle preciso do tempo possuem algum tipo de RTC.

Três modelos bastante usados com Arduino são:

Todos possuem preços que não ultrapassam os 7,30€ e podem ser facilmente incorporados em projetos eletrónicos. Vamos ver um pouco de cada um e suas principais diferenças.

RTC DS3231

O DS3231 é um RTC de alta precisão e baixo consumo de energia. O módulo possui um sensor de temperatura de fábrica e também um oscilador para melhorar ainda mais a sua exatidão.

Funciona tanto no formato 12 horas como 24 horas, e as informações de meses com menos de 30/31 dias e anos bissextos são corrigidos automaticamente pelo módulo.

Uma bateria acompanha o módulo para evitar a perda de dados no caso de uma falha de energia do circuito. Um aspeto importante e que diferencia dos outros modelos é o protocolo de comunicação utilizado. No caso do DS3231 o protocolo I2C é usado. Assim, são dois canais(pinos) de comunicação: SCL(Clock) e SDA(dados).

Módulo RTC DS3231

As especificações são:

  • Tensão de operação: 3,3-5V;
  •  Computa segundos, minutos, horas, dias da semana, dias do mês, meses e anos (de 2000 a 2099);
  • Sensor de temperatura com ± 3 °C de exatidão;
  • Chip de memória: AT24C32 de 32K bytes que podem ser usadas como RAM estendida do microcontrolador;
  • Circuito de deteção de falhas de energia;
  • Consumo menor que 500nA no modo bateria com oscilador em funcionamento;
  • Dimensões: 38 x 22 x 14 mm;
  • Peso: 8g.

É recomendado a leitura do datasheet.

RTC DS1302

O RTC DS1302 é o mais simples dos três. Comunica-se via protocolo serial, com um pino chamado CE e outro SCL. É capaz de fornecer informações como: segundo, minuto, dia, data, mês e ano. Meses com menos de 31 dias e anos bissextos são tratados automaticamente pelo módulo. Opera nos formatos 12 e 24 horas.

Módulo RTC DS1302

As principais especificações são:

  • Chip: DS1302.
  • 31-Bytes de memória RAM para armazenamento de dados.
  • Tensão: 2,0V ~ 5,5V.
  • Corrente: menos de 300nA em 2V e até 1,2mA em 5V.
  • Sinal de saída programável em onda quadrada.
  • Consome menos de 300nA no modo oscilador.

O datasheet pode ser encontrado aqui.

RTC DS1307

Este Real Time Clock (RTC) é um relógio de tempo real com calendário completo e mais de 56 bytes de SRAM de memória não-volátil. Tal como os outros RTCs, fornece informações de segundos, minutos, dia, data, mês e ano. Na sua placa há um circuito que deteta falhas de energia e aciona a bateria embutida com o objetivo de evitar perda de dados.

Utiliza protocolo I2C e trata automaticamente os casos de meses com menos de 31 dias e anos bissextos.

Módulo RTC DS1307

Especificações:

  • Chip: DS1307.
  • Computa segundos, minutos, horas, dias da semana, dias do mês, meses e anos (de 2000 a 2099).
  • 56 bytes de SRAM.
  • Tensão: 4,5~5,5V.
  • Circuito de deteção de falhas de energia.
  • Consome menos de 500nA no modo bateria com oscilador em funcionamento.
  • Faixa de temperatura: -40°C a +85°C.
  • Dimensões: 2.9×2.6 cm.

O datasheet do DS1307 pode ser encontrado aqui.

Diferenças entre os módulos

As principais diferenças entre os módulos dizem respeito ao protocolo utilizado, tamanho e tipo da memória interna, dimensões e consumo de energia. Os módulos DS1307 e DS3231 utilizam o protocolo I2C, enquanto o DS1302 utiliza um protocolo serial. O protocolo I2C utiliza 2 pinos: o SDA(dados) e o SCL(clock de sincronismo). Já o DS1302 utiliza três pinos: SCL(Clock de sincronismo), CE(Chip Enable – para habilitar a transmissão de dados) e I/O(dados).

A grande diferença é que o I2C sinaliza o início e fim da transmissão de dados por meio de mudanças no estado lógico nos pinos SCL e SDA.  Basicamente, se SCL estiver no nível alto e houver uma transição de alto para baixo no SDA, o DS1307/3231 reconhece como INÍCIO de comunicação. Agora, se SCL estiver no nível alto e houver uma transição de baixo para alto no SDA, o DS1307/3231 reconhece como FIM de comunicação.

No DS1302, o papel feito por estas combinações lógicas é desempenhado pelo pino CE. Se ele estiver no nível alto, a comunicação tem início, se for para o nível baixo, a transferência de dados termina. Ou seja, sempre que um procedimento de leitura ou escrita for executado com o DS1302, o pino CE deve ser colocado no nível alto.

Aqui cabe uma informação importante. No próprio datasheet do DS1302 há a informação de que nos datasheets antigos, o pino CE era erradamente chamado de Reset(RST). Mas a funcionalidade era a mesma, ou seja, era um erro técnico na redação do datasheet.

As tensões de alimentação também são diferenças importantes, com o DS1302 a operar com um mínimo de 2V, enquanto o DS1307 opera com no mínimo 4,5V.

Aspetos do Hardware

Para ilustrar como usar o RTC nos seus projetos, vamos fazer a seguinte montagem:

Repare que o RTC DS1307 foi ligado diretamente ao Arduino. Isto é possível pois ambos trabalham com os mesmos níveis de tensão. Além do RTC, conectamos também um LCD para mostrarmos os dados de data e hora. Caso tenha alguma dúvida em relação ao LCD, leia este post e saiba mais detalhes.

RTC pino SDA = pino A4 Arduino

RTC pino SCL = pino A5 Arduino

Do ponto de vista de hardware, a montagem é simples. Caso os outros RTCs fossem usados, a montagem seria basicamente a mesma.

Aspectos Software

Do ponto de vista de software, vamos utilizar a biblioteca RTClib.h, que pode ser encontrada no GitHub.

#include <Wire.h>
#include "RTClib.h"
#include <LiquidCrystal.h>

#define InterfaceLCD 1
RTC_DS1307 rtc;
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
LiquidCrystal lcd(9, 8, 4, 5, 6, 7);//RS E D4 D5 D6 D7

void setup() {
 Serial.begin(57600);
 if (! rtc.begin()) {
   Serial.println("Couldn't find RTC");
   while (1);
 }
 if (! rtc.isrunning()) {
   Serial.println("RTC is NOT running!");
   // ajusta para a data e hora de compilação
   rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
   // Ajusta para uma data definida por você
   //rtc.adjust(DateTime(2020, 03, 13, 12, 00, 00));
 }
 lcd.begin(16, 2);
 delay(2000);
}

void loop() {
 if (InterfaceLCD == 1) {
   showLCD();
 } else {
   showSerial();
 }
 Serial.println();
 delay(3000);
}

void showLCD() {
 DateTime now = rtc.now();
 // ano = now.year();
 lcd.clear();
 //mostra a data
 lcd.print(now.year());
 lcd.write('/');
 lcd.print(now.month());
 lcd.write('/');
 lcd.print(now.day());
 //Mostra as horas
 lcd.setCursor(1, 2);
 lcd.print(now.hour());
 lcd.write('/');
 lcd.print(now.minute());
 lcd.write('/');
 lcd.print(now.second());
}

void showSerial() {
 DateTime now = rtc.now();
 Serial.print(now.year(), DEC);
 Serial.print('/');
 Serial.print(now.month(), DEC);
 Serial.print('/');
 Serial.print(now.day(), DEC);
 Serial.print(" (");
 Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
 Serial.print(") ");
 Serial.print(now.hour(), DEC);
 Serial.print(':');
 Serial.print(now.minute(), DEC);
 Serial.print(':');
 Serial.print(now.second(), DEC);
 Serial.println();
}

Veja que no software usamos duas funções para mostrar os dados de data e hora. A função showLCD mostra os dados no LCD, e a função showSerial mostra na interface serial. Para selecionar qual usar basta alterar a flag InterfaceLCD.

Os pontos importantes a serem entendidos no programa são:

  • A função rtc.adjust(DateTime(F(__DATE__), F(__TIME__))) ajusta o tempo do RTC para a data e hora na qual o programa foi convertido.
  • A função rtc.adjust(DateTime(2020, 03, 13, 12, 00, 00)) ajusta o tempo do RTC para a data e hora definida pelo usuário. Neste caso, 13 de março de 2020, 12 horas.
  • Após a função rtc.adjust ser chamada, o RTC irá começar a partir daquela data e você não precisará de ajustá-lo (a não ser que queira). O RTC continuará a contagem até o dia em que a bateria do módulo se esgotar, geralmente depois de alguns anos.
  • Para ler os dados de data e hora, é criado o objeto now da classe Datetime(DateTime now = rtc.now()). Com este objeto é feita a leitura das diversas informações de tempo, como mostrado nas funções showLCD e showSerial.

Carregue o software na sua montagem e faça o teste. Usando a interface serial, você terá algo como na imagem abaixo na sua saída:

A primeira vez que o software rodar, a mensagem “RTC is not running!” será exibida. Depois disso, a função rtc.adjust() será chamada e o RTC começará a contar o tempo normalmente.

Com tudo ajustado, você deve receber mensagens como as mostradas na tela acima. Detalhe: Para alterar a forma de exibição, como mudar de “Wednesday” para “Quarta-feira” ou mostrar a hora primeiro, basta ajustar a ordem das funções Serial.println e lcd.print dentro das funções showSerial e ShowLCD. Este ajuste fica como trabalho de casa para que possa treinar.

Para usar o LCD, basta fazer a montagem conforme mostramos na secção “Aspetos do Hardware”. Se tiver alguma dúvida sobre o LCD ou quiser saber mais informações sobre ele, leia este post específico sobre este componente. Lembre-se de ajustar o contraste pelo potenciómetro até que as letras possam ser vistas de forma clara.

Agora já pode incorporar as informações de data e hora nos seus projetos.