#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <RTClib.h>
// Configuración del LCD I2C (0x27 es la dirección común del LCD, pero puede variar)
LiquidCrystal_I2C lcd(0x27, 16, 2);
// Inicializa el RTC DS1307
RTC_DS1307 rtc;
const int buttonPin = 2; // Pin para el botón de reinicio
unsigned long timeElapsed = 0; // Tiempo transcurrido en milisegundos
unsigned long previousMillis = 0;
unsigned long lastButtonPress = 0; // Tiempo de la última pulsación del botón
bool buttonState = HIGH; // Estado actual del botón
bool lastButtonState = HIGH; // Estado previo del botón
// Variables para almacenar el tiempo anterior para comparación
unsigned long prevSeconds = 0, prevMinutes = 0, prevHours = 0;
void setup() {
// Inicia la comunicación serial
Serial.begin(9600);
// Configura el LCD
lcd.begin(16, 2);
lcd.backlight(); // Enciende la luz de fondo del LCD
// Configura el pin del botón
pinMode(buttonPin, INPUT_PULLUP); // Botón conectado con resistencia interna pull-up
// Inicia el RTC
if (!rtc.begin()) {
Serial.println("No se encuentra el RTC");
while (1); // Se detiene si no se encuentra el RTC
}
if (!rtc.isrunning()) {
Serial.println("El RTC no está corriendo, ajustando la hora...");
rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); // Ajusta la hora al cargar el código
}
// Muestra el inicio en el LCD
lcd.setCursor(0, 0);
lcd.print("Tiempo: 00:00:00");
}
void loop() {
// Lee el estado del botón
int reading = digitalRead(buttonPin);
// Implementación de debounce para el botón
if (reading != lastButtonState) {
lastButtonPress = millis(); // Se reinicia el contador de debounce
}
// Si el tiempo de debounce ha pasado (50 ms) y el botón fue presionado
if ((millis() - lastButtonPress) > 50) {
if (reading == LOW && buttonState == HIGH) { // El botón ha sido presionado
timeElapsed = 0; // Reinicia el cronómetro
}
buttonState = reading;
}
lastButtonState = reading; // Actualiza el estado anterior del botón
// Actualiza el tiempo cada 1000 ms
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= 1000) {
previousMillis = currentMillis;
// Aumenta el tiempo transcurrido en segundos
timeElapsed += 1000;
// Calcula el tiempo transcurrido
unsigned long seconds = (timeElapsed / 1000) % 60;
unsigned long minutes = (timeElapsed / 60000) % 60;
unsigned long hours = (timeElapsed / 3600000);
// Actualiza solo si ha cambiado el tiempo
if (seconds != prevSeconds || minutes != prevMinutes || hours != prevHours) {
lcd.setCursor(8, 0); // Posiciona en la parte de tiempo
if (hours < 10) lcd.print("0");
lcd.print(hours);
lcd.print(":");
if (minutes < 10) lcd.print("0");
lcd.print(minutes);
lcd.print(":");
if (seconds < 10) lcd.print("0");
lcd.print(seconds);
// Actualiza las variables anteriores
prevSeconds = seconds;
prevMinutes = minutes;
prevHours = hours;
}
// Obtén la hora actual del RTC y muéstrala en la segunda línea
DateTime now = rtc.now();
lcd.setCursor(6, 1); // Posiciona en la parte de la hora
if (now.hour() < 10) lcd.print('0');
lcd.print(now.hour());
lcd.print(":");
if (now.minute() < 10) lcd.print('0');
lcd.print(now.minute());
lcd.print(":");
if (now.second() < 10) lcd.print('0');
lcd.print(now.second());
}
}