Monte um relógio despertador de verdade: ele usa um módulo RTC que mantém a hora certa mesmo depois de desligado, um display LCD que mostra as horas e um encoder rotativo para ajustar o alarme girando e clicando. Perfeito para organizar estudos com a técnica Pomodoro.

O coração deste projeto é o módulo RTC DS3231 — um relógio de tempo real com bateria própria, que continua contando as horas mesmo com o Arduino desligado. É o mesmo tipo de componente que mantém a hora certa no seu computador. O Arduino lê a hora do RTC e mostra num display LCD. Com o encoder rotativo (aquele botão que gira e também clica), você ajusta o horário do alarme: gira para mudar a hora, clica para confirmar. Quando chega o horário marcado, o buzzer toca. Tanto o LCD quanto o RTC se comunicam por I²C, um protocolo que usa apenas 2 fios de dados — por isso a ligação fica bem mais limpa.
Todos os componentes disponíveis na A2 Robotics — clique em cada item para comprar
Arduino Nano
1 unidade
Display LCD 16x2 com módulo I²C
1 unidade
Módulo RTC DS3231 (relógio)
1 unidade
Encoder rotativo KY-040 (com botão)
1 unidade
Buzzer ativo 5V
1 unidade
Protoboard
1 unidade
Jumpers (cabos de ligação)
1 kit
| Componente | Ligação no Nano |
|---|---|
| LCD I²C (SDA / SCL) | A4 / A5 |
| RTC DS3231 (SDA / SCL) | A4 / A5 (compartilhado) |
| Encoder CLK / DT / SW | D2 / D3 / D4 |
| Buzzer | D9 |
| Alimentação dos módulos | 5V e GND |
Na IDE do Arduino, em Ferramentas → Gerenciar Bibliotecas, instale três bibliotecas: LiquidCrystal_I2C (para o display), RTClib da Adafruit (para o relógio) e a Wire (que já vem instalada). Sem elas o código não compila.
O código mostra a hora no LCD e permite ajustar o alarme com o encoder: clique para entrar no modo de ajuste da hora, gire para mudar, clique de novo para ajustar os minutos e mais uma vez para ativar. Se o seu LCD não acender, tente trocar o endereço 0x27 por 0x3F na linha do LiquidCrystal_I2C.
// Relógio despertador com RTC e encoder — A2 Robotics #include <Wire.h> #include <LiquidCrystal_I2C.h> #include "RTClib.h" // Pinos do encoder e do buzzer #define ENC_CLK 2 #define ENC_DT 3 #define ENC_BTN 4 #define BUZZER 9 LiquidCrystal_I2C lcd(0x27, 16, 2); // se não acender, troque para 0x3F RTC_DS3231 rtc; volatile int giro = 0; int estadoClkAnterior; unsigned long ultimoClique = 0; // Horário do alarme (padrão 07:00) int alarmeHora = 7; int alarmeMin = 0; bool alarmeAtivo = true; // Modos: mostrar hora, ajustar hora, ajustar minuto enum Modo { MOSTRAR, AJUSTA_HORA, AJUSTA_MIN }; Modo modo = MOSTRAR; void setup() { lcd.init(); lcd.backlight(); if (!rtc.begin()) { lcd.print("Erro no RTC!"); while (1); } if (rtc.lostPower()) { rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); // acerta pela hora do PC } pinMode(ENC_CLK, INPUT_PULLUP); pinMode(ENC_DT, INPUT_PULLUP); pinMode(ENC_BTN, INPUT_PULLUP); pinMode(BUZZER, OUTPUT); estadoClkAnterior = digitalRead(ENC_CLK); attachInterrupt(digitalPinToInterrupt(ENC_CLK), lerEncoder, CHANGE); } void loop() { DateTime agora = rtc.now(); tratarBotao(); tratarGiro(); atualizarTela(agora); verificarAlarme(agora); delay(100); } // Lê o giro do encoder (chamado por interrupção) void lerEncoder() { int clk = digitalRead(ENC_CLK); if (clk != estadoClkAnterior && clk == LOW) { if (digitalRead(ENC_DT) != clk) giro++; else giro--; } estadoClkAnterior = clk; } // Clique do encoder muda de modo void tratarBotao() { if (digitalRead(ENC_BTN) == LOW && millis() - ultimoClique > 300) { giro = 0; if (modo == MOSTRAR) modo = AJUSTA_HORA; else if (modo == AJUSTA_HORA) modo = AJUSTA_MIN; else modo = MOSTRAR; lcd.clear(); ultimoClique = millis(); } } // Aplica o giro ao ajuste de hora ou minuto void tratarGiro() { if (giro == 0) return; if (modo == AJUSTA_HORA) { alarmeHora = (alarmeHora + giro + 24) % 24; } else if (modo == AJUSTA_MIN) { alarmeMin = (alarmeMin + giro + 60) % 60; } giro = 0; } // Mostra hora e alarme no LCD void atualizarTela(DateTime agora) { lcd.setCursor(0, 0); lcd.print("Hora "); doisDigitos(agora.hour()); lcd.print(":"); doisDigitos(agora.minute()); lcd.print(":"); doisDigitos(agora.second()); lcd.setCursor(0, 1); if (modo == MOSTRAR) { lcd.print("Alarme "); doisDigitos(alarmeHora); lcd.print(":"); doisDigitos(alarmeMin); lcd.print(alarmeAtivo ? " *" : " "); } else if (modo == AJUSTA_HORA) { lcd.print("Ajuste hora: "); doisDigitos(alarmeHora); } else { lcd.print("Ajuste min: "); doisDigitos(alarmeMin); } } void doisDigitos(int n) { if (n < 10) lcd.print("0"); lcd.print(n); } // Toca o buzzer quando chega o horário do alarme void verificarAlarme(DateTime agora) { if (alarmeAtivo && agora.hour() == alarmeHora && agora.minute() == alarmeMin) { for (int i = 0; i < 10; i++) { if (digitalRead(ENC_BTN) == LOW) { alarmeAtivo = false; break; } digitalWrite(BUZZER, HIGH); delay(200); digitalWrite(BUZZER, LOW); delay(200); } } }
Ambos usam I²C: ligue SDA no A4 e SCL no A5 do Nano. Os dois podem compartilhar os mesmos pinos. Alimente com 5V e GND.
CLK no D2, DT no D3 e o botão (SW) no D4. O pino "+" vai no 5V e o GND no terra.
Terminal positivo no D9 e negativo no GND.
LiquidCrystal_I2C e RTClib pelo Gerenciador de Bibliotecas da IDE.
Carregue o código. Clique no encoder para ajustar a hora do alarme (gire para mudar), clique de novo para os minutos e mais uma vez para ativar. Quando o horário chegar, o buzzer toca.
Com o relógio funcionando, você pode transformá-lo num timer Pomodoro completo: programe ciclos de 25 minutos de foco e 5 de pausa, mostre no LCD qual ciclo está ativo, ou adicione um segundo alarme. O RTC também abre portas para projetos de datalogger (registro de dados com data e hora), agendadores e automação temporizada.