Relógio com o módulo RTC DS1307 e LCD 20×4

Relógio com o módulo RTC DS1307 e LCD 20×4

Aqui no blog já trabalhamos anteriormente com o módulo RTC DS1307, mostrando como ligar o módulo ao Arduino e exibir as informações de data e hora no serial monitor. Agora nesse post, vamos utilizar como base esse mesmo artigo (Relógio com o módulo RTC DS1307) e exibir essas informações em um Display LCD 20×4, deixando o nosso relógio muito mais profissional.

Conectando DS1307 e Display ao Arduino

O Display LCD 20×4 possui a mesma pinagem dos displays LCD 16×2 que usamos anteriormente em outros artigos, portanto a ligação será a mesma. Observe atentamente a pinagem do módulo DS1307 para não inverter nenhum fio. Na dúvida, consulte o artigo anterior:

 

Circuito Arduino - DS1307 - LCD 20x4

Programando Relógio Arduino com DS1307

O programa usa a biblioteca Wire, já presente na IDE do Arduino. Para setar a data e a hora, altere o valor das variáveis segundos, minutos, horas, diadasemana, diadomes, mes e ano, entre as linhas 32 e 38. Definido o horário, retire o comentário (barras duplas) da linha 21 abaixo:

// SelecionaDataeHora(); 

Carregue o programa no Arduino e volte a comentar a linha acima, para que os dados do relógio se mantenham atualizados.

// Programa: Relogio com modulo DS1307 e LCD 20x4
// Autor : FILIPEFLOP

#include "Wire.h"
#include <LiquidCrystal.h>

#define DS1307_ADDRESS 0x68

// Inicializa o LCD
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

byte zero = 0x00; 

void setup()
{
 // Define o LCD com 20 colunas e 4 linhas
 lcd.begin(20, 4);
 Wire.begin();
 Serial.begin(9600);
 // A linha abaixo pode ser retirada apos setar a data e hora
 // SelecionaDataeHora(); 
}

void loop()
{
 Mostrarelogio();
 delay(1000);
}

void SelecionaDataeHora() // Seta a data e a hora do DS1307
{
 byte segundos = 01; // Valores de 0 a 59
 byte minutos = 59; // Valores de 0 a 59
 byte horas = 23; // Valores de 0 a 23
 byte diadasemana = 4; // Valores de 0 a 6 (0=Domingo, 1 = Segunda...)
 byte diadomes = 23; // Valores de 1 a 31
 byte mes = 4; // Valores de 1 a 12
 byte ano = 15; // Valores de 0 a 99
 Wire.beginTransmission(DS1307_ADDRESS);
 // Stop no CI para que o mesmo possa receber os dados
 Wire.write(zero); 

 // As linhas abaixo escrevem no CI os valores de 
 // data e hora que foram colocados nas variaveis acima
 Wire.write(ConverteParaBCD(segundos));
 Wire.write(ConverteParaBCD(minutos));
 Wire.write(ConverteParaBCD(horas));
 Wire.write(ConverteParaBCD(diadasemana));
 Wire.write(ConverteParaBCD(diadomes));
 Wire.write(ConverteParaBCD(mes));
 Wire.write(ConverteParaBCD(ano));
 Wire.write(zero); //Start no CI
 Wire.endTransmission(); 
}

byte ConverteParaBCD(byte val)
{ 
 // Converte o número de decimal para BCD
 return ( (val/10*16) + (val%10) );
}

byte ConverteparaDecimal(byte val) 
{ 
 // Converte de BCD para decimal
 return ( (val/16*10) + (val%16) );
}

void Mostrarelogio()
{
 Wire.beginTransmission(DS1307_ADDRESS);
 Wire.write(zero);
 Wire.endTransmission();
 Wire.requestFrom(DS1307_ADDRESS, 7);
 int segundos = ConverteparaDecimal(Wire.read());
 int minutos = ConverteparaDecimal(Wire.read());
 int horas = ConverteparaDecimal(Wire.read() & 0b111111); 
 int diadasemana = ConverteparaDecimal(Wire.read()); 
 int diadomes = ConverteparaDecimal(Wire.read());
 int mes = ConverteparaDecimal(Wire.read());
 int ano = ConverteparaDecimal(Wire.read());
 // Imprime mensagem na primeira linha do display
 lcd.setCursor(0,0);
 lcd.print("---- FILIPEFLOP ----");
 
 // Mostra a hora atual no display
 lcd.setCursor(6, 2);
 if (horas < 10)
 {lcd.print("0");}
 lcd.print(horas);
 lcd.print(":");
 if (minutos < 10)
 {lcd.print("0");}
 lcd.print(minutos);
 lcd.print(":");
 if (segundos < 10)
 {lcd.print("0");}
 lcd.print(segundos);
 
 // Mostra a data atual no display
 lcd.setCursor(0, 3);
 lcd.print("Data : ");
 lcd.setCursor(7,3);
 if (diadomes < 10)
 {lcd.print("0");}
 lcd.print(diadomes);
 lcd.print(".");
 if (mes < 10)
 {lcd.print("0");}
 lcd.print(mes);
 lcd.print(".");
 lcd.print(ano);
 
 //Mostra o dia da semana no display
 lcd.setCursor(17, 3);
 switch(diadasemana)
 {
 case 0:lcd.print("Dom");
 break;
 case 1:lcd.print("Seg");
 break;
 case 2:lcd.print("Ter");
 break;
 case 3:lcd.print("Qua");
 break;
 case 4:lcd.print("Qui");
 break;
 case 5:lcd.print("Sex");
 break;
 case 6:lcd.print("Sab");
 }
}

Uma sugestão de utilização é alterar o programa para que ele mostre na tela, alternadamente, as informações de data e hora, ou até mesmo informações sobre as outras portas do Arduino.

Gostou ? Ajude-nos a melhorar o blog atribuindo uma nota aos posts (estrelas no início ou no final do artigo) e visite nossa loja FILIPEFLOP !

6
Relógio com o módulo RTC DS1307 e LCD 20×4
55 votos, 4.73 classificação média (94% pontuação)

Formado em Ciência da Computação pela Universidade de Mogi das Cruzes, atualmente responsável pelo departamento técnico da FILIPEFLOP.

Compartilhe este Post

72 Comentários

  1. João Paulo - 8 de março de 2017

    Como obter o valor de hora e minuto separados… ?
    hora = rtc.getTimeStr();
    h = hora.substring(0,2);
    m = hora.substring(3,5);
    s = hora.substring(6,8);

    tentei dessa forma mas da erro.. ‘hora’ does not name a type

  2. Rafael Forte - 23 de janeiro de 2017

    Boa tarde amigo.
    Hoje eu pensei em fazer um relogio onde, quando se aperta um botão, ele deixa registrado a hora. Caso seja apertado novamente, ele substitui aquele registro pelo atual
    Temos um problema com a hora que foi dada ração para os cães, ninguem nunca sabe se ja foi dado ou não.
    Com isso, penso em que quando alguem der a ração, aperta-se o botão e fica marcado a hora, ai quando outro vier com essa dúvida, ele apenas olha a hora da ultima vez que foi dada a ração.
    Se puder me ajudar, eu agradeço desde já.
    Obrigado.
    abraço.

  3. Carrie Pascoal Kopczinski - 30 de dezembro de 2016

    Boa noite!

    Estou com um RTC1307 em um outro projeto, consegui verificar as informações no Serial Monitor e tudo mais.
    Como faço para ligar uma lampada das 06:00 às 22:00? Já tenho todo o esquema dos reles montados e funcionais, mas não estou conseguindo extrair a hora/minuto para manipular no algorítimo e ligar/desligar o relê. Algum exemplo? Printar já esta fácil, só quero acionar um relê dentro de um determinado período.

    Adilson, pode me auxiliar nessa questão? Valeuzão!

  4. Ismênio Bacci - 16 de novembro de 2016

    Vi este projeto, e gostaria de saber se é possível criar uma nova void para o controle de um motor, ciclando a partir de um horário e em dias definidos da semana.
    Ou se não vai ser possível acionar duas void ao mesmo tempo.
    obrigado.

  5. Marino - 28 de outubro de 2016

    Olá! Estou com dificuldade em implementar este relógio utilizando arduino Mega. Poderiam auxiliar nas alterações necessárias? Obrigado!

  6. Anderson Silva - 25 de outubro de 2016

    Primeiramente gostaria de estar agradecendo há todos do site, sempre boas e novas ideias e dicas de como solucionar quaisquer duvida e dificuldade que tive em meu trabalho de TCC, que por sinal utilizei esse post do modulo RTC com LCD aonde mondei um Shield para usar com o LCD usando apenas 3 porta do Arduino, que ao meu ponte de vista foi bem mais vantajoso já que o custo de montar o shield foi bem baixo.
    Adicionei vários outros programa na mesma programação e tudo funcionou completamente como eu queria.
    Obrigado galera do FILIPEFLOP.

  7. Gabriel Galdino - 24 de outubro de 2016

    Estou começando com alguns projetos, e me interessei nesse, queria saber quais sao os resistores utilizados nesse projeto. Aguardo e grande abraço

  8. Mack Matsu - 11 de outubro de 2016

    Sensacional ! ! !
    Liguei o RTC com um I2C… um shiel de relógio e um display 20×4 ocupando somente duas portas do Arduíno mais duas em comum de alimentação ! !

  9. israel rocha costa - 19 de setembro de 2016

    eu fiz um relógio desses para minha máquina de lavar roupas. com arduino uno, rtc 1307 e lcd 16×2. Encontrei um problema na hora da mudança do dia da semana de Sábado para Domingo. sempre que passava das 23:59:59 a string Domingo, não aparecia. aquele byte do dia da semana vai de 0 à 6 ou de 1 à 7? pergunto por que só apareceu no lcd a string “Domingo” quando mudei no switch(diadasemana) o case 0: Domingo, para case 7: Domingo, removendo o case 0. me dá uma dica sou leigo no assunto

  10. Marcelo - 3 de agosto de 2016

    Boa noite !
    Estou fazendo a ligação do meu LCD 20 x 4, mas somente colocando a enerigia. Ele ainda não está comunicando com o meu PIC. Minha dúvida é: Quando eu energizo ele, somente sa linhas 2 e 4 ficam mais destacadas, ou seja mais definidos os dígitos (mais iluminados e definidos). As linhas 1 e 3 ficam mais apagadas, parecendo que não está habilitando ou meio apagado. Isto é normal ?
    Fico no aguardo de sua resposta e obrigado !

    att. Marcelo

  11. Tiago - 9 de junho de 2016

    Gostaria de saber por que o ds1307 foi endereçado em 0x68?

  12. Daniel Fernandes - 19 de maio de 2016

    Primeiramente, obrigado pelo tutorial;
    Talvez eu esteja fazendo errado mas, eu não entendi isso: “retire o comentário (aspas duplas) da linha 21″; sendo essa linha um comentário, o próprio IDE do Arduino o ignora como código pois, é iniciada com barras duplas.
    Outrossim, altero o valor das variáveis, nas linhas 32 a 38 e nada acontece (não altera no LCD);
    Obs.: estou usando o RTC3231
    Obrigado

    • Adilson Thomsen - 19 de maio de 2016

      Boa tarde Daniel,

      Você retira as barras duplas da linhas 21, seta a data e a hora entre as linhas 32 a 38 e carrega o programa. Isso vai setar no RTC a data e a hora que você configurou.

      Feito isso, volte a comentar a linha 21 e carregue o programa novamente.

      (realmente não são aspas, são barras. texto corrigido. Obrigado)

      Abraço!

      Adilson – Equipe FILIPEFLOP

  13. Paulo VIctor - 12 de fevereiro de 2016

    Bom dia, tem algum projeto usando RTC para Raspberry?

  14. Anderson Silva - 4 de fevereiro de 2016

    Boa noite amigos!
    Estou aqui mais uma vezes para agradecer primeiramente, muito bom mesmo o blog, vários programinhas já realizados por aqui!
    Estou como um problema que me deparei ao tentar realizar dois projeto daqui, aonde executei corretamente um e outro separadamente e agora estou com um pouco de dificuldade em juntar os dois programas.
    Gostaria de saber se algum de vocês poderia me ajudar?
    Desde já agradeço pela forca.

    Então realizei primeiro a programação do RFid com o Lcd e Depois o do RTC DS1307 com Lcd
    mais quando vou juntar os dois dá erro!
    dependendo de como carrega trava um e não deixa ler o outro
    se alguem poder dar uma luz agradece…

  15. Thalles - 1 de fevereiro de 2016

    Olá,

    Fiz algumas alterações neste código apenas para imprimir no Serial Monitor ao invés de imprimir em um display e obtive o mesmo problema que estou tendo usando outros códigos (alguns de minha própria autoria). Anteriormente estava tentando usar a biblioteca da Adafruit “RTClib.h” mas como nao estava obtendo êxito fiz mais algumas pesquisas e achei esse tutorial de como fazer somente pela “Wire.h”. O meu problema é o seguinte: a hora mostrada simplesmente não atualiza de segundo em segundo, passam-se 12 segundos e só depois ele contabiliza 1 segundo. Por exemplo, agora meu RTC está marcando 10:13:10. Ele imprimi essa hora aproximadamente 12 vezes (algumas vezes mais, outras menos) e depois imprimi 10:13:11. Se alguém puder me ajudar, será de muuita ajuda.

  16. fabio - 17 de novembro de 2015

    tem como usar o rtc para ligar dispositivos em hora especifica? tipo: ligar relé 18:00 até 06:00

  17. Mauricio - 13 de outubro de 2015

    Eu ja consegui meter o lcd a dar e o rtc a dar ( este apenas so aceita a sexta feira e sempre que carregue o codigo tenho que mudar a hora para começar a funcionar) mas nao estou a conseguir juntar estes dois

  18. jaime - 7 de setembro de 2015

    olá! gostaria de saber se tem como mostrar nesse relógio o nº de dias corrente ( ex : 115 dias) ; 7/9/15. Não sou bom em programação.

  19. Gabriel - 2 de setembro de 2015

    Bom dia senhores, peguei como base uma programação de uma dosadora de liquidos, onde ela EM HORA MARCADA liga, dosa a quantidade de ml programada no tempo e desliga, esta programação aciona 3 bombas em tempos diferentes. porém agora vai:
    TENTEI APLICAR ESTA PROGRAMAÇÃO EM UM PWM PARA ACIONAR LUZES EM HORÁRIOS DIFERENTES DE UMA LUMINÁRIA DE AQUÁRIO, TIPO: 10h aciona os leds em 30% de sua portência, 15h todos os leds ficam 100% de sua potência, a partir das 21h ele inicia seu desligamento até meia noite apagar totalmente e acionar uma outra porta com 2 leds chamados de MOON LIGHT pra não ficar no breu total! queria sincronizar isso com o RTC para fazer, alguem sabe me indicar alguma programação?!

  20. alexsandro - 18 de agosto de 2015

    Boa tarde,gostaria de saber como faço para que a cada hora seja ativado um servo motor,(a cada hora o servo iria movimentar 7°)

    • FILIPEFLOP - 19 de agosto de 2015

      Bom dia Alexsandro,

      Acho que uma maneira bem simples de fazer isso é vc testar o valor da variável “minutos”, assim, toda vez que ela chegar no valor que você colocou, ele aciona o motor. Vamos supor que vc queira que ele acione o motor em hora “cheia”, tipo 2:00, 3:00, 13:00, etc. Fica mais ou menos assim:

      if (minutos == 0)
      {
      //Comando para acionar o motor 7°
      }

      Abraço!

      Adilson – Equipe FILIPEFLOP

  21. Jacob - 21 de julho de 2015

    Excelente tutorial. Principalmente a interface com o RTC, porque usualmente faz-se uso de uma biblioteca à parte ( e há várias, todas confusas!) e aqui usou-se somente a Wire, nativa do Arduino. Aprendi MUITO. Obrigado.

  22. alexsandro - 2 de julho de 2015

    Bom dia, você poderia me informa se através desse código eu posso colocar um alarme com o próprio Rtc ds1307, agradeço desde já.

  23. Sérgio - 2 de junho de 2015

    Bom dia Filipe,
    Montei o circuito como indicado, porem o display lcd 16×2 só mostra a data, não mostra a hora e nem o dia da semana.

    • FILIPEFLOP - 3 de junho de 2015

      Bom dia Sérgio,

      Você alterou o programa para a utilização com o display 16×2 ? Se não foi feito, as coordenadas (lcd.setCursor()) podem fazer com que o texto fique “fora” do display.

      No setup, altere a linha lcd.begin(20, 4) para lcd.begin(16, 2), e nos comandos lcd.setCursor(), lembre-se de que você pode ter no máximo o valor 1 para a linha.

      Para posicionar um texto na primeira linha, 3a. coluna: lcd.setCursor(3,0)
      Para posicionar um texto na segunda linha, 4a. coluna: lcd.setCursor(4,1)

      Abraço.

      Adilson – Equipe FILIPEFLOP

  24. Moises Lima - 4 de maio de 2015

    Sempre acompanho seus tutoriais
    Adquiri um LCD QC2004A Azul com letras brancas, mas de forma alguma consigo colocar ele para funcionar.
    Tem alguma dica que possa me ajudar.
    Obrigado
    Moises Lima

  25. PLT PROJETOS - 30 de março de 2015

    Bom Dia !
    Gostaria de saber como deixo os dias da semana em portugues no display, pois no meu aparece os dias em inglês e não estou conseguindo mudar, estou usando a biblioteca DS1307.h

  26. mateus - 28 de dezembro de 2014

    Pra quem não está conseguindo setar a data e a hora certa, observe o modulo que está usando. O meu RTC é o 12c e o esquema de ligacao é diferente do dsi1307. Pessoal , pra quem não estava conseguindo visualizar as horas e datas corretas no display , e pra quem não conseguiu manipular as variáveis , observar que no modulo RTC 12C você deve ligar o GND no terra, o VCC no 5 volts, o SDA no A4 e o SCL no A5.

  27. Luciano - 21 de dezembro de 2014

    Boa noite, poderia me dizer como ligo o DS1307 com o shield display que já vem com os botões (LCD keypad shield)?
    Obrigado!

    • Luciano - 3 de janeiro de 2015

      Boa noite Filipe!
      Na mensagem anterior fiz uma pergunta de como ligar este módulo seu:
      LCD Shield com Teclado para Arduino
      R$ 34,90
      no circuito acima, já que ele é o modelo sem botões.
      Obrigado!

    • FILIPEFLOP - 5 de janeiro de 2015

      Boa noite Luciano,

      Você pode soldar uma barra de pinos ao shield e utilizar as portas digitais 0,1,2,3,11,12 e 13, e também as portas analógicas A1, A2, A3, A4 e A5.

      Abraço.

      Adilson – Equipe FILIPEFLOP

      • Luciano - 6 de janeiro de 2015

        Bom dia Filipe, trabalho a mais de 25 anos com eletrônica (bancada), mas no Arduino a alguns meses… Ainda preciso do esquema elétrico ou físico.
        Muito obrigado pela pronta resposta!

  28. Pedro Henrique - 19 de novembro de 2014

    Pessoal , pra quem não estava conseguindo visualizar as horas e datas corretas no display , e pra quem não conseguiu manipular as variáveis , está aqui o código nesse site: http://www.arduinoecia.com.br/2013/04/real-time-clock-rtc-ds1307.html

    Abracos

  29. Joubert - 18 de novembro de 2014

    Amigo, estou tentando comparar a data e hora atual trazida pelo DS1307 com uma inserida manualmente pelo usuário via botôes para o acionamento de um relé para ligar uma válvula, mas não consigo fazer uma comparação, pode me ajudar?

    if (rtc.getTimeStr() == 22) {
    digitalWrite(rele, HIGH);

    mas como é um ponteiro não tem dado certo

  30. Delmir Ferronatto - 28 de outubro de 2014

    Filipe, estou montando um projeto onde uso o DS1307 e um display lcd 20×4 em I2C tambem, poren não estou conseguindoque apareça nada no display, estou utilizando os resistors terminadores na rede mas mesmo assin não funciona, tem algum exemplo que eu possa me basear, acho que esta tendo conflito entre os dois componentes.
    Desde já agradeço sua ajuda!

  31. Uline - 28 de outubro de 2014

    Gostaria de saber se com este Módulo (Relógio e Display) posso deixar que o próprio usuário possa programar os dias da semana e horários que um Motor de Passo irá funcionar?

    • FILIPEFLOP - 3 de novembro de 2014

      Boa tarde Uline,

      Sim, você pode fazer isso no próprio programa, testando a data e a hora e verificando se ela está de acordo com o que o usuário programou.

      Abraço.

      Adilson – Equipe FILIPEFLOP

  32. Gileno - 7 de outubro de 2014

    Olá então estou copiando essa programação mas sempre aparece um erro no rtc e outras programações tbm o que eu faço eu estou rodando no windows 8 e baixai o programa direto do site do Arduíno me de uma luz.

    Obrigado valeu!!!!

  33. claudinei - 17 de setembro de 2014

    Ola amigo e muito complicado fazer as seguintes alteracoes…
    Display 16×2 e modulo Relógio de tempo real DS1302?

  34. Douglas - 14 de agosto de 2014

    Eu fiz exatamente como no tutorial, mas no lcd a hora fica 27:85:85 e a data 85.85.2165, qual seria o problema?

    • Marcio - 16 de agosto de 2014

      Estou com o mesmo problema…

    • pedro - 17 de novembro de 2015

      Vocês devem inicializar o RTC, a maneira de inicializar é colocar no programa uma vez as seguintes linhas
      rtc.setDOW(MONDAY);
      rtc.setTime(16, 30, 47);
      rtc.setDate(5, 6, 2014);

      Porém com a data, hora e dia da semana que desejar.

      Após carregar o programa uma vez vocês podem comentar essas tres linhas, caso contrário esta data será sempre redefinida no RTC.

  35. Eduardo - 6 de agosto de 2014

    Ola, tudo bem?

    Gostaria de saber se você tem o código para PIC?

    obrigado

    Eduardo

  36. Douglas - 2 de agosto de 2014

    É possível modificar a maneira de exibir as horas, exemplo, ao invés de 22:39:12, 22h39, além da data, só exibir o dia e o mês separados por “/’?

  37. Luis - 25 de julho de 2014

    OLÁ . O meu arduíno é o Mega. No código vc descreve as portas para o UNO, que são A4 eA5. No mega, com esse código, ele não exibe as horas nem data, apenas zeros no lugar. Sei que no mega as portas SDA e SCL são 20 e 21. Como seria o código para o mega?

    Acho que seria só mudar essa linha: DS1307 rtc(A4, A5);

    Detalhe: Outros códigos exibem a hora e data, sendo assim as ligações físicas parecem estar ok.
    Desde já muito grato a todos!
    Um abraço!

    • Adilson - 29 de julho de 2014

      Boa noite Luis,

      Eu fiz um teste com o Arduino Mega e funcionou sem problemas nas portas 20 e 21.

      Usei o mesmo programa, só mudando o comando para

      DS1307 rtc(20, 21);

      Talvez seja algum problema de conexão, não sei dizer ao certo.

      Abraço !

      Adilson – Equipe FILIPEFLOP

    • Rafael - 10 de agosto de 2014

      Estou com o mesmo problema!! ja tentei tudo, inclusive usar outras bibliotecas mas nada parece funcionar!!

  38. João Airton Bitencourt - 7 de julho de 2014

    Caro Filipe, preciso acionar um rele com horário marcado, mas no código acima não sei qual variável ou função me dariam essa possibilidade. Gostaria de uma ajudinha se possível.
    Att. João

    • FILIPEFLOP - 15 de julho de 2014

      Boa noite João,

      Essa biblioteca não tem a função de alarme. Nossa sugestão é montar algum tipo de comparador com o valor de rtc.getTimeStr(), por exemplo, que é a hora atual.

      Adilson – Equipe FILIPEFLOP

    • ARGEL - 14 de julho de 2015

      Olá joão tudo bem ? tambem estou tentando fazer isso a um bom tempo mas ainda não consegui , se voce teve sucesso e puder me ajudar com o codigo agradeço.
      OBRIGADO

  39. Eric - 29 de junho de 2014

    Ótimo post. Eu gostaria de saber aonde eu posso encontrar o sensor de temperatura.

  40. claudio olímpio da silva - 23 de junho de 2014

    Eu, gostaria de saber se dá para colocar um no relógio.

Deixe uma resposta