RTC


O tutorial a seguir foi destinado ao modulo Tiny RTC mas funciona com a maioria dos módulos RTC baseados na comunicação I2C.

Podemos fazer muitas coisas com microcontroladores, desde controlar motores, enviar sinais, ler sensores. Entretanto, funções que normalmente não conseguimos realizar são computar as horas, minutos ou a data de hoje via esses dispositivos. Poder realizar essas tarefas seria muito útil para diversos projetos que usam sensores, temporizadores e, principalmente, que envolvam “data analysis” (análise de dados).

Para poder saber a data e a hora atuais, normalmente, precisamos de uma alimentação de energia ininterrupta e computamos os dados com circuitos integrados, ou podemos utilizar módulos dedicados a esse trabalho, que possuem uma bateria interna e não perdem a referência de data e hora mesmo com interrupções de energia em sua placa Arduino. Esses módulos são chamados de RTC, do inglês Real Time Clock, ou relógio de tempo real.

Bateria do módulo Tiny RTC.

Neste tutorial vamos apresentar o Tiny RTC, módulo dedicado a contagem e computação de tempo.

Características principais do Módulo Tiny RTC:
  • É capaz de computar de horas, minutos, segundos, dias, semanas, meses e anos;
  • Utiliza o circuito integrado DS1307, dedicado à contagem de tempo;
  • Modo AM/PM;
  • Contagem de tempo que chega até o ano 2100 usando sua memória RAM de 32kb;
  • Gerador de onda quadrada;
  • Comunicação I2C;
  • Pino especial para bateria externa com detector de falha de energia;
  • Consumo menor que 500uA no modo bateria;
  • Contém um soquete de bateria externa para falhas de energia;
  • Possibilita o uso conjunto de um sensor de temperatura DS18B20.
Módulo Tiny RTC.
Pinagem:
  • VCC: Alimentação positiva (5v);
  • GND: Alimentação negativa;
  • SDA: Responsável pela transmissão de dados no protocolo I2C;
  • SCL: Responsável pelo sinal de clock do protocolo I2C;
  • DS: Sinal do sensor de temperatura;
  • SQ: Sinal de onda quadrada.

Por mais que o módulo tenha pinos de conexão nos dois lados da placa, só é necessário conectar um deles.

Barramento I2C

Já utilizamos o barramento I2C para nos comunicarmos com displays OLED, e agora vamos utilizá-lo com o nosso RTC.

Muito utilizado em módulos sensoriais, o protocolo de transmissão de dados I2C necessita de apenas dois fios para transmissão de dados, o SCL e SDA. Como falado anteriormente, o SCL é responsável pelo clock do barramento, e a linha SDA pela transmissão de dados. Para existir comunicação precisamos de um “controlador” (normalmente, o microcontrolador) e pelo menos um “periférico” ( normalmente, sensores ou atuadores).

Curiosidade

Nos últimos anos tornou-se cada vez mais comum a adoção de terminologias mais inclusivas e que não pudessem ser consideradas politicamente incorretas. Assim, diversas empresas e associações têm alterado a nomenclatura “mestre/escravo” para “controlador/periférico” ou outras equivalentes. Saiba mais neste link.

Neste barramento, é necessário ter resistores pull-up nos fios SDA e SCL. Resistores pull-up fazem com que, quando não existe um sinal ativo (LOW ou HIGH) no fio, seu estado lógico fique definido (no caso de resistores pull-up, que ligam a linha ao 5V, o seu estado lógico fica em HIGH; se forem usados resistores pull-down, que são ligados ao GND, o seu estado lógico ficaria em LOW). Caso contrário, não seria possível determinar se as placas veriam um sinal LOW ou HIGH no fio quando este não está ligado em um sinal ativo, ou seja, quando está em aberto. Quando você está utilizando uma placa Arduino para se comunicar com seu periférico, você não precisa se preocupar com esses resistores, pois seu Arduino já possui resistores pull-up internamente.

Ao serem conectados, cada dispositivo deve ter um endereço único de 7 bits, totalizando teoricamente até 127 dispositivos possíveis em uma única ligação. Na prática, alguns fatores como a capacitância dos fios e a existência de endereços reservados diminuem um pouco o número máximo de periféricos que podem ser conectados, mas ainda assim são muitos dispositivos!

File:I2C.svg
Esquema barramento I²C. Fonte: Cburnett / GNU Free Documentation License

Mais informações sobre o protocolo I2C:

Programação e montagem com Arduino

Como primeiro exemplo, iremos utilizar o Arduino Uno como controlador e o Serial Monitor para visualização das informações do módulo. No Arduino Uno, o pino SDA é o A4, e o pino SCL é o A5.

Esquema de ligação Arduino Uno e o módulo Tiny RTC.

Para a programação usaremos uma biblioteca especial:

  • RTClib: sua instalação pode ser feita através do gerenciador de bibliotecas da plataforma Arduino IDE. Saiba mais sobre essa biblioteca e as funções disponíveis neste link.

Ao utilizar a biblioteca RTClib, não é necessário chamar também a biblioteca para comunicação I2C, pois ela já faz isso internamente.

Aqui vemos um exemplo simples de como utilizar a RTClib:

 /*******************************************************************************
  * 
  * Exemplo de uso do módulo Tiny RTC com DS1307.
  * 
  * Referências:
  * https://github.com/adafruit/RTClib
  * 
  * Criado por: Erick León, 2022
  * 
  ********************************************************************************/
#include "RTClib.h"

RTC_DS1307 rtc;

char diasDaSemana[7][4] = {"DOM", "SEG", "TER", "QUA", "QUI", "SEX", "SAB"};

// esta função só roda quando é chamada dentro de outra função
void imprime_data_e_hora(DateTime data_e_hora){
    Serial.print(data_e_hora.day(), DEC);
    Serial.print('/');
    Serial.print(data_e_hora.month(), DEC);
    Serial.print('/');
    Serial.print(data_e_hora.year(), DEC);
    Serial.print(" (");
    Serial.print(diasDaSemana[data_e_hora.dayOfTheWeek()]);
    Serial.print(") ");
    Serial.print(data_e_hora.hour(), DEC);
    Serial.print(':');
    Serial.print(data_e_hora.minute(), DEC);
    Serial.print(':');
    Serial.print(data_e_hora.second(), DEC);
    Serial.println();
}

// esta função só roda uma vez, no início
void setup () {
    Serial.begin(9600);
  
    if (!rtc.begin()) { // Se o módulo não estiver conectado ao Arduino...
        Serial.println("Módulo RTC não encontrado.");
        Serial.flush();
        while (1);  // fica aqui parado em um loop infinito...
    }
  
    if (!rtc.isrunning()) { // Se o módulo não tiver sido inicializado ainda...
        Serial.println("Módulo RTC não inicializado. Ajustando data e hora.");
        rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); // ajusta com data e hora em que o programa foi compilado
    }
}

// esta função se repete indefinidamente
void loop () {
    DateTime agora = rtc.now();
    imprime_data_e_hora(agora);

    DateTime futuro = agora + TimeSpan(1,2,3,4); // agora + 1 dia, 2 horas, 3 minutos e 4 segundos
    Serial.print("Daqui 1 dia, 2 horas, 3 minutos e 4 segundos: ");
    imprime_data_e_hora(futuro);

    delay(3000);
}
Entendendo o código

Nas linhas 1 a 10, temos um comentário explicando o que o código faz, e que é ignorado pelo compilador.

Na linha 11, incluímos a biblioteca RTClib.

Na linha 13, criamos a variável do nosso RTC, e na linha 15, criamos uma tabela de caracteres, onde cada linha representa um dia da semana.

Nas linhas 17 a 33, criamos uma função nossa, que recebe uma variável do tipo DateTime, com uma determinada data e hora, e imprime a data e a hora pela porta serial. Essa função, neste momento, não faz nada, e ela só roda quando é chamada dentro de outra função. Vale lembrar que, no Arduino Uno, a porta serial utilizada é a própria porta USB utilizada para gravar o código na placa Arduino. Assim, para ver o que está sendo enviado para a porta serial, após gravar o código na placa, basta abrir um monitor serial e configurar a porta USB utilizada. A IDE do Arduino já vem com um monitor serial, que pode ser aberto pelo menu “Ferramentas” > “Monitor serial”. Não se esqueça de configurar a porta serial corretamente (a porta utilizada por ser vista no menu “Ferramentas” > “Porta”).

Nas linhas 35 a 49 temos nossa função setup(), que roda uma única vez sempre que a placa Arduino é ligada. Na linha 37, inicializamos uma comunicação serial, com velocidade de 9600bps. Nas linhas 39 a 43, verificamos se o módulo RTC está ligado ao Arduino e, em caso negativo, imprimimos uma mensagem na porta serial e paramos o programa (na verdade, ficamos em um loop infinito, o que não permite que o resto do programa continue rodando). Nas linhas 45 a 48, verificamos se o módulo já foi inicializado alguma vez e, caso não tenha sido, o que acontece na primeira vez que é utilizado ou sempre que fica sem alimentação (do Arduino e da bateria interna), ajustamos a data e hora nele. Aqui podemos gravar uma data e hora manualmente, mas o mais prático é utilizar a data e hora em que o programa foi compilado para ser enviado ao Arduino, ou seja, a data e hora atual de seu computador.

Nas linhas 51 a 61, temos nossa função loop(), que fica rodando repetidamente enquanto a placa Arduino estiver ligada. Na linha 53, criamos uma variável chamada agora, e já a inicializamos com a data e hora atual do nosso módulo RTC, com o comando rtc.now(). Em seguida, na linha 54, usamos a função que criamos para enviar essa data e hora pela porta serial. Na linha 56, apenas para demonstração, criamos uma nova variável futuro, e inicializamos seu valor como sendo a data e hora atuais, acrescidas de 1 dia, 2 horas, 3 minutos e 4 segundos, e na linha 58, imprimimos essa nova data pela serial.

Finalmente, na linha 60, aguardamos 3 segundos (ou 3000 milissegundos), antes que a função loop() seja rodada novamente.

A seguir vemos o resultado, que aparece no monitor serial:

Módulo RTC não inicializado. Ajustando data e hora.
31/5/2022 (TER) 16:33:44
Daqui 1 dia, 2 horas, 3 minutos e 4 segundos: 1/6/2022 (QUA) 18:36:48
31/5/2022 (TER) 16:33:47
Daqui 1 dia, 2 horas, 3 minutos e 4 segundos: 1/6/2022 (QUA) 18:36:51
31/5/2022 (TER) 16:33:50
Daqui 1 dia, 2 horas, 3 minutos e 4 segundos: 1/6/2022 (QUA) 18:36:54
31/5/2022 (TER) 16:33:53
Daqui 1 dia, 2 horas, 3 minutos e 4 segundos: 1/6/2022 (QUA) 18:36:57

Conclusão

Vimos como utilizar o módulo Tiny RTC quando programado para ser usado com uma placa Arduino Uno V3. Esse módulo se mostra super versátil para projetos que necessitam de sincronização com tempo real, tais como alarmes, projetos com hora marcada, análise de dados sensoriais baseados em tempo real etc.


Texto por: Lucas Jácome Cabral e Erick León


, , ,

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *