Neste tutorial, vais aprender a usar um módulo DS3231 Real Time Clock (RTC) com um ESP32.
Um módulo RTC é um relógio externo que mantém o controlo da hora e data atuais. Funciona independentemente da alimentação principal do sistema, permitindo manter a hora correta mesmo quando a energia está desligada.
Vou mostrar-te como usar um RTC em conjunto com o ESP32 em deep-sleep, como ajustar o RTC para o horário de verão e como sincronizar o RTC com um servidor de hora na internet.
Peças necessárias
Para este projeto vais precisar de um Módulo DS3231 RTC e um ESP32. Estou a usar o ESP32 lite como microprocessador, pois tem uma interface de carregamento de bateria, que permite alimentar o ESP32 e o RTC com uma bateria LiPo. No entanto, qualquer outro ESP32 ou ESP8266 também funciona. Para mostrar a hora, escolhi um OLED, mas também podes usar um LCD display.

ESP32 lite

Cabo USB de Dados

Módulo DS3231 RTC

Conjunto de fios Dupont

Breadboard

Ecrã OLED
Makerguides is a participant in affiliate advertising programs designed to provide a means for sites to earn advertising fees by linking to Amazon, AliExpress, Elecrow, and other sites. As an Affiliate we may earn from qualifying purchases.
Noções básicas do chip DS3231
O DS3231 é um chip pequeno (38 x 22 x 14mm) com um relógio de tempo real (RTC) de alta precisão e um oscilador de cristal compensado por temperatura integrado. Este chip inclui um suporte para bateria, permitindo funcionar mesmo quando a alimentação principal está desligada.

O RTC mantém o controlo dos segundos, minutos, horas, dia da semana, data, mês e ano. Para meses com menos de 31 dias, a data é ajustada automaticamente, incluindo correções para anos bissextos. O relógio pode funcionar em formato 24 horas ou 12 horas. Fornece dois alarmes de calendário programáveis e uma saída de onda quadrada programável. A comunicação é feita via barramento I2C.
Um circuito de referência de tensão compensado por temperatura e um comparador monitorizam o estado do VCC, detetam falhas de energia, fornecem uma saída de reset e mudam automaticamente para a alimentação de reserva quando necessário. O dispositivo integra um sensor de temperatura digital, acessível via interface I2C.
A secção seguinte lista as principais características do DS3231 (source):
Especificações técnicas
- Tensão de funcionamento: 3.3–5.5V
- Chip do relógio: Chip de relógio de alta precisão DS3231
- Precisão do relógio: 2ppm na faixa de 0-40°C, erro anual aproximadamente 1 minuto
- Dois alarmes de calendário
- Saída de onda quadrada programável
- Relógio de tempo real que gera segundos, minutos, horas, dia da semana, data, mês e ano, com compensação para anos bissextos válida até 2100
- Sensor de temperatura incorporado com precisão de ±3°C
- Chip de armazenamento: AT24C32 (capacidade de armazenamento de 32K)
- Interface de barramento IIC, velocidade máxima de transmissão 400KHz (quando a tensão de funcionamento é 5V)
- Pode ser encadeado com outros dispositivos IIC, o endereço 24C32 pode ser modificado ligando A0/A1/A2, o endereço padrão é 0x57
- Usa bateria CR2032 para garantir que o relógio continua a funcionar normalmente após uma falha de energia
Diagrama de blocos do DS3231
O diagrama de blocos seguinte mostra os componentes internos do DS3231. Podes ver o oscilador de cristal, o sensor de temperatura, o controlo de energia e a interface I2C.

Os pinos do DS3231 são os seguintes: VCC e GND para alimentação geral e VBAT para a bateria de reserva. SCL e SDA são para a interface I2C.
O pino rotulado “33kHz” fornece o sinal de relógio de 32kHz. INT/SQW é um pino de interrupção que pode ser usado para sinalizar alarmes ou servir como saída de onda quadrada programável.
RST é o pino de reset que pode ser usado para sinalizar ao microprocessador conectado que a energia foi perdida ou restaurada. Os pinos “33kHz”, INT/SQW e RST têm outras funções também. Para mais detalhes, consulta o datasheet ligado abaixo:
Noções básicas do módulo DS3231 RTC
O chip DS3231 é demasiado pequeno para ligar diretamente a um ESP32 e também falta-lhe algumas peças necessárias. Por isso, normalmente usas um módulo DS3231 RTC. O módulo tem os componentes em falta e também um suporte para uma CR2032 bateria que fornece a alimentação de reserva. A imagem abaixo mostra a frente e o verso de um módulo típico DS3231 RTC:

Em vez de uma CR2032 bateria, também podes usar uma bateria recarregável LIR2032 mas tens de ter cuidado com a tensão de alimentação. Falaremos mais sobre isto mais tarde.
Pinout do módulo DS3231 RTC
O pinout de um módulo DS3231 RTC é essencialmente o mesmo que o descrito para o chip DS3231.

VCC e GND são para alimentação, com uma tensão de 3.3–5.5V. SCL e SDA são os pinos para a interface I2C (com resistores pull-up integrados de 4.7k). Os pinos 32K e SQW são saídas para o sinal de relógio de 32kHz e o sinal de onda quadrada programável, mas não vais precisar deles aqui.
O endereço I2C do módulo DS3231 RTC é configurável via três pads de solda (A0, A1, A2) que podem ser ligados. Vê a secção destacada no canto inferior direito do módulo na imagem acima. O endereço I2C padrão é 0x57, quando não há ligações. A imagem abaixo mostra todas as configurações possíveis e os endereços I2C correspondentes.

Carregamento da bateria com o módulo DS3231 RTC
O módulo DS3231 RTC permite carregar a bateria de reserva a partir da alimentação principal (VCC). A imagem abaixo mostra o diagrama do circuito do módulo DS3231 RTC. Na secção marcada a amarelo, vês um resistor de 200Ω e um diodo 1N4148 que atuam como um circuito de carregamento muito simples.

No entanto, precisas de desativar este circuito de carregamento quando usares uma bateria CR2032 não recarregável com uma tensão de alimentação VCC de 5V. E se usares uma bateria recarregável LIR2032, o VCC nunca deve ultrapassar 4.7 volts para um carregamento seguro.
O artigo Battery charging circuit of DS3231 module descreve os problemas do circuito de carregamento em mais detalhe e também mostra como desativá-lo. A tabela seguinte do artigo lista os diferentes cenários com diferentes tensões de alimentação e tipos de bateria, e o que deve ser feito:
| Tipo de bateria | Alimentação 3.3 V | Alimentação 5 V |
|---|---|---|
| CR2032 | Bateria não afetada | Desativar circuito de carregamento |
| LIR2032 | Bateria não afetada Carregamento não funciona | Desativar circuito de carregamento, ou Garantir que os 5 V são na verdade 4.7 V |
Ligação do módulo DS3231 RTC ao ESP32 lite
Ligar o módulo DS3231 RTC a um ESP32 é simples. Primeiro liga o SCL do DS3231 ao pino 23 do ESP32. Depois liga o SDA ao pino 19 do ESP32. Finalmente, liga o terra ao GND e 3.3V ao VCC como mostrado abaixo:

Como estamos a alimentar o módulo DS3231 RTC a 3.3V, podes ter uma bateria CR2032 inserida enquanto está ligado à alimentação.
Código de teste simples para o módulo DS3231 RTC
Vais precisar de uma biblioteca de software para comunicar com o módulo DS3231 RTC. Existem várias, mas gosto mais da Arduino-DS3231 biblioteca de Korneliusz Jarzębski. Para a instalar, vai a github repo e clica no botão verde “Code”. Depois seleciona “Download Zip” no menu, como mostrado abaixo:

Isto vai descarregar um ficheiro chamado “Arduino-DS3231-dev.zip” para o teu computador. Para instalar esta biblioteca ZIP, segue os passos habituais. Clica em Sketch -> Add .ZIP Library, e depois seleciona o ficheiro Arduino-DS3231-dev.zip que acabaste de descarregar.

Com a biblioteca instalada, podemos testar a função do módulo DS3231 RTC. O código simples seguinte define a hora e data no módulo RTC para a hora de compilação do sketch e depois imprime a hora e data num ciclo:
#include "Wire.h"
#include "DS3231.h"
DS3231 rtc;
void setup() {
Serial.begin(9600);
rtc.begin();
rtc.setDateTime(__DATE__, __TIME__);
}
void loop() {
RTCDateTime dt = rtc.getDateTime();
Serial.printf("%4d-%02d-%02d %02d:%02d:%02d\n",
dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second);
delay(1000);
}
O código começa por incluir a biblioteca Wire.h para comunicação I2C e a biblioteca DS3231.h para comunicar com o DS3231 RTC.
De seguida, criamos uma instância da classe DS3231. Na função setup(), inicializamos o RTC e definimos a data e hora atuais usando rtc.setDateTime(). As macros __DATE__ e __TIME__ inserem automaticamente a data e hora em que o sketch foi compilado. Nota que a hora não será atual quando o ESP32 for reiniciado após o código ser compilado e carregado, mas vamos tratar disso mais tarde.
Na função loop, obtemos a data e hora atuais do RTC usando RTCDateTime dt = rtc.getDateTime() e usamos printf para imprimir a data e hora no Monitor Serial.
Exemplo de saída
Se carregares o código e abrires o Monitor Serial, deverás ver a data e hora impressas da seguinte forma:

Horário de Verão com o módulo DS3231 RTC
Embora o DS3231 mantenha o controlo preciso da data e hora, não ajusta automaticamente para o Horário de Verão (DST). Isso significa que o DS3231 vai mostrar a hora (e data) errada quando o teu país muda para DST ou volta ao Horário Normal (ST).
Existem basicamente duas formas de lidar com isto. 1) podes adicionar um botão que muda manualmente entre DST e ST e vice-versa. Obviamente, isto não é o ideal. 2) adicionas código que faz a mudança automaticamente para o fuso horário do teu país.
Nesta secção, mostro-te como lidar automaticamente com o horário de verão, usando o módulo DS3231 RTC. Vamos usar a biblioteca ezTime Library para isso. Podes instalá-la via Library Manager como de costume:

Depois de instalada, podes usá-la para ajustar o DS3231 RTC ao horário de verão com o seguinte código:
#include "Wire.h"
#include "DS3231.h"
#include "ezTime.h"
const char* TIMEZONE = "AEST-10AEDT,M10.1.0,M4.1.0/3"; // Melbourne
Timezone loc;
DS3231 rtc;
void setup() {
Serial.begin(9600);
rtc.begin();
rtc.setDateTime(2024,12,4,3,16,30); // UTC
loc.setPosix(TIMEZONE);
}
void loop() {
RTCDateTime dt = rtc.getDateTime();
UTC.setTime(dt.hour, dt.minute, dt.second, dt.day, dt.month, dt.year);
Serial.printf("RTC: %4d-%02d-%02d %02d:%02d:%02d\n",
dt.year, dt.month, dt.day,
dt.hour, dt.minute, dt.second);
Serial.printf("LOC: %4d-%02d-%02d %02d:%02d:%02d\n",
loc.year(), loc.month(), loc.day(),
loc.hour(), loc.minute(), loc.second());
Serial.println();
delay(5000);
}
No código acima, fazemos a interface de um ESP32 com um módulo DS3231 Real-Time Clock (RTC) para manter o controlo da hora atual, incluindo ajustes para o horário de verão. O programa inicializa o RTC, define uma data e hora específicas, e depois recupera e mostra continuamente a hora UTC e local a cada 5 segundos.
Vamos decompor o código em componentes para uma melhor compreensão.
Bibliotecas incluídas
Começamos por incluir as bibliotecas necessárias para o projeto. A biblioteca Wire.h é usada para comunicação I2C, que é como o ESP32 comunica com o DS3231 RTC. A biblioteca DS3231.h fornece funções específicas para interagir com o módulo DS3231, e ezTime.h é usada para gerir fusos horários e ajustes de horário de verão.
#include "Wire.h" #include "DS3231.h" #include "ezTime.h"
Constantes e variáveis
De seguida, definimos uma constante para o fuso horário. Neste caso, usamos AEST-10AEDT,M10.1.0,M4.1.0/3, que corresponde a Melbourne, Austrália. Esta string indica o desvio do horário padrão e as regras para o horário de verão.
const char* TIMEZONE = "AEST-10AEDT,M10.1.0,M4.1.0/3"; // Melbourne
As partes desta definição de fuso horário são as seguintes
- AEST: Australian Eastern Standard Time
- -10: Desvio UTC de 10 horas à frente do Tempo Universal Coordenado (UTC)
- AEDT: Australian Eastern Daylight Time
- M10.1.0: A transição para o horário de verão ocorre no 1º domingo de outubro
- M4.1.0/3: A transição de volta para o horário padrão ocorre no 1º domingo de abril, com uma diferença de 3 horas em relação ao UTC.
Para outras definições de fuso horário, consulta o Posix Timezones Database. Basta copiar a string que lá encontras e alterar a constante TIMEZONE em conformidade.
Também criamos instâncias das classes Timezone e DS3231. A variável loc vai guardar a informação da hora local, enquanto rtc vai gerir o módulo RTC.
Timezone loc; DS3231 rtc;
Função setup
Na função setup(), inicializamos a comunicação serial a 9600 baud para fins de depuração. Depois inicializamos o RTC e definimos uma data e hora específicas (4 de dezembro de 2024, às 03:16:30 UTC). Finalmente, definimos o fuso horário usando a constante definida anteriormente.
void setup() {
Serial.begin(9600);
rtc.begin();
rtc.setDateTime(2024,12,4,3,16,30); // UTC
loc.setPosix(TIMEZONE);
}
Função loop
A função loop() corre continuamente. Primeiro, obtemos a data e hora atuais do RTC usando rtc.getDateTime(). Depois definimos a hora UTC usando os valores obtidos.
RTCDateTime dt = rtc.getDateTime(); UTC.setTime(dt.hour, dt.minute, dt.second, dt.day, dt.month, dt.year);
De seguida, imprimimos a hora UTC atual no monitor serial numa string formatada. Isto inclui o ano, mês, dia, hora, minuto e segundo.
Serial.printf("RTC: %4d-%02d-%02d %02d:%02d:%02d\n",
dt.year, dt.month, dt.day,
dt.hour, dt.minute, dt.second);
Também imprimimos a hora local usando a variável loc, que foi ajustada para o fuso horário e horário de verão.
Serial.printf("LOC: %4d-%02d-%02d %02d:%02d:%02d\n",
loc.year(), loc.month(), loc.day(),
loc.hour(), loc.minute(), loc.second());
Finalmente, adicionamos uma linha em branco para melhor legibilidade na saída serial e introduzimos um atraso de 5000 milissegundos (5 segundos) antes do ciclo repetir.
Serial.println(); delay(5000);
Exemplo de saída
Se carregares o código e abrires o Monitor Serial, deverás ver a hora UTC do RTC e a hora local (LOC) impressas:

Sincronizar o DS3231 RTC com servidor SNTP
Embora o código acima agora trate automaticamente o ajuste para o horário de verão, ainda precisas de definir manualmente a hora do RTC ao iniciar o ESP32. Pior ainda, tens de ligar o ESP32 a um computador, alterar o código e reprogramar o ESP32. Isso é chato!
Poderias adicionar botões para editar a hora e data enquanto o ESP32 está a funcionar. Se quiseres fazer isso, vê o tutorial Arduino and RTC Module DS3231, onde usamos dois botões para definir a hora.
A melhor opção, no entanto, é sincronizar automaticamente o RTC com um Provedor de Hora na Internet (SNTP). Para mais informações, vê o tutorial How to synchronize ESP32 clock with SNTP server.
Se tiveres acesso consistente à internet e não te importares com o consumo de energia, não precisarias de um RTC, pois podes sincronizar regularmente o relógio interno do ESP32. Isso definiria automaticamente o relógio e também trataria do horário de verão. Vê os tutoriais Automatic Daylight Savings Time Clock e Digital Clock on e-Paper Display.
No entanto, para um projeto alimentado por bateria, queres evitar usar WiFi com muita frequência, pois consome muita energia. Um caso comum é um data logger, por exemplo para temperatura, que queres que funcione o máximo possível com bateria, mas que também precisa de carimbos de tempo precisos.
O código seguinte mostra como fazer isso. Usa WiFi apenas quando o ESP32 é reiniciado para sincronizar o RTC. Caso contrário, o ESP32 está em modo deep-sleep para poupar energia e só acorda ocasionalmente para obter a hora do RTC e imprimi-la:
#include "WiFi.h"
#include "esp_sntp.h"
#include "Wire.h"
#include "DS3231.h"
#include "ezTime.h"
const char* TIMEZONE = "AEST-10AEDT,M10.1.0,M4.1.0/3"; // Melbourne
const char* SSID = "SSID";
const char* PWD = "PASSWORD";
const int SLEEP = 10; // sec
DS3231 rtc;
Timezone loc;
void syncTime() {
WiFi.begin(SSID, PWD);
while (WiFi.status() != WL_CONNECTED)
;
configTzTime("UTC", "pool.ntp.org");
setRtcTime();
}
void setRtcTime() {
struct tm t;
getLocalTime(&t);
rtc.setDateTime(t.tm_year+1900, t.tm_mon+1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec);
}
void printTime() {
RTCDateTime dt = rtc.getDateTime();
UTC.setTime(dt.hour, dt.minute, dt.second, dt.day, dt.month, dt.year);
Serial.printf("RTC: %4d-%02d-%02d %02d:%02d:%02d\n",
dt.year, dt.month, dt.day,
dt.hour, dt.minute, dt.second);
Serial.printf("LOC: %4d-%02d-%02d %02d:%02d:%02d\n",
loc.year(), loc.month(), loc.day(),
loc.hour(), loc.minute(), loc.second());
Serial.println();
}
bool isReset() {
return esp_sleep_get_wakeup_cause() != ESP_SLEEP_WAKEUP_TIMER;
}
void setup() {
Serial.begin(9600);
rtc.begin();
loc.setPosix(TIMEZONE);
if (isReset()) {
syncTime();
}
printTime();
esp_sleep_enable_timer_wakeup(SLEEP * 1000000);
esp_deep_sleep_start();
}
void loop() {
}
Vamos decompor o código em componentes para melhor compreensão.
Bibliotecas e constantes
Começamos por incluir as bibliotecas necessárias para Wi-Fi, SNTP (Simple Network Time Protocol), comunicação I2C e o DS3231 RTC. Também definimos algumas constantes para o fuso horário, credenciais Wi-Fi e duração do sono.
#include "WiFi.h" #include "esp_sntp.h" #include "Wire.h" #include "DS3231.h" #include "ezTime.h" const char* TIMEZONE = "AEST-10AEDT,M10.1.0,M4.1.0/3"; // Melbourne const char* SSID = "SSID"; const char* PWD = "PASSWORD"; const int SLEEP = 10; // sec
Obviamente, terás de substituir as credenciais Wi-Fi pelas tuas próprias.
Objetos RTC e fuso horário
Criamos instâncias da classe DS3231 para o RTC e da classe Timezone para gerir os cálculos da hora local.
DS3231 rtc; Timezone loc;
Função de sincronização da hora
A função syncTime() liga-se à rede WiFi e configura o fuso horário para o servidor NTP. Depois chama setRtcTime() para atualizar o RTC com a hora atual.
void syncTime() {
WiFi.begin(SSID, PWD);
while (WiFi.status() != WL_CONNECTED)
;
configTzTime("UTC", "pool.ntp.org");
setRtcTime();
}
Função para definir a hora do RTC
Na função setRtcTime(), obtemos a hora local e definimos a data e hora do RTC em conformidade. O ano é ajustado somando 1900 porque o campo tm_year retorna o número de anos desde 1900.
void setRtcTime() {
struct tm t;
getLocalTime(&t);
rtc.setDateTime(t.tm_year+1900, t.tm_mon+1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec);
}
Nota que também temos de somar 1 a tm_mon para obter o mês correto, pois a estrutura de dados struct tm usa intervalos inconsistentes. Por exemplo, o dia do mês começa em 1 mas o mês do ano começa em 0:
Member Type Meaning Range tm_sec int seconds after the minute 0-61* tm_min int minutes after the hour 0-59 tm_hour int hours since midnight 0-23 tm_mday int day of the month 1-31 tm_mon int months since January 0-11 tm_year int years since 1900 tm_wday int days since Sunday 0-6 tm_yday int days since January 1 0-365 tm_isdst int Daylight Saving Time flag
Função para imprimir a hora
A função printTime() obtém a data e hora atuais do RTC e imprime-as no Monitor Serial. Também imprime a hora local usando o objeto do fuso horário.
void printTime() {
RTCDateTime dt = rtc.getDateTime();
UTC.setTime(dt.hour, dt.minute, dt.second, dt.day, dt.month, dt.year);
Serial.printf("RTC: %4d-%02d-%02d %02d:%02d:%02d\n",
dt.year, dt.month, dt.day,
dt.hour, dt.minute, dt.second);
Serial.printf("LOC: %4d-%02d-%02d %02d:%02d:%02d\n",
loc.year(), loc.month(), loc.day(),
loc.hour(), loc.minute(), loc.second());
Serial.println();
}
Função para verificar o reset
A função isReset() verifica se o ESP32 acordou do deep sleep devido a um temporizador ou outra causa. Isto ajuda a determinar se deve sincronizar a hora ou não.
bool isReset() {
return esp_sleep_get_wakeup_cause() != ESP_SLEEP_WAKEUP_TIMER;
}
Função setup
Na função setup(), inicializamos a comunicação Serial, o RTC e definimos o fuso horário. Se o ESP32 estiver a iniciar do zero (não a acordar do deep sleep), sincronizamos a hora. Finalmente, imprimimos a hora e colocamos o ESP32 em modo deep sleep pela duração especificada.
void setup() {
Serial.begin(9600);
rtc.begin();
loc.setPosix(TIMEZONE);
if (isReset()) {
syncTime();
}
printTime();
esp_sleep_enable_timer_wakeup(SLEEP * 1000000);
esp_deep_sleep_start();
}
Função loop
A função loop() está vazia porque o ESP32 não executa código enquanto está em deep sleep. Só acorda para executar a função setup() novamente após o tempo de sono.
void loop() { }
Mostrar a hora do RTC no OLED
Como exemplo final, quero mostrar-te como adicionar um OLED para mostrar a hora e data do RTC num ecrã. Isto é apenas uma extensão simples do código acima.
Ligar o OLED é fácil, pois também é um dispositivo I2C. Basta ligar SDA, SCL, VCC e GND do OLED em paralelo com o DS3231, como mostrado abaixo

Abaixo está o código que mostra a hora e data no OLED. Nota que usa a biblioteca Adafruit_SSD1306, que podes instalar via Library Manager como de costume.
#include "WiFi.h"
#include "esp_sntp.h"
#include "Wire.h"
#include "DS3231.h"
#include "ezTime.h"
#include "Adafruit_SSD1306.h"
const char* TIMEZONE = "AEST-10AEDT,M10.1.0,M4.1.0/3";
const char* SSID = "SSID";
const char* PWD = "PASSWORD";
const int SLEEP = 10; // sec
DS3231 rtc;
Timezone loc;
Adafruit_SSD1306 oled(128, 64, &Wire, -1);
void oled_init() {
oled.begin(SSD1306_SWITCHCAPVCC, 0x3C);
oled.setTextSize(2);
oled.setTextColor(WHITE);
}
void syncTime() {
WiFi.begin(SSID, PWD);
while (WiFi.status() != WL_CONNECTED)
;
configTime(0, 0, "pool.ntp.org");
setRtcTime();
}
void setRtcTime() {
struct tm t;
getLocalTime(&t);
rtc.setDateTime(t.tm_year+1900, t.tm_mon+1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec);
}
void displayTime() {
RTCDateTime dt = rtc.getDateTime();
UTC.setTime(dt.hour, dt.minute, dt.second, dt.day, dt.month, dt.year);
oled.clearDisplay();
oled.setCursor(10, 15);
oled.println(loc.dateTime("H:i:s"));
oled.setCursor(2, 45);
oled.println(loc.dateTime("d/m/Y"));
oled.display();
}
bool isReset() {
return esp_sleep_get_wakeup_cause() != ESP_SLEEP_WAKEUP_TIMER;
}
void setup() {
rtc.begin();
loc.setPosix(TIMEZONE);
oled_init();
if (isReset()) {
syncTime();
}
displayTime();
esp_sleep_enable_timer_wakeup(SLEEP * 1000000);
esp_deep_sleep_start();
}
void loop() {
}
As únicas adições e alterações ao código são a função oled_init(), que inicializa o OLED, e a função displayTime(), que mostra a hora e data no OLED. Se carregares o código no teu ESP32, deverás ver o seguinte no OLED:

E é tudo! Agora deves ser capaz de usar o DS3231 RTC juntamente com um ESP32.
Conclusões
Neste tutorial aprendeste a usar um módulo DS3231 Real Time Clock (RTC) com um ESP32.
O ESP32 lite com um relógio de tempo real é especialmente adequado para projetos alimentados por bateria que precisam de manter a hora correta sem consumir muita energia. Casos comuns são data loggers ou relógios eletrónicos. Para estes últimos, recomendo ecrãs e-Paper, pois consomem quase nenhuma energia. Vê os nossos tutoriais, Analog Clock on e-Paper Display e Digital Clock on e-Paper Display.
Se quiseres aprender um pouco mais sobre relógios com diferentes tipos de ecrã e sincronização de hora, vê o Digital Clock on e-Paper Display,
Se tiveres alguma dúvida, não hesites em deixar nos comentários.
Boas experiências a criar ; )

