DCF 77
J'ai voulu faire ma propre horloge atomique DCF77, avec un genre un peu rétro en utilisant des afficheurs LED à l'ancienne, un cercle de 60 neopixels pour afficher les bits reçus par un module récupéré d'une pendule radio-pilotée, le tout commandé par un MSP430.
J'ai commencé avec un prototype pour débroussailler le terrain et voir ce que je devais afficher, ce qui a été fort utile. Je passerai plus tard à une réalisation plus aboutie.
En particulier, non seulement pour aider le debug, mais aussi comprendre ce qui se passe, je suis arrivé à la conclusion qu'il fallait afficher en permanence :
- Une information sur le niveau de bruit. Ici, ce sera le nombre de créneaux dans une seconde, qui vaut 1 si le signal est parfait.
- Une information sur le déphasage de l'horloge locale par rapport au signal DCF. Le décalage temporel estimé ainsi que le niveau de corrélation de la mesure sera utile.
- La largeur du signal mesuré, qui doit être théoriquement 0, 100 ou 200 ms
- L'état instantané des bits reçus, et un décodage immédiat (donc erroné si le signal est mauvais), par exemple afficher les minutes sous la forme des 7 bits converties en 2 chiffres.
- L'heure et la date, après correction.
Synoptique
Dans les pages précédentes, nous avons vu comment recevoir le signal DCF77 issus d'une horloge atomique basée à Mainflingen.
J'ai alors réalisé un premier prototype pour tester mes idées, qui présentera une finition "ingénieur" (tout ça pour dire que ce sera moche, mais que la base fonctionnera).
Il fallait afficher :
- La date en clair, de préférence sous forme alphanumérique. Un afficheur à matrice de points LED à l'ancienne fera l'affaire.
- L'heure, sous la forme habituelle numérique avec un afficheur 7 segments.
- L'écoulement des secondes avec une information sur les bits reçus, et une chaîne de 60 neopixels devrait permettre d'afficher cela d'une manière élégante.
Finalement trois types de matériels à piloter. J'ai donc testé sur mon prototype trois types d'affichage.
Le signal DCF est fourni par un module récupéré d'une horloge bas coût, cela revient moins cher que d'en acheter un tout seul.
Le cœur du système sera un microcontrôleur MSP430g2553, de Texas Instrument qui fournit l'ensemble du matériel à faible coût, y compris le software, et en le faisant pédaler à 16 MHz, nous avons une puissance suffisante pour faire nos calculs et nos commandes, vu que l'on travaille une fois par seconde pour l'affichage, (ou même dix fois si on veut afficher des dixièmes de seconde), et que l'échantillonnage du signal DCF requiert peu de ressource.
On se retrouve avec un synoptique simple :
Les données à afficher sont envoyées sur une interface série, ce qui réduit le cablâge et permet d'utiliser un microcontrôleur avec un faible nombre de "pattes".
Les composants choisis sont chainables : on peut en ajouter sans avoir à utiliser de nouvelles entrées-sorties du microcontrôleur, ce qui permet d'augmenter l'affichage simplement.
60 neopixels
Afficher les secondes avec un anneau de LED requiert de piloter 60 LEDs au minimum. Si en plus on veut pouvoir contrôler la couleur, cela fait 180 LEDs, ce qui devient impossible à piloter individuellement avec un simple microcontrôleur.
Heureusement un neopixel est un groupe de 3 LEDs RVB que l'on peut piloter simplement avec un seul fil qui sert d'interface série, et en plus ils sont chainables.
De plus, ils se vendent sous la forme d'un quart de cercle de 15 LEDs, ce qui facilite le montage.
côté programmation, il suffit d'utiliser astucieusement une interface SPI du MSP430 ce qui réduira considérablement le code sans avoir à faire de prouesse de programmation car la largeur d'un signal est de 1.25 microseconde, et notre MSP430 tourne à 16 MHz, soit 16 instructions au mieux par microseconde.
Un neopixel ayant 3 couleurs codées chacunes sur 8 bits, cela nous fait 24 bits, soit 1440 bits pour 60 neopixels, et donc environ 2 millisecondes pour mettre à jour l'affichage, ce qui commence à prendre du temps par rapport à l'échantillonnage du signal DCF77, il faudra y faire attention (priorité des interruptions à gérer).
Afficheurs 7 segments
Un afficheur 7 segments est une collection de 7 LEDs, à multiplier par le nombre de chiffres souhaités, ce qui fait beaucoup à piloter.
On aimerait bien avoir des chiffres que l'on puisse adresser avec une interface série, et chainable comme pour les neopixels :
Mais les produits vraiment intégrés sont plutôt rares, on trouve souvent des modules avec un microcontrôleur classique, et le protocole n'est jamais aussi simple que celui des neopixels.
Voici les quelques afficheurs à entrée série, tous obsolètes.
Chez LiteOn, ils avaient manifestement réutilisé leur puce d'interface à 35 bits, mais pas sérialisable, il faut sélectionner chaque module individuellement. Il reste également quelques sorties "libres" à piloter :
- LTM-8522xx 3 x 7 segments
- LTM-8529xx 1.5 x 7 segments
- LTM-8530xx 2 x 7 segments
- LTM-8647xx 2 x 14 segments
Chez Broadcom :
- HPDL-1414 4 x 16 segments
En clair, il faut faire son propre module avec un microcontrôleur, éventuellement en acheter un du genre ceux proposés avec un Arduino, et dans ce cas autant utiliser la solution courante : un MAX7219 ou MAX7221 qui permet d'adresser ces LEDs assez facilement à l'aide d'une interface série SPI, qui est heureusement chainable.
Ce circuit pilote des afficheurs à cathode commune.
On notera que ce circuit pilote 64 LEDs: on aurait pu réaliser l'anneau de 60 LEDs avec ce circuit, mais avec un cablâge super-pénible à faire. A tripler pour avoir 3 couleurs.
La solution à l'ancienne pour piloter des 7 segments est le circuit d'interface MC14499 qui a le bon goût d'être sérialisable. C'est la solution la plus simple en interface, mais plus rustique. Il faudra gérer les tensions, et limiter le courant. On trouve encore ce vieux circuit.
Affichage alphanumérique
Pour afficher la date sous forme alphanumérique tout en conservant un aspect rétro, on peut utiliser des matrices 5x7 LEDs présentant l'aspect suivant :
Ces circuits comportent une puce de pilotage qui permet d'envoyer les données sur une interface de type série, et ils sont chainables.
Quelques références :
- Broadcom / Avago : Smart Alphanumeric Displays / Serial Interface / 5x7 LED, hauteur 5mm et 3.7mm
Obsolète :
- ams-Osram/Siemens: SCDxx, DLRxx, HDSPxx, ISDxx, PDxx, SCExx, SLxx
- HP: 5082-7101, HDSP-2000, HDSP-2112, QDSP-2273
- Agilent HPDL1414 (16 segments / 4 char)
- Everlight: ELMM-457 obsolete
Matrice 5x7 LEDs "rétro", pas d'adressage, obsolète :
Machine d'états
Le fonctionnement de l'horloge repose sur une machine d'états, autrement dit on définit certains états, et sur quels critères les changements s'opèrent.
- Le premier état, au démarrage, est l'observation du niveau de bruit, qui sera en fait exécutée en continu. Il s'agit simplement de compter le nombre de créneaux par seconde, normalement 1 seul dans le meilleur des cas. Un seuil indiquera si on peut passer à l'état suivant.
- Le calcul de corrélation permettra d'ajuster la phase du signal reçu avec la phase de l'horloge interne. Une fois que l'on constate que le déphasage est faible et stable, on passe à l'état suivant.
- La recherche de la seconde 59 est simple : c'est une absence de signal.
- On peut alors commencer à lire une trame complète. Lorsqu'elle est valide, nous avons l'heure atomique !
- L'horloge est alors dans son mode normal, où l'heure DCF est affichée, et mise à jour une fois par minute. Si jamais la trame est mauvaise, on sort de cet état.
- C'est alors l'horloge locale RTC qui prend le relai, jusqu'à ce qu'une trame valide soit reçue. Si jamais trop de mauvaises trames arrivent, alors on passe dans l'état suivant.
- C'est toujours l'horloge locale RTC qui tourne, mais en même temps le niveau de bruit est vérifié, et s'il est assez faible, alors on effectue un recalage de phase, jusqu'à ce qu'une trame valide soit enfin lue.
Une trame valide sera une trame où les 3 bits de parité sont bons, et où la date et l'heure ne seront pas débiles, par exemple une année antérieure à 2024. Il arrive en effet assez souvent que deux bits soient simultanément faux, et alors le bit de parité indique que c'est valide car il ne peut pas détecter cela.
On pourra armer un flag lorsqu'une dizaine de trames consécutives auront été lues : il est alors très probable que la date soit OK, on pourra facilement le vérifier car les données ne doivent pas changer, sauf à minuit. Si on a perdu le signal depuis longtemps, comme on est certain que la dernière trame valide reçue est OK, on pourra effectuer un contrôle de cohérence avec une nouvelle trame reçue car le décalage sera certainement inférieur à une minute, vu on connait le temps écoulé.
Prototype
J'ai réalisé un prototype pour mettre au point ma machine d'état, et voir ce qui est utile à afficher, et je peux vous assurer que visualiser le niveau de bruit, le déphasage et la largeur des signaux reçus est très utile pour le debug, ainsi que pour comprendre ce qui arrive dans la transmission des signaux, par exemple les différences jour/nuit, et les variations de largeur des créneaux.
J'ai eu deux bits faux concernant l'année, indétectable par le bit de parité.
C'est une version moche de ma future horloge atomique. Mais le mécanisme est validé.
Un truc pénible fut les colonnes mortes constatées sur mes afficheurs alphanumériques HCMS-2975, d'abord une, puis les autres ont aussi lachés. Faudra que je les monte sur des supports pour pouvoir les changer dans la version finale.
J'ajouterai probablement un capteur photoélectrique pour ajuster la luminosité de l'horloge, qu'elle soit plus faible dans le noir.
Horloge finale
Faut que je fasse ça... et que je n'oublie pas de publier.
1 an après, c'est fait 😁
Vous avez à présent les informations utiles à connaitre pour réaliser vous-même votre propre horloge.
Je n'ai pas publié de code source car de toutes manières, c'est utile uniquement pour celui qui le fait, surtout que vous aurez certainement du matériel différent, et c'est nettement plus satisfaisant quand on le fait soi-même. Mais le principe est là pour vous guider sur les grandes lignes.