Arduino ed evento ogni 48 ore precise

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 ?

Grazie e Buon 2015 a tutti !!!!

Buon 2015 anche a te e benvenuto!

Se hai già provato il DS1307 e ti soddisfa la sua precisione, puoi benissimo usarlo per il tuo scopo.

Di librerie ce ne sono parecchie ma ti consiglio la RTClib che, tra l'altro puoi usare anche senza modulo.

Dai un'occhiata a questo link:
http://arduino-info.wikispaces.com/DS1307_RealTime_Clock_Brick

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.

Ringrazio tantissimo entrambi per le risposte.

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...

Come promesso ecco un esempio (da provare):

/* 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?

Zamundo:
Come da titolo avrei necessità di programmare un evento ogni 48 h precise.

Ma non erano 108 minuti?


:grin: :grin: :grin: :grin: :grin:

OK... potete anche bannarmi per 24 ore. :slight_smile:

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 ?

link della libreria : GitHub - JChristensen/DS3232RTC: Arduino Library for Maxim Integrated DS3232 and DS3231 Real-Time Clocks

uso arduino mega 2560 con IDE 1.6.9

grazie

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

#include <DS3232RTC.h>    //http://github.com/JChristensen/DS3232RTC
#include <Time.h>

al posto di

#include "RTClib.h"
RTC_DS1307 RTC;

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();

sei stato gentilissimo....ma come posso risolvere il mio problema?

mi puoi aiutare?

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?

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

Basta usare breakTime()...

Si ma Zamundo si è Lost!! ... [perduto]

PaoloP:
Ma non erano 108 minuti?


:grin: :grin: :grin: :grin: :grin:

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.

Ciao. :slight_smile:

... e' sufficente che le 48 ore siano precise al centomiliardesimo di microsecondo ... :stuck_out_tongue: :smiley:

... e' sufficente che le 48 ore siano precise al centomiliardesimo di microsecondo ... :stuck_out_tongue: :smiley:

FPU error: unrepresentable data (0x01)
FPU recovery error: unrepresentable data (0x02)
FPU error: unrepresentable data (0x01)
FPU recovery error: unrepresentable data (0x02)
FPU error: unrepresentable data (0x01)

CPU error: overheated
CPU EXA: shutdown
:kissing: