Appunti digitali

Arduino: Hacking Time


No, non è il titolo di uno degli ultimi film di fantascienza di Hollywood, e non è neanche un gruppo di esperti informatici che hanno preso di mira il famoso quotidiano.
È solo una semplice realizzazione fatta attraverso il famoso e poliedrico Arduino; realizzazione forse neanche così poi tanto utile......

Allora cosa è?

Bene, avete presente gli orologi che grazie ad un segnale radio impostano automaticamente l'orario? Si, sto parlando degli orologi "Radio Controlled" tipo "Oregon Scientific ™" che utilizzano il sistema di diffusione dell'ora ufficiale della Germania denominato DCF77.

Riporto da Wikipedia (https://it.wikipedia.org/wiki/DCF77) da dove potete, se volete, iniziare a fare gli approfondimenti su tale primordiale tecnica di trasmissione dati via radio:
"Con la sigla DCF77 si definisce un sistema tedesco di trasmissione dell'ora legale e delle previsioni meteorologiche attraverso delle onde radio, verso un'ampia zona di copertura. È stato creato dal Physikalisch-Technische Bundesanstalt (PTB) su iniziativa del governo tedesco."

Da un pò di tempo gli orologi che ho in casa difficilmente riescono a ricevere tale segnale radio con la conseguenza che sono diventati dei normali orologi elettronici (tra l'altro qualcuno senza DCF77 non è neanche più preciso) con la necessità di impostazione dell'ora manuale.
Certo si fa, non è un problema, ma li avevo comprati soprattutto per questa funzione...
Pensate che noia quando si cambia da ora solare a legale e viceversa...

L'idea...

Il motivo per il quale questi orologi non ricevano più il segnale non l'ho ancora capito. L'unica associazione che ho fatto, ma è solo una sensazione che non ho mai approfondito, è forse la difficoltà di ricezione del segnale radio correlato con l'aumento dei router Wi-Fi nelle vicinanze della mia abitazione....
Boh!?!? Sarà vero?
Con questa sensazione ho iniziato ad approfondire per cercare di risolvere il problema e riavere i miei orologi auto aggiornanti; ma cercavo principalmente soluzioni di tipo radioelettrico (preamplificatori d'antenna, antenne esterne ecc.) che però mi avrebbero dato una soluzione solo per un unico orologio ed inoltre il risultato poteva non essere garantito (se il segnale arriva molto disturbato o non arriva proprio ci si può fare poco...).

Poi ho iniziato ad approfondire il metodo di trasmissione (protocollo e tipo di modulazione) ed ho appreso che l'informazione viene trasmessa attraverso una modulazione di tipo "ASK" (Amplitude Shift Keying) di una portante con frequenza molto bassa (77,5 KHz) utilizzando un protocollo BCD molto semplice ed ampiamente documentato.
Allora da qui l'idea che ha funzionato:   mi costruisco da solo, a casa mia, il trasmettitore DCF77
e così ho fatto!


Lo studio

Ho iniziato quindi a studiare come realizzare il mio trasmettitore DCF77. A dire il vero più che studiare - ma credo ormai sia una pratica comune - ho iniziato a "frugare" per internet che come al solito ti spegne l'entusiasmo visto che, quando pensi di avere avuto una idea "ganza", trovi sempre qualcuno che l'ha già realizzata e magari anche meglio.
Ma non mi sono perso d'animo ed ho continuato ad approfondire notando che, o almeno non le ho trovate, non vi erano realizzazioni tramite Arduino.
Visto che la modulazione ASK altro non è che un abbattimento dell'ampiezza della portante, di una certa percentuale e per un periodo di tempo, ho trovato una relazione molto stretta con una delle prime applicazioni che si utilizzano con Arduino e che non necessitano neanche di realizzazioni HW:
è l' Hello World! per eccellenza di Arduino ovvero il famoso "Blink" che spegne ed accende ciclicamente il led che si trova a bordo della scheda.
Utilizzando questa funzione alzando ed abbassando il livello logico del pin (on e off del led) nei corretti tempi dettati dal protocollo DCF77, potevo pilotare un "attenuatore" di segnale proveniente da un generatore sinusoidale a 77,5 Khz (la portante).

In particolare la modulazione si ottiene attraverso la riduzione dell'ampiezza della portante di circa l'85% del suo livello massimo per 0,1 o 0,2 secondi all'inizio di ogni secondo. La riduzione per 0,1 secondi contraddistingue un codice binario "0", mentre con una riduzione di 0,2 secondi viene contraddistinto il codice binario "1".

Da qui l'idea di base che a blocchi rappresento nella seguente figura:


La realizzazione

Devo dire che ho cercato di semplificare le cose: quanto già pronto è stato studiato, analizzato ed utilizzato semplificandone il risultato. Beh, siamo o non siamo nell'epoca del "copia e incolla"?
Comunque prima di arrivare al risultato esposto, ho fatto una serie di prototipi sia HW che SW. Questo per sottolineare che, secondo me, anche il "copia e incolla" va fatto mettendoci la "capoccia" approfondendo e comprendendo necessariamente sempre ciò che si prende in considerazione e che si realizza.

Anche se costruire un oscillatore a 77,5 KHz non è particolarmente complesso, ho sfruttato il mio generatore di funzioni Philips PM 5190 che con una semplice programmazione, mi permette di avere una portante sinusoidale stabile e di una ampiezza di 2 volts picco/picco senza grosse difficoltà.


Per l'attenuatore ho eseguito vari test ed ho fatto varie ricerche fino a trovare la soluzione "già pronta" su internet di una realizzazione similare. In particolare tale soluzione, insieme ad altre, sono state un pò la base di partenza che meglio fanno comprendere la tecnica del codice DCF77. La soluzione di riferimento per l'attenuatore, indicato come "level shifter", è quella che ho trovata al seguente link http://endorphino.de/projects/electronics/timemanipulator/index_en.html da dove è possibile recuperare un valido schema/esempio per la realizzazione di un oscillatore a 77,5 KHz oltre ad un interessante amplificatore lineare realizzato con un integrato tipico per l'amplificazione audio.

L'attenuatore/modulatore da me realizzato è praticamente la copia di quello proposto nel link precedente ma con alcune piccole modifiche, ed in particolare:

  • Eliminato il 7400 in quanto tramite Arduino genero i livelli H e L già in logica sia "diretta" che "negata" (TTL e TTL negato);
  • Aggiunto il collegamento per l'uscita TTL da inviare direttamente ad un modulo decodificatore all'interno dell'orologio (l'ho utilizzato su un orologio al quale ho "cannibalizzato" l'antenna ed eliminato il modulo ricevitore demodulatore DCF-77);
  • Eliminato i LED (abbiamo il LED sulla scheda di Arduino in corrispondenza del pin 13);
  • Semplificato il circuito utilizzando solamente due dei quattro switch che il CD4066 mette a disposizione.


  • Il funzionamento è molto semplice: con i livelli TTL si pilotano i due switch del CD4066 che connettono il segnale a 77,5 KHz in ingresso (BNC) o direttamente all'antenna (U1B "attivo" mentre U1A è "chiuso") oppure lo connettono all'antenna passando da un trimmer (RV1) che ne attenua l'ampiezza (U1B "chiuso" mentre U1A è "attivo").
    La realizzazione (un pò caotica in quanto ancora in formato breadboard) la potete vedere nelle foto successive:



    Il fatto che il tutto funziona con una realizzazione non particolarmente "pulita" ci fa capire che, seppur parliamo di radiofrequenza, la lunghezza d'onda così alta non è particolarmente critica. Vi posso assicurare per esperienza che realizzazioni siffatte su frequenze più elevate sarebbero un sicuro fallimento.
    Da notare l'antenna che ho prelevato da uno dei miei orologi.


    Il codice per Arduino

    Come accennato prima, il codice si basa sull'uso del digitalWrite() alla base del semplice programma di test di lampeggio del led. Nella mia realizzazione ho utilizzato "Arduino Duemilanove", ma vista la semplicità del codice presumo possa essere utilizzato, senza vincoli, qualsiasi modello.
    All'inizio in una matrice (int min [12][59]) vengono impostati, per ognuna delle 12 righe, tutti i bit della stringa del minuto che devono essere trasmessi e corrispondenti alla data/ora di partenza più gli 11 minuti successivi. Ciò al fine di evitare ritardi di calcolo durante la trasmissione e, di conseguenza, settaggi meno precisi.

    In ogni byte della matrice viene impostato il valore in millisecondi corrispondente al bit "1" o "0" (200 per per il bit "1", 100 per il bit "0"). All'atto della trasmissione dell'informazione - il protocollo prevede la trasmissione di 60 bit, uno al secondo - in un semplice loop:

  • vengono impostati i pin 12 e 13 in "HIGH" e "LOW" (digitalWrite(HO,LOW), digitalWrite(LO,HIGH)),
  • letto il valore del byte all'i-esimo bit del j-esimo minuto nella matrice ed impostato il valore del tempo di "attesa" (delay(min[j][i]));
  • vengono invertiti, con la digitalWrite, le logiche dei piedini;
  • viene impostata la delay per il complemento al secondo (delay(1000 - min[j][i])).
  • Al termine della trasmissione del minuto e trasmesso il 60° secondo (portante al 100% per l'intero secondo), il ciclo ricomincia per i rimanenti minuti preimpostati.

    Per il calcolo dei bit dati e dei bit di controllo (bit di parità) ho utilizzato parte di codice di un programma del 2003 di Matthias Wenzel (https://github.com/mazzoo/dcf77) scritto in C, e quindi compatibile con Arduino, che per sincronizzare gli orologi DCF-77 utilizza un metodo particolare: sfrutta la frequenza di sincronismo dei monitor dei PC, attraverso un particolare disegno di strisce sul monitor, emettendo una frequenza modulata.
    È stata una delle mie prime prove, ma a me non ha mai funzionato.
    Ovviamente nel programma tutta la parte di calcolo del protocollo era comunque valido e l'ho quindi recuperato.

    Il codice (in allegato) va caricato su Arduino avendo cura di pre-impostare le variabili (in testa al codice) di Giorno ("gg"), Mese ("mm"), ultime due cifre dell'anno ("aa"), giorno della settimana (1-7; Lunedi=1, Domenica=7 - "gi"), Ore ("hh"), Minuti ("mi") e il parametro CEST (1 si 0 = CET - "cest") ed aperta la consolle (9600) si vedrà a video la predisposizione di tale matrice:


    A questo punto, con un orologio preciso e ben in evidenza, occorre solamente dare il via alla trasmissione inserendo, in consolle, qualsiasi carattere seguito da invio. Siccome il protocollo prevede la trasmissione del minuto che conclude esattamente allo "00" del minuto che è stato trasmesso, occorre iniziare la trasmissione allo scoccare del minuto prima che abbiamo impostato nelle variabili. Ad esempio se abbiamo impostato la data/ora alle 11:16, occorre dare l'invio in consolle alle 11:15:00 esatte.
    La modulazione avrà inizio e si potrà vedere il classico simbolo sugli orologi di "corretta ricezione". Al termine, dopo qualche minuto, tutti gli orologi si saranno sincronizzati sullo stesso orario...

    in fase di sincronizzazione

    Sincronizzati!!


    Sicuramente non sarà una sincronizzazione dell'ordine del millisecondo, ma per l'uso che ne faccio ritengo che il risultato sia più che soddisfacente (medesimo secondo tra tutti gli orologi e l'orologio dell'i-Pad, sincronizzato con NTP, e preso a riferimento).
    Nell'immagine successiva potete vedere, grazie alla connessione effettuata con la "sonda blu" tra l'antenna e l'oscilloscopio, come la portante dei 77,5 KHz viene modulata:


    Bene, e adesso?

    Adesso nulla. Con questo "progetto" ho potuto dedicare un pò del mio tempo ad uno dei miei passatempi preferiti.
    Certo il codice, la realizzazione ecc. possono sicuramente essere migliorati ed avere un "aspetto" più professionale, ma è o non è un passatempo? Allora lo farò... Forse... Anche perchè, a pensarci bene, per le cose professionali c'è il lavoro.


    NOTA IMPORTANTE:

    La costruzione di trasmettitori è soggetta a regolamentazione di legge sia in Italia che in altri paesi. Ciò è possibile solo a scopo sperimentale per i Radioamatori con regolare licenza, solo su frequenze adibite allo scopo e regolamentate in maniera diversa da paese a paese.
    Quanto da me esposto è da intendersi unicamente per scopo divulgativo. Se lo realizzate fatelo a vostro rischio e senza attribuirmene responsabilità.
    Io sono in possesso di regolare licenza Radioamatoriale.