Componentes · 20 min de leitura

Módulo RTC com Arduino: DS3231 vs DS1307 vs DS1302, hora e alarmes

Guia do módulo RTC para Arduino: DS3231, DS1307 e DS1302 comparados, como acertar a hora com a RTClib, relógio no LCD, irrigação programada, a armadilha do carregamento da CR2032 e NTP no ESP32.

Um módulo RTC para Arduino é uma pequena placa de relógio que continua contando a data e a hora mesmo quando a sua placa fica sem energia. RTC é a sigla de “Real Time Clock”, ou relógio de tempo real. O contador millis() do próprio Arduino começa do zero toda vez que a placa é ligada e pode desviar minutos em poucos dias, enquanto um módulo RTC continua marcando a hora com precisão de segundos por anos, graças à sua bateria de botão (CR2032). Você encontra esse módulo em relógios de mesa, sistemas de irrigação automática, alimentadores de pets, registradores de dados com data e hora e projetos de iluminação temporizada.

Neste guia você vai comparar os três chips mais comuns, DS1307, DS3231 e DS1302, e ver qual escolher e por quê. Depois, passo a passo, vamos acertar e ler a hora com a biblioteca RTClib, mostrar a hora e a data em um LCD I2C, montar um temporizador que aciona uma bomba em horários definidos todos os dias e usar o alarme por hardware do DS3231. As seções finais tratam da armadilha do circuito de carga da CR2032, que estraga muitos módulos, de como obter a hora pela internet com NTP no ESP32 e do RTC interno do Raspberry Pi Pico.

Módulo de relógio RTC DS1307
Módulo RTC DS1307: pinos GND, 5V, SDA, SCL e SQW à esquerda, o chip DS1307 no meio e o suporte da bateria de botão CR1220 à direita.

O que é um módulo RTC e como ele funciona?

No coração de um chip RTC há um cristal de relógio de 32,768 kHz. Esse número não é aleatório: 32.768 é 2 elevado a 15, então o chip divide essa frequência por dois 15 vezes para obter um pulso exato de 1 segundo. A cada pulso, os registradores de segundos, minutos, horas, dia, mês e ano são atualizados; a duração de cada mês e os anos bissextos são tratados automaticamente até o ano 2100. O Arduino lê esses registradores pelo I2C ou grava neles uma nova hora. Os valores ficam guardados no formato BCD (por exemplo, 59 segundos é armazenado como 0x59); as bibliotecas fazem essa conversão por você.

O grande truque de um RTC são as suas duas entradas de alimentação. Quando o VCC some, o chip passa automaticamente para a entrada da bateria (VBAT) e consome só a corrente necessária para continuar contando: menos de um microampere ou alguns microamperes. Enquanto isso, o DS1307 desliga o acesso pelo I2C, já o DS3231 ainda pode ser lido na bateria; em qualquer caso, o relógio não para. Quando a energia volta, o Arduino inicia, lê a hora correta do RTC e continua de onde parou. Por causa da tolerância do ressonador cerâmico do Arduino Uno, um relógio mantido com millis() pode errar minutos por dia e se perde a cada reset; por isso qualquer projeto que depende da hora precisa de um RTC separado.

DS1307 vs DS3231 vs DS1302: as diferenças

CaracterísticaDS1307DS3231DS1302
ComunicaçãoI2C (100 kHz), endereço 0x68I2C (até 400 kHz), endereço 0x68Serial de 3 fios: CE (RST), I/O (DAT), SCLK (CLK)
Tensão de alimentação4,5–5,5 V2,3–5,5 V2,0–5,5 V
CristalExterno de 32,768 kHz (12,5 pF)Integrado ao chip, com compensação de temperatura (TCXO)Externo de 32,768 kHz (6 pF)
PrecisãoDepende do cristal; com ±20 ppm, cerca de 1,7 s/dia, cerca de 1 min/mês±2 ppm (0–40 °C): cerca de 5 s/mês, cerca de 1 min/anoDepende do cristal; parecida com a do DS1307 ou pior
Recursos extras56 bytes de RAM com backup por bateria, saída de onda quadrada (SQW)2 alarmes, saída INT/SQW, sensor de temperatura (±3 °C), ajuste de envelhecimento (aging trim)31 bytes de RAM, carregador lento integrado (trickle charger)
Corrente na bateriaCerca de 300–500 nACerca de 1–3 µAMenos de 300 nA a 2 V
Biblioteca para ArduinoRTClib (da Adafruit)RTClib (da Adafruit)Rtc by Makuna
Indicado paraProjetos simples de relógio em 5 VQuase todo projeto; ideal também para ESP32 e PicoKits antigos e projetos de aprendizado

Vamos deixar a diferença de precisão mais concreta: 1 ppm significa uma parte por milhão, e um dia tem 86.400 segundos. Um cristal comum de ±20 ppm pode desviar até 1,7 segundo por dia, cerca de 52 segundos por mês, e quanto mais longe da temperatura ambiente, mais a frequência do cristal muda e maior fica o erro. O DS3231, por outro lado, leva o cristal dentro do chip, mede a temperatura a cada 64 segundos e corrige a frequência de acordo. Isso dá ±2 ppm entre 0 e 40 °C, mais ou menos um minuto por ano, e ele fica dentro de ±3,5 ppm mesmo de -40 a +85 °C.

Qual módulo RTC escolher?

  • Projeto novo, ESP32 ou Pico: escolha um DS3231. Ele funciona tanto em 3,3 V quanto em 5 V, tem alarmes e é o que mantém a hora com mais precisão. A diferença de preço é pequena.
  • Você já tem um DS1307 e usa um Arduino Uno: pode usar sem medo; só conte com cerca de um minuto de desvio por mês e corrija a hora de vez em quando.
  • Seu kit iniciante veio com um DS1302: ele serve bem para aprender como um RTC funciona, mas não espere um relógio que continue preciso por meses.
  • ESP32 com conexão permanente à internet: comece com NTP e sem módulo; adicione um DS3231 se a hora precisar ser conhecida depois de uma queda de energia, antes de a internet voltar.

Você vai encontrar principalmente duas placas prontas: a ZS-042, com chip DS3231, e a Tiny RTC, com DS1307. As duas também trazem uma EEPROM AT24C32 de 4 KB para guardar dados. Por isso é normal ver um segundo endereço ao lado do 0x68 quando você roda um scanner I2C (geralmente 0x57 na ZS-042 e 0x50 na Tiny RTC); esse endereço pertence à EEPROM, não ao relógio. O DS1302 nem usa I2C: ele se comunica pelo seu próprio protocolo de 3 fios e ocupa três pinos digitais.

Não tente usar um DS1307 em 3,3 V. Quando o VCC cai abaixo de cerca de 1,25 vez a tensão da bateria (cerca de 3,75 V com uma bateria de 3 V), o chip entende que a energia acabou e para de responder no I2C. Em placas de 3,3 V, como o ESP32 e o Pico, o DS3231 funciona diretamente. Para saber mais sobre endereços I2C e resistores de pull-up, veja O que é I2C?.

Ligação do módulo RTC: Arduino Uno, ESP32 e Pico

Pino do RTCArduino UnoESP32Raspberry Pi Pico
VCC5V3V3 (DS3231)3V3(OUT), pino físico 36 (DS3231)
GNDGNDGNDGND
SDAA4GPIO 21GP4 (I2C0)
SCLA5GPIO 22GP5 (I2C0)
SQW / INT (opcional)D2 (pino de interrupção)Qualquer GPIO (ex.: GPIO 4)Qualquer pino GP (ex.: GP15)

No Uno R3, os pinos SDA e SCL ao lado do pino AREF também estão ligados ao A4 e ao A5, então tanto faz quais você usa. O RTC pode compartilhar os mesmos dois fios com um LCD I2C ou um display OLED; cada dispositivo tem o seu próprio endereço, então não há conflito. Manter os fios com menos de 20–30 cm evita erros de leitura aleatórios, principalmente na protoboard. Você só precisa ligar o pino SQW/INT se for usar o alarme por hardware.

Quando módulos como o DS1307 e a ZS-042 são alimentados com 5 V, os resistores de pull-up da placa também puxam as linhas SDA e SCL para 5 V. Os pinos do ESP32 e do Raspberry Pi Pico não toleram 5 V. Nessas placas, alimente sempre o módulo pelo pino 3V3; se você precisar usar um chip que exige 5 V, como o DS1307, coloque um conversor de nível lógico entre eles.

Instalando a RTClib e acertando a hora

  1. Abra o Gerenciador de Bibliotecas no Arduino IDE, digite RTClib e instale a biblioteca da Adafruit. Quando ele perguntar sobre as dependências, escolha Instalar tudo para que a Adafruit BusIO também seja instalada. Se você nunca adicionou uma biblioteca, o guia Como instalar uma biblioteca no Arduino mostra o passo a passo.
  2. Ligue o módulo como mostra a tabela acima e coloque a bateria no suporte.
  3. Carregue o código abaixo. Na primeira execução o módulo não sabe a hora, então o código grava no RTC o horário de compilação do seu computador.
  4. Abra o Monitor Serial em 9600 baud com o final de linha “Nova linha”. Para acertar a hora até o segundo, digite-a no formato 2026-11-03 14:30:00 e pressione Enter.
  5. Desconecte o cabo USB, espere alguns minutos e conecte de novo. Se o relógio continuar certo a partir de onde parou, o backup da bateria está funcionando.
C++ (Arduino IDE)
1#include <Wire.h>
2#include <RTClib.h>
3
4RTC_DS3231 rtc;   // DS1307 kullanıyorsan: RTC_DS1307 rtc; / for a DS1307: RTC_DS1307 rtc;
5
6void setup() {
7  Serial.begin(9600);
8  if (!rtc.begin()) {                         // modül I2C hattında yok / module not found on the I2C bus
9    Serial.println(F("RTC bulunamadi / RTC not found"));
10    while (true);
11  }
12  if (rtc.lostPower()) {                      // ilk çalıştırma ya da pil bitmiş / first run or dead battery
13    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));   // derleme saatini yaz / write the compile time
14    Serial.println(F("Saat derleme zamanina ayarlandi / Clock set to compile time"));
15  }
16  Serial.println(F("Ayar icin yaz / To set, type: 2026-11-03 14:30:00"));
17}
18
19void loop() {
20  // Seri monitörden saat geldiyse ayarla / set the time sent from the Serial Monitor
21  if (Serial.available()) {
22    String line = Serial.readStringUntil('\n');
23    int y, mo, d, h, mi, s;
24    if (sscanf(line.c_str(), "%d-%d-%d %d:%d:%d", &y, &mo, &d, &h, &mi, &s) == 6) {
25      rtc.adjust(DateTime(y, mo, d, h, mi, s));
26      Serial.println(F("Saat ayarlandi / Time set"));
27    }
28  }
29
30  DateTime now = rtc.now();
31  char buf[] = "DD.MM.YYYY hh:mm:ss";         // biçim şablonu / format template
32  Serial.print(now.toString(buf));
33  Serial.print(F("  "));
34  Serial.print(rtc.getTemperature());         // yalnız DS3231 / DS3231 only
35  Serial.println(F(" C"));
36  delay(1000);
37}

rtc.begin() retorna false se o módulo não for encontrado no barramento I2C; nesse caso, confira primeiro a ligação. rtc.lostPower() lê a flag de parada do oscilador (OSF) do DS3231: a função retorna true se o módulo está funcionando pela primeira vez ou se o relógio parou porque a bateria acabou, e então o código acerta o relógio para o horário de compilação. DateTime(F(__DATE__), F(__TIME__)) usa o momento em que o compilador gerou o seu código; como o carregamento leva alguns segundos, o relógio fica um pouco atrasado, por isso o ajuste fino pelo Monitor Serial é útil. toString() substitui as letras do modelo “DD.MM.YYYY hh:mm:ss” pelos valores reais.

FunçãoO que faz
rtc.begin()Inicia o módulo; retorna false se ele não for encontrado
rtc.adjust(DateTime(...))Grava a hora e a data
rtc.now()Lê a hora atual como um objeto DateTime
now.year(), now.month(), now.day() (data)Ano, mês, dia
now.hour(), now.minute(), now.second() (hora)Hora (0–23), minuto, segundo
now.dayOfTheWeek()Dia da semana: 0 = domingo, 6 = sábado
now.unixtime()Segundos desde 1º de janeiro de 1970; ideal para comparar dois horários
now + TimeSpan(0, 1, 30, 0)Soma 1 hora e 30 minutos (dias, horas, minutos, segundos)
rtc.lostPower() / rtc.isrunning() (validade)Informa se a hora é válida (DS3231 / DS1307)
rtc.getTemperature()Temperatura do chip em °C (só no DS3231)

Se você estiver usando um DS1307, a única diferença é o nome do objeto: escreva RTC_DS1307 rtc;, use uma verificação !rtc.isrunning() no lugar de lostPower() e apague a linha getTemperature(). Quando um DS1307 é alimentado pela primeira vez, o oscilador começa parado (bit CH em 1); adjust() limpa esse bit e põe o relógio para funcionar. Você pode guardar pequenas configurações, como o horário de um alarme, nos 56 bytes de RAM com backup por bateria do DS1307 usando rtc.writenvram() e rtc.readnvram(); graças à bateria, esses dados também sobrevivem às quedas de energia.

O erro mais comum é deixar a linha rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); em setup() sem nenhuma condição. Assim, toda vez que o Arduino reinicia ou a energia volta, o relógio volta para o momento em que o código foi compilado. Só acerte a hora quando lostPower() retornar true, ou transforme a linha em comentário depois de acertar a hora e carregue o código de novo.

Mostrando a hora e a data em um LCD

Ver a hora em um display em vez do Monitor Serial transforma o projeto em um relógio de mesa de verdade. Um LCD I2C 16x2 e o RTC se ligam ao mesmo barramento SDA-SCL: o LCD costuma ficar no endereço 0x27 ou 0x3F e o RTC no 0x68. O código abaixo escreve a data e a abreviação do dia na linha de cima, e a hora mais a temperatura medida pelo DS3231 na linha de baixo. Para a ligação do LCD e a instalação da biblioteca, dê uma olhada em Como usar um display LCD I2C.

C++ (Arduino IDE)
1#include <Wire.h>
2#include <RTClib.h>
3#include <LiquidCrystal_I2C.h>
4
5RTC_DS3231 rtc;
6LiquidCrystal_I2C lcd(0x27, 16, 2);           // adres 0x27 ya da 0x3F / address 0x27 or 0x3F
7
8// dayOfTheWeek(): 0 = Pazar / 0 = Sunday
9const char* const days[7] = {"Paz", "Pzt", "Sal", "Car", "Per", "Cum", "Cmt"};
10int lastSecond = -1;
11
12void setup() {
13  lcd.init();
14  lcd.backlight();
15  if (!rtc.begin()) {
16    lcd.print("RTC yok!");                     // modül bulunamadı / module not found
17    while (true);
18  }
19  if (rtc.lostPower()) rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
20}
21
22void loop() {
23  DateTime now = rtc.now();
24  if (now.second() == lastSecond) return;      // saniye değişmediyse yazma / skip until the second changes
25  lastSecond = now.second();
26
27  char line1[17], line2[17];
28  snprintf(line1, sizeof(line1), "%02d.%02d.%04d %s",
29           now.day(), now.month(), now.year(), days[now.dayOfTheWeek()]);
30  snprintf(line2, sizeof(line2), "%02d:%02d:%02d   %2dC",
31           now.hour(), now.minute(), now.second(), (int)rtc.getTemperature());
32  lcd.setCursor(0, 0);
33  lcd.print(line1);                            // ör. / e.g. 03.11.2026 Sal
34  lcd.setCursor(0, 1);
35  lcd.print(line2);                            // ör. / e.g. 14:05:09   23C
36}

O %02d dentro do snprintf acrescenta um zero à esquerda nos números de um dígito, então a hora aparece como 09:05:03 em vez de 9:5:3 e o comprimento da linha nunca muda. Graças ao comprimento fixo, você não precisa de lcd.clear(); limpar a tela a cada ciclo do loop causa tremulação. O código só escreve no display quando o segundo muda, assim não ocupa o barramento I2C à toa. O array days traz abreviações em turco; troque-as por Dom, Seg, Ter e assim por diante, mantendo o domingo como primeiro elemento.

Para mostrar a hora grande o bastante para ler do outro lado da sala, use um display de 7 segmentos de 4 dígitos ou uma matriz de LED MAX7219. Fazer os dois-pontos entre as horas e os minutos piscarem a cada segundo é um toque clássico que mostra que o relógio está funcionando.

Alarmes e tarefas programadas: irrigação automática e alimentação do pet

O mais útil de um RTC é fazer as tarefas acontecerem no horário: regar as plantas todas as manhãs às 08:00, liberar a ração do gato às 19:30 ou desligar a luz do aquário à noite. Há duas formas de fazer isso. A primeira é a comparação por software: você lê a hora em loop() e verifica se chegou o horário de uma tarefa. É simples, e você pode adicionar quantas tarefas quiser. A segunda é o alarme por hardware do DS3231: no momento definido, o chip coloca o pino INT em LOW e avisa o Arduino com uma interrupção; ele pode até acordar um microcontrolador que está dormindo.

Um erro comum na comparação por software é verificar um segundo exato, como now.second() == 0. Se houver um delay() longo em loop(), esse segundo pode passar e a tarefa nunca roda. O código abaixo compara a hora e o minuto, guarda uma chave formada pelo dia e pelo minuto para que a tarefa não rode duas vezes no mesmo minuto e controla o tempo da bomba com millis(). A bomba é acionada por um módulo relé; a ligação da bomba está no artigo sobre a mini bomba d'água.

C++ (Arduino IDE)
1#include <Wire.h>
2#include <RTClib.h>
3
4RTC_DS3231 rtc;
5
6const byte RELAY_PIN = 7;
7const byte RELAY_ON = LOW;                    // çoğu röle modülü LOW ile çeker / most relay modules switch on LOW
8const byte RELAY_OFF = HIGH;
9const unsigned long RUN_MS = 10000;           // pompa 10 saniye çalışır / the pump runs for 10 seconds
10
11struct Task { byte hour; byte minute; };
12Task tasks[] = { {8, 0}, {19, 30} };          // her gün 08:00 ve 19:30 / every day at 08:00 and 19:30
13const byte TASK_COUNT = sizeof(tasks) / sizeof(tasks[0]);
14
15long lastRunKey = -1;                         // aynı dakikada ikinci kez çalışmasın / never run twice in one minute
16bool running = false;
17unsigned long startMs = 0;
18
19void setup() {
20  pinMode(RELAY_PIN, OUTPUT);
21  digitalWrite(RELAY_PIN, RELAY_OFF);         // açılışta kapalı / off at start-up
22  rtc.begin();
23}
24
25void loop() {
26  DateTime now = rtc.now();
27  long key = (long)now.day() * 1440 + now.hour() * 60 + now.minute();   // gün + dakika / day + minute
28
29  for (byte i = 0; i < TASK_COUNT; i++) {
30    if (now.hour() == tasks[i].hour && now.minute() == tasks[i].minute && key != lastRunKey) {
31      lastRunKey = key;
32      running = true;
33      startMs = millis();
34      digitalWrite(RELAY_PIN, RELAY_ON);      // pompayı aç / pump on
35    }
36  }
37
38  if (running && millis() - startMs >= RUN_MS) {
39    running = false;
40    digitalWrite(RELAY_PIN, RELAY_OFF);       // pompayı kapat / pump off
41  }
42  delay(200);
43}

Incluir o dia na chave é importante: se você guardasse só o minuto e tivesse uma única tarefa, a chave continuaria a mesma naquele minuto no dia seguinte e a tarefa nunca mais rodaria. Para montar um alimentador de pet, use um servo motor no lugar do relé: girar o servo para 90 graus no horário da tarefa e voltá-lo um segundo depois abre a portinhola do reservatório e libera uma porção de ração. Para deixar a irrigação mais inteligente, leia um sensor de umidade do solo no horário da tarefa e não acione a bomba se o solo já estiver úmido. O segundo exemplo abaixo faz o mesmo trabalho com o alarme por hardware do DS3231.

C++ (Arduino IDE)
1#include <Wire.h>
2#include <RTClib.h>
3
4RTC_DS3231 rtc;
5const byte ALARM_PIN = 2;                     // DS3231 SQW/INT -> D2 (kesme pini / interrupt pin)
6volatile bool alarmFlag = false;
7
8void onAlarm() {                              // kesme fonksiyonu kısa olmalı / keep the ISR short
9  alarmFlag = true;
10}
11
12void setup() {
13  Serial.begin(9600);
14  rtc.begin();
15  rtc.disable32K();                           // 32K çıkışını kapat / turn off the 32K output
16  rtc.writeSqwPinMode(DS3231_OFF);            // SQW pini alarm çıkışı olur / SQW becomes the alarm output
17  rtc.clearAlarm(1);
18  rtc.clearAlarm(2);
19  rtc.disableAlarm(2);
20
21  // Her gün 07:30:00; tarih kısmı yok sayılır / every day at 07:30:00; the date part is ignored
22  rtc.setAlarm1(DateTime(2026, 1, 1, 7, 30, 0), DS3231_A1_Hour);
23
24  pinMode(ALARM_PIN, INPUT_PULLUP);           // INT çıkışı open-drain / INT is an open-drain output
25  attachInterrupt(digitalPinToInterrupt(ALARM_PIN), onAlarm, FALLING);
26}
27
28void loop() {
29  if (alarmFlag) {
30    alarmFlag = false;
31    rtc.clearAlarm(1);                        // temizlenmezse pin LOW kalır / the pin stays LOW until cleared
32    Serial.println(F("Alarm: mama vakti / Feeding time"));
33    // Servo, röle ya da buzzer kodunu buraya yaz / put your servo, relay or buzzer code here
34  }
35}

O DS3231 tem dois alarmes. O alarme 1 tem resolução de um segundo; o modo DS3231_A1_Hour dispara quando horas, minutos e segundos coincidem, ou seja, no mesmo horário todos os dias. Com os outros modos você pode programar um alarme a cada segundo (PerSecond), a cada minuto (Second), a cada hora (Minute), em um dia específico do mês (Date) ou em um dia específico da semana (Day). O alarme 2 tem resolução de um minuto. O pino SQW/INT é uma saída de dreno aberto, ativa em LOW: ele vai para LOW quando o alarme dispara e fica assim até clearAlarm() ser chamado. Por isso o melhor é apenas levantar uma flag na função de interrupção e fazer o trabalho de verdade em loop(). Para entender como as interrupções funcionam, veja Interrupções no Arduino.

Quanto tempo dura a bateria de um RTC?

Estimar a duração da bateria é fácil: autonomia (horas) = capacidade da bateria (mAh) ÷ consumo de corrente (mA). Uma CR2032 tem cerca de 220 mAh. No modo bateria, o DS3231 consome cerca de 3 µA no pior caso, ou seja, 0,003 mA: 220 ÷ 0,003 ≈ 73.000 horas, ou cerca de 8 anos. A bateria só é usada enquanto o VCC está desligado; se o módulo fica em um aparelho sempre ligado, a bateria quase não é usada e dura muito mais. Na prática, o limite costuma ser definido pela vida útil de armazenamento da própria bateria (shelf life) e pelo circuito de carga do módulo.

Chip RTCCorrente na bateriaAutonomia calculada com uma CR2032 (220 mAh)
DS1307~0,5 µA~50 anos; na prática, limitada pela vida útil de armazenamento da bateria (cerca de 10 anos)
DS3231~3 µA (pior caso)~8 anos
DS1302~0,3 µALimitada pela vida útil de armazenamento da bateria
Módulo com carregador ativo + CR2032A bateria recebe corrente à forçaImprevisível; a bateria pode estufar e acabar antes da hora
Para fazer as contas do seu próprio projeto, basta informar a capacidade da bateria e a corrente média na calculadora de autonomia da bateria. O mesmo cálculo também mostra quantos dias vai durar um Arduino alimentado por bateria e equipado com um RTC.

A armadilha da bateria CR2032 e do circuito de carga

A maioria dos módulos baratos DS3231 (ZS-042) e DS1307 (Tiny RTC) inclui um circuito de carga simples que, na verdade, foi projetado para uma bateria LIR2032 recarregável. Na ZS-042, a corrente vai do VCC para a bateria através de um diodo 1N4148 e um resistor de 200 Ω; a Tiny RTC tem um circuito parecido. O problema é que esses módulos muitas vezes são vendidos com uma CR2032 não recarregável. Quando o módulo funciona em 5 V, os cerca de 4,3 V que sobram depois do diodo ficam empurrando corrente para a bateria de lítio de 3 V. Com o tempo, uma bateria que nunca deveria ser carregada pode estufar, vazar e acabar antes da hora, e você fica com o problema “tem bateria, mas o relógio vive zerando”.

  • Se você vai usar uma CR2032, corte o caminho de carga: na ZS-042, dessolde o resistor SMD de 200 Ω marcado com “201”, perto da barra de pinos, ou o diodo ao lado dele. Para resistores cujo código você não consegue ler, use o decodificador de código SMD. Essa é a solução mais comum e mais segura.
  • Se você deixar o circuito como está, use uma LIR2032: a capacidade da bateria recarregável (cerca de 40 mAh) é mais ou menos um quinto da de uma CR2032 (cerca de 220 mAh), mas ela fica sempre carregada enquanto o módulo tiver energia.
  • Se você alimenta o módulo com 3,3 V: só cerca de 2,6 V chegam à bateria depois do diodo; uma LIR2032 nunca carrega por completo, e quase nenhuma corrente vai para uma CR2032. Ainda assim, remover o resistor é a solução mais limpa.
  • O carregador lento integrado do DS1302 (trickle charger) vem desligado quando o chip é ligado; se você usa uma CR2032, não o ative pelo código.
  • Meça a bateria: uma CR2032 nova marca 3,0–3,2 V; troque-a quando cair abaixo de 2,5 V.
Confira as letras na bateria: CR indica uma bateria de lítio não recarregável, e LIR, uma bateria recarregável de íon-lítio. Usar uma CR2032 por meses em 5 V em um módulo com circuito de carga ativo pode fazê-la estufar e vazar. Retire uma bateria estufada imediatamente e leve-a a um ponto de coleta de pilhas e baterias.

Usando o DS1302 (ligação de 3 fios)

Módulo de relógio RTC DS1302
Módulo RTC DS1302: pinos VCC, GND, CLK, DAT e RST à esquerda, o chip DS1302 de 8 pinos e o seu cristal no meio e o suporte da CR2032 à direita.

O módulo DS1302 tem cinco pinos: VCC, GND, CLK, DAT e RST. Como ele não usa I2C, é ligado a quaisquer três pinos digitais em vez de A4-A5; no exemplo abaixo, o DAT vai para o D4, o CLK para o D5 e o RST para o D2, e o módulo é alimentado pelo 5V. A RTClib da Adafruit não suporta o DS1302, então instale a biblioteca Rtc by Makuna pelo Gerenciador de Bibliotecas. O DS1302 tem dois bits de proteção: enquanto a proteção contra gravação está ativa, a hora não pode ser acertada, e enquanto o bit de parada do relógio está ativo, o relógio não avança. O código verifica os dois e acerta o relógio para o horário de compilação se a hora guardada não for válida.

C++ (Arduino IDE)
1#include <RtcDS1302.h>
2
3ThreeWire myWire(4, 5, 2);                    // DAT, CLK, RST pinleri / DAT, CLK, RST pins
4RtcDS1302<ThreeWire> rtc(myWire);
5
6void setup() {
7  Serial.begin(9600);
8  rtc.Begin();
9  if (rtc.GetIsWriteProtected()) rtc.SetIsWriteProtected(false);   // yazma korumasını kaldır / remove write protection
10  if (!rtc.GetIsRunning()) rtc.SetIsRunning(true);                  // saati başlat / start the clock
11
12  RtcDateTime compiled(__DATE__, __TIME__);
13  if (!rtc.IsDateTimeValid() || rtc.GetDateTime() < compiled) {
14    rtc.SetDateTime(compiled);                                      // derleme saatine ayarla / set to compile time
15  }
16}
17
18void loop() {
19  RtcDateTime now = rtc.GetDateTime();
20  char buf[20];
21  snprintf(buf, sizeof(buf), "%02u.%02u.%04u %02u:%02u:%02u",
22           now.Day(), now.Month(), now.Year(), now.Hour(), now.Minute(), now.Second());
23  Serial.println(buf);
24  delay(1000);
25}

A reclamação mais comum sobre os módulos DS1302 é que o relógio desvia minutos por semana. Um dos motivos é que o chip precisa de um cristal ajustado para uma capacitância de carga de 6 pF, enquanto módulos baratos podem usar cristais com outra especificação. Fios longos e mal encaixados também causam erros de leitura na linha serial do DS1302. Se você tem um DS1302, ele é uma ótima forma de aprender como um RTC funciona; mas, se for montar um relógio que precisa continuar preciso por meses, passe para um DS3231.

NTP em vez de RTC no ESP32: obtendo a hora pela internet

Como o ESP32 consegue se conectar ao Wi-Fi, muitas vezes ele nem precisa de um módulo RTC: com o NTP (Network Time Protocol), ele obtém a hora correta de servidores de tempo como pool.ntp.org em poucos segundos. O core Arduino do ESP32 oferece as funções prontas configTzTime() e getLocalTime() para isso, e o fuso horário é informado como uma string de regra. A Turquia está em UTC+3 sem horário de verão desde 2016, por isso a regra no código é um deslocamento fixo de +3 horas. No Brasil, o horário de verão foi extinto em 2019; para o horário de Brasília (UTC−3), use a regra “BRT3”. Em regiões com horário de verão, como a maior parte da Europa, a regra da Europa Central que está no comentário do código calcula sozinha as datas de mudança; no Reino Unido, use “GMT0BST,M3.5.0/1,M10.5.0”.

O ponto fraco do NTP é depender da internet: depois de uma queda de energia, até o roteador iniciar, ou quando a senha do Wi-Fi muda, o ESP32 não tem como saber a hora. O timer RTC interno do próprio ESP32 mantém a hora durante o deep sleep, mas é zerado quando a alimentação é totalmente cortada. A solução mais robusta combina os dois: na inicialização, o ESP32 sincroniza o DS3231 com a hora da internet se conseguir acessar o NTP; caso contrário, lê a hora do DS3231; e volta a sincronizar uma vez por dia. Para saber mais sobre NTP, veja Hora via NTP no ESP32.

C++ (Arduino IDE)
1#include <WiFi.h>
2#include <Wire.h>
3#include <RTClib.h>
4#include <time.h>
5
6const char* WIFI_SSID = "AgAdin";             // Wi-Fi ağ adı / Wi-Fi network name
7const char* WIFI_PASS = "Sifren";             // Wi-Fi şifresi / Wi-Fi password
8// Türkiye: UTC+3, yaz saati yok / Turkey: UTC+3, no daylight saving
9// Orta Avrupa / Central Europe: "CET-1CEST,M3.5.0,M10.5.0/3"
10const char* TZ_INFO = "<+03>-3";
11
12RTC_DS3231 rtc;
13unsigned long lastSync = 0;
14
15void syncFromNtp() {
16  struct tm t;
17  if (getLocalTime(&t, 10000)) {              // en fazla 10 sn bekle / wait up to 10 s
18    rtc.adjust(DateTime(t.tm_year + 1900, t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec));
19    Serial.println("DS3231 NTP ile ayarlandi / DS3231 synced from NTP");
20  }
21  lastSync = millis();
22}
23
24void setup() {
25  Serial.begin(115200);
26  Wire.begin(21, 22);                         // SDA, SCL pinleri / SDA, SCL pins
27  rtc.begin();
28
29  WiFi.begin(WIFI_SSID, WIFI_PASS);
30  unsigned long start = millis();
31  while (WiFi.status() != WL_CONNECTED && millis() - start < 15000) delay(250);
32
33  if (WiFi.status() == WL_CONNECTED) {
34    configTzTime(TZ_INFO, "pool.ntp.org", "time.google.com");
35    syncFromNtp();
36  } else {
37    Serial.println("Wi-Fi yok, DS3231 saati kullaniliyor / No Wi-Fi, using the DS3231");
38  }
39}
40
41void loop() {
42  DateTime now = rtc.now();
43  char buf[] = "DD.MM.YYYY hh:mm:ss";
44  Serial.println(now.toString(buf));
45
46  if (WiFi.status() == WL_CONNECTED && millis() - lastSync > 86400000UL) {
47    syncFromNtp();                            // günde bir kez eşitle / sync once a day
48  }
49  delay(1000);
50}

O RTC interno do Raspberry Pi Pico

O chip RP2040 do Raspberry Pi Pico tem um bloco RTC, enquanto o RP2350 do Pico 2 faz o mesmo trabalho com um timer sempre ligado (AON timer). No MicroPython, os dois são usados pela mesma classe machine.RTC: RTC().datetime() lê ou grava a hora no formato (ano, mês, dia, dia da semana, horas, minutos, segundos, subsegundos), e time.localtime() também usa esse relógio. Mas esse relógio não tem bateria: quando o Pico fica sem energia, o MicroPython reinicia o relógio em 1º de janeiro de 2021, 00:00.

Aqui há uma armadilha que pega os iniciantes: por padrão, o Thonny sincroniza o relógio do Pico com o relógio do seu computador quando se conecta. Assim, tudo parece certo nos testes, mas, assim que você liga o Pico em um carregador de celular ou em uma bateria, o relógio volta para 2021. A solução é ligar um DS3231 ao Pico e acertar o RTC interno a partir dele na inicialização. O código abaixo não precisa de nenhum arquivo de driver; ele lê os sete primeiros registradores do DS3231 pelo I2C e os converte de BCD para decimal. Em um Pico W, você também pode buscar a hora na internet com ntptime.settime(); como essa função fornece a hora em UTC, você precisa aplicar o deslocamento do seu fuso horário (no horário de Brasília, subtrair 3 horas). Se o Pico é novidade para você, comece por O que é o Raspberry Pi Pico?.

MicroPython
1from machine import Pin, I2C, RTC
2import time
3
4i2c = I2C(0, sda=Pin(4), scl=Pin(5), freq=100000)
5DS_ADDR = 0x68                                  # DS3231 ve DS1307 adresi / DS3231 and DS1307 address
6
7def bcd2dec(b):
8    return (b >> 4) * 10 + (b & 0x0F)
9
10def dec2bcd(d):
11    return ((d // 10) << 4) | (d % 10)
12
13def ds_read():
14    b = i2c.readfrom_mem(DS_ADDR, 0x00, 7)      # saniyeden yıla 7 kayıt / 7 registers, seconds to year
15    return (2000 + bcd2dec(b[6]), bcd2dec(b[5] & 0x1F), bcd2dec(b[4] & 0x3F),
16            bcd2dec(b[2] & 0x3F), bcd2dec(b[1] & 0x7F), bcd2dec(b[0] & 0x7F))
17
18def ds_write(y, mo, d, h, mi, s):
19    # 24 saat biçiminde yazar; 4. bayt haftanın günü (1-7) / writes 24-hour time; 4th byte is day of week (1-7)
20    i2c.writeto_mem(DS_ADDR, 0x00, bytes([dec2bcd(s), dec2bcd(mi), dec2bcd(h), 1,
21                                          dec2bcd(d), dec2bcd(mo), dec2bcd(y - 2000)]))
22
23# İlk kurulumda bir kez çalıştır, sonra satırı sil / run once on first setup, then delete the line
24# ds_write(2026, 11, 3, 14, 30, 0)
25
26y, mo, d, h, mi, s = ds_read()
27RTC().datetime((y, mo, d, 0, h, mi, s, 0))     # dahili RTC'yi ayarla / set the internal RTC
28
29while True:
30    t = time.localtime()                        # artık dahili RTC'den okunur / now read from the internal RTC
31    print("{:02d}.{:02d}.{} {:02d}:{:02d}:{:02d}".format(t[2], t[1], t[0], t[3], t[4], t[5]))
32    time.sleep(1)

Ideias de projetos com módulo RTC

  • Relógio de mesa digital e calendário: mostre a hora, a data e a temperatura medida pelo DS3231 em um LCD, OLED ou matriz de LED.
  • Irrigação automática de plantas: verifique a umidade do solo todas as manhãs e acione a bomba por um tempo definido, se necessário.
  • Alimentador de pet: abra a portinhola do reservatório com um servo duas ou três vezes por dia e libere uma porção de ração.
  • Registrador de dados com data e hora: grave leituras de temperatura e umidade junto com a data e a hora em um módulo de cartão SD e depois faça gráficos no Excel.
  • Sinal de escola ou de oficina: toque um buzzer ou uma campainha acionada por relé no início e no fim de cada aula, e pule os fins de semana com dayOfTheWeek().
  • Temporizador para aquário e luz de cultivo: acenda a luz de manhã e apague à noite, variando o brilho devagar com PWM para um efeito de nascer e pôr do sol.

Erros comuns e como corrigi-los

  • “RTC não encontrado”, begin() retorna false: SDA e SCL estão invertidos, o GND não é comum ou o módulo não está alimentado. Rode um sketch scanner I2C e veja se o endereço 0x68 aparece.
  • Valores sem sentido, como o ano 2165, 165 ou 85: não está chegando nenhum dado do chip e todos os bytes lidos são 0xFF. Confira a ligação; se você está alimentando um DS1307 com 3,3 V, passe para 5 V.
  • O relógio volta para o mesmo momento a cada reset: a linha rtc.adjust() ainda está em setup() sem condição; condicione-a a lostPower().
  • O relógio zera depois de uma queda de energia: a bateria acabou, foi colocada invertida ou não está lá. Meça a tensão dela e lembre-se de que o circuito de carga pode ter estragado a CR2032.
  • O relógio desvia minutos por semana: o cristal de um DS1307 ou DS1302 e as variações de temperatura causam isso. Passe para um DS3231 ou sincronize a hora regularmente com NTP.
  • A hora está errada em exatamente uma ou mais horas: o fuso horário ou o horário de verão está configurado errado. Grave a hora local no RTC; se você usa NTP, escolha a regra de fuso horário correta.
  • O DS3231 marca uma temperatura mais alta que a do ambiente: esse valor é a temperatura do próprio chip, com precisão de ±3 °C e afetada pelo aquecimento da placa. Use um sensor separado para a temperatura ambiente.
Quando algo der errado, rode primeiro o scanner I2C: se o RTC não aparece no endereço 0x68, o problema está na ligação, não no código. Para verificar a tensão da bateria e a alimentação do módulo, o guia Como usar um multímetro vai ajudar.

Resumindo: o DS3231 é a escolha certa para quase todo projeto que precisa de data e hora; o DS1307 dá conta do recado em projetos simples de 5 V e o DS1302 serve para aprender. No ESP32, use NTP quando houver internet e um DS3231 quando não houver; no Pico, acertar o RTC interno a partir de um DS3231 na inicialização é a abordagem mais confiável. No app BlueGrays você encontra projetos passo a passo com esquema do circuito e código: configuração de relógio com DS1302 e relógio com LCD, relógio e calendário em matriz de pontos com DS1307, relógio digital com RTC no ESP32, hora da internet com NTP e registrador de temperatura com data e hora.

Perguntas frequentes

Um módulo RTC funciona sem bateria?

Enquanto o VCC estiver ligado, o relógio funciona e pode ser lido. Mas, assim que a energia acaba, o relógio para ou zera, e você precisa acertá-lo de novo na próxima inicialização. Como a razão de ser de um RTC é manter a hora durante as quedas de energia, você quase sempre precisa da bateria; se usar um DS1307 sem ela, o pino VBAT deve ser ligado ao GND.

Qual é melhor, o DS3231 ou o DS1307?

O DS3231 é melhor em quase todos os casos. Graças ao cristal integrado com compensação de temperatura, ele erra só cerca de um minuto por ano, enquanto um DS1307 pode desviar até um minuto por mês. O DS3231 também funciona de 2,3 a 5,5 V, então trabalha diretamente com o ESP32 e o Pico, e tem dois alarmes e um sensor de temperatura. Com a RTClib, o código dos dois é quase idêntico.

Quanto tempo dura a bateria de um módulo RTC?

Quando o módulo funciona só na bateria, um DS3231 consome até cerca de 3 µA e um DS1307 em torno de 0,5 µA. No papel, uma CR2032 de 220 mAh dura mais de 8 anos com essas correntes. Na prática, a vida útil de armazenamento da bateria e o circuito de carga do módulo podem encurtar esse tempo; em um módulo com carregador ativo, uma CR2032 pode acabar bem antes.

Por que o meu módulo RTC vive zerando a hora?

Há três causas comuns: a linha rtc.adjust() em setup() voltando o relógio para o horário de compilação a cada inicialização, uma bateria descarregada ou invertida e um circuito de carga que estragou a CR2032. Primeiro condicione a linha adjust() a lostPower(), depois meça a tensão da bateria com um multímetro e troque-a se estiver abaixo de 2,5 V.

Preciso de um módulo RTC com o ESP32?

Não, se o aparelho estiver sempre on-line; o ESP32 obtém a hora correta via NTP em poucos segundos. Para projetos em que a internet pode cair, em que a hora precisa ser conhecida depois de uma queda de energia antes de o roteador voltar ou que funcionam totalmente off-line, adicionar um DS3231 é a opção mais segura. O ideal é usar os dois e sincronizar o DS3231 com o NTP uma vez por dia.

Posso colocar uma CR2032 em um módulo DS3231?

Pode, mas em módulos com circuito de carga, como a ZS-042, você precisa cortar o caminho de carga antes. Se dessoldar o resistor de 200 Ω (código 201) ou o diodo ao lado dele, a CR2032 funciona com segurança por anos. Se não quiser mexer na placa, use uma LIR2032 recarregável.

Ver todos os projetos
Configuração do módulo de relógio RTC DS1302
#45Iniciante

Configuração do módulo de relógio RTC DS1302

Coloque em funcionamento um pequeno módulo de relógio que mantém a hora mesmo quando o Arduino é desligado. O módulo tem sua própria pilha e, depois de ajustar o relógio, a data e a hora aparecem na t

4.5(23)
31
Relógio RTC DS1302 com display LCD
#46Intermediário
Premium

Relógio RTC DS1302 com display LCD

Um pequeno relógio de mesa que mantém a hora mesmo quando falta energia. O módulo de relógio DS1302 mantém a hora graças à sua própria pilha; a cada segundo, o Arduino lê essa informação e exibe a hor

4.7(41)
51
Relógio digital com ESP32 e RTC DS1307 (I2C + LCD)
#120Intermediário
Premium

Relógio digital com ESP32 e RTC DS1307 (I2C + LCD)

Neste projeto, exibimos a hora e a data em um display LCD I2C 16x2 usando o módulo de relógio de tempo real (RTC) DS1307. O DS1307 é um RTC com bateria de reserva que mantém a hora mesmo quando o ESP32 é desligado. Os dois módulos compartilham o mesmo barramento I2C (SDA/SCL), permitindo aprender a controlar vários dispositivos com apenas dois fios de sinal. Você aprenderá na prática o protocolo de comunicação I2C, o funcionamento dos módulos RTC e a exibição de dados dinâmicos em um LCD.

4.6(26)
40
Relógio e calendário de matriz de LEDs (MAX7219, DS1307)
#84Intermediário
Premium

Relógio e calendário de matriz de LEDs (MAX7219, DS1307)

Um painel luminoso para a mesa ou a parede que mostra a hora e a data em texto deslizante. O display de LEDs 8x32 exibe um relógio com dígitos grandes e dois pontos que piscam a cada segundo; no iníci

5.0(37)
59
Relógio, calendário e estação meteorológica de matriz de pontos (MAX7219, DS1307)
#85Intermediário
Premium

Relógio, calendário e estação meteorológica de matriz de pontos (MAX7219, DS1307)

Um painel com texto em rolagem para sua mesa ou parede que mostra, em sequência, a hora, a data e as condições do ambiente. No display LED 8x32, você vê primeiro a temperatura em Celsius e Fahrenheit,

5.0(50)
66
Registrador de temperatura com ESP32 (DHT22 + DS1307 RTC + microSD + OLED)
#144Avançado
Premium

Registrador de temperatura com ESP32 (DHT22 + DS1307 RTC + microSD + OLED)

Monte um registrador de temperatura com data e hora usando ESP32! Leia a temperatura e a umidade do DHT22 a cada minuto, obtenha a hora real do DS1307 RTC e grave os dados em CSV no cartão microSD. O OLED exibe a temperatura atual em letras grandes, a porcentagem de umidade, a data e a hora e o contador de registros. O arquivo /temp_log.csv no cartão SD pode ser aberto no Excel, Google Sheets ou pandas do Python para análise — ideal para monitorar estufas, acompanhar a temperatura de casa ou…

4.7(7)
12
Hora exata pela internet com ESP32 e NTP
#128Avançado
Premium

Hora exata pela internet com ESP32 e NTP

O ESP32 se conecta ao Wi-Fi e obtém a hora exata com precisão de milissegundos de servidores NTP (Network Time Protocol). Com a função configTzTime(), o fuso horário configurado (TRT, UTC+3 neste exemplo) é aplicado automaticamente, e as mudanças nos países que adotam horário de verão são gerenciadas automaticamente por uma string POSIX TZ. A hora é exibida tanto no Monitor Serial quanto em um LCD I2C opcional.

4.5(13)
21
Relógio digital com display de 7 segmentos de 4 dígitos
#48Intermediário
Premium

Relógio digital com display de 7 segmentos de 4 dígitos

Um relógio digital luminoso de quatro dígitos, parecido com o de um forno de cozinha. O módulo de relógio DS1302 mantém a hora e, a cada segundo, o Arduino lê as horas e os minutos e os exibe no displ

4.8(56)
73