Real Time Clock no Arduino

Os RTCs(Real-Time Clock/Relógio de tempo real) são capazes de armazenar data e hora com grande precisão e baixo consumo de energia. Geralmente em formas de CIs, eles estão presentes em muitos eletrônicos, como em computadores e embarcados.

Embora seja possível o controle de tempo sem o uso de um RTC, ele se destaca por ser mais preciso que os outros métodos e por ter um baixíssimo consumo de energia.

Nesse tutorial nós vamos usar um módulo que trabalha com o CI DS1307. Esse módulo ainda conta com um sensor de temperatura One-Wire DS18B20. O módulo também possuí uma bateria CR2032 que mantém o CI contando quando não há energia.

O Tutorial também é compatível com o RTC DS3231, sucessor do DS1307.

Conexão:

circuito_ds1307_serial_monitor2
Imagem: Filipe Flop

Recomendo usar os pinos SDA e SCL ao invés de A4 e A5:

led_matrix_pinchange
O Arduino Uno também possuí esses pinos.

Skecth(sem o uso de outras bibliotecas):


#include "Wire.h" //Incluí a biblioteca para comunicação com o módulo

#define RTC_addr 0x68 //endereço do CI DS1307

#define hora 0 //constantes que vão facilitar
#define minuto 1 //encontrar os valores
#define segundo 2 //dentro do nosso array
#define diasemana 3 //que vai guardar
#define dia 4 //hora, minuto, segundo
#define mes 5 //dida da semana
#define ano 6 //dia, mes e ano

byte RTC[7]; //array de bytes que vai guardar a resposta do RTC

void RTC_get(){
Wire.beginTransmission(RTC_addr); //Iniciamos a comunicação com o endereço do RTC
Wire.write(0x00);
Wire.endTransmission();
Wire.requestFrom(RTC_addr, 7); //solicitamos 7 respostas do módulo
RTC[segundo] = c2dec(Wire.read()); //resposta 1 = segundo e vamos armazenar no array na posição 2
RTC[minuto] = c2dec(Wire.read()); //resposta 2 = minuto
RTC[hora] = c2dec(Wire.read() & 0b111111); //resposta 3 = hora
RTC[diasemana] = c2dec(Wire.read()); //...
RTC[dia] = c2dec(Wire.read());
RTC[mes] = c2dec(Wire.read());
RTC[ano] = c2dec(Wire.read());
}

void RTC_set(byte hh, byte nn, byte ss, byte ds, byte dd, byte mm, byte yy){
//método que vai alterar a hora do rtc
//para usar: RTC_set(hora, minuto, segundo, dia da semana[0..6], dia, mes, ano);
Wire.beginTransmission(RTC_addr); //iniciamos a transmissão com o RTC
Wire.write(0x00); //enviamos 0x00 para ele se preparar para receber os dados
Wire.write(c2BCD(ss)); //enviamos os bytes na mesma sequencia que recebemos:
Wire.write(c2BCD(nn)); //segundos, minutos, horas, dia da semana, dia, mes, e ano
Wire.write(c2BCD(hh));
Wire.write(c2BCD(ds));
Wire.write(c2BCD(dd));
Wire.write(c2BCD(mm));
Wire.write(c2BCD(yy));
Wire.write(0x00); //dizemos para ele continuar
Wire.endTransmission(); //finalizamos a transmissão
}

byte c2dec(byte val){ //para lermos as respostas do CI, precisamos converte-las para decimal
return((val / 16 * 10) + (val % 16));
}

byte c2BCD(byte val){ //e para o CI entender nossas respostas, convertermos para BCD(Binary-coded decimal) antes de envia-las
return((val / 10 * 16) + (val % 10));
}

void setup(){
Wire.begin(); //Responsável pela comunicação com o módulo
Serial.begin(9600); //iniciamos a serial com 9600 bauds
//RTC_set(16, 56, 0, 6, 12, 12, 15); --> Altera a hora e data
//RTC_set(hora, minuto, segundo, dia da semana[0..6], dia, mes, ano);
}

void loop(){
RTC_get(); //chamamos a função RTC_get que vai atualizar os valores dos nossos arrays
Serial.print(RTC[hora]);
Serial.print(':');
Serial.print(RTC[minuto]);
Serial.print(':');
Serial.print(RTC[segundo]);
Serial.print(", ");
//imprimimos: xx:xx:xx,

String dias[7] = {"Domingo", "Segunda-feira", "Terca-feira", "Quarta-feira", "Quinta-feira", "Sexta-feira", "Sabado"}; //array com os dias da semana
int dia_da_semana = RTC[diasemana]; //guardamos o dia da semana
Serial.print(dias[dia_da_semana]); //imprimimos a String do array dias[] armazenado na posição do dia da semana
Serial.print(", dia ");
Serial.print(RTC[dia]); //imprimimos o dia
Serial.print(" de ");

String meses[12] = {"Janeiro", "Fevereiro", "Marco", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"}; //mesmo esquema dos dias da semana
int mes_do_ano = RTC[mes] - 1; //mas a resposta do dia da semana é de 0..6, e do mês 1..12, então descontamos 1 da variável
Serial.print(meses[mes_do_ano]);//imprimimos o mês

Serial.print(" de 20"); //como o CI envia apenas 0..99, imprimimos "20" antes, assim 2015
Serial.print(RTC[ano]);//imprimimos o ano YY
Serial.println(); //imprimimos o final da linha

delay(1000); //esperamos 1 segundo, se você for utilizar um display, recomendo no máximo 500ms
}

 

O módulo também conta com outros recursos, que ficaram para próximos tutoriais.

Se você quer incluir um RTC como esse no seu projeto, recomendo o uso de uma biblioteca, para deixar seu sketch visualmente mais limpo e facilitar a programação.
Bibliotecas:

Para Instalar uma biblioteca .zip, vá na IDE do Arduino, menu, sketch, incluir biblioteca, Adicionar biblioteca .ZIP

Você ainda pode encontrar mais bibliotecas:
Arduino IDE >> menu >> Sketch >> Incluir biblioteca >> Gerenciar bibliotecas… >> Tipo: Todos, Tópico: timing, busca: RTC

Anúncios

7 comentários sobre “Real Time Clock no Arduino

    1. Realmente atrasa, mas o ds3231 também é compatível com tutorial.
      Eu reparei que o DS1307 atrasa muito mais quando desconectado do Arduino. Eu estava pensando em atualizar o horário dele de 3 em 3 dias usando a Internet.
      Obrigado pela participação Paulo

      Curtir

      1. Mas usando a internet, pode fazer relogio por NTP.
        O maior dos problemas destes modulos que atrasam, é que o iniciante cai ou é desviado a cair no uso do mesmo, pois quem sabe programar nao usa arduino pra fazer relogio, kkkkk.
        Mesmo sabendo que estes modulos têm problemas, há pouca divulgação dos mesmos, quando existe solução razoavel, pois o custo do ds3132 nao exagerado em relação aos ds1307, 1302.

        Curtir

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair /  Alterar )

Foto do Google

Você está comentando utilizando sua conta Google. Sair /  Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair /  Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair /  Alterar )

Conectando a %s