conteúdo revisto e atualizado – publicado originalmente em 2015
Estes módulos permitem adicionar um relógio em tempo real (RTC – Real Time Clock) aos seus projetos de uma forma bem simples e barata. Mesmo que falte energia ao seu Arduino, o relógio continua a contar pois é alimentado com uma bateria que pode durar muitos e muitos anos!
A maioria dos módulos RTC são equipados com os circuitos integrados DS1307 e DS3231 ambos da empresa californiana Maxim Integrated e utilizam o barramento de comunicação I2C.
I2C
I2C (IIC – Inter Integrated Circuit) é um barramento de comunicação desenvolvido pela Philips, hoje NXP Semiconductors, para permitir troca de dados entre os componentes que residem na mesma placa de circuito impresso. Este barramento também é conhecido por TWI (Two Wire Interface) implementado pela ATMEL, hoje Microchip Technology.
A vantagem de usar este tipo de barramento é que precisamos de apenas dois pinos para comunicação, além do pino de alimentação (5V) e o pino terra (GND).
Os módulos I2C possuem um endereço único para cada módulo. A seleção do endereço é feita pela combinação dos pads A0, A1 e A2, para o DS3231 .
Mas como saber o endereço do módulo se não tenho a documentação disponível? 🙁
A biblioteca Wire.h (necessária para utilizar o I2C), contém um exemplo que faz uma varredura em módulos I2C acoplados a placa Arduino. Esta biblioteca é nativa no software Arduino, ou seja, não é preciso instalar.
Na comunicação I2C temos dois terminais conhecidos por SDA (Serial Data Line) e SCL (Serial Clock Line).
Nas placas Arduino Uno e compatíveis, o
SDA é o pino analógico 4 (A4)
e o
SCL é o pino analógico 5 (A5).
No Arduino Mega o SDA é o pino digital 20 e o SCL é o pino digital 21.
Conectando o módulo DS1307 (Tiny RTC)
Primeiro verifique se você vai usar um módulo com um dos dois chips indicados no começo do artigo. Após, verifique se tem instalado a biblioteca RTClib.h (esta biblioteca serve para os dois modelos).
Vá até o gerenciador de bibliotecas (atalho CTRL-SHIFT-i), digite rtclib. Caso não encontre, acesse o site Arduino Library List e faça o download em https://www.arduinolibraries.info/libraries/rt-clib
Monte o circuito orientando-se pela tabela a seguir:
pino Tiny RTC | pino Arduino |
GND (jumper preto) | GND |
VCC (jumper vermelho) | 5V |
SDA (jumper amarelo) | A4 |
SCL (jumper azul) | A5 |
Agora iremos verificar o endereço do módulo. Carregue o IDE Arduino e acesse: menu File (Arquivo) e navegue até Examples (Exemplos), Wire e i2c_scanner. Execute o sketch e veja qual o endereço retornado no monitor serial.
Você deve ter visto esta informação:
Scanning…
I2C device found at address 0x50 !
I2C device found at address 0x68 !
done
Foram exibidos dois endereços. Um é do chip DS1307 (0x68) e o outro da memória EEPROM (0x50). Este sketch é muito útil para identificar outros módulos que usam I2C.
Exemplos
É quase certo que o seu módulo novo está com a data e hora incorretas. Vamos fazer o ajuste e será necessário apenas uma vez, visto que o módulo contém uma bateria para mantê-lo funcionando.
O ajuste será feito utilizando duas macros da linguagem C: __DATE__ e __TIME__, que retornam respectivamente a data e hora do seu sistema operacional. Note que este recurso é válido somente em tempo de compilação do sketch. Não dá para colocar estas macros em um laço de repetição, por exemplo, e exibir valores atualizados. Sempre conterá o valor no momento da compilação.
Aqui temos os métodos:
begin() – retorna false caso não seja detectado um módulo RTC ou o seu endereço é inválido.
adjust() – grava data e hora no seguinte formato ano (AAAA), mês (MM), dia (DD), hora (HH), minuto (MM) e segundo (SS). A classe DateTime formata os valores das macros __DATE__ e __TIME__ corretamente para este método.
now() – retorna data e hora corrente. Novamente usamos a classe DateTime que monta uma estrutura com os seguintes métodos: day(), month(), year(), hour(), minute() e second().
#include <Wire.h>; #include <RTClib.h>; RTC_DS1307 rtc; void setup() { Serial.begin(9600); delay(1000); if (rtc.begin()) { rtc.adjust(DateTime((__DATE__), (__TIME__))); DateTime now = rtc.now(); int dia = now.day(); int mes = now.month(); int ano = now.year(); int hora = now.hour(); int minuto = now.minute(); int segundo = now.second(); Serial.print(dia); Serial.print("/"); Serial.print(mes); Serial.print("/"); Serial.print(ano); Serial.print("\t"); Serial.print(hora); Serial.print(":"); Serial.print(minuto); Serial.print(":"); Serial.print(segundo); } else { Serial.println("Modulo RTC nao encontrado!"); } } void loop() { }
No próximo exemplo vamos formatar os dados retornados pelo módulo .
Foram inicializados três vetores: um para armazenar o texto formatado, um contendo os dias da semana e o último contendo os meses do ano.
Os dados foram formatados com a função sprintf() da linguagem C. Aliás, temos um mini curso de linguagem C que acreditamos seja útil para um melhor entendimento da linguagem Arduino. Não deixe de fazê-lo 😉
Mais um método utilizado:
dayOfTheWeek() – retorna um inteiro (0 a 6) que representa o dia da semana começando em 0 (domingo).
#include <Wire.h> #include <RTClib.h> RTC_DS1307 rtc; void setup() { char texto[255]; char diasDaSemana[7][10] = { "Domingo", "Segunda", "Terca", "Quarta", "Quinta", "Sexta", "Sabado" }; char mesDoAno[13][10] = { "", "Janeiro", "Fevereiro", "Marco", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro" }; Serial.begin(9600); delay(1000); if (rtc.begin()) { DateTime now = rtc.now(); int dia = now.day(); int mes = now.month(); int ano = now.year(); int hora = now.hour(); int minuto = now.minute(); int segundo = now.second(); sprintf(texto, "Hoje: %s, %02d/%02d/%04d Hora: %02d:%02d:%02d", diasDaSemana[now.dayOfTheWeek()], dia, mes, ano, hora, minuto, segundo); Serial.println(texto); sprintf(texto, "Hoje: %s, %02d/%s/%04d Hora: %02d:%02d:%02d", diasDaSemana[now.dayOfTheWeek()], dia, mesDoAno[mes], ano, hora, minuto, segundo); Serial.println(texto); } else { Serial.println("Modulo RTC nao encontrado!"); } } void loop() { }
A saída no monitor serial será a data e hora do dia que você executou este sketch:
Hoje: Sexta, 21/08/2020 Hora: 17:31:42
Hoje: Sexta, 21/Agosto/2020 Hora: 17:31:42
Links úteis:
- http://www.nxp.com/i2c
- http://www.avrbeginners.net/architecture/twi/twi.html
- https://datasheets.maximintegrated.com/en/ds/DS1307.pdf
- https://datasheets.maximintegrated.com/en/ds/DS3231.pdf
pretendo ligar e desligar lâmpadas com horas determinadas, é possível com esse módulo?
obrigado
fabao1966@yahoo.com.br
Olá Fabio, sim! Apenas lembrando que este módulo é apenas para data/hora. Para acionamento de cargas, como lâmpadas, utilize um módulo com relés por exemplo.