Archivi tag: Real Time Clock

Utilizzare un orologio RTC con Arduino – Modulo Tiny RTC I2C

Scrivo questo post come base di partenza per le sperimentazioni che farò svolgere ai miei studenti nei prossimi giorni sull’uso degli RTC. L’acronimo RTC si riferisce a Real Time Clock, un orologio in tempo reale. Un RTC ed è alla base di moltissime automazioni in cui è indispensabile gestire una serie di processi in funzione di una specifica data e ora, si pensi ad esempio alla semplice gestione dell’illuminazione di un locale oppure alla realizzazione di un data logging o ancora la gestione del condizionamento automatico di un locale in funzione della data e dell’ora.
Ricordo ai miei studenti che nella sessione ordinaria del 2018 dell’esame di maturità per l’indirizzo elettronica ed elettrotecnica, articolazione di automazione, si faceva riferimento ad un sito archeologico in cui erano presenti due locali affrescati in cui era necessario controllare il numero massimo di persone presenti, gestire la temperatura in maniera diversa nel periodo invernale ed estivo ed inoltre doveva essere controllata anche l’umidità relativa.
Erano presenti inoltre domande in riferimento all’illuminazione massima all’interno dei locali ed altri quesiti a cui darete risposta durante le esercitazioni di laboratorio nelle prossime settimane.

Cito parte del testo dell’esame di maturità:


a) la temperatura deve essere mantenuta tra i 6°C e i 12°C nel periodo invernale e tra i 20°C e i 24°C nel periodo estivo; quando la temperatura scende al di sotto dei valori minimi si attivano delle piccole piastre riscaldanti, poste a 1 metro dal pavimento, fino al raggiungimento della temperatura media, mentre se la temperatura è troppo elevata si attiva il sistema di aerazione che al raggiungimento della temperatura media si disattiva;

b) l’umidità relativa deve essere mantenuta nel range 45% ±5% per evitare la proliferazione di muffe; tale livello viene garantito azionando per 10 minuti, se si è fuori dal range, gli aeratori o il sistema di nebulizzazione a pompa posto a muro.

L’obiettivo di questo post è quello di mostrare come gestire un RTC.

Il modulo utilizzato è un Tiny RTC I2C dotato di un integrato DS1307 I2C RTC di cui allego datasheet. Sulla scheda è presente una batteria tampone ricaricabile al litio LIR2032 che permette il funzionamento dell’RTC in assenza di alimentazione esterna, ovvero il mantenimento dell’ora e della data anche quando viene disconnesso dal microcontrollore che lo utilizza.

Il pilotaggio dell’RTC avviene mediante il protocollo I2C, che come già spiegato in precedenti lezioni, permette la comunicazione tra due o più dispositivi I2C utilizzando un bus a due fili più un terzo filo per il riferimento di massa comune a tutti i dispositivi.
Poiché il protocollo I2C utilizza 7 bit per indirizzare il dispositivo sul bus, il numero massimo di dispositivi collegabili sul bus è di 128 dispositivi, però il numero scende a 112 in quanto 16 indirizzi sono riservati.
Il bus è costituito da una linea dati SDA (Serial Data line), una line di clock SCL (Serial Clock line) e come detto sopra al filo di massa comune a tutti i dispositivi.

Per collegare il Tiny RTC I2C si faccia riferimento allo schema che segue:

Per poter pilotare il DS1307 è necessario installare una libreria specifica, ne esistono diverse quella che utilizzeremo sarà quella di Adafruit la RTClib. Installate la libreria: Sketch > Include Library > Manage Libraries

Si aprirà il gestore librerie, nel campo di ricerca inserite il testo RTClib come indicato nell’immagine che segue e procedere con l’installazione dell’ultima versione disponibile:

Al termine dell’installazione apparirà la voce INSTALLED a fianco della libreria installata

Con la libreria vengono resi disponibili una serie di sketch di esempio che potete aprire direttamente da: File > Examples > RTClib.

Aprite lo schetch: DS1307 di seguito indicato:

// Date and time functions using a DS1307 RTC connected via I2C and Wire lib
#include "RTClib.h"

RTC_DS1307 rtc;

char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

void setup () {
  while (!Serial); // for Leonardo/Micro/Zero

  Serial.begin(57600);
  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }

  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(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
  }
}

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(daysOfTheWeek[now.dayOfTheWeek()]);
    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, 12 hours, 30 minutes, and 6 seconds into the future
    DateTime future (now + TimeSpan(7,12,30,6));

    Serial.print(" now + 7d + 12h + 30m + 6s: ");
    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);
}

Nello sketch sono presenti due righe fondamentali, che risultano commentate e che secondo necessità possiamo decommentare ed utilizzare.

Se desideriamo che l’ora e la data venga impostata non appena viene caricato sulla scheda lo sketch bisogna decommentare la riga:

rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));

che permette di leggere la data e l’ora corrente in cui sono presenti le costanti predefinite all’interno dell’IDE Arduino: DATE e TIME, che si riferiscono alla data e all’ora di compilazione dello sketch, quindi non appena compilate vengono impostate e passate all’orologio che assume queste come data e ora corrente.

Nel caso si desidera impostare manualmente l’ora e la data bisognerà decommentare la riga:

rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));

inserendo data e ora corrente, ad esempio facendo riferimento alla data 08/01/2020 ore 01:37 dovrete scrivere:

rtc.adjust(DateTime(2020, 1, 8, 1, 37, 0));

La parte restante del codice si occupa di stampare sulla Serial Monitor data e ora corrente. Nel codice è presente una parte in cui viene stampato una data futura ed il numero di secondi trascorsi da una specifica data.

Ricordate che, come specificato nella setup() la seriale è impostata con una velocità di 57600 caratteri al secondo e quindi nella finestra della Serial Monitor dovrete impostare questa velocità per visualizzare il testo:

Questo il risultato:

Per i miei studenti:

Esercizio 1

Convertire nel formato italiano data e ora ottenendo un output come quello indicato nell’immagine che segue:

Esercizio 2

Realizzare uno sketch che permette l’accensione di un led connesso al pin 3 ogni minuto nell’intervallo da 0 a 15 secondi, spento nei restanti secondi all’interno del minuto. Visualizzare sulla Serial Monitor l’ora corrente.

Esercizio 3

Fare in modo che il led dal 50° al 59° secondo incominci a lampeggiare velocemente e nell’intervallo da 0 a 15 secondi sia acceso.

Esercizio 4

Stesse specifiche dell’esercizio 4 però facendo aumentare progressivamente la frequenza di lampeggio del LED all’approssimarsi del 59° secondo.

Buon lavoro 🙂