Real Time Clock per rpi/arduino usando C#

Hai mai fatto un progetto DIY su raspberry/arduino e hai sentito il bisogno di loggare oppure utilizzare una qualsiasi funzionalità che abbia bisogno del timestamp corrente?

Allora ti sarai sicuramente imbattuto nel problema del time keeping. I computer e i laptop hanno una piccola batteria che preserva l'ora (insieme ad altre funzionalità) anche se il dispositivo non è connesso ad internet per aggiornarsi da solo sull'ora e sul fuso orario locale. Dunque quando accendiamo il pc, lui prende l'ora da un modulo perennemente alimenetato per mantenere l'ora e altre impostazioni sempre salvate e pronte all'uso.

Ma un Raspberry oppure un Arduino sono microcontrollori che non hanno un componente built-in per effettuare tale lavoro e quando viene spento e rimossa l'alimentazione, l'ora viene persa. C'è dunque bisogno di un modulo.

Hardware: moduli in commercio

Tra i vari moduli disponibili sul mercato uno dei più comuni (sopratuttto su aliexpress e banggoodd) è il DS2321 che spicca per tempo di funzionamento, durabilità e tolleranza a temperature variabili (ritrovarsi con 10 minuti di ritardo dell'rtc dopo 2 giorni di uso solo perchè stava al sole scoccia parecchio).
Della famiglia DS vi sono vari moduli che ne sfruttano le potenzialità (DS1302 più economico, il DS1307 con modulo integrato...) e si differiscono per l'elettronica aggiuntiva, per i pin femmina disposti in modo da essere connessi direttamento al Raspberry o arduino.

RTC SHIM con integrato MCP7940N

Un altro modulo interessante è il MCP7940N montato sul modulo RTC SHIM che ha una connessione diretta sul Raspberry ed è più professionale. Uno dei pochi punti negativi è che prende uno spazio troppo grande (anche se i pin effettivamente utilizzati sono molti meno di quelli su cui si appoggia e quindi possono essere riutilizzati senza problemi.

Software: come usare i moduli

Ora veniamo dunque alla parte principale dell'articolo: l'uso.
Questi moduli possono essere usati semplicemente per effettuare get e set dell'ora, ma anche per settare allarmi, timer e altro (in base al modulo vi saranno funzionalità specifiche).
Ma in pratica come si usano? Basta effettuare un collegamento con Raspberry (o arduino attraverso jumpers) e comunicare attraverso una porta seriale attaccata a due pin.
Su arduino potremmo benissimo usare la libreria SoftwareSerial per configurare una seriale al volo e inviare dati (comodo perchè sulla seriale di base TX0 e RX1 normalmente ci comunichiamo attraverso l'ide di arduino).
Su raspberry usando per esempio RTC SHIM basta scaricare il driver apposito dalla repository github e seguire le istruzioni (Linux).
Ma se stessimo usando Windows 10 iotcore ? Beh in questo caso dovremmo aprire manualmente una seriale da un programma scritto da noi e inviare i comandi giusti per utilizzare tali funzionalità

Software: uso con .NET per iotcore in C#

Chiaramente prima di fare tutto ciò chiunque con un minimo di esperienza di programmazione sa la regola principale condivisa da tutti: cercare su google "raspberry iotcore C# RTC SHIM" per poi finire o su stack overflow o su qualunque altro sito.
Peccato che la maggior parte degli articoli riguardino proprio il DS2321 e non si trova niente per quanto riguradna il MCP7940N.

Dunque qualcuno con un pò di tempo disponibile si è messo a creare una piccola app UWP installabile su iotcore per poter comunicare con tale modulo e settare l'ora.
In alternativa è possibile utilizzare le classi di comunicazione al suo interno per incorporarle nel proprio progetto in modo da sfruttarne le capacità.

Trovate tutto nella repo github.

MCP7940N overview

Per tutti i dettagli tecnici del modulo in questione è possibile consultare il datasheet.
A noi serve sapere che per leggere l'ora basta inviare 1 byte posto a 0x00 sulla seriale ed aspettare che arrivino i dati, mentre per scrivere basta inviare 8 byte di cui il primo posto a 0x00 e gli altri contenenti i vari campi.
Da notare che il microcontrollore usa BCD come sistema di encoding (Binary-Coded Decimal), quindi ogni volta che vorremmo inserire un byte da inviare dovremo traformalo da decimale a bcd:
byte bcd = (byte)(((int)val / 10 * 16) + ((int)val % 10));

Mentre per convertire in lettura da bcd a decimale:
byte dec = (byte)(((int)val / 16 * 10) + ((int)val % 16));

La memoria del dispositivo è suddivisa in settori. Quello che interessa a noi è TimeKeeping (vedi immagine).

Sezione TimeKeeping della memoria dentro il modulo MCP7940§N

Dunque sia in lettura che in scrittura i dati viaggeranno in BCD quindi verranno processati a dovere.
Per scriverte l'ora sevirà inviare il primo byte a 0x00 mentre il secondo conterrà i secondi, il terzo i minuti ecc... (vedi immagine sezione TimeKeeping).
Però oltre a tutto ciò bisogna settare il bit #7 del registro RTCSEC a 1 (bit ST, se uguale ad 1 allora il tempo viene mantenuto ed incrementato a dovere). Senza tale accorgimento la data e l'ora verranno settatai ma rimarranno tali per sempre.
Altri bit importanti possono essere consultati nel manuale (memoria completa a pagina 12).

Dettagli della repository

La gestione della seriale viene effettuata dalla classe I2cDevice della libreria Windows.Devices.I2c mantenuta nella classe MCP7940N.

I metodi di comunicazione si trovano nella classe RTCManager che usa internamente un oggetto di tipo MCP7940N per inviare le richieste giuste.

Sicuramente saranno effettuate modifiche a tale repository quindi per tutto il codice e le altre info consultare il readme della repo.

Ingegnere informatico conosciuto (si spera) nel web con il nickname “fabian_57” (ma alcuni siti non me lo consentono, in quel caso fabian57fabian). Sempre pronto ad esplorare nuovi progetti con arduino, raspberry e molto altro.

Real Time Clock per rpi/arduino usando C# ultima modifica: 2019-07-04T13:51:59+01:00 da Fabian Greavu


Advertisment ad adsense adlogger