Per realizzare la centralina del tuo impianto di irrigazione, vedi articolo sulla prima parte, ti serve conoscere l’ora.
In aiuto ti viene una shield, e quando mai non ne esiste una ad hoc per il tuo progetto 🙂
Io ho acquistato la RTC Shield da robot-domestici e fatto i primi test in funzione del progetto finale.
Montaggio
La shield RTC è venduta in Kit
quindi prima di utilizzarla procurati un saldatore e dello stagno per assemblarla, non è difficile i componenti sono molto distanti tra loro ed il DS1307 è montato su uno zoccoletto a 8 pin che rende facile la saldatura senza compromettere l’integrato.
Come sempre il consiglio è di partire dai componenti più bassi per salire man mano che monti il tuo kit, parti dalle resistenze, 3 in tutto:
quindi salda il condensatore ceramico, l’unico denominato C1, l’atro è un condensatore elettrolitico ed è più alto:
salda il quarzo, è il secondo componente per ordine di importanza e come dalla serigrafia il mio consiglio è di montarlo orizzontale per rendere il circuito più basso:
ora puoi montare lo zoccolo che ospiterà il processore:
ed a seguire il condensatore elettrolitico ed il led, facendo attenzione alla polarità di entrambi:
posiziona e salda il portabatteria per la CR2032, contenuta nella confezione:
salda il jumper JSQW che ti consente di scegliere se inviare ad arduino il clock del DS1307 sul piedino A3 o lasciare che la shield non comunichi questa informazione ad Arduino, dipenderà da progetto a progetto:
infine salda i connettori per inserire la shield su Arduino:
Nella confezione sono presenti più connettori:
- 3 connettori da 8 pin
- 1 connettore da 10 pin
- 1 connettore da 6 pin
a cosa servono?
il connettore da 6 pin va in corrispondenza dei pin analogici, A0-A5, di Arduino; un connettore da 8 pin devi saldarlo in corrispondenza dei pin Vin, GND, GND, 5v, 3v3 e RST di Arduino ed un’altro connettore da 8 pin devi saldarlo in corrispondenza dei primi 8 pin digitali di arduino, 0-7.
I connettori da 8 e 10 sono alternativi, ossia dipende dalla scheda Arduino a cui devi collegare lo shield: se utilizzerai una Arduino Rev 3 devi usare il connettore da 10pin in corrispondenza dei pin digitali 8-13 e successivi GND, AREF, SDA ed SCL in quanto questa versione ha 2 pin in più corrispondenti proprio alle uscite SDA ed SCL che permettono alla shield di comunicare con Arduino mediante I2C collegati su questi pin. Nelle versioni precedenti alla Rev3 ( rev 2 o inferiore, duemilanove, ecc… ) questi 2 pin mancano e devi saldare il connettore da 8 pin in corrispondenza dei pin digitali 8-13 e successivi.
Important!
Se usi arduino in versione precedente alla Rev3 ricordati di ponticellare le due piazzole presenti, sul lato opposto ai componenti della schield, questi ponticelli ti permettono di vere i segnali SDA ed SCL rispettivamente sui pin A4 ed A5 di arduino, in quanto in quelle versioni i pin A4 ed A5 sono destinati all’ I2C.
Terminato l’assemblaggio puoi inserire la CR2032 nell’apposito portapila.
Il costruttore della shield indica in 5/6 anni l’autonomia della pila.
Libreria
per funzionare la shield ha bisogno della liberia RTClib.h che puoi scaricare in versione modificata per questa shield a questo link
Potresti anche decidere di non utilizzare la libreria RTClib ma in tal caso dovrai scriverti tutte le righe di codice necessarie a comunicare con il DS1307 attraverso il protocollo I2C e la libreria Wire.h.
Sketch
Come primo test ho utilizzato quello fornito con la libreria stessa, Examples -> RTClib -> DS1307 che ti propongo:
// Date and time functions using a DS1307 RTC connected via I2C and Wire lib #include <Wire.h> #include "RTClib.h" RTC_DS1307 RTC; void setup () { Serial.begin(57600); Wire.begin(); RTC.begin(); RTC.sqw(1); //0 Led off - 1 Freq 1Hz - 2 Freq 4096kHz - 3 Freq 8192kHz - 4 Freq 32768kHz if (! RTC.isrunning()) { Serial.println("RTC is NOT running!"); // following line sets the RTC to the date & time this sketch was compiled //RTC.adjust(DateTime(__DATE__, __TIME__)); } } void loop () { DateTime now = RTC.now(); Serial.print(now.year(), DEC); Serial.print('/'); Serial.print(now.month(), DEC); Serial.print('/'); Serial.print(now.day(), DEC); Serial.print(' '); Serial.print(now.hour(), DEC); Serial.print(':'); Serial.print(now.minute(), DEC); Serial.print(':'); Serial.print(now.second(), DEC); Serial.println(); Serial.print(" since midnight 1/1/1970 = "); Serial.print(now.unixtime()); Serial.print("s = "); Serial.print(now.unixtime() / 86400L); Serial.println("d"); // calculate a date which is 7 days and 30 seconds into the future 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(); delay(3000); }
avrai notato che la linea 16 è commentata nello sketch sopra mentre nell’esempio fornito no, vedrai a breve a cosa serve e perchè l’ho fatto.
linea 03: includi la liberia Wire.h necessaria alla comunicazione su I2C;
linea 04: includi la RTClib.h di cui hai già letto le caratteristiche e che ti aiuta nella scrittura del codice del tuo progetto;
linea 06: crea l’oggetto RTC di tipo RTC_DS1307;
linea 09: inizializza la comunicazione seriale, sulla quale vedrai riportato data e orario;
linea 10: inizializza la clase Wire con il metodo begin(), la classe Wire serve alla RTClib per la comunicazione I2C;
linea 11: inizializza l’oggetto RTC con il metodo begin();
linea 12: il metodo utilizzato è valido solo per la RTClib modificata e per questo sketch, il suo utilizzo consente di definire la frequenza di lampeggio del led secondo le impostazioni riportate anche nello sketch:
- 0 led spento
- 1 led che lampeggia con frequenza di 1Hz
- 2 led che lampeggia con frequenza di 4096kHz
- 3 led che lampeggia con frequenza di 8192kHz
- 4 led che lampeggia con frequenza di 32768kHz
nello sketch è impostato a 1 in quanto la frequenza di 1Hz corrisponde ad un lampeggio ogni secondo;
linea 13: la condizione verifica che l’RTC sia impostato, essendo negata ( ! ) le istruzioni presenti tra le parentesi graffe vengono eseguite solo se l’RTC non è in funzione, cosa che si verifica solo alla prima accensione o in seguito al reset del DS1307, essendoci la batteria tampone anche se il circuito resta senza alimentazione l’RTC continua a mantenere l’ora esatta.
linea 14: scrivi sul monitor seriale che si è verificata la condizione di mancato funzionamento dell’RTC;
linea 16: questa linea, come detto sopra, la puoi commentare al primo avvio se sei curioso di vedere a che data è impostato il DS1307 alla prima accensione, infatti questa linea di codice utilizza il metodo adjust( date, time ) dell’oggetto RTC per impostare la data e l’ora corrente. Utilizzata con le variabili di ambiente __DATE__ e __TIME__ al momento della compilazione queste due variabili vengono sostituite dall’IDE con la data e l’ora corrente impostate sul computer e passate ad Arduino in fase di upload, quindi il funzionamento dello sketch dice al DS1307 di impostare la data e l’ora inviate se non è presente una data ed ora.
Questo è quello che mi è apparso alla prima accensione:
Puoi a questo punto ricompilare lo sketch decommentando questa linea ed imposterai la data ed ora corrente sull’RTC:
avrai notato che la freccia indica la data del mio computer e che questa corrisponde a quella impostata sul DS1307.
Ogni volta che vorrai impostare la data puoi utilizzare la funzione adjust(), se vuoi reimpostarla identica a quella del computer dovrai ricompilare ed uplodare lo skecth, solo in questa fase le variabili __DATE__ e __TIME__ assumono il valore di data e ora correnti.
linea 21: definisci una variabile now come istanza di tipo DateTime a cui assegni il valore ritornato dal metodo now() della libreria RTC;
linee 23-34: utilizzando i metodi messia a disposizione dall’istanza now puoi scrivere sul monitor seriale aaaa/mm/gg hh:mm:ss così come restituiti dall’RTC;
linee 36-40: sempre utilizzando i metodi offerti dall’istanza now puoi ottenere il numero di secondi passati dal 01/01/1970 e il suo valore in giorni;
linee 42-57: utilizzando le funzioni di DateTime puoi anche calcolare una data futura partendo da quella corrente, nell’esempio la data è 7 giorni e 30 secondi avanti;
linea 60: imposta un tempo di attesa di 3 secondi tra un ciclo di loop() ed il successivo;
Video
ho realizzato un semplice video in cui si vede il led lampeggiare alla frequenza di 1Hz, scandisce i secondi:
Buona scansione del tempo !!!
63 commenti
4 ping
Vai al modulo dei commenti
Bello! quanto l’hai pagato? quanto ci hai messo a saldarlo?
Autore
Ciao Leonardo,
Mi sembra 11,00 euro.
Per montarlo dipende dalla tua esperienza io ci ho messo meno di un’ora sono pochi componenti.
Posso confermarti che è davvero incredibile, presto potrai leggere altri tutorial con questa Shield.
Mauro
Ciao Mauro, inizio col dirti che i tuoi tutorial sono molto interessanti oltre che ben fatti.
Sono uno studente d’informatica, e mi sto avventurando nella programmazione arduino, e l’impianto d’irrigazione è il mio progetto che vorrei portare a termine, per poi ampliarlo. L’unico problema è che sono abbastanza scarso in elettronica, salature e montaggi, per cui ti chiederei se esiste un RTC Shield con DS1307 già montata; ho provato su robot-domestici ma cè da aspettare fino ad agosto, mentre su ebay ho trovato de i moduli che visti i costi (sui 5 euro) penso siano solo parti del componente.
ps….l’ultimo pezzo che mi manca per il progetto d’irrigazione oltre all’rtc è il relay 12vdc, che non riesco a trovare.
Riesci a darmi qualche dritta?
Autore
Ciao Gianvito,
come RTC puoi utilizzare un qualsiasi modulo RTC basato sul DS1370, io ne ho presentati diversi nel blog.
Ne trovi uno già montato in vendita sui siti che riporti, l’unico che io conosco già fatto a shield è quello presentato in questo articolo.
Tuttavia tutti i moduli basati sul DS1370 si collegano allo stesso modo: +5v,Gnd,SDA ed SCL
Per i relay puoi optare per una shield già pronta con 1,2,4,6,8 relay le trovi sui siti che hai visitato.
Mauro
Ciao,ho realizzato l’orologio con un altro RTC e mi piacerebbe poter modificare ora e data con dei pulsanti. Potresti darmi un consiglio per poterlo fare ?? Grazie. IDRIS.
Autore
Ciao Idris,
sarà oggetto di un prossimo articolo, posso anticiparti che l’ide di fondo è assegnare ad una variabile l’ora, un’altra i minuti e un’altra i secondi.
Ti occorrono 4 pulsanti: 1 setting, 2 change, 3 più e 4 meno.
Con il pulsante 1 entri in modalità setting, cursore fa lampeggiare le ore;
con i pulsanti 3 e 4 incrementi o decrementi il valore delle ore;
con il pulsante 2 ti sposti ai minuti, poi ai secondi ecc…;
con il pulsante 1 esci dalla modalità setting e salvi l’ora nell RTC;
Il gioco è fatto, è più complesso raccontarlo che farlo 🙂
Mauro
Non hai detto come salvare i nuovi dati sull’rtc.
Come si convertono secondi, minuti, ore, giorni, mesi ed anni in una variabile DateTime?
Autore
Ciao Fil,
trovi tutto nella descrizione dello sketch. Alla linea 14 c’è proprio il comando che mi chiedi per memorizzare la data e l’ora nell’RTC.
Per le conversioni le trovi nelle linee successive.
Grazie per aver letto e commentato l’articolo.
Mauro
Intanto complimenti, stai facendo un gran bel lavoro e io che mi sono avvicinato da poco tempo ad arduino ti ringrazio molto.
Sto cercando di realizzare un orologio con display che mi visualizzi anche il giorno della settimana, ho visto che con la RTClib.h questo non viene fornito, però so che il DS1307 lo gestisce, quindi la mia domanda è semplice, è possibile modificare la libreria per gestirlo o bisogna usare un’altra libreria e nel caso quale consigli?
Autore
Ciao Stefano,
non ho ancora avuto modo di studiare bene la libreria RTClib.h, se come dici il DS1307 gestisce questa informazione è senza dubbio possibile modificare la libreria aggiungendovi un metodo che ti ritorni l’informazione che ti occorre.
Se vuoi inviami rispondi con qualche link in cui hai trovato l’informazione sul DS1307 e magari io o qualche altro appassionato possiamo collaborare con te a realizzare la modifica.
A che progetto stai lavorando? Mi piacerebbe, se vuoi, condividerlo e dedicarti un articolo sul blog.
Mauro
Ciao e grazie per la risposta, venendo subito al punto, il mio progetto è un po’ più ampio e forse per me non realizzabile, ma vorrei provarci e sono dell’idea di arrivarci per gradi. Il primo passo sarebbe appunto realizzare un semplice orologio con display 16×2 (come quello che hai realizzato nell’altro articolo del RTC DS1307), che in un determinato giorno della settimana ad una determinata ora faccia succedere un evento tipo una sveglia, per farla semplice accendere il famoso led sul canale digitale 13. Fatto questo vorrei aggiungerci una sonda termica tipo il DS18B20 (cosa che ho già fatto in un altro progettino) e gestire l’evento anche in base alla temperatura come fanno i cronotermostati e se la pazienza e le capacità mi assistono vorrei anche poter gestire il tutto da web, comunque imango dell’idea che bisogna fare un passo alla volta.
Ti chiedevo appunto della libreria perché ho visto nel file RTClib.h che utilizza la libreria wire (cosa logica perché il DS1307 comunica su I2C) e che il codice per scrivere i dati che ci interessano (secondi-minuti-ore-giorno-mese-anno) è il seguente:
void RTC_DS1307::adjust(const DateTime& dt) {
byte i = 0;
Wire.beginTransmission(DS1307_ADDRESS);
Wire.write(i);
Wire.write(bin2bcd(dt.second()));
Wire.write(bin2bcd(dt.minute()));
Wire.write(bin2bcd(dt.hour()));
Wire.write(bin2bcd(0));
Wire.write(bin2bcd(dt.day()));
Wire.write(bin2bcd(dt.month()));
Wire.write(bin2bcd(dt.year() - 2000));
Wire.write(i);
Wire.endTransmission();
}
La scrittura inizia dal byte 0x68 e va avnti per 7 byte, il quarto è il byte del giorno della settimana e qui viene lasciato a zero.
Se programmiamo direttamente il ds1307 tramite la wire invece possiamo fare così:
Wire.beginTransmission(0x68);
Wire.write((byte)0x00);
Wire.write((byte)0x00); //1° byte SECONDI da 0x00 a 0x59
Wire.write((byte)0x00); //2° byte MINUTI da 0x00 a 0x59
Wire.write((byte)0x80 | 0x00); //3° byte ORE da 0x00 a 0x24 (il byte 0x80 non va toccato)
Wire.write((byte)0x00); //4° byte GIORNO della settimana da 0x01 a 0x07
Wire.write((byte)0x00); //5° byte GIORNO del mese da 0x00 a 0x31
Wire.write((byte)0x00); //6° byte MESE da 0x00 a 0x12
Wire.write((byte)0x00); //7° byte ANNO 0x00 a 0x99
Wire.endTransmission();
Questo medoto permette la lettura così:
Wire.requestFrom(0x68, 7);
byte secondi = Wire.read();
byte minuti = Wire.read();
byte ora = Wire.read();
byte giorno_sett = Wire.read();
byte giorno_mese = Wire.read();
byte mese = Wire.read();
byte anno = Wire.read();
Il mio problema è che un dato in decimale come quello dato dalla RTClib è più facilmente gestibile rispetto ad un dato esadecimale ottenuto con la wire, però senza il giorno della settimana non posso andare avanti,
é per questo motivo che chiedevo appunto se era possibile modificare la libreria oppure se eri a conoscenza di una libreria che già facesse questa funzione.
In rete (forum di Arduino) ho trovato una libreria che dovrebbe teoricamente fare queste cose, ma non riesco a farla funzionare, proprio la libreria stessa mi da un errore in fase di compilazione.
Scusami per il post lunghissimo, ma non so come avrei potuto condensare il tutto!
Dimenticavo di dire che il codice che vedi qui è tutto trovato in rete, ovviamente io non ho inventato niente.
Autore
Ciao Stefano,
progetto interessante ed anche il tuo approccio è molto preciso, procedere per gradi è senza dubbio il metodo migliore.
Per la modifica alla classe puoi farla, e se vuoi magari puoi anche condividere la tua modifica su qualche repository ufficiale, se non ne trovi sarò lieto di dedicarci un articolo.
In merito al codice che hai trovato in rete è molto interessante e mi sembra che tu lo abbia ben compreso, lo hai spiegato a me in modo eccelso.
Il tuo unico problema mi sembra sia poter passare un valore giorno da 0 a 7 alla 4° posizione, non hai necessità di cambiare il metodo di lettura o scrittura della classe.
Puoi provare ad analizzare il valore di DateTime per verificare se contenga quel dato, probabilmente no altrimenti lo avrebbero già incluso, ed in alternativa passartelo come ulteriore valore alla adjust in modo da inserirlo nella corretta posizione.
Il valore che puoi inserire è solo di tipo numerico e probabilmente gestito dal DS1307 come un conteggio sequenziale.
Mauro
Ciao Mauro,
Girando in rete ho trovato la soluzione per bypassare il mio problema, in altre parole ho trovato una libreria per il DS1307 molto interessante che fa già tutto quello che mi serve direttamente in decimale ed è semplice da utilizzare, considera che io l’ho scaricata stasera, ho buttato giù un po’ di righe di codice che ho già testato e sono funzionanti, considerando le mie conoscenze software posso considerarlo un bel risultato, anche perché quando ho letto nella tua risposta “modifica alla classe” mi è venuta una bella espressione interrogativa, io non ho grosse basi di programmazione.
Comunque la libreria si chiama DS1307new e c’è il relativo progetto su code.google all’indirizzo http://code.google.com/p/ds1307new/.
Se può interessare come base questo è il codice che ho scritto stasera:
#include //includo la libreria per la comunicazione su bus I2C
#include //aggiungo la libreria RTCnew che mi permette di avere i dati in decimale
int led = 13; //visualizzo la variazione di stato sul canale digitale 13 (con led)
void setup()
{
Serial.begin(9600); //inizializzo la seriale
pinMode (termostato, OUTPUT); // stabilisco che il canale digitale 13 è un'uscita
Wire.begin(); //inizializzo la libreria wire
/*parte commentata da utilizzare solo per rimettere l'orologio, questione da sviluppare*/
//RTC.stopClock();
//RTC.fillByYMD(2013,1,3);
//RTC.fillByHMS(22,58,0);
//RTC.setTime();
//RTC.startClock();
}
/*nuovo loop con libreria DS1307new*/
void loop()
{
RTC.getTime(); //abilito l'acquisizione dei dati
Serial.println(" ");
Serial.println("giorno della settimana");
switch (RTC.dow)
{
case 1:
Serial.print("LUNEDI'");
break;
case 2:
Serial.print("MARTEDI'");
break;
case 3:
Serial.print("MERCOLEDì");
break;
case 4:
Serial.print("GIOVEDI'");
break;
case 5:
Serial.print("VENERDI'");
break;
case 6:
Serial.print("SABATO");
break;
case 7:
Serial.print("DOMENICA");
break;
}
Serial.println(" ");
Serial.println(" ");
Serial.println("GG/MM/AAAA");
Serial.print(RTC.day, DEC);
Serial.print("/");
Serial.print(RTC.month, DEC);
Serial.print("/");
Serial.print(RTC.year, DEC);
Serial.println(" ");
Serial.println(" ");
Serial.println("hh:mm:ss");
Serial.print(RTC.hour, DEC);
Serial.print(":");
Serial.print(RTC.minute, DEC);
Serial.print(":");
Serial.print(RTC.second, DEC);
Serial.println(" ");
delay (1000);
if (RTC.dow == 4 && RTC.hour == 23 && RTC.minute == 40) {
digitalWrite(led, HIGH);
}
}
Come si può vedere l’ultima prova risale alle ore 23 e 40 di giovedì (RTC.dow == 4 indica il giorno della settimana -Day Of Week quindi dow), ma questi valori sono facilmente sostituibili.
Mi dispiace averti fatto perdere del tempo, ma spero che questa mia esperienza possa essere di aiuto per altri in futuro e grazie di nuovo.
Autore
Ciao Stefano,
grazie per il tuo contributo, proprio oggi ho pubblicato un articolo sull’RTC shield ds1307.
Il tuo contributo è prezioso e non si perde mai tempo ad imparare cose nuve.
Mi spiace di averti spaventato con l’idea di modificare la classe, credimi spaventa all’inizio ma non è nulla di impossibile e tu mi hai dimostrato di aver ben chiaro sia cosa volessi sia i pezzi di codice che mi hai postato, anche se trovati in rete.
Proverò la classe che mi hai inviato e magari ci scrivo su un articolo.
Mi farebbe piacere pubblicare il tuo progetto, se vorrai, quando sarà ultimato.
Mauro
Ciao Mauro.
Grazie a te per le belle parole e stai tranquillo che se completo il progetto te lo passerò sicuramente e se ritieni potrai anche pubblicarlo!
Ho letto proprio oggi il tuo articolo sul DS1307 e l’uso dei pulsanti e l’ho trovato molto interessante, io vorrei ovviamente implementare qualcosa del genere, ma come ho detto procedo per gradi.
Grazie di tutto.
Stefano
Un’ultima cosa, nel codice non sono scritte le librerie (non so perché, avrò sbagliato il “copia e incolla”), le prime due righe vanno scritte così:
#include //includo la libreria per la comunicazione su bus I2C
#include //aggiungo la libreria RTC new che mi permette di avere i dati in decimale
Ciao
Buonasera,
sono alle prime armi e non so dove sta il mio problema…
ho seguito la guida da lei scritta e aprendo il monitor seriale vedo tutto tranne scritte leggibili….
leggo questo..
” OözÅ* B’¡ Ýä¦$æî”(J&A©äÂ6ìÁtFSá$Kð6äÆ>#F3á$𦠶zÑ(J’á _ä¦ ¶zÑ(J’á _Û6KäÆ>ëF3á$Kð4äî”<N&Aù¦ æî"(J&A©ù£ûÆj# M:I"á䣫Æj#
: M ¹þ"
che problema potrebbe essere??
Autore
Ciao Simone,
il problema che rilevi è che nello sketch c’è scritto di impostare la comunicazione seriale a 57600, probabilmente il tuo monitor seriale è impostato sui 9600, varia una delle due informazioni o cambi lo sketch o modifichi la velocità ( baud ) sul monitor seriale.
Mauro
buonasera, pure io sono alle prime armi, il mio problema : dopo il montaggio ho scaricato il programma ma il led rimane acceso fisso e dal monitor seriale appare:
RTC is NOT running!
2165/165/165 165:165:85
since midnight 1/1/1970 = 1385768785s = 16038d
now + 7d + 30s: 2013/12/6 23:46:55
2165/165/165 165:165:85
since midnight 1/1/1970 = 1385768785s = 16038d
now + 7d + 30s: 2013/12/6 23:46:55
il modello di arduino che utilizzo è il 2009.ho ponticellato scl-sda, ma i due pin in piu’ VIO come li devo collegare?
grazie.
Autore
Ciao Claudio,
il ponticello abilita l’RTC a comunicare con Arduino sui pin A4 ed A5, sulla 2009 non hai i due pin dopo HREF per cui è corretto.
L’errore che hai sembra dovuto proprio alla comunicazione tra RTC e Arduino, prova ad utilizzare la libreria RTC che trovi sul sito di Futura Elettronica.
Mauro
Buongiorno Mauro, come mi hai consigliato nella mail diretta, ti scrivo nel blog più opportuno (ossia quello RTC) anche se il mio piccolo progettino coinvolge diverse parti. Sono il ragazzo che ti aveva scritto per il pluviometro.
Per non riportare tutto lo sketch metto solo la parte iniziale:
#include
#include
#include
#include
#include “RTClib.h”
RTC_DS1307 RTC;
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192,168,1, 130 };
EthernetServer server(80); //imposta il server a rispondere sulla porta 80
File htmlFile;
float TotPioggia;
void setup(){
Serial.begin(9600);
Serial.println(“Start”);
pinMode(10,OUTPUT); //settando CSETH output si fa in modo che la libreria SD abbia la capacità di attivarsi e disattivarsi automaticamente
digitalWrite(10,HIGH); //disattivo ethernet
//dopo il begin sarà la libreria della sd a preoccuparsi di portare il pin 10 high (disatt ethernet) quando si ha bisogno di accedere alla sd
// e di portarlo low quando ha smesso di leggere/scrivere file in modo da riattivare ethernet
if (!SD.begin(4)) { //inizializzo microSD
Serial.println(“Card failed, or not present”);
return;
}
Serial.println(“Card initialized.”);
Ethernet.begin(mac, ip); //inizializzo chip di rete
server.begin(); //avvio il server
Serial.print(“Server is at “);
Serial.println(Ethernet.localIP());
//attivo interrupt 0 dove arrivano 5V quando il pluvio bascula
attachInterrupt(0, Basculata, FALLING); //LOW CHANGE RISING FALLING
Wire.begin(); //inizializzo libreria per protocollo I2C
RTC.begin(); //inizializzo libreria RTC
RTC.sqw(1); //0 Led off – 1 Freq 1Hz – 2 Freq 4096kHz – 3 Freq 8192kHz – 4 Freq 32768kHz
if (! RTC.isrunning()) {
Serial.println(“RTC is NOT running!”);
RTC.adjust(DateTime(__DATE__, __TIME__)); //imposta RTC con orario del pc
}
}
e la parte della routine di interrupt:
void Basculata(){
noInterrupts();
TotPioggia=TotPioggia+0.2; //conta la pioggia
Serial.println(TotPioggia);
String strTmp = “Pioggia;0.2;mm;cumulato;”;
strTmp = strTmp + “;”;
//scrivo su file
File dataFile = SD.open(“rain.csv”, FILE_WRITE);
if (dataFile) {
dataFile.print(strTmp);
dataFile.close();
}
else {
Serial.println(“errore apertura file”);
}
String strNow;
DateTime now = RTC.now();
strNow=strNow+now.day() + “/”;
strNow=strNow+now.month() + “/”;
strNow=strNow+now.year() + ” “;
strNow=strNow+now.hour() + “:”;
strNow=strNow+now.minute() + “:”;
strNow=strNow+now.second();
Serial.println(strNow);
}
Nella parte del loop c’è la parte di rete. Se un client esegue una richiesta viene restituito il file csv presente nella sd card.
Veniamo al problema: se inserisco la lettura da RTC nel loop va benissimo, ma la stessa lettura messa nella routine di interrupt non funziona. Sembra che non venga nemmeno invocata la routine. Può darsi che sia precluso l’uso di RTC nell’interrupt?
Grazie anticipate per la risposta.
Giordano
Autore
Ciao Giordano,
purtroppo gli sketch si rovinano quando li inserisci nei commenti, é un problema della piattaforma che uso per il Blog.
Premetto questo perché potrei mal interpretare ciò che hai scritto.
Non vedo dove si chiude la setup() e dove sia la loop() ma ad occhio mi sembra che il problema sia l’oggetto RTC che devi passare alla funzione BASCULA come parametro.
Ovviamente tale oggetto deve esistere prima di dichiarare l’interrupt.
Mauro
La funzione Basculata non è una semplice funzione ma è la routine invocata dall’interrupt (vedi riga attachinterrupt), e pertanto non soggetta a passaggio parametri, o sbaglio?
Per capirci meglio ho estrapolato un piccolo programmino dove si nota chiaramente il problema:
//test interrupt
#include
#include “RTClib.h”
float TotPioggia;
RTC_DS1307 RTC;
void setup(){
Serial.begin(9600);
Serial.println(“Inizio”);
Wire.begin();
RTC.begin();
RTC.sqw(1);
if (! RTC.isrunning()) {
Serial.println(“RTC is NOT running!”);
RTC.adjust(DateTime(__DATE__, __TIME__));
}
attachInterrupt(0, funct, FALLING);
}
void loop(){
delay(1000);
//ScriviOra();
}
void funct(){
TotPioggia=TotPioggia+0.2;
Serial.println(TotPioggia);
ScriviOra();
}
void ScriviOra(){
String strNow;
DateTime now = RTC.now();
strNow=strNow+now.day() + “/”;
strNow=strNow+now.month() + “/”;
strNow=strNow+now.year() + ” “;
strNow=strNow+now.hour() + “:”;
strNow=strNow+now.minute() + “:”;
strNow=strNow+now.second();
Serial.println(strNow);
}
La routine ScriviOra provvede a scrivere la dataora nella console di debug.
Se la uso nel Loop (dove vedi che è remmata) funziona bene ma se la metto nella routine dell’interrupt Basculata non viene nemmeno invocato l’interrupt. E’ un mistero che mi stà facendo impazzire.
Lo stò provando su un Arduino Uno Rev3 con sopra una ethernet shield con sopra un RTC shield.
Grazie ancora anticipate per la risposta.
Giordano
Autore
Ciao Giordano,
Ora mi é più chiaro.
Le funzioni di interrupt non possono ricevere parametri ne restituire valori, sono solo funzioni di servizio.
Puoi impostare un valore di una variabile globale nella funzione ma devi utilizzare la loop() per scrivere RTC + valore
Mauro
Buongiorno Mauro, grazie del consiglio. In effetti ho dichiarato una variabile globale nella loop()
ed in quel punto posso usufruire della lettura dell’RTC.
Poi nella routine dell’interrupt uso quella variabile globale. In questo modo funziona.
Speriamo sia di aiuto a tutti sapere che non si interroga RTC shield nel frangente della routine di interrupt!
Mi rimane una domanda sull’utilizzo del mio “castello” di shield…
E’ giusto mettere le 2 righe sotto nel setup():
pinMode(10,OUTPUT);
digitalWrite(10,HIGH); //disattivo ethernet
quando si utilizza la ethernet shield assieme alla sd?
Giordano
Autore
Ciao Giordano,
sono contento che il mio consiglio ti sia stato utile.
La dichiarazione pinMode è corretta nella setup(), l’impostazione digitalWrite non è sbagliata ma limitata alla sola prima eseguzione dello sketch.
Mauro
Buongiorno Gent.Mauro ! Spero vivamente che possa risolvere il mio problema: ossia, ho acquistato una rtc-shield in kit d’assemlaggio, l’ho montata in mezzoretta senza difficolta’, inserita su arduino uno ed al momento del caricamento dello sketch RTC Lib che ho trovato su futuroelettronica, l’ IDE di arduino mi da’ una serie di errori che sinceramente non comprendo.Sono alle prime armi con arduino d’accordo, pero’ ho provato sia la IDE 1.05 che la vecchia 022 ma in tutte e due i casi gli errori dello sketch sono a dir poco numerosi. Riesce in qualche modo a darmi una mano perche’ sono abbastanza avvilito anche perche’ in tutti i miei esperimenti succede spesso che gli sketch non funzionino……Grazie mille !!!! roberto.
ah dimenticavo…. la lista degli errori dell’IDE :
ds1307.pde:4:20: error: RTClib.h: No such file or directory
ds1307:6: error: ‘RTC_DS1307’ does not name a type
ds1307.pde: In function ‘void setup()’:
ds1307:11: error: ‘RTC’ was not declared in this scope
ds1307:16: error: ‘DateTime’ was not declared in this scope
ds1307.pde: In function ‘void loop()’:
ds1307:21: error: ‘DateTime’ was not declared in this scope
ds1307:21: error: expected `;’ before ‘now’
ds1307:23: error: ‘now’ was not declared in this scope
ds1307:43: error: expected `;’ before ‘future’
ds1307:46: error: ‘future’ was not declared in this scope
« Last Edit: Today at 11:12:06 pm by roberto dm »
Autore
Ciao Roberto,
se vuoi realizzare progetti con arduino devi armarti di tanta pazienza ed attenzione ai particolari, perché spesso la soluzione è sotto i tuoi occhi ma per vederla ci impieghi giorni di test.
Te lo dico perché capita anche a me molto più spesso di quando immagini.
Solitamente l’IDE ti dice cosa non va, quando si tratta di errori eclatanti nel codice, e la prima linea è quella che da il via, non sempre, ma spesso.
Nel tuo caso:
RTClib.h: No such file or directory
Vuol dire che non trova la libreria RTClib.h nella posizione in cui la aspetta, prova a verificare come si installa una libreria da includere nel tuo sketch e controlla di averlo fatto con la RTClib.h
Mauro
Salve, vorrei sapere che pin utilizza la shield in questione su arduino rev3.
Autore
Ciao Luca,
se non ricordo male utilizza i due pin SCL ed SDA che nell’Arduino Uno sono presenti dopo il pin AREF.
Tuttavia ricorda che tali pin sono connessi ai pin A4 ed A5, per cui non puoi utilizzare entrambi.
Mauro
salve
vorrei saper se è possibile far accendere , in sequenza 10 led nell’intervallo da un secondo e l’altro, in pratica una strisci luminosa
Grazie
Viviano
Autore
Ciao Viviano,
si è possibile, ti invito a leggere i miei articoli sui giochi di luce a Led pubblicati in occasione delle feste natalizie del 2011.
Mauro
Dove si compra la shield? oppure mi puoi inviare lo schema elettrico?
Autore
Ciao Filippo,
io acquisto il mio materiale da robot-domestici.it e mi trovo bene.
Mauro
Ciao Mauro.
Mi sono avvicinato ad arduino da poco, anche se mastico un poco di elettronica e molto di informatica.
Ho visto questo RTC proprio qui nel tuo sito e quindi ho voluto prenderlo subito per fare un effetto alba tramoto nel mio acqurio.
L’assemblaggio è davvero molto semplice come dici tu.
Mi capita pero questo…
Carico il progetto nell’esempio apro monitor seriale e mi appare solo ed esclusivamente caratteri di questi tipo
3!MIHOBoFÜ¡³K ;ÄBãBK2á©þ&5[»
Intervallati chiaramente dal Delay(3000)…
Dove sbaglio ?
Grazie… Continua così
Autore
Ciao Enrico,
prova ad impostare la stessa impostazione di baudrate tra il monitor seriale e l’istruzione Serial.begin() nello sketch.
Mauro
Scusami se ho disturbato.. Mi sono accorto di non aver impostato la velocità in baud correttamente ora è tutto funzionante. Perdonami.
Enrico
Autore
Ciao Enrico,
ottimo hai risolto da solo e questo è lo spirito giusto.
Mauro
Ottimo sito, grazie,
non riesco a far funzionare l’RTC di futuraelettronica, funziona perfettamente su Arduino UNO R3, ma sul mega R2 non riesco,non capisco bene qual’è il ponticello da eseguire tre opzioni, provate tutte:
1)i pin 4 e 5 del lle piazzole dei ICSP
2)i pin 4 e 5 del connettore a fianco dell’alimentazione, lato destro basso
3)SDA e SCL i due pin del connettrore lato sinistra alto vicino all’integraro
grazie in anicipo
luigi
Autore
Ciao Luigi,
leggendo la documentazione ti accorgerai che SDA ed SCL della Mega non corrispondono ai pin A4 ed A5 come su Arduino UNO R3.
Non ricordo di ponticelli da fare sulla RTC Shield per adattarla all’Arduino MEGA, ti consiglio semplicemente di collegare i pin SDA ed SCL della RTC ai pin corretti sulla Mega.
Se ti occorre lo schema dei pin della MEGA puoi far riferimento al sito ufficiale arduino.
Buonasera Mauro
ho un problema simile a quello segnalato più sopra.
Ho predisposto lo shield con il saldatore, non sono un mago, ma ho controllato per bene tutto, apparentemente non ci sono corti.
Il problema è che ottengo sempre la stringa 2165/165/165 165:165:85 con il led fisso.
Il ponticello JSQW è collegato.
Cosa può causare il malfunzionamento? Ho cercato in internet e non mi sembra ci sia una sola possibilità (batteria, collegamenti, ….)
Grazie mille
Andrea
Autore
Ciao Andrea,
tale problema può capitare quando colleghi ai pin A4 ed A5 altri dispositivi ( led, potenziometri, ecc… )
In alternativa controlla di non aver dichiarato il pin mode per A4 ed A5 e di non usarli con qualche altro comando o libreria.
ciao a tutti scusate io lo montato tutto però non riesco a farlo funzionare. mi indica un errore giallo tipo rtc_ds1307 rtc;
Autore
Ciao Nicola,
senza maggiori dettagli è difficile darti aiuto, apparentemente non hai caricato la libreria RTC.
Ciao Mauro. Innanzitutto volevo farti i miei complimenti per la tua disponibilità, competenza e professionalità e anche pazienza con noi poveri “sperimentatori”. Ne approfitto subito 🙂
Ho seguito passo passo la costruzione di questa shield e del suo relativo sketch, con tanto di librerie ecc ecc. Quando vado a compilare il tutto, la compilazione va in errore con il seguente codice;
Arduino:1.6.3 (Windows 8.1), Scheda:”Arduino Uno”
In file included from C:\Program Files\Arduino\hardware\arduino\avr\cores\arduino/WString.h:29:0,
from C:\Program Files\Arduino\hardware\arduino\avr\cores\arduino/Print.h:26,
from C:\Program Files\Arduino\hardware\arduino\avr\cores\arduino/Stream.h:26,
from C:\Program Files\Arduino\hardware\arduino\avr\libraries\Wire/Wire.h:26,
from C:\Users\Administrator\Documents\Arduino\libraries\RTClib\RTClib.cpp:4:
C:\Users\Administrator\Documents\Arduino\libraries\RTClib\RTClib.cpp:17:31: error: variable ‘daysInMonth’ must be const in order to be put into read-only section by means of ‘__attribute__((progmem))’
static uint8_t daysInMonth [] PROGMEM = { 31,28,31,30,31,30,31,31,30,31,30,31 };
^
Errore durante la compilazione
Puoi aiutarmi? Grazie della tua attenzione.
Saluti
Attilio Romani
Autore
Ciao Attilio,
non sei il primo che mi segnala un problema simile.
Ho il dubbio che l’autore della libreria la abbia modificata eliminando il metodo “daysInMonth” per cui puoi eliminare la linea corrispondente dallo sketch e dovrebbe funzionare tutto alla perfezione.
Ciao Mauro, grazie per la risposta e soprattutto piacere di conoscerti.
Il problema l’ho risolto tornando indietro di versione dell’IDE di Arduino. Ho installato la versione 1.0.5 r2 e ha funzionato senza problema. Proverò anche a commentare la linea che mi dici e riprovare. Ti terrò aggiornato.
Grazie ancora.
Saluti
Attilio Romani
Ciao Mauro.
Approfitto della tua gentilezza e professionalità per esporti un problema sempre con questa scheda. Una volta fatto digerire alla scheda lo sketch di cui sopra, ho pensato di aggiungere un modulo relè a 4 relè per far si che ad una certa ora scatta un relè e poi si spegne ad un altra ora (insomma un brutale timer). Ho collegato gli elementi a pila partendo dal basso con l’arduino, poi sopra il modulo DS1307 e dai pin di quest’ultimo ho fatto partire 3 fili (+5V, Ground e segnale dal pin 8), che ho portato sul modulo relè (modulo Keyes funduino).
Ho caricato il seguente sketch:
[[ codice rimosso in automatico ]]
Ho inserito l’orario di aggancio e quello di sgancio relè, ma una volta caricato su Arduino, il led del DS1307 lampeggia, ma il relè non scatta quando è il momento. Il monitor seriale rimane su ” Simple timer running”. Qualche suggerimento?
Grazie ancora
Autore
Ciao Attilio,
come hai letto in fondo ad ogni articolo ci sono l regole del blog da rispettare, tra queste c’è scritto che non è consentito incollare sketch nei commenti.
Su come attivare dei relay ad arduino ed attivarli a timer trovi degli articoli dettagliati, prova a verificarli e capire le differenze con il tuo.
Salve Mauro, vorrei porLe un quesito:
Io ho copiaincollato il suo codice per prova.
Da quanto ho capito le istruzioni
RTC.adjust(DateTime(__DATE__, __TIME__));
dovrebbero sincronizzare l’ora dell’RTC con quella del PC.
Una volta avviato il serial monitor però mi trovo valori tipo
2000/1/1 0:14:47
Mi saprebbe dire in cosa sbaglio?
Grazie
Autore
Ciao Gianni,
quelle istruzioni sono subordinate ad un “if” che verifica che sul DS1307 non ci sia impostata già un’ora, serve per evitare che ad ogni reset dell’arduino l’ora ritorni a quella di upload dello sketch.
Nel tuo caso l’RTC possiede già un’ora ed il controllo impedisce alla linea RTC.adjust( .. ) di essere invocata.
Puoi scrivere uno sketch in cui lasci la linea libera dalla condizione di if, in modo che funzioni la sincronizzazione, e poi rimetti lo sketch di questo articolo.
ciao Mauro,
sto usando questa stessa shield; la mia idea era far stampare anche su lcd i valori letti.
Eppure pare che il collegamento I2C dell’lcd e il lettore SD non siano compatibili. Potresti aiutarmi?
Autore
Ciao Gianni,
non so che display tu stia utilizzando, di certo posso dirti che la scrittura su SD, non presente in questa scheda, avviene su SPI e non su I2C per cui a meno che la tua shield non converta la SPI in I2C non dovresti incontrare questo tipo di conflitto.
Ciao Mauro;
non riesco a fare funzionare il RTC di futura che lampeggiava da quando ho realizzato il circuito
uso la libreria modificata uso l’ide 1.0.6 ho provato anche l’ultima versione ma niente
volevo fare con ” LCD keypad shield ” un orologio non trovo niente di funzionante in rete quindi partivo dalla base per far lampeggiare il led ma mi da questo errore
in rosso la prima riga poi le altre, grazie anticipatamente Lorenzo
‘class RTC_DS1307′ has no member named’sqw’
ds1307.pde: In function ‘void setup()’:
ds1307:12: error: ‘class RTC_DS1307’ has no member named ‘sqw’
Autore
Ciao Lorenzo,
nei commenti ho risposto a questo tipo di errore più volte, sii tratta di una modifica eseguita sulla libreria che non supporta più il metodo sqw, ti è sufficente commentare la linea 12 relativa alla chiamata sqw.
Ciao, ho comprato di recente il modulo, ma non riesco a trovare la libreria di futura elettronica, in quanto semra essere stata cancellata dal loro sito. Tutti i tutorial su questa scheda usano quella libreria, però io ho provato a usare la libreria RTClib che esce cercando rtc sul library manager di arduino.
Compila togliendo la chiamata a RTC.sqw. Tuttavia ottengo solo :
”
RTC is NOT running!
2165/165/165 165:165:85
since midnight 1/1/1970 = 1385768785s = 16038d
now + 7d + 30s: 2013/12/6 23:46:55
2165/165/165 165:165:85
since midnight 1/1/1970 = 1385768785s = 16038d
now + 7d + 30s: 2013/12/6 23:46:55
”
Credi dipenda dalla libreria o da altro?
Ciao
inoltre ho questo problema sul tuo sito: il tasto invia commento è sovrapposto al pulsante del recaptcha!
Ho dovuto giocare con html per mandare il messaggio!
Autore
Grazie per la segnalazione, ho aggiornato questa mattina il plugin.
Autore
Ciao Nic,
la libreria puoi usare quella presente nell’IDE 1.6.9 di arduino.
In merito all’errore e ciò che vedi sul monitor seriale io penso che tu possa aver sbagliato il collegamento o utilizzato i pin A4 ed A5 anche per altre funzioni e non solo per l’RTC, controlla che siano connessi al solo componente RTC.
Salve Mauro, se sostituissi il ds1307 con un ds1337, quali modifiche hardware e software dovrei apportare?
Autore
Ciao Vittorio,
non conoscevo l’esistenza di un RTC DS1337, probabilmente dovrai cambiare la libreria perché non penso siano compatibili.
Buongiorno
Prima di tutto grazie per l’ aiuto con i tuoi articoli
Ho realizzato l’RTC ed il relativo orologio con regolazione SET + – un po’ di tempo addietro
Adesso purtroppo, forse per le nuove edizioni dell’IDE di Arduino, la libreria RTCLib per il DS1307 da errore di compilazione
=================================================================
C:\Users\Administrator\Documents\Arduino\libraries\RTClib\RTClib.cpp:17:31: error: variable ‘daysInMonth’ must be const in order to be put into read-only section by means of ‘__attribute__((progmem))’
static uint8_t daysInMonth [] PROGMEM = { 31,28,31,30,31,30,31,31,30,31,30,31 };
^
Errore durante la compilazione
=================================================================
Ho provato a caricare nuove librerie simili (es Adafruit) ma la parte di regolazione non funziona più e l’istruzione per l’l’uscita SQW da errore
Il problema persiste anche con la libreria scaricata da ElettronicaIn
Grazie ancora e buon lavoro
Autore
Ciao Feliciano,
è un po’ che non realizzo progetti con l’RTC per cui non sono aggiornatissimo sulle evoluzioni delle librerie.
Come suggerimento generale ti consiglio di leggere la documentazione della libreria che hai individuato ( scegline una ben documentata ) e valuta quali parti dello sketch debbano essere modificate per adattarsi alla nuova libreria.
L’errore relativo al metodo SQW è probabilmente dovuto al fatto che quel metodo nella libreria scelta non esiste, valuta se è per te importante o puoi ometterlo.
L’errore sulla daysInMonth sembra più legato al tipo di micro controllore su cui vuoi caricare il progetto, lo hai cambiato ?
[…] tempo fa ti ho parlato della shield RTC Arduino basata sul DS1307 della Dallas in grado di scandire il tempo nei tuoi progetti con pochi […]
[…] commenti dell’articolo Tutorial rtc shield con ds1307 stesso puoi leggere alcune delle richieste di […]
[…] livello con arduino. Tutto ha avuto inizio quando Stefano commentando l’articolo sull’RTC mi ha chiesto una mano per il suo progetto a cui ho risposto ( leggi risposte nei commenti […]
[…] linee 27-34: inizializza l’oggetto Wire ed RTC, imposta a 1 secondo la frequenza di lampeggio del led SQW presente sulla RTC Shield e in caso di orario non configurato imposta l’ora corrente del Pc sull’RTC, per la procedura leggi l’articolo Tutorial: RTC Shield con DS1307; […]