tiempo transcurrido

buenas, hice un conteo de tiempo en horas y días sobre un RTC la idea es que valla contando las horas y los días que lleva prendido el aparato este seria el código

//tiempo en horas y dias transcurrido 
   DateTime tiempo = rtc.now();
    if (tiempo.unixtime() %3600 == 0){
      hora_C = (hora_C + 1);
      EEPROM.put(28, hora_C);
      if (hora_C == 24){
        hora_C = 0;
        EEPROM.put(28, hora_C);
        dias_C = (dias_C + 1);
         EEPROM.put(30, dias_C);
      }
    }

bien el programa empieza a contar las horas correctamente y las grava en la EEPROM ahora surge un problema cuando llega al dia una ves que llega a 24 horas pasa a marcar un dia pero antes de marcar 0 en las horas marca 3 horas luego si se espera nuevamente una hora pasa a marcar 7 horas me refiero que después de grabar un dia va gravando de a 4 horas y no de a una como tendría que ser

Hola, postea el código completo para verlo completo.

Por otro lado, yo buscaría optimizar el uso de la memoria EEPROM, por su condición de que puede ser escrita un numero finito de veces, cerca de 10k, eso te va a dar un poco mas de 400 días de uso escribiendo cada hora, sin contar que cuando llega a 24 se escribe 2 veces.

Tengo una duda, si quieres cuantificar horas de uso de un equipo, ¿Por qué usar un RTC?

gracias por responder no coloque todo el código porque no me lo permite al ser muy largo , la idea de usar la EEPROM para controlar dia y horas es para poder tener un registro desde el dia que se inicia el programa y si se corta la luz no se pierde ese registro , uso RTC para poder encender un rele a la hora corres pendiente ya que use millis y se va atrasando de apoco

#include <RTClib.h>

int hora_C;
int dias_C;

RTC_DS1307 rtc;

void setup() {
}

void loop() {
    lcd.setCursor(0, 1);
    lcd.print(" Hora:");
    lcd.print(EEPROM.get(28, hora_C));
    lcd.print(" Dia:");
    lcd.print(EEPROM.get(30, dias_C));

//tiempo en horas y dias transcurrido 
   DateTime tiempo = rtc.now();
    if (tiempo.unixtime() %3600 == 0){
      hora_C = (hora_C + 1);
      EEPROM.put(28, hora_C);
      if (hora_C == 24){
        hora_C = 0;
        EEPROM.put(28, hora_C);
        dias_C = (dias_C + 1);
         EEPROM.put(30, dias_C);
      }
    }
}

Para que eso funcione, en el setup debes leer el tiempo anterior si por alguna razón el Arduino pierde Energía.
Además ese código tarde o temprano por mas que guarde los datos cada 24 hs va a destruir la EEPROM en el grupo de direcciones que estas usando.

No se usa de ese modo.

El código tiene muchos errores.
No inicializas lcd. Se nota que has copiado y pegado de varias lugares y que ni siquiera lo has compilado porque claramente te daría varios errores.
Falta incluir la libreria EEPROM.h
Falta incluir la librería lcd
falta definir el objeto lcd
varias cosas.

#include <RTClib.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <EEPROM.h>

int hora_C;
int dias_C;

RTC_DS1307 rtc;
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7);//delcaramos pines del i2c

void setup() {
  //inicio I2C
  lcd.setBacklightPin(3,POSITIVE);
  lcd.setBacklight(HIGH);
  lcd.begin(16,2);
//rtc.adjust(DateTime(__DATE__, __TIME__)); //se usa para configurar la hora luego se comenta
}

void loop() {
    lcd.setCursor(0, 1);
    lcd.print(" Hora:");
    lcd.print(EEPROM.get(28, hora_C));
    lcd.print(" Dia:");
    lcd.print(EEPROM.get(30, dias_C));

//tiempo en horas y dias transcurrido
   DateTime tiempo = rtc.now();
    if (tiempo.unixtime() %3600 == 0){
      hora_C = (hora_C + 1);
      EEPROM.put(28, hora_C);
      if (hora_C == 24){
        hora_C = 0;
        EEPROM.put(28, hora_C);
        dias_C = (dias_C + 1);
         EEPROM.put(30, dias_C);
      }
    }
}

No veo que consultes la memoria EEPROM para ver en que estado quedó el ciclo, después de un reset o pérdida de alimentación.

Yo pienso que mejor en vez de estar escribiendo en memoria cada hora que pasa, sería apropiado guardar en EEPROM el tiempo en formato unix (quizá en minutos incluso) cuando se inicia el ciclo, y compararlo contra el valor actual, allí sabremos el tiempo que lleva un ciclo en particular (claro hay que hacer la conversión para que sea legible por el humano si quieres leerlo), pero no conozco todo tu proceso, estoy pensando y sugiriendo una solución con base en el código que estás presentando.

por el momento busco la forma de poder monitorear las horas y días por medio de un botón , me refiero que al apretar un botón empiece a controlar la hora y días y con otro botón poder reiniciar esos días y horas para que vuelva a hacer el conteo

el condigo que muestro es hasta donde pude llegar hacer con lo poco que se sobre el tema estoy viendo la librería de RTClib pero no logro a entender mucho sobre como hacerlo

Si uno tiene que estar monitoreando el tiempo transcurido, para controlar la actividad.
Uno a veces tiene que tener calculado el tiempo para disparar ciertos funciones o procesos y el delay del tiempo a veces, no es lo mismo o queres calcular para recibir mensajes hackearplus o monitorear ciertos datos de otras modulos.
Siempre hay que fijarse bien el delay que este funcionando bien para poder hacer funcionar bien el programa.
Es cosa de revisar bien el codigo y saber que este todo bien antes de hacerlo andar en un dispositivo.

No se como empezar.
Si usas un RTC para llevar el tiempo debes hacer cálculos restando tiempos precisamente.
Empiezas con T0 y si quieres lo guardas. Cuando quieres saber el tiempo transcurrido debes hacer cuentas como T1-T0 y eso no es tan simple pero claramente se puede hcer.
Mas facil es llevar el tiempo en millis() que te permite usarlo hasta 49.7 dias.

Cuando el arduino se pone en marcha inicia su contador de milisegundos. Tu tomas en algun momento ese valor y luego preguntas cuando quieras que valor tiene millis(). Restar dos números de 32 bits es fácil, o sea dos unsigned long.
La diferencia es tu tiempo en marcha de lo que sea. Eso luego lo puedes traducir en segundos, minutos, horas, dias.

como 2^32 = 4.294.967.296 =>

si divido por 1000 tengo segundos
si divido por 60 tengo minutos
si divido por 60 tengo horas
si divido por 24 tengo dias

veamos
4.294.967.296 / 1000 = 4.294.967 segundos
4.294.967 / 60 = 71.582 minutos
71.582 / 60 = 1193 horas
1193 /24 = 49 dias

Creo que es mas que suficiente, pero si eso no alcanza puedes seguir.

Entonces

Prueba a ver como se comporta este código en elque yo simulo que se presiona cada 2 segundos un boton. Reemplaza eso por el boton o por lo que tu desees para tomar el tiempo.

const byte boton = 2;
unsigned long inicioTimer = 0, start;
bool estado, estadoAnt = false;

void presentoLCD() {
  char buffer[20];
  unsigned long dif = start - inicioTimer;
  long tmp = dif/1000; // / 1000;
  int segundos = tmp % 60;
  tmp /= 60;
  int minutos = tmp % 60;
  tmp /= 24;
  int horas = tmp % 24;
  tmp -= horas;
  int dias = tmp/24;
  sprintf(buffer, "%02d %02d:%02d:%02d",  dias, horas, minutos, segundos); 
  Serial.println(buffer);
}

void setup() {
    Serial.begin(9600);
    Serial.println("Probando codigo");
    pinMode(2, INPUT_PULLUP);
    inicioTimer = millis();
    Serial.println(inicioTimer);
}

void loop() {

    if (millis() - start >= 1000) {
        estado = true;
        start = millis();
    }
    else 
        estado = false;

  if (estado && !estadoAnt) {
    if (inicioTimer != 0) {
      presentoLCD();        // Siempre que presiones mostrará valores en el LCD 
    }
    else 
      inicioTimer = millis();
  }
  estadoAnt = estado;
}

muchas gracias por responder usaba un conteo con millis el problema que obtuve fue que se iba retrasando de apoco cuando llego al dia 1 y 10 horas ya se había retrasado 5 horas este era el código que usaba para controlar con millis

    if((millis()-task_time_ms)>=1000){
      task_time_ms=millis();
      segundos_C = (segundos_C + 1);
      if ((segundos_C == 60)) {
        segundos_C = 0;
        minutos_C = (minutos_C + 1);
        if ((minutos_C == 60)) {
          minutos_C = 0;
          hora_C = (hora_C + 1);
          EEPROM.put(28, hora_C);
            if (( hora_C == 24)) {
             hora_C = 0;
            dias_C = (dias_C + 1);
            EEPROM.put(30, dias_C);
          }

        }

      }
    }

por eso decidí implementar RTC DS1307 para que me lleve el tiempo un poco mas preciso , estuve viendo sobre guardar el unixtime grabándolo en la EEPROM con un botón y me lo compare con el tiempo actual y de esa forma me de el resultado de cuanto lleva prendido pero no es tan fácil como se describe al menos para mi que mucho aun no entiendo del tema

5 horas es demasiado retraso, te adjunto un código que uso para llevar el tiempo millis()

  uint32_t seg = millis() / 1000;

  if (seg % 2 && !par) {
    par = 1;
    uptimeSecond++;
    updateTime();
  }

  if (!(seg % 2) && par) {
    par = 0;
    uptimeSecond++;
    updateTime();
  }

Básicamente lo que se hace es comprobar si el segundo actual es par o impar y compararlo con el ultimo valor, si hay cambio aumenta el contador, y se verifican todos los valores para mantener los valores en dias horas minutos y segundos con la siguiente función

void updateTime(){
  if (uptimeSecond > 59) {
    uptimeMinute++;
    uptimeSecond = 0;
  }

  if (uptimeMinute > 59) {
    uptimeHour++;
    uptimeMinute = 0;
  }

  if (uptimeHour > 23) {
    uptimeDay++;
    uptimeHour = 0;
  }
}