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.