Salve a tutti,
sono Alessandro (nick Zamundo), mi sono presentato nell'apposita sezione e questo è il mio primo post.
Come da titolo avrei necessità di programmare un evento ogni 48 h precise.
Escluso ovviamente il delay, ho provato con il millis(), ma presenta un "ritardo congenito" di circa 1 secondo al giorno (un'enormità).
Allora ho provato con le varie librerie che gestiscono il modulino RTC DS1307 e con esse è possibile programmare un evento ogni giorno ad un'ora prestabilita o addirittura con la libreria TimeAlarms.h programmare un evento ad esempio ogni lunedì alle 15.00.
A me servirebbe tuttavia un evento a prescindere dal giorno della settimana ogni 48h partendo da orario "impostabile".
C'è qualcuno capace di darmi qualche suggerimento ?
In essa vedrai l'uso della funzione future che, a partire da un determinata data, calcola i valori di anno, giorno, mese, ore, minuti e secondi dopo un incremento qualsiasi.
Confrontando nel loop questi valori con quelli della funzione now, puoi ottenere quanto richiedi.
ciao e auguri....
secondo me le cose che dici presentano un problema alla radice....
dici che per te 1 secondo di sfasamento è un'enormità, ma poi utilizzi un ds1307 che è un rtc molto impreciso.
Allora se ti interessa davvero la precisione inizia ad utilizzare un rtc più preciso tipo il ds3231, e già le cose cambieranno.
Per aggiornare l'allarme "ogni 48h" basta che a fine sketch imposti la sveglia aggiungendo all'ora attuale 48h, magari con arduino che ogni ora si sveglia, aggiunge 1h alla variabile che porta il conto e quando raggiunge la 48esima ora fa partire nuovamente il tutto.
A questo punto ordino il DS3231 come consigliato da giorgio90.
@cyberhs: Potrò sempre utilizzare la RTClib che mi consigli con il DS3231 ? Potresti scrivermi due righe di codice per "confrontare" valori di now.unixtime() con DateTime future che ho visto nel link che mi hai postato, e soprattutto per azzerare la funzione per permetterle di "ricominciare il conteggio" ?
@giorgio90: non ho la padronanza per comprendere il tuo consiglio di porre una sveglia = ora attuale +48h (non mi serve che arduino si risvegli tipo WatchDog Timer ogni ora), potresti essere così gentile anche tu da mostrarmi due righe di codice ?
Come ho scritto nella presentazione sono nuovo nel mondo Arduino e nonostante l'entusiasmo, ancora non padroneggio bene il sistema... mi scuso.
allora, onestamente non ho capito benissimo cosa devi fare, il mio consiglio era per questa situazione-tipo:
arduino svolge un'azione (ad esempio controllare dei sensori e una volta completato smette di funzionare (parlavi di delay quindi tra i due intervalli non devi fare niente giusto?) poi dopo 48h si risveglia e ricompie l'azione presente nel loop.
Da ciò il consiglio...
Se non ti interessa addormentare arduino, e quindi risparmiare corrente, puoi saltare la funzione di "addormentamento", considerando che il ds3231 ha due allarmi utilizzabili come interrupt puoi semplicemente settare, a fine sketch, un allarme come ora attuale + 2 giorni (48h = 2d). Impostando quel pin come interrupt non appena sarà valida la condizione dell'allarme, questo farà scattare l'interrupt azionando il tuo evento.
non sono a casa, quindi trovo scomodo scrivere da touch, di codici ne trovi un sacco anche dalle librerie che ci sono in giro per quel rtc...altrimenti quando torno vedo di trovare qualcosa per te...
/* YourDuino.com Example Software Sketch
DS1307 Real Time Clock test
CONNECTIONS:
Ground
+5V
UNO MEGA
SDA A4 20
SCL A5 21
*/
#include <Wire.h>
#include "RTClib.h"
RTC_DS1307 RTC; // dichiara oggetto
unsigned long Timer = 0; // memoria ultimo evento (secondi)
void setup() {
Serial.begin(9600);
Wire.begin(); // Start the Wire (I2C communications)
RTC.begin(); // Start the RTC Chip
// RTC.adjust(DateTime(__DATE__, __TIME__)); // Set the date/time to the time this program was compiled
}
void loop() {
DateTime now = RTC.now(); // preleva data e oraio dal RTC ed inseriscilo in now
if (Timer = 0) { // timer non ancora settato
DateTime future(now.unixtime() + 2 * 86400L); // calcola la data futura dopo 24h (2 giorni)
Timer = future.unixtime; // memorizza i secondi che devono trascorrere
}
if (now.unixtime() > Timer) { // sono passate 24 ore
//
// inserisci qui le operazioni da fare
//
Timer = 0; // resetta timer
}
/* questa parte serve solo a controllare il funzionamento del RTC e può esssere omessa
Serial.print(now.day(), DEC);
Serial.print('/');
Serial.print(now.month(), DEC);
Serial.print('/');
Serial.println(now.year(), DEC);
Serial.print(now.hour(), DEC);
Serial.print('.');
Serial.print(now.minute(), DEC);
Serial.print('.');
Serial.print(now.second(), DEC);
Serial.println();
Serial.print("Secondi trascorsi da 01/01/1970 0.00.00 ");
Serial.println(now.unixtime());
Serial.print("Giorni ");
Serial.println(now.unixtime() / 86400L);
*/
delay(1000);
}
io ho lo stesso problema di ramundo ma ho un rtc ds3231 con il quale leggo perfettamente dia la data che l'ora du lcd.....
come posso adattare questo sketch con il mio rtc?
ho fatto alcune prove ma credo che abbia un problema di librerie.
puoi aiutarmi cyberhs?
linus72:
io ho lo stesso problema di ramundo ma ho un rtc ds3231 con il quale leggo perfettamente dia la data che l'ora du lcd..... come posso adattare questo sketch con il mio rtc? ho fatto alcune prove ma credo che abbia un problema di librerie.
puoi aiutarmi cyberhs?
Beh le librerie sono diverse per i vari rtc.
Tu quale libreria usi per il tuo ds ? Metti un link.
Versione IDE che usi ?
Purtroppo quella libreria è MOLTO diversa.
Quella RTC_lib del pezzo di @cybers è una classica libreria che poi ha i suoi "comandi" (metodi e funzioni) per leggere le varie parti dell'ora/data
Quella del link invece si appoggia alla libreria Time.h, delegando a questa i comandi per leggere le parti della ora/data.
A differenza dell'altra, mi pare (non la uso) devi metter include sia per lei che per la Time.h
nella setup() ci deve essere per forza almeno questo pezzo:
Serial.begin(9600);
setSyncProvider(RTC.get); // the function to get the time from the RTC
if(timeStatus() != timeSet)
Serial.println("Unable to sync with the RTC");
else
Serial.println("RTC has set the system time");
al posto di
RTC.begin(); // Start the RTC Chip
A questo punto nel programma (loop) puoi usare le funzioni tipo hour() SENZA mettere davanti RTC.hour()
Quindi sono comandi della time.h LINK.
La time.h ha anche il comando now() (senza RTC. davanti)
time_t now=now();
Difficile. Quella Time.h lavora tutta dentro a sue variabili interne. Non puoi creare due variabili DateTime come ha fatto @cybers nel suo esempio.
La lib Time.h usa una variabile di tipo t_time che poi è semplicemente una unsigned long ma non si capisce come memorizza dentro a questa i vari pezzi (ora,minuti,anno,etc)
Penso siano i secondi passati dal 1 gennaio 1970. Ma dentro alla libreria per calcolarla fa un macello di calcoli
mi sto studiando come funziona la libreria EEPROM.h così da poter riuscire a memorizzarmi nella EEPROM di arduino sia la data che l'ora....così posso valutare se sono passati due giorni e posso passare poi al comando del mio evento......che dite? è la strada giusta? qualche suggerimento e possibilmente qualche aiutino....!!
scusami nid69ita ma non avevo letto la fine del tuo post....
è proprio come l'hai scritto tu....
il mio problema adesso è simile a quello di zamundo (vedi inizio discussione forum)..
ho la necessità di programmare un evento ogni 48ore precise....
mi puoi aiutare?
Permettimi di prendere come spunto la tua richiesta per argomentare su: 48 ore precise.
Di recente ho letto un libro (leggo quanto più spesso posso) in cui si fa notare al lettore che molti degli aggettivi o requisiti noi li esprimiamo in modo da essere comprensibile al 100% soltanto da noi.
Cosa significa per te "48 ore precise", no perché di preciso non è possibile fare nulla neanche con un orologio atomico, quindi inseriamo un altro dato che quantifica la precisione o l'imprecisione tollerabile.
PS: Non è un appunto personale verso l'utente specifico, sono stato influenzato dal libro ed ho voluto dire la mia solo per condividere.