18 novembro 2014

Data e hora no Arduino com o módulo RTC DS1302

Neste artigo vamos ver como extrair as informações de data e hora do módulo RTC DS1302, um módulo que funciona da mesma forma que o DS1307, mas possui algumas diferenças principalmente na parte de comunicação com o Arduino, já que o DS1307 usa I2C e o DS1302 usa comunicação com 3 fios.

Módulo RTC DS1302


O módulo é controlado pelo DS1302 ,um chip do tipo RTC (Real Time Clock, ou Relógio de Tempo Real), com funções de data, hora e calendário. Ele é capaz de fornecer as informações de horas, minutos, segundos, dia da semana, data, mês e ano, e ajusta automaticamente os dados referentes aos meses com menos de 31 dias e também anos bissextos.

Pinagem DS1302

Na imagem abaixo temos a pinagem do CI DS1302 (datasheet) e a função de cada pino :


CI RTC DS1302 - Pinagem

E abaixo a disposição do CI DS1302 no módulo, que na verdade não possui muitos componentes adicionais, apenas o cristal de 32.768 kHz e a bateria (CR2032) para manter a alimentação do chip em caso de falta de energia :


Módulo RTC DS1302 - Pinagem


O CI aceita alimentação de 2 à 5.5V, logo podemos ligar o módulo utilizando os pinos 3.3V ou 5V do Arduino.

Ligação módulo DS1302 ao Arduino

São utilizados três pinos para conexão ao Arduino : RST (Reset ou CE - Chip Enable), DATA (I/O) e CLK (ou SCLK / Serial Clock). Para testes vou alimentar o módulo com os 5V do Arduino :


Circuito Arduino Uno - DS1302


Como pinos de dados usamos os pinos 6, 7 e 8 do Arduino. Você pode escolher outros pinos do Arduino e mudar essa configuração nas linhas iniciais do programa.

Mostrando as informações de data e hora do DS1302

Existe um artigo no site oficial do Arduino, mostrando em detalhes como ler as informações do DS1302. Para quem gosta de entender como essa comunicação é feita, byte a byte, vale a pena dar uma olhada nessa página: http://playground.arduino.cc/Main/DS1302.

Para a maioria das aplicações esse código é bem extenso e não muito simples de entender, por isso o pessoal da Virtuabotix adaptou esse código e criou uma biblioteca chamada virtuabotixRTC (clique aqui para efetuar o download da biblioteca). Com ela fica muito fácil de extrair as informações do DS1302 e utilizá-las junto com outras funções do Arduino.

Note que no início do programa temos essa linha, que serve para determinar a data e hora atuais :

myRTC.setDS1302Time(<segundos>, <minutos>, <hora>, <dia da semana>, <dia do mês>, <mês>, <ano>)

Uma vez setada a data e a hora, a linha acima deve ser comentada e o programa novamente carregado no Arduino. 

Criei o programa abaixo baseado nos exemplos da biblioteca, e acrescentei a rotina que mostra o dia da semana por extenso :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
// Programa : Data e hora com modulo RTC DS1302
// Alteracoes e adaptacoes : Arduino e Cia
//
// Baseado no programa original de Krodal e na biblioteca virtuabotixRTC

// Carrega a biblioteca virtuabotixRTC
#include <virtuabotixRTC.h>           

// Determina os pinos ligados ao modulo
// myRTC(clock, data, rst)
virtuabotixRTC myRTC(6, 7, 8);

void setup()  
{      
  Serial.begin(9600);
  // Informacoes iniciais de data e hora
  // Apos setar as informacoes, comente a linha abaixo
  // (segundos, minutos, hora, dia da semana, dia do mes, mes, ano)
  myRTC.setDS1302Time(00, 58, 23, 2, 17, 11, 2014);
}

void loop()  
{
  // Le as informacoes do CI
  myRTC.updateTime(); 

  // Imprime as informacoes no serial monitor
  Serial.print("Data : ");
  // Chama a rotina que imprime o dia da semana
  imprime_dia_da_semana(myRTC.dayofweek);
  Serial.print(", ");
  Serial.print(myRTC.dayofmonth);
  Serial.print("/");
  Serial.print(myRTC.month);
  Serial.print("/");
  Serial.print(myRTC.year);
  Serial.print("  ");
  Serial.print("Hora : ");
  // Adiciona um 0 caso o valor da hora seja <10
  if (myRTC.hours < 10)
  {
    Serial.print("0");
  }
  Serial.print(myRTC.hours);
  Serial.print(":");
  // Adiciona um 0 caso o valor dos minutos seja <10
  if (myRTC.minutes < 10)
  {
    Serial.print("0");
  }
  Serial.print(myRTC.minutes);
  Serial.print(":");
  // Adiciona um 0 caso o valor dos segundos seja <10
  if (myRTC.seconds < 10)
  {
    Serial.print("0");
  }
  Serial.println(myRTC.seconds);

  delay( 1000);
}

void imprime_dia_da_semana(int dia)
{
  switch (dia)
  {
    case 1:
    Serial.print("Domingo");
    break;
    case 2:
    Serial.print("Segunda");
    break;
    case 3:
    Serial.print("Terca");
    break;
    case 4:
    Serial.print("Quarta");
    break;
    case 5:
    Serial.print("Quinta");
    break;
    case 6:
    Serial.print("Sexta");
    break;
    case 7:
    Serial.print("Sabado");
    break;
  }
}

Esse programa envia as informações de data e hora para o serial monitor :

Data e hora DS1302 - Serial Monitor

Em um próximo artigo sobre o DS1302, vou utilizar esse módulo para montar um relógio utilizando display 7 segmentos. Até lá !


39 comentários:

  1. Oi Adilson, excelente post, como sempre.
    Por favor se for fazer o relógio com o 1302 faça uma postagem com o 1307 também. Eu estou travado na parte de usar botões pra acertar a hora. Rsrs. Continue o bom trabalho. :-D

    ResponderExcluir
    Respostas
    1. Bom dia Márcio !

      Muito obrigado. :-)

      Bem lembrado. rs. Agora que você falou estava revendo os posts e vi que não fiz nenhum com o módulo DS1307, apenas com o chip, mas vou providenciar. Valeu.

      Abraço !

      Excluir
  2. Boa tarde, Adilson.

    Primeiro gostaria de parabenizá-lo pelo blog, são pessoas como vc só fazem aumentar a comunidade de usuários do Arduino. Parabéns pela iniciativa.

    Agora queria saber se vc pode me ajudar, pois ao configurar e carregar o sketch, meu DS 1302, funcionou perfeitamente, entretanto, ao imprimir na serial os dígitos começados em em 0, estes só aparecem os números de 1 a 9, ou seja, por exemplo: se a hora é 14:02:05, esta aparece da seguinte forma: 14:2:5, será que vc poderia me ajudar a solucionar isto?

    Muito obrigado.

    ResponderExcluir
    Respostas
    1. Bom dia Alexsandro !

      Muito obrigado. Realmente esse é um "bug" nesse programa. :-)

      Se não me engano, eu já resolvi algo parecido em algum outro post. Vou procurar a solução e alterar o programa desse post aqui.

      Abraço e obrigado !

      Excluir
    2. Oi Alexsandro !

      Eu alterei o código para incluir o "0" caso o valor da hora, minutos ou segundos seja menor do que 10. Deve resolver o seu problema. :-)

      Abraço !

      Excluir
  3. Olá, eu fiz exatamente conforme as instruções, porem ao desligar o Arduíno e re-ligar ele no projeto que estou fazendo o relógio, o horário volta ao que foi setado no inicio. Como posso resolver esse problema, ou o que estou fazendo de errado?

    ResponderExcluir
    Respostas
    1. Oi Marcos,

      Se você fez o procedimento direitinho, vc "comentou" a linha que atualiza o relógio, certo ?

      Você tem condições de medir a bateria do módulo para ver se está ok ?

      Abraço.

      Excluir
  4. Parabens amigo, me ajudou muito. pt´s consegui falta passar para lcd a hora, ja fiz algumas msg no lcd falta aparecer relogio, mas creio que ta facil pois melo monitor relogio trab. 10
    Deus continue te iluminando vc e todo QTH de Familia.

    ResponderExcluir
  5. olá! estou desenvolvendo um projeto simples, apenas para começar com o arduino. Onde iria acender uma lampada a determinado horário e desliga-lá após duas horas (por exemplo). Preciso de um modulo desses para fazer isso ? obs. já tenho o rele.

    ResponderExcluir
  6. olá! estou desenvolvendo um projeto simples, apenas para começar com o arduino. Onde iria acender uma lampada a determinado horário e desliga-lá após duas horas (por exemplo). Preciso de um modulo desses para fazer isso ? obs. já tenho o rele.

    ResponderExcluir
    Respostas
    1. Boa noite Alexsandro,

      Isso, um módulo baseado no DS1307 ou no DS1302 já basta. O resto você faz manipulando as portas do Arduino.

      Abraço !

      Excluir
  7. Olá Amigo, excelente Blog, poderia me auxiliar como guardar dados e ler neste módulo? Vou fazer um velocímetro para a minha moto e gostaria de usar a memória deste módulo para armazenar informações como odômetro e próxima troca de óleo para não sobrecarregar o arduino ou ter de recorrer a um cartão SD só para isso. VALEU!!!

    ResponderExcluir
    Respostas
    1. Boa noite,

      Dependendo da informação, você pode guardar na própria memória EEPROM do Arduino :

      http://www.arduinoecia.com.br/2015/03/gravar-dados-memoria-eeprom-arduino.html

      O cartão SD também não é uma má idéia :

      http://www.arduinoecia.com.br/2014/11/gravando-dados-arduino-cartao-sd.html

      Abraço !

      Excluir
  8. Olá, procurando achei outros tipos de RTC, como DS3231 e DS1307, existem grandes diferenças entre estes dois e tbm este apresentado no tutorial?

    ResponderExcluir
    Respostas
    1. Boa tarde Pedro,

      Estou aguardando um DS3231 para testar. Parece que ele é mais estável do que o DS1307 e o DS1302.

      Abraço !

      Excluir
  9. Não consigo colocar ele para gravar as informações. sempre que ligo o arduino ele volta à hora que eu programei, a bateria está boa, o que pode ser ?

    ResponderExcluir
    Respostas
    1. Oi Douglas,

      Você comentou essa linha, que seta a data e a hora ?

      myRTC.setDS1302Time(00, 58, 23, 2, 17, 11, 2014);

      Abraço !

      Excluir
  10. Tentei fazer aqui e apareceu só 00:00 00/00/00, estou fazendo algo errado?

    ResponderExcluir
    Respostas
    1. Bom dia Gabriel,

      Me parece ser algum problema de conexão ou até mesmo defeito no módulo, caso você tenha montado corretamente e verificado as conexões.

      Abraço.

      Excluir
    2. Descobri uma solução! Olhei umas imagens, e parece que em alguns modelos o chip que vem no módulo vem de cabeça para baixo, aí é só inverter! Ainda não tinha achado solução em lugar nenhum da internet.

      Excluir
    3. Bom dia Gabriel,

      Legal, ainda bem que essa inversão não queimou o chip. rs

      Abraço !

      Excluir
  11. Parabéns pelo site e iniciativa.
    Estou com um problema, carreguei o programa conferir as ligações e não consigo visualizar as horas.
    Aparece o texto:

    "Data : Sabado, 45/25/2165 Hora : 45:85:85.

    Você ja viu esse problema ?
    Carlos Correia

    ResponderExcluir
    Respostas
    1. Bom dia Carlos,

      O seu módulo é o DS1302 ou o DS1307 ? Já vi isso acontecer bastante com o DS1307...

      Abraço!

      Excluir
    2. DS 1302, Estou trabalhando com o Arduino Uno também.

      Excluir
    3. pode ser que você está com a blibioteca errada, copia desse site novamente exclua a pasta libraries e tente novamente

      Excluir
  12. HOLA AMIGO SALUDOS COMENTASTE EN ESTE POST QUE HARÍAS HACER UN RELOJ DE 7 SEGMENTOS LO REALIZASTE? ME INTERESA HACER UNO
    MUCHAS GRACIAS SALUDS DESDE MEXICO

    ResponderExcluir
  13. Boa Tarde Mestre
    Teria como com esse rtc eu determinar uma ação em horario programado?
    ex: Bomba liga 12:00hs e desliga 12:02ks?

    Obrigado e parabens pelo blog

    ResponderExcluir
    Respostas
    1. Bom dia Michel,

      Você pode tentar fazer um "if" simples. Fica mais ou menos assim:

      if (myRTC.hours == "12" & myRTC.minutes == "00")
      {
      //Comando para ligar a bomba;
      }

      E a mesma coisa para desligar.

      Abraço!

      Excluir
  14. por favor pode me passar o codigo nao sei programar quero que ligue e desligue 3x ao dia ex: liga as 06:00 desliga 06:10, liga 12:00 desliga 12:10 , liga 18:00 desliga 18:10 uso o rtc ds 1302 com display i2c 16x2

    ResponderExcluir
  15. Estou com um problema a hora aparece 0:0 0/0/2000 e nao anda nenhum minuto configurei tudo certo e nao vai o que pode ser?

    ResponderExcluir
  16. Parabéns pelo trabalho amigo.
    Estou com um problema, carreguei o programa conferir as ligações e não consigo visualizar as horas.
    Aparece o texto:

    "Data : Sabado, 45/25/2165 Hora : 45:85:85.

    certeza que estou usando o 1302. o que vc sugere?
    Kleber.ufcg@gmail.com

    ResponderExcluir
  17. BOA NOITE, NO MEU FUNCIONOU PERFEITAMENTE ATÉ EU DEIXAR LIGADO POR ALGUNS MINUTOS E PERCEBER QUE A HORA VAI ATRASANDO AOS POUCOS. VC SABE O PROBLEMA?

    ResponderExcluir
  18. Olá, Gostaria de saber, como posso acionar um servomotor em um determinado horario, exemplo as 8am e 4pm, por ate 05 dias. Muito obrigada

    ResponderExcluir
  19. Ola boa noite !!!
    Gostaria de uma ajuda estou tentando carregar um programa que e esta apresentando esse erro !!

    Arduino: 1.6.12 (Windows 7), Placa:"Arduino/Genuino Uno"

    F:\Arduino\Automação_livre\AutomationHome-master\Testes\Temp\Arduino\Arduino.ino: In function 'void loop()':

    Arduino:262: error: 'BuscaDataHora' was not declared in this scope

    Arduino:263: error: 'BuscaTemperatura' was not declared in this scope

    Arduino:264: error: 'AguardaComandos' was not declared in this scope

    Arduino:265: error: 'ModoAuto' was not declared in this scope

    Arduino:266: error: 'RetornaDados' was not declared in this scope

    Arduino:268: error: 'PrintLcd' was not declared in this scope

    F:\Arduino\Automação_livre\AutomationHome-master\Testes\Temp\Arduino\Arduino.ino: In function 'void AguardaComandos()':

    Arduino:355: error: 'disparacomando' was not declared in this scope

    F:\Arduino\Automação_livre\AutomationHome-master\Testes\Temp\Arduino\Arduino.ino: In function 'void disparacomando()':

    Arduino:890: error: 'setDateDs1302' was not declared in this scope

    F:\Arduino\Automação_livre\AutomationHome-master\Testes\Temp\Arduino\Arduino.ino: In function 'void BuscaDataHora(byte*, byte*, byte*, byte*, byte*, byte*, byte*)':

    Arduino:1318: error: 'bcdToDec' was not declared in this scope

    exit status 1
    'BuscaDataHora' was not declared in this scope

    Este relatório teria mais informações com
    "Mostrar a saida detalhada durante a compilação"
    opção pode ser ativada em "Arquivo -> Preferências"



    não consigo identificar o erro sou novo com arduino !!

    parabéns pelo blog ótimo

    att

    antonio

    ResponderExcluir
    Respostas
    1. Boa noite Antonio,

      Isso me parece erro de biblioteca..... você instalou corretamente ?

      Abraço!

      Excluir
    2. Sim inclusive baixei no link que esta no blog

      Excluir
  20. Ola consigo colocar para ligar uma lampada exemplo 6 horas da manha segunda a sexta ? todos os dias ? se sim fica dica de mais um tutorial pra gente rs

    ResponderExcluir