Go Down

Topic: Arduino ed evento ogni 48 ore precise (Read 3781 times) previous topic - next topic

Zamundo

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 !!!!
Che Arduino sia con Voi !

cyberhs

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.

giorgio90

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.
WWW.GIORGIOCASIELLO.COM

Zamundo

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.
Che Arduino sia con Voi !

giorgio90

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...
WWW.GIORGIOCASIELLO.COM

cyberhs

Come promesso ecco un esempio (da provare):
Code: [Select]

/* 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);
}



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?

PaoloP

#7
Oct 04, 2016, 04:02 pm Last Edit: Oct 04, 2016, 04:03 pm by PaoloP
Come da titolo avrei necessità di programmare un evento ogni 48 h precise.
Ma non erano 108 minuti?

 :smiley-mr-green:  :smiley-mr-green:  :smiley-mr-green:  :smiley-mr-green:  :smiley-mr-green:




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

nid69ita

#8
Oct 04, 2016, 04:34 pm Last Edit: Oct 04, 2016, 04:35 pm by nid69ita
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 ?
my name is IGOR, not AIGOR

linus72

link della libreria : https://github.com/JChristensen/DS3232RTC

uso arduino mega 2560 con IDE 1.6.9

grazie

nid69ita

#10
Oct 04, 2016, 06:06 pm Last Edit: Oct 04, 2016, 06:24 pm by nid69ita
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
Code: [Select]
#include <DS3232RTC.h>    //http://github.com/JChristensen/DS3232RTC
#include <Time.h>

al posto di
Code: [Select]
#include "RTClib.h"
RTC_DS1307 RTC;


nella setup() ci deve essere per forza almeno questo pezzo:
Code: [Select]
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
Code: [Select]
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();
my name is IGOR, not AIGOR

linus72

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

mi puoi aiutare?

linus72

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?

nid69ita

#13
Oct 04, 2016, 06:34 pm Last Edit: Oct 04, 2016, 06:42 pm by nid69ita
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
my name is IGOR, not AIGOR

SukkoPera

"Code is read much more often than it is written, so plan accordingly. Design for readability."

Guida rapida a ESP8266: https://goo.gl/kzh62E

Go Up