Utilizzo di un RTC al posto di millis

Salve, al posto del consueto millis, per la temporizzazione ho pensato all'uso di un RTC come potete vedere dal codice. Ho utilizzato la medesima procedura che uso con millis prendendo come riferimento i secondi del RTC ( now.second() ): se now.second() meno la variabile lasttime è maggiore o uguale a TOT, stampa e lasttime diventa uguale a now.second(). Adesso, come potete notare, ho fatto un semplice esempio dove ogni 3 secondi nel monitor seriale vengono stampate data e ora. Funziona, ma in parte, perchè il problema ce l'ho nel momento in cui arrivo al secondo 57, 58 o 59 (specificamente per questa temporizzazione a 3 secondi).
Infatti se ad esempio raggiungo il secondo 57, nella variabile lasttime viene memorizzato appunto 57, e quando now.second() ripartirà da 0, la variabile lasttime che conserva il numero 57, sarà maggiore di now.second() e quindi logicamente non mi stampa niente più e si ferma.

Quindi per ovviare a questo problema, come potrei fare?
Vi ringrazio in anticipo.

#include "RTClib.h"
RTC_DS1307 rtc;

void setup () {
  Serial.begin(57600);
 if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    Serial.flush();
    abort();
  }

  if (! rtc.isrunning()) {
    Serial.println("RTC is NOT running, let's set the time!");
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }
}

int lasttime;

void loop () {
    DateTime now = rtc.now();

    if(now.second() - lasttime >= 3){
     Serial.print(now.year());
     Serial.print('/');
     Serial.print(Zero(now.month()));
     Serial.print('/');
     Serial.print(Zero(now.day()));
     Serial.print(" () ");
     Serial.print(Zero(now.hour()));
     Serial.print(':');
     Serial.print(Zero(now.minute()));
     Serial.print(':');
     Serial.print(Zero(now.second()));
     Serial.println();

    lasttime=now.second();
      
    } 

  }

String Zero(uint8_t suffisso) {
  if (suffisso < 10) {
    return "0" + String(suffisso);
  }
  return String(suffisso);
}

Per queste cose, conviene sempre lavorare il "secondi" utilizzando lo UNIX time (o Epoch) ... normalmente le librerie forniscono un'apposita chiamata per trasformare i vari campi (data/ora) in un unico "unsigned long" (uint32_t) che rappresenta i secondi a parture da un certo istante (che è fisso).

In questo modo lavori con un semplice numero intero e puoi fare tutte le operazioni e confronti che vuoi :wink:

Guglielmo

Esattamente !!

➜

uint32_t lasttime;
...
    if(now. secondstime() - lasttime >= 3){
...
        lasttime=now.secondstime();
    }

Grazie mille, spulciando la libreria non mi ero accorto che c'era un UNIX dei secondi, grazie anche a @J-M-L - ho risolto.

la libreria offre due versioni per il tempo in secondi:

uint32_t DateTime::unixtime(void) const;
➜ Numero di secondi dal 1970-01-01 00:00:00

uint32_t DateTime::secondstime(void) const;
➜ Numero di secondi dal 2000-01-01 00:00:00.


... molti stanno offrendo questa possibilità dato che il classico Unix Time (inizio 01.01.1970) arriverà al limite tra poco più di una quindicina di anni ... 19 Gennaio 2038 :slight_smile:

Almeno con la seconda versione (quella con inizio 01.01.2000) si arriva circa 30 anni oltre :grin:

Guglielmo

l'RTC DS3231 rappresenta il secolo su 1 bit e gli anni compresi tra 0 e 99. Dopo il 2100 non sarà più valido :slight_smile:

... no, perchè? Quello è solo un indicatore di overflow ... quando il campo anno passa da 99 a 00 quel bit viene alzato per indicarti la cosa, ma ... onestamente mai usato.

Dal datasheet:

The century bit (bit 7 of the month register) is toggled when the years register overflows from 99 to 00.

Normalmente si usa solo il campo "Year", ovviamente facendo le dovute somme a seconda del progetto e ... si, ogni 100 anni si dovrà fare manutenzione per cambiare il valore aggiunto ... se dopo 100 anni il progetto sarà ancorà in funzione :wink:

Guglielmo

:wink:

Di quello non mi preoccupo ... dubito che nel 2100 useremo ancora i DS3231 :laughing: :laughing: :laughing:

Guglielmo

per quanto mi riguarda, chiaramente non li userò :grimacing: :scream: :skull:

Chissà... Qualche invenzione di importanza storica... :slight_smile:

La soluzione è stata trovata. Ma comunque bastava gestire il ritorno a zero calcolando in modulo 60:

int elapsed = now.second() - lasttime;
if (elapsed < 0) { elapsed += 60; }
if(elapsed >= 3) { .... }

In questo modo si possono contare tempi fino a 59 secondi indipendentemente dal momento del ritorno a zero.