Lezione 9: Come associare un modulo RTC ad Arduino
Per chi ha avuto modo di usare Arduino, si sarà accorto che non è presente un modulo RTC all’interno della scheda. Questo significa che Arduino non è in grado “da solo” si sapere l’ora attuale; l’unica operazione che è in grado di fare è quello di contare i millisecondi che sono passati dall’accensione del dispositivo, ma non niente di più.
Come fare per poter utilizzare l’ora, nei nostri progetti con il dispositivo ?
A questa domanda ci sono ben 3 soluzioni:
- Utilizzare delle librerie “speciali” di Arduino, che permettono di sfruttare la funzione di calcolo dei millisecondi presenti nel microcontrollore
- Utilizzare un modulo separato RTC, in grado di essere supportato da Arduino
- Sfruttare il web, con i relativi server NTC, per ricevere l’ora attuale
In questo post vedremo le prime due soluzioni, mentre la terza verrà mostrata, quando introdurremo le schield per connettere Arduino al web.
1° Metodo: Librerie software per Arduino
Per il donwload della libreria, occorre andare al seguente link https://github.com/leomil72/swRTC
/* This file is part of swRTC library. Please check the README file and the notes inside the swRTC.h file to get more info This example will print the time every second to the computer through the serial port using the format HH:MM or HH:MM:SS Written by Leonardo Miliani <leonardo AT leonardomiliani DOT com> This library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3.0 of the License, or (at your option) any later version. */ #include <swRTC.h> swRTC rtc; //create a new istance of the lib const byte WITHOUT_SECONDS = 0; const byte WITH_SECONDS = 1; void setup() { rtc.stopRTC(); //stop the RTC rtc.setTime(12,0,0); //set the time here rtc.setDate(4,6,2012); //set the date here rtc.startRTC(); //start the RTC Serial.begin(19200); //choose the serial speed here delay(2000); //delay to let the user opens the serial monitor } void loop() { printTime(WITHOUT_SECONDS); printTime(WITH_SECONDS); Serial.println(""); delay(1000); } void printTime(byte withSeconds) { sendNumber(rtc.getHours()); Serial.print(":"); sendNumber(rtc.getMinutes()); if (withSeconds) { Serial.print(":"); sendNumber(rtc.getSeconds()); } Serial.println(""); } void sendNumber(byte number) { byte temp; if (number>9) { temp=int(number/10); Serial.print(char(temp+48)); number-=(temp*10); } else { Serial.print("0"); } Serial.print(char(number+48)); }
Come si può notare dal codice del programma, all’interno della funzione void setup(), è possibile impostare la data attuale, in modo che Arduino si in grado di calcolarsela, sfruttando il contatore presente nel dispositivo. Ovviamente, qualora Arduino venisse spento, durante la fase di riavvio, verrebbe ricaricato il programma presente in memoria, con l’ora che non è più aggiornata, quindi occorre prestare attenzione per questa soluzione.
2° Metodo : Utilizzare un RTC hardware esterno
Per questa seconda soluzione è necessario utilizzare un dispositivo esterno Arduino. Sul web se ne trovano tanti disponibili. Per questo programma ho scelto il DS1302.
Ecco la documentazione del dispositivo:
Ecco il codice per utilizzare questo modulo RTC con Arduino:
/* Questo programma permette di utilizzare il modulo RTC DS1302 con Arduino, in modo da poter utilizzare le funzionalità dell'ora e data nei vari progetti */ // Vengono definiti i PIN a cui è connesso il modulo #define SCK_PIN 4 #define IO_PIN 3 #define RST_PIN 2 #include <DS1302.h> // Viene inizializzata la libreria DS1302 rtc(RST_PIN, IO_PIN, SCK_PIN); void setup() { rtc.halt(false); // Viene disattiva la protezione alla scrittura rtc.writeProtect(false); Serial.begin(9600); } /* Main program */ void loop() { /* Qui è necesario impostare l'ora e la data. Durante la fase di impostazione occorre togleire via i commenti laterali e compilare una prima volta. Successivamente occorre commentare le tre righe di codice e compilare. In questo modo qualora Arduino dovesse riavviarsi, non verrano impostati i dati precedenti (sbagliati) */ // rtc.setDOW(TUESDAY); //rtc.setTime(12,03,0); //rtc.setDate(21, 01, 2014); /* Read the time and date once every second */ while(1) { Serial.print("It is "); Serial.print(rtc.getDOWStr()); Serial.print(" "); Serial.print(rtc.getDateStr()); Serial.print(" "); Serial.print("and the time is: "); Serial.println(rtc.getTimeStr()); delay (1000); } }
Per un corretto funzionamento del programma, è necessario leggere quanto spiegato tra i commenti. Riassumendo occorre impostare una volta i dati relativi all’ora e alla data, compilare. Dopo aver fato ciò, occorre commentare le righe di codice che permettono di impostare i dati e compilare ancora. In questo modo, un eventuale riavvio di Arduino, non farà impostare i dati sbagliati !
Ed ecco il risultato finale:
Come sempre i codici dei programmi riportati in questo post sono scaricabili dal seguente link.
Salve,
ho utilizzato il suo codice per iniziare a utilizzare il DS1302 ma quando provo a compilare mi da errore e mi dice che setDOW, setTime, rtc.setDate, getDOWStr, getDateStr, getTimeStr non sono membri della classe DS1302.
Come posso risolvere?
Saluti e grazie Mattia
Sembrerebbe un problema di conflitti di librerie di Arduino.
Salve,
ho utilizzato il suo codice per iniziare a utilizzare il DS1302 ma quando provo a compilare mi da errore e mi dice che setDOW, setTime, rtc.setDate, getDOWStr, getDateStr, getTimeStr non sono membri della classe DS1302.
Come posso risolvere?
Saluti e grazie Mattia
Dove trovo la libreria ds1302 che usi nel tuo sketch ? Grazie !
In questo https://github.com/msparks/arduino-ds1302
Salve,
in una riga mi da la giusta data/ora in un’altra una data/ora diversa.
Perchè???
Quale programmi utilizzi?