RTC DS3231 – Registrando data e hora com Arduino 

Bem sabemos como o tempo é a variável mais importante do mundo e da nossa vida. Nos organizamos a partir de horários e datas e por isso precisamos de relógios e agendas para nos guiar a todo momento. Se queremos construir sistemas inteligentes que auxiliam nossas atividades cotidianas, é fundamental saber como manter nosso Arduino sincronizado com a hora e a data do local onde estamos.  Pensando nisso, elaboramos este tutorial voltado para contemplar o uso de um Relógio de Tempo Real (Real-Time Clock) em conjunto com uma placa Arduino, em especial o RTC DS3231.  

Neste conteúdo será demonstrado como utilizar o RTC em questão para adquirir valores de data e hora, assim como, envia-los, por exemplo, através da porta serial para que o leitor possa conferir o resultado do projeto.  Além disso, explicaremos também a importância desse módulo.

[toc]

O que é um RTC?

Um RTC, do inglês Real-Time Clock, é um elemento que possibilita o registro de valores de data e hora no decorrer do tempo. Em poucas palavras, um RTC é um relógio em que o usuário indica os valores iniciais de data e hora, para que então, a partir destes, o mesmo passe a contar o tempo por conta própria (geralmente este dispositivo possui uma fonte de energia própria (como a apresentada na figura abaixo) para manter continuamente os valores de data e hora, de modo que, se o equipamento ao qual o RTC está conectado, ficar sem alimentação, a contagem do tempo não é interrompida).

Note que este tipo de dispositivo existe dentro de muitos aparelhos, como relógios digitais, despertadores, microondas,  entre outros, que mesmo após serem desligados, podem manter a contagem correta do tempo até serem ligados novamente .

 

Exemplo de uma bateria de um RTC em uma placa mãe de um computador

 

Caso você já tenha desmontando um computador certamente já viu uma bateria como a da imagem acima. Ela está associada ao circuito de um circuito RTC, que por sua vez, é responsável por manter seu computador com a data e a hora atualizadas mesmo estando desligado. Quando o horário e data do computador começam a ficar defasados dos valores reais da região, deve-se ficar atento, pois, este pode ser um sinal de que está na hora de trocar esta bateria.

As funções delay() e millis()

Quando um programa é desenvolvido para ser inserido em uma placa Arduino, de modo que, este tenha alguma relação com o conceito de tempo, fala-se, na maioria das vezes em progressão de tempo, por exemplo, pode-se determinar que o Arduino execute uma ação x após alguns segundos de ocorrência de uma condição y. Em grande parte destes casos, a função delay() é suficiente para atingir o objetivo proposto, ao passo que, em alguns casos é mais conveniente a utilização da função millis().

  • delay(): Pausa o programa por um certo tempo (especificado em milissegundos).
  • millis(): Retorna um número (em milissegundos) referente ao tempo que passou desde que o programa atual inserido na placa Arduino começou a rodar.

Note que a função millis() pode ser utilizada para determinar se uma certa quantidade de tempo já se passou, porém, sem que haja algum tipo de “congelamento” do programa que está rodando no Arduino.

Por que utilizar um RTC junto com um Arduino?

Como dito anteriormente, a função millis() atua como um contador, de modo que este, é incrementado a cada momento, no entanto, quando o Arduino for desligado, este contador começará novamente do zero. Por este motivo, pode-se utilizar um RTC para ter um controle melhor sobre a progressão do tempo.

Além disso, é importante saber que a função millis() retorna um elemento do tipo unsigned long (que representa a quantidade de milissegundos), que por sua vez, possui o tamanho de 32 bits. Com esta informação, pode-se chegar a conclusão de que com este tipo de dado pode-se realizar a contagem do tempo em aproximadamente 50 dias, ou seja, pouco menos de 2 meses até que o contador seja reiniciado. Em contrapartida, a autonomia de um RTC pode chegar a 10 anos dependendo do modelo do mesmo e da bateria utilizada.

Características do RTC DS3231

O RTC que será utilizado no desenvolvimento do projeto proposto neste tutorial é o RTC DS3231. Este RTC consiste em um relógio de tempo real de alta precisão, baixo consumo de energia e baixo custo. Este módulo é capaz de trabalhar com informações como segundos, minutos, horas, dias, meses, anos e ainda é capaz de ajustar-se automaticamente em casos de meses com menos de 31 dias e em situações de ocorrência de anos bissextos. Além disso, o RTC DS3231 pode operar tanto no formato 12 horas (utilizando a nomenclatura AM/PM) como no formato 24 horas.

RTC DS32312
RTC DS32312

Ao lado das características citadas, também deve-se ressaltar que o RTC DS3231 se comunica com uma placa Arduino através do protocolo I2C (onde os dados são transferidos através de um barramento bidirecional) e que o mesmo possui um compartimento para que seja inserida uma bateria externa (em caso de falha de energia no elemento principal, esta é automaticamente acionada para manter o controle sobre a passagem do tempo), um sensor de temperatura embutido, dois alarmes programáveis, além de outras características mais avançadas que serão apresentadas em tutoriais posteriores.


Mãos à obra – Realizando a aquisição dos valores de data e hora com o Arduino

Componentes utilizados:

Montando o projeto

Na figura abaixo, o leitor poderá conferir como foi realizada a montagem do projeto apresentado neste tutorial.  Lembre-se de montar o projeto com o seu Arduino desligado.

 

Veja como ficou o nosso:

 

Programando

Antes de adentrarmos na apresentação do código, disponibilizamos uma seção para ajudar aqueles que são iniciantes no assunto. Sinta-se livre para prosseguir caso você já tem domínio da IDE do Arduino.

Conectando o Arduino ao computador

Primeiramente, conecte seu Arduino ao computador e abra a IDE Arduino. Em seguida, é necessário selecionar a porta COM na qual o Arduino está conectado (este procedimento pode ser feito clicando no menu Ferramentas (tools) e em seguida escolhendo-se a porta correspondente no submenu Porta (port). Neste caso, a porta na qual está o Arduino é apresentada da seguinte maneira: COM3 (Arduino Micro).

 

 

Por fim, garanta também que o tipo de placa apropriado esteja selecionado (isso pode ser feito acessando o menu Ferramentas (tools) e o submenu Placa (board)).

 

– Biblioteca

Para desenvolver o projeto proposto com o RTC DS3231 utilizou-se uma biblioteca capaz de atuar sobre o protocolo I2C para facilitar os processos de endereçamento e troca de dados que fazem parte do funcionamento do protocolo citado. Esta biblioteca foi produzida por  Jarzebski e pode ser encontrada aqui.

Adquirindo e instalando a biblioteca que será utilizada

Para adquirir a biblioteca em questão, basta acessar o link apresentado anteriormente, clicar no botão clone or Download e por fim, no botão Download ZIP, conforme a figura abaixo.

Após a realização do download dos arquivos compactados no formato ZIP, abra a IDE do Arduino, selecione o menu Sketch, o submenu Incluir Bilioteca e por fim, basta clicar na opção Adicionar biblioteca .ZIP (Add ZIP Library) e encontrar o arquivo que acabou de ser baixado.

 

 

Uma outra forma de fazer isso é extrair o conteúdo do arquivo ZIP dentro da pasta Libraries (onde foi instalada a IDE do Arduino).

– Código do projeto

Segue o código a ser utilizado no Arduino para imprimir os valores de data e hora no Serial Monitor.

#include <Wire.h>        //Biblioteca para manipulação do protocolo I2C
#include <DS3231.h>      //Biblioteca para manipulação do DS3231

DS3231 rtc;              //Criação do objeto do tipo DS3231
RTCDateTime dataehora;   //Criação do objeto do tipo RTCDateTime

void setup()
{
  Serial.begin(9600);     //Inicialização da comunicação serial
  rtc.begin();            //Inicialização do RTC DS3231

  rtc.setDateTime(__DATE__, __TIME__);   //Configurando valores iniciais 
                                         //do RTC DS3231
}

void loop()
{
  dataehora = rtc.getDateTime();     //Atribuindo valores instantâneos de 
                                     //data e hora à instância dataehora


  Serial.print(dataehora.year);     //Imprimindo o Ano   
  Serial.print("-");
  Serial.print(dataehora.month);    //Imprimindo o Mês
  Serial.print("-");
  Serial.print(dataehora.day);      //Imprimindo o Dia
  Serial.print(" ");
  Serial.print(dataehora.hour);     //Imprimindo a Hora
  Serial.print(":");
  Serial.print(dataehora.minute);   //Imprimindo o Minuto
  Serial.print(":");
  Serial.print(dataehora.second);   //Imprimindo o Segundo
  Serial.println("");

  delay(1000);     //Tempo p atualização do valor enviado pela porta
                   //serial
}

Nota: é importante ler a seção Entendendo a fundo deste tutorial para entender como funciona o ajuste de data e hora.

Após escrever o código, salve e depois clique em Carregar (Upload) para que o programa seja transferido para seu Arduino.

Colocando para funcionar

Para verificar o resultado da gravação deste código no Arduino Micro basta acessar o Serial Monitor (para realizar este procedimento, basta utilizar o atalho Ctrl+Shift+M). Espera-se que o leitor consiga obter um resultado semelhante ao demonstrado a seguir.

 

RTC DS32312 resposta
RTC DS32312 resposta

Entendendo a fundo

Software

– Incluindo as bibliotecas a serem utilizadas no projeto

Inicialmente, observe que foi necessário incluir duas bibliotecas no código para que o mesmo pudesse funcionar corretamente. A biblioteca wire.h é a responsável pela comunicação utilizando o protocolo I2C enquanto a biblioteca DS3231.h atua sobre a biblioteca wire.h simplificando o processo de comunicação através do protocolo citado, para que assim, o usuário possa utilizar o RTC DS3231 de maneira mais fácil.

#include <Wire.h>
#include <DS3231.h>

– Declarando os objetos rtc e dataehora

Em seguida, cria-se dois objetos que serão utilizados posteriormente, de modo que, um destes é do tipo DS3231, chamado rtc (que representará o RTC DS3231 no código) e outro do tipo RTCDateTime, chamado dataehora (que será responsável por manipular os valores de data e hora existentes).

Lembre-se: rtc e dataehora são apenas nomes, sendo assim, é importante ressaltar que, os objetos identificados por rtc e dataehora poderiam ser chamados de quaisquer outros nomes, como por exemplo, modulo e informacaoatual, respectivamente.

DS3231 rtc;                //construindo o objeto rtc da classe DS3231
RTCDateTime dataehora;     //construindo o objeto dataehora da classe RTCDateTime

– Definindo as configurações iniciais

Primeiramente, na função setup(), utiliza-se a função Serial.begin() para inicializar a comunicação serial do Arduino Micro com o computador  (onde será possível ver o resultado do projeto)

 Serial.begin(9600);

Em seguida, utiliza-se a função rtc.begin() (repare que o nome rtc corresponde ao objeto criado anteriormente) para inicializar o RTC DS3231.

rtc.begin();

Posteriormente, recorre-se à função rtc.setDateTime() para configurar os valores iniciais do RTC DS3231, ou seja, os valores de data e hora que servirão de ponto de partida para o mesmo.

Conforme será explicado em seguida, na seção Ajuste de hora do RTC, ao passarmos __DATE__, __TIME__ como parâmetros da função rtc.setDateTime(), fazemos com que os valores iniciais de data e hora do RTC DS3231 sejam correspondentes ao momento da compilação do código.

rtc.setDateTime(__DATE__, __TIME__);

De acordo com a explicação dada, a função setup() deve possuir o seguinte conteúdo:

void setup()
{
  Serial.begin(9600);

  rtc.begin();

  rtc.setDateTime(__DATE__, __TIME__); 
}

– Aquisição dos valores de data e hora

Na função loop(), utiliza-se primeiramente a função rtc.GetDateTime() para atribuir os valores de data e hora de um determinado momento ao objeto dataehora. Neste momento é importante ressaltar que o objeto em questão irá conter várias informações (segundo, minuto, hora, dia, mês e ano), que por sua vez, podem ser acessadas separadamente.

dataehora = rtc.getDateTime();

Imagine que seja necessário extrair a informação referente ao ano que o RTC DS3231 está registrando. Para isso, basta referir-se ao objeto dataehora por dataehora.year. Portanto, se quisermos enviar o valor do ano através da porta serial, deve-se utilizar dataehora.year como argumento da função Serial.print().

Serial.print(dataehora.year);

Observe as demais correspondências na figura abaixo:

 

 

Por fim, veja como ficou a função loop() (perceba que ao final da mesma existe uma função delay() determinando a disponibilização das informações a cada um segundo).

void loop()
{
  dataehora = rtc.getDateTime();

  Serial.print(dataehora.year);   //Imprimindo o ano
  Serial.print("-");
  Serial.print(dataehora.month);  //Imprimindo o mês
  Serial.print("-");
  Serial.print(dataehora.day);    //Imprimindo o dia
  Serial.print(" ");
  Serial.print(dataehora.hour);   //Imprimindo a hora
  Serial.print(":");
  Serial.print(dataehora.minute); //Imprimindo os minutos
  Serial.print(":");
  Serial.print(dataehora.second); //Imprimindo os segundos  
  Serial.println("");

  delay(1000);
}

 

Hardware

As ligações realizadas no hardware em questão são bem simples, de modo que, deve-se lembrar apenas, que a comunicação entre o RTC DS3231 e uma placa Arduino é dada através do protocolo I2C, portanto, no Arduino Micro, além dos pinos referentes à alimentação do módulo, utilizou-se os pinos SDA (pino 3, responsável pela troca de dados entre os dispositivos) e SCL (pino 4, responsável pela sincronização entre os dispositivos). No RTC DS3231 estes pinos estão nomeados, portanto, são de fácil identificação.


Ajuste de hora do RTC

É importante que nosso RTC esteja com a hora correta, portanto, torna-se necessário saber como mante-lo com a hora ajustada.

Primeiramente, note que no código apresentado anteriormente, fizemos o uso um recurso muito interessante, disponibilizado pela biblioteca DS3231.h. Este recurso consiste na utilização dos parâmetros __DATE__ e __TIME__ dentro da função rtc.setDateTime(), que por sua vez, fazem com que os valores data e hora da compilação sejam usados para ajustar a data e a hora do nosso módulo RTC DS3231.

rtc.setDateTime(__DATE__, __TIME__);

Neste momento, o leitor deve estar atento a um pequeno detalhe: Apesar da função apresentada anteriormente determinar os valores iniciais de data e hora do RTC de acordo com o momento da compilação, caso o seu Arduino seja reiniciado, o ele irá definir novamente as informações de partida do módulo RTC DS3231 com os valores referentes ao momento da compilação realizada anteriormente (e não com as dados de data e hora de quando ele foi reiniciado, pois, sempre que o Arduino for ligado, o conteúdo da função setup() será executado e consequentemente, a função rtc.setDateTime() também), portanto, teremos um relógio desatualizado.

Solução para o ajuste dos valores de data e hora

O ideal é que a gravação do programa no Arduino seja feita duas vezes:

  1. Na primeira vez você deve enviar o código tal como apresentado anteriormente.
  2. Em seguida, você terá que modificar a função setup(), comentando ou excluindo a linha que contém a função de ajuste de data e hora, para então, gravar novamente o programa no Arduino.

Primeira gravação:

#include <Wire.h>        //Biblioteca para manipulação do protocolo I2C
#include <DS3231.h>      //Biblioteca para manipulação do DS3231

DS3231 rtc;              //Criação do objeto do tipo DS3231
RTCDateTime dataehora;   //Criação do objeto do tipo RTCDateTime

void setup()
{
  Serial.begin(9600);     //Inicialização da comunicação serial
  rtc.begin();            //Inicialização do RTC DS3231

  rtc.setDateTime(__DATE__, __TIME__);   //Configurando valores iniciais 
                                         //do RTC DS3231
}

void loop()
{
  dataehora = rtc.getDateTime();     //Atribuindo valores instantâneos de 
                                     //data e hora à instância dataehora


  Serial.print(dataehora.year);     //Imprimindo o Ano   
  Serial.print("-");
  Serial.print(dataehora.month);    //Imprimindo o Mês
  Serial.print("-");
  Serial.print(dataehora.day);      //Imprimindo o Dia
  Serial.print(" ");
  Serial.print(dataehora.hour);     //Imprimindo a Hora
  Serial.print(":");
  Serial.print(dataehora.minute);   //Imprimindo o Minuto
  Serial.print(":");
  Serial.print(dataehora.second);   //Imprimindo o Segundo
  Serial.println("");

  delay(1000);     //Tempo p atualização do valor enviado pela porta
                   //serial
}

Segunda gravação:

#include <Wire.h>        //Biblioteca para manipulação do protocolo I2C
#include <DS3231.h>      //Biblioteca para manipulação do DS3231

DS3231 rtc;              //Criação do objeto do tipo DS3231
RTCDateTime dataehora;   //Criação do objeto do tipo RTCDateTime

void setup()
{
  Serial.begin(9600);     //Inicialização da comunicação serial
  rtc.begin();            //Inicialização do RTC DS3231

  //rtc.setDateTime(__DATE__, __TIME__);   *******ESTA LINHA DEVE SER COMENTADA OU EXCLUÍDA*******
}

void loop()
{
  dataehora = rtc.getDateTime();     //Atribuindo valores instantâneos de 
                                     //data e hora à instância dataehora


  Serial.print(dataehora.year);     //Imprimindo o Ano   
  Serial.print("-");
  Serial.print(dataehora.month);    //Imprimindo o Mês
  Serial.print("-");
  Serial.print(dataehora.day);      //Imprimindo o Dia
  Serial.print(" ");
  Serial.print(dataehora.hour);     //Imprimindo a Hora
  Serial.print(":");
  Serial.print(dataehora.minute);   //Imprimindo o Minuto
  Serial.print(":");
  Serial.print(dataehora.second);   //Imprimindo o Segundo
  Serial.println("");

  delay(1000);     //Tempo p atualização do valor enviado pela porta
                   //serial
}


Considerações finais

Neste tutorial elaboramos um conteúdo introdutório sobre o RTC DS3231 visando apresentar os conceitos básicos de funcionamento do mesmo e como utiliza-lo em conjunto com uma placa Arduino. Esperamos que você tenha gostado deste conteúdo, sinta-se à vontade para nos dar sugestões, críticas ou elogios. Lembre-se de deixar suas dúvidas nos comentários abaixo.

 

Privacy Preference Center