RTC shield timer

Ciao a tutti!
ho acquistato una rtc shield e sto cercando di usarla. fin'ora ho scritto la data e l'ora sulla seriale (quindi niente di particolare). ora vorrei temporizzare un relè.
ho cercato in giro ma trovo praticamente solo gli sketch di esempio che però non mi aiutano.
non capisco come confrontare l'ora ad esempio in un:

if (ora_aggiornata = ora_timer){
relè on;
}

Non so se si possa scrivere qualcosa di simile o se sto dicendo cavolate...
Qualcuno puo' aiutarmi?
Grazie a tutti!
Ciao

Per evitare di incasinarsi è sempre bene effettuare questo tipo di confronti lavorando con "Unix Epoch Time" (guarda ad esempio QUI) che ha il vantaggio di rappresentare data/ora con un numero intero lungo e quindi facilmente confrontabile.

Ci dovrebbe essere una delle librerie di Leo72 che, tra le altre cose, mette a disposizione le funzioni di conversione ... dovrebbe essere QUESTA.
Guarda dove parla dei "Timestamp" :wink:

Guglielmo

In questo semplice modo a me funziona:

DateTime now = RTC.now();
 int Th = now.hour();
int Tm = now.minute();
if( (Th == 7) && (Tm== 35)){ AllarmeBiancoOn();  }
ecc.
...

70agiuseppe:
In questo modo a me funziona:
....

...pessimi esempi di codici funzionanti se ne trovano a bizzeffe ]:smiley: ]:smiley: ]:smiley:

Stavo suggerendo quale è la prassi comune per evitare problemi nei confronti con date/ore (... specie se magari ci sono di mezzo giorni differenti) ... e non un singolo caso particolare !

Guglielmo

gpb01:
...pessimi esempi di codici funzionanti se ne trovano a bizzeffe ]:smiley: ]:smiley: ]:smiley:

Grazie! :~ Troppo buono :~

P.S.
Con il mio esempio volevo dire che Per far funzionare il tuo codice:
Un solo = corrisponde a assegnazione per la comparazione sono richiesti due ==

grazie per le risposte...

il consiglio quindi sarebbe di cambiare libreria?
adesso stavo usando quella che consigliano da dove ho comprato la shield RTC che si chiama RTClib.

se era possibile usare questa preferivo...

il metodo scritto da 70agiuseppe può dare problemi?
io devo accendere e spegnere una luce tramite relè, acceso e spento una volta al giorno niente di strano....

lucadh:
...
il consiglio quindi sarebbe di cambiare libreria?
adesso stavo usando quella che consigliano da dove ho comprato la shield RTC che si chiama RTClib.
...

NO,
il consiglio e di usare la libreria che ti ho indicato (e che puoi mettere assieme alla tua) SOLO per fare le conversioni da "gg/mm/aaaa hh:mm:ss" in "Epoch" e viceversa (ovvero usare ALCUNE delle funzioni che sono all'interno di quella libreria).

Con la buona volontà ... potresti anche studiartele e riscrivertele senza includere tutta la libreria XD XD XD

Ripeto comunque che, quando si fanno operazioni e confronti con le date, se non si vuole impazzire, il formato "Epoch" è il più adatto (è un NUMERO e, come tale, facilmente manipolabile ... somma, sottrazione, confronto, ecc) poi ...
... ognuno scrive il codice che gli pare che ... magari funziona in un caso e ... in tutti gli altri casi lo deve buttare :wink:

Guglielmo

lucadh:
...
il metodo scritto da 70agiuseppe può dare problemi?
...

Probabilmente non da problemi, ma ...
... di sicuro NON avrai imparato NULLA e, alla prima occasione, sarai ancora qui a chiedere aiuto perché non avrai capito come fare operazioni e confronti con date/ore ]:smiley:

Guglielmo

70agiuseppe:

gpb01:
...pessimi esempi di codici funzionanti se ne trovano a bizzeffe ]:smiley: ]:smiley: ]:smiley:

Grazie! :~ Troppo buono :~
....

Era ovviamente una battuta bonaria ...
... per farti capire che soluzioni di quel tipo, sono molto specifiche e ... appena la cosa si compilca, ti trovi nei guai. Meglio quindi sforzarsi un po' ed imparare come gestire correttamente certe cose :wink:

Guglielmo

Probabilmente non capisco io. Ma quella libreria calcola data ora con il clock di arduino in poche parole...giusto? Io uso la rtc shield con a bordo il ds1307. E se uso la libreria che mi hai indicato invece no...

Ripeto, forse non capisco io...scusatemi...

lucadh:
Probabilmente non capisco io. Ma quella libreria calcola data ora con il clock di arduino in poche parole…giusto? Io uso la rtc shield con a bordo il ds1307. E se uso la libreria che mi hai indicato invece no…

No, no, probabilmente sono io che non riesco a farmi capire e che non mi sono espresso bene … :wink:

Allora, tu giustamente devi usare la libreria per il DS1307 … ma dato che devi fare delle operazioni sulle date/ore, per non avere problemi dovresti convertirle in formato “Epoch” (che è un NUMERO) … e fino qui credo che ti sia chiaro.

Ora … o ti metti ad reinventare la ruota (= ti scrivi tu la routine che trasforma data/ora in formato “Epoch”) oppure … ti guardi come viene fatta la conversione all’interno della swRTC e ti semplifichi la vita.

Dovrebbe essere questa funzione :

//returns a timestamp giving the number of seconds since a part year (default=1970)
unsigned long swRTC::getTimestamp(int yearT){
	unsigned long time=0;

	//check the epoch
	if (yearT == 0) {
		yearT = 1970;
	} else if (yearT < 1900) {
		yearT = 1900;
	} else if (yearT > 1970) {
		yearT = 1970;
	} else if ((yearT != 1900) && (yearT != 1970)) {
		yearT = 1970;
	}

	//One revolution of the Earth is not 365 days but accurately 365.2422 days.
	//It is leap year that adjusts this decimal fraction. But...
	time += (getYear() - yearT) * 365.2422;
	for (int i = 0; i < getMonth() - 1; i++){
		time += daysPerMonth[i]; //find day from month
	}
	time = (time + getDay()) * 24UL; //find hours from day
	time = (time + getHours()) * 60UL; //find minutes from hours
	time = (time + getMinutes()) * 60UL; //find seconds from minute
	time += getSeconds(); // add seconds
	if (time > 951847199UL) { time += 86400UL; } //year 2000 is a special leap year, so 1 day must be added if date is greater than 29/02/2000
	return (time - 86400UL); //because years start at day 0.0, not day 1.
}

Prendi la funzione, te la sistemi con le TUE variabili che contengono giorno/mese/anno ore:minuti:secondi ed hai una funzione che ti fa la conversione … senza grossi sforzi … usando quanto già fatto da Leo.

Più chiaro adesso ?

Una volta che hai data/ora in formato “Epoch” … in tutti i tuoi programmi (presenti e futuri :smiley:) puoi fare tutti i confronti che vuoi senza avere problemi :wink:

Guglielmo

Ecco, guarda, mi sono divertito a riscrivertela come una semplice funzione staccata ed indipendete dalla libreria (… Leo perdona se ho estratto/copiato la funzione dalla tua libreria XD) …

unsigned long timeStamp(byte gg, byte mm, int yy, byte hh, byte mn, byte ss, int yearT) {
  byte daysPerMonth[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
  unsigned long time=0;

  //check the epoch
  if (yearT == 0) {
    yearT = 1970;
  } 
  else if (yearT < 1900) {
    yearT = 1900;
  } 
  else if (yearT > 1970) {
    yearT = 1970;
  } 
  else if ((yearT != 1900) && (yearT != 1970)) {
    yearT = 1970;
  }

  //One revolution of the Earth is not 365 days but accurately 365.2422 days.
  //It is leap year that adjusts this decimal fraction. But...

  time += (yy - yearT) * 365.2422;
  for (int i = 0; i < mm - 1; i++){
    time += daysPerMonth[i]; //find day from month
  }
  time = (time + gg) * 24UL; //find hours from day
  time = (time + hh) * 60UL; //find minutes from hours
  time = (time + mn) * 60UL; //find seconds from minute
  time += ss; // add seconds

  if (time > 951847199UL) { 
    time += 86400UL; 
  } //year 2000 is a special leap year, so 1 day must be added if date is greater than 29/02/2000

  return (time - 86400UL); //because years start at day 0.0, not day 1.
}

… gli passi giorno, mese, anno, ore, minuti, secondi, anno di riferimento (di solito 1970) e ti ritorna il tutto in formato “Epoch” :wink:

Buon divertimento …

Guglielmo

Edit : … l’ho buttata giù a tarda ora, dovrebbe essere giusta, ma … verificala (magari confrontando un po di valori con il sito che ti avevo indicato) :wink:

Grazie davvero di cuore per l'aiuto.
più tardi proverò e vi farò sapere.

ok! ora sto iniziando a capire meglio.

forse la libreria che uso, RTClib, ha già la possibilità di usare il formato epoch. questa è una parte dello sketch di esempio della libreria e credo che usi già quel tipo di formato e calcoli una data futura... a quel punto basterebbe un if per decidere qualcosa ad una determinata ora. questo è un altro metodo che però una sempre un numero e che quindi può andare molto bene. è così?

    Serial.print(" since midnight 1/1/1970 = ");  
   Serial.print(now.unixtime());
   Serial.print("s = ");
   Serial.print(now.unixtime() / 86400L);
   Serial.println("d");
   
   //calcolare una data che è di 7 giorni e 30 secondi nel futuro (timer)
   DateTime future (now.unixtime() + 7 * 86400L + 30);
   
   Serial.print(" now + 7d + 30s: ");   
   Serial.print(future.year(), DEC);
   Serial.print('/');
   Serial.print(future.month(), DEC);
   Serial.print('/');
   Serial.print(future.day(), DEC);
   Serial.print(' ');
   Serial.print(future.hour(), DEC);
   Serial.print(':');
   Serial.print(future.minute(), DEC);
   Serial.print(':');
   Serial.print(future.second(), DEC);
   Serial.println();
   
   Serial.println();

SI, vedo unixtime() che è l'equivalente del formato "Epoch" ... quindi ... l'avevi già :wink:

Una volta che hai trasformato una data/ora in un numero ... capisci che ci puoi fare di tutto ... confronti, aggiungere, sottrarre, ecc. ecc. E' il sistema più comodo :slight_smile:

Guglielmo

P.S. Racchiudi SEMPRE il codice tra i tag CODE (usa il bottone con il simbolo # che hai tra i vari bottoni della seconda fila)

scusami se ti stresso. ma adesso pensavo: se devo accendere una luce tutti i giorni alla solita ora diventa scomodo usare unixtime perchè ogni giorno ho un valore diverso in quanto fa riferimento al 1970. dico bene? quindi oggi alle 10:00 avrò un certo N e domani alle 10:00 avrò lo stesso N di ieri +86400. dico bene? devo capire bene la logica di come funzionano queste librerie trc...

... scusa è, ma se NON tieni conto del giorno e metti un valore fisso per gg, mm, yy (es. 1,1,1970) ... il numero che otterrai sarà sempre e solo funzione delle ore (hh,mn,ss) indipendetemente dalla data ... non ti pare ? XD

... cercate di pensare sempre la soluzione più semplice ... di solito è quella giusta :wink:

Guglielmo