«

»

ago 08

Tutorial: RTC Shield con DS1307

Per realizzare la centralina del tuo impianto di irrigazione, vedi articolo sulla prima parte, ti serve conoscere l’ora.

RTC shield

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

RTC Shield

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:

RTC shield resistenze

quindi salda il condensatore ceramico, l’unico denominato C1, l’atro è un condensatore elettrolitico ed è più alto:

RTC shield condensatore C1

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:

RTC shield quarzo Q1

ora puoi montare lo zoccolo che ospiterà il processore:

RTC shield zoccolo processore

ed a seguire il condensatore elettrolitico ed il led, facendo attenzione alla polarità di entrambi:

RTC shield condensatore C2 e led

posiziona e salda il portabatteria per la CR2032, contenuta nella confezione:

RTC shield portabatteria CR2032

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:

RTC shield jumper JSQW

infine salda i connettori per inserire la shield su Arduino:

RTC shield pin per 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:

RTC in modalità not running

Puoi a questo punto ricompilare lo sketch decommentando questa linea ed imposterai la data ed ora corrente sull’RTC:

RTC in modalità Time set

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

Important!


Gentilmente NON incollare sketch nei commenti, usa la casella info del blog che trovi nella pagina contatti.ù

Ti è stato utile questo articolo?
Sostienimi cliccando sugli sponsor, io potrò continuare ad acquistare materiale per scrivere articoli e aiutarti nei tuoi progetti.

Basta un solo click al giorno.

Be Sociable, Share!

Related posts

26 comments

4 pings

  1. leonardo

    Bello! quanto l’hai pagato? quanto ci hai messo a saldarlo?

    1. Mauro Alfieri

      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

      1. gianvito

        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?

        1. Mauro Alfieri

          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

  2. idris

    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.

    1. Mauro Alfieri

      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

      1. Fil

        Non hai detto come salvare i nuovi dati sull’rtc.
        Come si convertono secondi, minuti, ore, giorni, mesi ed anni in una variabile DateTime?

        1. Mauro Alfieri

          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

  3. Stefano Sforzi

    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?

    1. Mauro Alfieri

      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

  4. Stefano Sforzi

    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 0×68 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.

    1. Mauro Alfieri

      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

      1. Stefano Sforzi

        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.

        1. Mauro Alfieri

          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

          1. Stefano Sforzi

            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

          2. Stefano Sforzi

            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

  5. Simone

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

    1. Mauro Alfieri

      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

  6. claudio

    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.

    1. Mauro Alfieri

      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

  7. Giordano

    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

    1. Mauro Alfieri

      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

      1. Giordano

        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

        1. Mauro Alfieri

          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

          1. Giordano

            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

          2. Mauro Alfieri

            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

  1. RTC Arduino: usa arduino come orologio - Mauro Alfieri Elettronica

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

  2. RTC shield DS1307: impostare data e ora - Mauro Alfieri Elettronica

    [...] commenti dell’articolo Tutorial rtc shield con ds1307 stesso puoi leggere alcune delle richieste di [...]

  3. Termostato e sensore di livello con Arduino Mauro Alfieri Elettronica

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

  4. Data logging con Arduino - Mauro Alfieri Elettronica

    [...] 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; [...]

Lascia un Commento

L'indirizzo email non verrà pubblicato. I campi obbligatori sono contrassegnati *

Puoi usare i seguenti tag HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>