Arduino · 27 novembre 2011 31

swRTC, un Orologio in Tempo Reale via software

In questo articolo vi illustro swRTC, una implementazione software, basata sui timer, di un Orologio in Tempo Reale (Real-Time Clock, o RTC) per le schede Arduino e diversi microcontrollori Atmel.

La libreria al momento supporta i seguenti microcontrollori Atmel:

  • Atmega640/1280/1281/2560/2561 e le schede Arduino MEGA
  • Atmega48/88/168/328 e le schede Arduino 2009/UNO
  • Attiny24/44/84
  • Attiny25/45/85
  • Attiny2313/4313
  • Atmega644/1284 e le schede Sanguino
Le frequenze di clock supportate sono 1/4/8/16 MHz.
Requisiti
  • la libreria swRTC usa l’IDE di Arduino versione 0022 per lavorare con gli Atmega48/88/168/328/328 (con o senza il core “P”, PicoPower), con gli Atmega640/1280/1281/2560/2561 e con gli Atmega8/8A;
  • per lavorare con gli Attiny24/44/84, gli Attiny25/45/85 e gli Attiny2313/4313 bisogna installare il core Tiny che può essere scaricato da http://code.google.com/p/arduino-tiny/
  • per lavorare con gli Atmega644/1284 e le schede Sanguino è necessario il core Sanguino che può essere scaricato da http://sanguino.cc/useit

Le istruzioni per installare ed utilizzare i core Tiny e Sanguino sono fornite dai loro rispettivi autori.

Installazione
  1. scompattare l’archivio e copiare la cartella swRTC all’interno della cartella /libraries contenuta nella propria cartella degli sketch. Se tale cartella non esiste, bisogna crearla.
    Per conoscere dove risiede la propria cartella degli sketch, bisogna aprire l’IDE di Arduino, selezionare la voce del menu “File/Preferences” e controllare il percorso alla voce “Sketchbook location”.
    Alla fine del processo dovrebbe risultare un percorso simile al seguente (da un’installazione su Linux):
    /home/username/sketchbook/libraries/swRTC
  2. Dopo ciò bisogna sostituire un file del core Tiny. Consiglio di farsene una copia di backup in caso si volesse ripristinare la versione originale dello stesso.
    Per fare questo cercate il file denominato core_build_options.h che è contenuto nella cartella percorso-alla-vostra-IDE-di-Arduino/hardware/tiny/cores/tiny/ e cambiate il nome del file in core_build_options.bck (o in qualcosa che vi piace di più).
  3. Adesso copiate il file core_build_options.h che è contenuto nella libreria swRTC al posto del precedente.

Grazie a questi passi potrete avere sia la libreria swRTC che le funzioni temporali di Arduino delay/millis funzionanti sui microcontrollori Attiny.

Utilizzo e metodi

Prima di tutto bisogna includere la libreria nel proprio sketch con:

#include

Fatto ciò, per usarla bisogna creare un’istanza della libreria, ad esempio così:

swRTC rtc;

Adesso bisogna impostare l’RTC con dei valori validi di orario e data. Questo può essere fatto sia via software sia direttamente dall’utente tramite un’interfaccia (ad esempio un display LCD) usando i seguenti metodi:

rtc.setTime(hours, minutes, seconds);
rtc.setDate(day, month, year);

Suggerisco di fermare sempre il swRTC prima di cambiare la data/ora:

rtc.stopRTC();

e poi di riattivarlo quando le impostazioni sono state fatte:

rtc.startRTC();

Il metodo startRTC() imposta anche il timer HW in base alla frequenza di clock dell’Arduino o del microcontrollore, sincronizzando il prescale del timer per ottenre le giuste temporizzazioni.

Per ottenere la data o l’ora si usano i seguenti metodi:

rtc.getSeconds();
rtc.getMinutes();
rtc.getHours();
rtc.getDay();
rtc.getMonth();
rtc.getYear();

Quasi tutti restituiscono un valore di tipo byte, ad eccezione di rtc.getYear() che restituisce una variabile di tipo signed integer.

Se si vuole controllare se un dato anno è bisestile, basta chiamare il seguente metodo:

rtc.isLeapYear([year])

per avere un valore booleano che è vero nel caso l’anno sia bisestile. L’argomento “year” è facoltativo: se non si fornisce, la libreria controlla l’anno attuale.

La libreria supporta anche i timestamp.

rtc.getTimeStamp([epoch]);
rtc.setClockWithTimestamp(timestamp[, epoch]);
rtc.weekDay(timestamp);
rtc.getWeekDay();

La prima funzione restituisce il numero di secondi dall’inizio di una particolare epoca (1900 o 1970). Di default essa restituisce il numero di secondi dal 1970.0, o 01/01/1970, l’era UNIX, ma può essere usata anche l’epoca 1900.0, o 01/01/1900. La seconda imposta l’orologio interno con un timestamp (ad esempio il timestamp fornito da un server NTP). Se specificata, sarà usata epoch come epoca di riferimento. La terza e la quarta funzione restituiscono un numero che indica il giorno della settimana di uno specifico timestamp o del giorno corrente, con valore da 0 per la domenica fino a 6 per il sabato.

Ci sono ancora 2 metodi che sono utilizzati per correggere la differenza tra il tempo segnato dall’orologio interno e quello reale.

rtc.setDeltaT(value);
rtc.getDeltaT();

Il primo è un metodo molto importante. Introdotto a partire dalla versione 0.8 vi è il concetto di correzione temporale rappresentato dal parametro interno deltaT, un valore che corregge la deviazione tra il tempo calcolato ed il tempo reale, ossia lo scostamento tra il tempo calcolato dalla libreria ed il tempo effettivamente trascorso. Questo metodo è stato introdotto per correggere gli scostamenti che possono essere introdotti nel computo del tempo sia a livello software (ad esempio altre librerie che utilizzano gli interrupt, come la NewSoftSerial) sia a livello hardware. Ad esempio, bisogna considerare che i risonatori esterni (come nel caso di quello presente sulle nuove schede Arduino UNO) o gli oscillatori interni non sono molto precisi, con variazioni anche di +/- 10% rispetto alla frequenza nominale.

Valori accettati dal metodo setDeltaT variano da -8.400 a +8.400, che corrispondono ad una correzione massima di -14.0/+14.0 minuti/giorno. Il deltaT è il numero di decimi di secondo al giorno da applicare al computo interno per correggere la deviazione dal tempo reale. Se l’RTC è in anticipo rispetto all’ora reale, provate ad aggiustare il swRTC con valori positivi, se il swRTC è più lento provate a correggerlo con valori negativi.Es.: 102 significa una correzione di 10200 millisecondi/giorno, ossia 10.2 secondi/giorno.

Invece, getDeltaT() restituisce il valore corrente della correzione temporale.

IMPORTANTE:l’utilizzo della correzione in virgola mobile è ora DEPRECATO. I vecchi codici che usavano questo formato sono ancora compatibili con la swRTC (il metodo accetta un valore che indica il numero di secondi da aggiungere/sottrarre con una 1 singola cifra decimale, nell’intervallo -840,0..+840,0) ma ciò non significa che lo saranno anche in futuro per cui si raccomanda di aggiornare il codice ed iniziare ad utilizzare la nuova sintassi basata sugli interi.

Dalla versione 1.2.0 la libreria supporta l’uso del Real-Time Counter (RTC) presente su diverse MCU. Questo modulo permette di utilizzare il timer 2 in modalità asincrona con un quarzo esterno da 32.768 Hz. Impostando il timer con un prescaler a 128, si ha esattamente 1 overflow ogni secondo per cui è possibile incrementare l’orologio software in maniera più accurata. Al momento, l’uso del deltaT non è supportato in combinazione con l’uso del modulo RTC.

Per usare il modulo RTC (presente solo negli Atmega88/168/328, Atmega8, Atmega344/644/1284 e Atmega1280/256x), basta ggiungere la seguente #define prima dell’inclusione della libreria

#define USE_INTERNAL_RTC
#include “swRTC.h”

Il modulo Real-Time Counter può essere usato solo in abbinamento con l’oscillatore interno perché il quarzo esterno da 32.768 Hz deve essere connesso agli stessi pin usati per i normali quarzi (non dimenticatevi i condensatori ceramici da 18/22 pF).

La libreria è stata modificata e il file .cpp rimosso perché il suo contenuto è stato integrato nel file header. Questo non modifica l’uso della libreria stessa.

Frequenze/microcontrollori supportati e limitazioni

La libreria introduce un contatore temporale pilotato tramite interrupt ed usa un timer ad 8 bit interno al microcontrollore. Questa è l’elenco completo dei microcontrollori supportati:

  • ATMEL Atmegax0: Atmega640/1280/1281/2560/2561
    La libreria supporta i microcontrollori Atmega640/1280/1281/2560/2561; gli Atmega1280/2560 sono i chip installati sulle schede Arduino MEGA/MEGA2560. Su questi micro viene usato il timer 2.
  • ATMEL Atmegax8: Atmega48/88/168/328/328 e le loro varianti /P (core PicoPower) (ciò non significa che lo specifico micro sia anche supportato dall’IDE di Arduino e/o da avrdude)
    La libreria supporta i microcontrollori Atmega48/88/168/328 anche nelle varianti /P ed usa il timer 2. Non ci sono limitazioni sull’Arduino perché le funzioni temporali quali delay() o millis() usano l’INT0/timer 0 ma prestate attenzione al fatto che non potete utilizzare la funzione PWM dei pin 3 ed 11 dato che essa è gestita su quei pin proprio dal timer 2, che è usato appunto dalla libreria swRTC.
  • ATMEL Atmega8/8A
    Questo è il micro usato sugli Arduino molto vecchi: ad esempio, si trova sull’ArduinoNG. Anche con questo micro viene usato il timer 2.
  • ATMEL Attinyx5: Attiny25/45/85
    Su questa famiglia di microcontrollori la libreria utilizza l’INT0/Timer 0. Le funzioni delay() e millis() del core Tiny usano su questi micro l’INT1/Timer 1 per cui la swRTC usa l’INT0/Timer 0 senza conflitti.
  • ATMEL Attinyx4: Attiny24/44/84
    La libreria usa l’INT0/Timer 0 perché su questi micro il timer 1 è a 16 bit: le librerie temporali vengono perciò spostate sul timer 1. Ciò è possibile grazie al file modificato core_build_options.h che abbiamo installato nel core Tiny.
  • ATMEL Attiny2313/4313
    Stesso discorso relativo agli Attiny24/44/84: le funzioni delay() e millis() sono stato spostate sul timer 1 per poter usare il timer 0 ad 8 bit.
  • ATMEL Atmega644/1284 e loro varianti /P
    Su questi micro la libreria usa il timer 2.
IMPORTANTE: attualmente la libreria supporta solo frequenze di 1/4/8/16 MHz a causa di problemi di arrotondamento che escono fuori usando altre frequenze, arrotondamenti che non permettono un calcolo preciso all’intero del valore iniziale del timer.

Come funziona

La libreria imposta il timer interno in modalità contatore con overflow così da avere esattamente 1 overflow ogni millisecondo. Ogni 1000 millisecondi essa incrementa i registri interni a partire da quello dei secondi fino ad arrivare a quello degli anni, per tenere il conto dello scorrere del tempo.

Per fare ciò, la libreria calcola il corretto valore di partenza del contatore e del prescaler del timer, a seconda della frequenza di clock. Essa sceglie anche il corretto timer interno dato che questo sistema funziona solo sui timer ad 8 bit.

Il deltaT introduce un anticipo o un ritardo sull’avanzamento del registro dei secondi così da avere 1 secondo “software” più o meno lungo rispetto ad 1 secondo reale.

Aggiornamenti:

  • 1.0: prima versione stabile della libreria
  • 1.0.1: aggiornamento per cambio di licenza, adesso il software è distribuito sotto GNU GPL3 o successive
  • 1.0.2: corretto un bug nella funzione getTimestamp
  • 1.0.3: aggiunto il supporto ai 4 MHz
  • 1.0.5: introdotto il nuovo metodo getWeekDay
  • 1.0.6: corretto un bug nella funzione usata per impostare l’orologio dato un timestamp
  • 1.1.0: nuova sintassi per setDeltaT – nuovo metodo getDeltaT
  • 1.1.1: sistemato un bug in setDeltaT
  • 1.1.2: getDelta restituisce il valore di deltaT con il giusto segno
  • 1.2.0: la libreria supporta il modulo Real-Time Counter presente su diverse MCU Atmel
  • 1.2.1: aggiustamenti minori
  • 1.2.2: sistemato un bug per cui negli anni bisestili la funzione getWeekDay restituiva un giorno sbagliato fino al 29/02
  • 1.2.3: sistemato il tipo del prototipo della funzione setClockWithTimestamp
  • 1.2.4: aggiornamento per l’uso con l’IDE di Arduino >= 1.6.7

Licenza

La libreria è “software libero” (free software); puoi ridistribuirla e/o modificarla sotto i termini della GNU General Public License come pubblicata dalla Free Software Foundation, o la versione 2.1 della Licenza o (a tua scelta) una qualunque versione più recente.
La libreria è distribuita nella speranza che sia utile a qualcuno ma SENZA NESSUNA GARANZIA; senza anche la garanzia implicita di COMMERCIABILITA’ o IDONEITA’ PER UN PARTICOLARE UTILIZZO. Vedi la GNU General Public License per maggiori dettagli.

Autore

Scritta da Leonardo Miliani con il contributo di lesto del forum di www.arduino.cc.

SwRTC
SwRTC
swRTC-1.2.4.zip
Version: 1.2.4
27.2 KiB
9114 Downloads
Dettagli...