Manual
do
Maker
.
com
Um RTC (Real Time Clock) é um relógio de precisão dedicado a registro de data e hora, utilizado em projetos que necessitam acuidade de tempo. Apesar de parecer um dispositivo especial, trata-se de um acessório comum a praticamente todo o equipamento microprocessado como smartphones, tablets, computadores desktop, notebooks, máquinas fotográficas, filmadoras, etc.
Se você chegou até esse post, a sorte é minha e não sua, porque é muito simples e comum a utilização desse popular dispositivo e você encontra facilmente tutoriais com uma simples busca no google. Ainda assim, eu não poderia deixar de ter uma referência e vou tentar ter algum diferencial em relação aos demais posts para que valha a pena para você utilizar o meu tutorial invés de outros.
Tenha paciência com a leitura, é bom saber exatamente o que você tem em suas mãos.
O DS1307 é um relógio dedicado que exibe segundos, minutos, horas, dia do mês, mês, dia da semana e ano, incluindo ano bi-sexto.
Além da sua função especialista, ele oferece ainda um espaço extra de 56 bytes de NVRAM (Non Volatile Randomic Access Memory), que é mantida pela bateria com praticamente nenhum consumo. É um recurso bastante interessante, pois se você precisa armazenar dados de tempo inclusive para registrar startup e shutdown, não será necessário esmirilhar a EEPROM do Arduino.
Ele possui uma interface serial two-wire e para utilizá-lo com Arduino, uma das bibliotecas a ser utilizada é a Wire.
Ele possui uma saída de sinal de onda quadrada programável, de 1Hz a 32.768kHz.
Seu consumo é incrivelmente baixo; menos de 500 nA (nano Ampere).
Essas informações que disponibilizo estão no datasheet, sinta-se à vontade para lê-lo (em inglês).
Sua pinagem oferece cascata para comunicação I2C; endereço e dados são transferidos via 2-wire bidirecional. Seu ajuste para meses de 31 dias e anos bisexto são feitos automaticamente, portanto você não precisará se preocupar em monitorá-lo. Outra característica importante é que ele oferece o modo 24h ou 12h com indicador AM/PM. Ele tem um circuito sensitivo que detecta falhas de alimentação e entra automaticamente em modo de bateria, consumindo menos de 500nA.
Esse RTC é um dispositivo passivo, ou seja, ele recebe comandos via barramento serial. O protocolo de comunicação tem uma condição de START e se encerra na condição de STOP.
VCC e GND - são conectados ao Arduino em 5v e ground.
Vbat - o slot recebe uma bateria de lithium de 3v, que é considerada em boas condições de uso quando entre 2v e 3.5v. Em baixa tensão, não é possível utilizar a NVRAM. Uma bateria de 48mAh teoricamente dá ao dispositivo uma capacidade de trabalho superior a 10 anos, trabalhando a 25 graus.
SCL - Serial Clock. Utilizado para sincronismo na interface serial.
SDA - Serial Data I/O. Comunicaçãoda interface 2-wire.
A precisão é dependente do cristal e variação de temperaturas. Ruídos de circuito externo à MCU podem acelerar o relógio, mas podemos considerar um circuito de qualidade esse do Tiny RTC.
Não é algo que tenhamos que nos preocupar, uma vez que utilizaremos um interface de alto nível para a comunicação, mas se tiver interesse em saber a estrutura dos dados. O relógio está na área de endereço de 00H (segundos) ao 07H (controle). De 08H até 3FH está toda a memória.
Você pode obter de forma independente cada um dos valores dos registros de memória, consultando-os diretamente. Os dados são armazenados no formato BCD (binary-coded decimal). O bit 6 do registrador de hora define o forma 12/24 (lembrando que cada registrador possui 8 bits).
Só descrevi alguns detalhes extras para se ter uma idéia de como o hardware funciona e de que não é trivial a comunicação, por isso as bibliotecas são muito bem-vindas.
Optei por utilizar a DS1307new porque apesar da suave diferença, me pareceu mais flexível para fazer uma função de ajuste do relógio a qualquer momento. Não vi algo do tipo em nenhum tutorial, então achei um diferencial legal, espero que goste tambem.
Criei a função de ajuste de relógio e um menu para exibir hora, data, data/hora e fazer o tal ajuste. Para ver o menu, apenas digite "ajuda" (sem aspas).
A biblioteca pode ser baixada nesse link. O código que utilizei já nesse primeiro momento no Arduino:
#include <Wire.h>
#include <DS1307new.h>
#include <string.h>
//dias da semana
#define SUNDAY 0
#define MONDAY 1
#define TUESDAY 2
#define WEDNESDAY 3
#define THURSDAY 4
#define FRIDAY 5
#define SATURDAY 6
uint16_t TimeIsSet = 0xaa55;
uint16_t startAddr = 0x0000;
uint16_t lastAddr;
DS1307new rtc;
/*
* https://www.manualdomaker.com
*/
String adjustment; //string para fazer os ajustes do relogio
char option = 0;
void getRequired(String thisValue){
if (thisValue.equals("ajudan")){
Serial.println("Opcoes:");
Serial.println("ajuda - Este menu");
Serial.println("ajustar - Ajuste da data e hora");
Serial.println("dataHora - Exibe data e hora");
Serial.println("data - Exibe apenas data");
Serial.println("hora - Exibe apenas horario");
return;
}
rtc.getTime();
if (thisValue.equals("horan")){
//Serial.println(rtc.time2000,DEC);
adjustment = String(rtc.hour) + ":" + String(rtc.minute) + ":" + String(rtc.second);
Serial.print("Hora: ");
Serial.println(adjustment);
}
else if (thisValue.equals("dataHoran")){
Serial.print("Data e Hora: ");
adjustment = String(rtc.day) + "/" + String(rtc.month) + "/" + String(rtc.year-48); //data...
adjustment += " - " + String(rtc.hour) + ":" + String(rtc.minute) + ":" + String(rtc.second); //...e hora
Serial.println(adjustment);
}
else if(thisValue.equals("datan")){
adjustment = String(rtc.day) + "/" + String(rtc.month) + "/" + String(rtc.year-48);
Serial.print("Data: ");
Serial.println(adjustment);
}
else{
Serial.println("Digite 'ajuda' se tiver duvidas");
}
}
void clockAdjustment(){
TimeIsSet = 0xffff;
rtc.setRAM(54, (uint8_t *)&TimeIsSet, sizeof(uint16_t));
rtc.getRAM(54, (uint8_t *)&TimeIsSet, sizeof(uint16_t));
if (TimeIsSet == 0xaa55){
Serial.println("Impossivel configurar: 0xaa55");
return;
}
rtc.stopClock();
char inChar = 0;
adjustment = "";
Serial.println("");
Serial.print("Defina o horario (HH:MM:SS (nesse formato)): ");
while (inChar != 'n'){
if (Serial.available()){
inChar = Serial.read();
adjustment += inChar;
}
}
rtc.hour = adjustment.substring(0,2).toInt(); //0 e 1.
rtc.minute = adjustment.substring(3,5).toInt(); //3 e 4.
rtc.second = adjustment.substring(7).toInt(); //7 e 8.
adjustment = "";
Serial.println(" ");
Serial.print("Entre com a data no formato DD/MM/AAAA (nesse formato):");
inChar = 0;
while (inChar != 'n'){
if (Serial.available()){
inChar = Serial.read();
adjustment += inChar;
}
}
rtc.day = adjustment.substring(0,2).toInt();
rtc.month = adjustment.substring(3,5).toInt();
rtc.year = adjustment.substring(7).toInt(); //7 ao fim
adjustment = "";
rtc.fillByYMD(rtc.year,rtc.month,rtc.day);
rtc.fillByHMS(rtc.hour,rtc.minute,rtc.second); //redundante, se vc ler a lib...but
//rtc.fillByYMD(2015,11,18);
//rtc.fillByHMS(3,25,0);
rtc.setTime();
TimeIsSet = 0xaa55;
rtc.setRAM(54, (uint8_t *)&TimeIsSet, sizeof(uint16_t));
rtc.startClock();
rtc.ctrl = 0x00; //SQW pode ser usado como interrupcao
rtc.setCTRL();
Serial.println("");
if (TimeIsSet == 0xaa55){
Serial.println("Configurado.");
asm volatile(" jmp 0"); //reset automatico
}
Serial.println("Nao configurado");
}
void setup() {
pinMode(2, INPUT);
digitalWrite(2, HIGH);
Serial.begin(9600);
}
void loop() {
while (option != 'n'){
if (Serial.available()){
option = Serial.read();
adjustment += option;
}
}
option = 0;
if (adjustment.equals("ajustarn")){
clockAdjustment();
}
else if (adjustment.equals("horan")|| adjustment.equals("dataHoran")|| adjustment.equals("datan") || adjustment.equals("ajudan")){
getRequired(adjustment);
}
adjustment = "";
}
O terminal serial precisa estar com a opção newline selecionada porque 0x0D (ou "LF" (Line Feed), ou 'n') está sendo usado como delimitador na leitura serial.
Resta uma etapa; utilizar essa memoria sobressalente do RTC, que além de tudo é NVRAM e pode ser escrita à vontade. Mas essa deixarei para um próximo post porque preciso escrever mais dois que estão na fila.
Inscreva-se em nosso canal Dobitaobyte no Youtube!
Autor do blog "Do bit Ao Byte / Manual do Maker".
Viciado em embarcados desde 2006.
LinuxUser 158.760, desde 1997.