Le but est de réutiliser un vieux disque dur 3.5 pouces pour le transformer en horloge.
Il faut d'abord trouver un disque dur capable de tourner tout seul, sans connectique externe, je veux dire sans qu'il soit relié à un ordi. Ensuite, l'idéal est de pouvoir se passer des têtes de lectures, ca laisse plus de place pour les composants et c'est plus esthétique. Là aussi, certains disques dur peuvent refuser de démarrer (ou s'arrêtent de tourner) s'ils détectent que les têtes ne sont plus présentes.
Une fois le disque sélectionné, vous le mettez de coté.
Pour le reste des courses, il vous faudra la liste suivante :
un chip ATMEGA 328P avec boot-loader, ainsi qu'un quartz 16Mhz et 2 condensateurs de 22pf
un bouton de reset avec une résistance de 10K et un condensateur de 100nf
de quoi connecter un programmateur FTDI
un programmateur FTDI, évidemment.... Soit un modèle tout fait, soit un bricolé avec un arduino uno (vous trouverez des exemples sur internet)
un ULN2003 pour piloter les LEDS
un bandeau de LED RVB à anodes communes, avec au moins 9 LEDs. J'ai trouvé ce bandeau sur superbrightleds.com. Voici le lien :
un module horloge sauvegardée type DS1307, peu importe le modèle ils fonctionnent tous de la même façon, prenez le moins cher...
une plaque de veroboard
de quoi faire une alimentation 5V régulée (sauf si vous reprenez celle du disque dur)
une alimentation 5V et 12V pour le disque dur (et indirectement l'arduino).
un capteur à effet hall avec son aimant.
Le fonctionnement est assez basique. Une fente est amménagée sur le disque dur (un rayon seulement et on laisse 2mm non découpé coté centre et coté extérieur afin de rigidifier le disque). Plus la fente est fine, plus l'affichage sera précis, attention de bien couper sur un rayon...
Des LEDS sont disposées derrière le disque, dans le boitier, au niveau de la tranche. Le but est d'allumer les LEDs lorsque la fente est bien placée. S'il est par exemple 11H, lorsque la fente est sur la position 11h, on allume les leds et on les éteint juste après. Tout est basé sur la persistence rétinienne.
S'il est 11h10, on allume par exemple les LEDS rouges quand la fente est sur 11H, on éteint et quand la fente passe sur 10mn on allume les LEDS vertes par exemple.
Pour cela, le mouvement du disque doit être synchronisé avec l'arduino. A tout moment l'arduino doit savoir où se trouve la fente du disque dur. Comme le disque dur est autonome, c'est lui qui va donner sa position à l'arduino. Comment me direz vous ? Avec un capteur à effet hall comme celui-ci.
Le capteur à trois pattes : une à la masse, une sur le 5V et la troisième est la sortie. Cette sortie est connecté via une résistance de pull-up sur le 5V.
A vide, la sortie sort 5V. Si un aimant est proche du capteur, la tension de sortie passe à 0V
Un aimant est ensuite collé à l'araldite sous le disque, près du bord. A chaque révolution, l'aimant passe devant le capteur et sa sortie passe à 0V. Cette sortie est reliée à la pin D2 (INT0) de l'arduino et celui-ci est programmé pour déclencher une procédure sur une interruption externe, ce qui veut dire que quelque soit l'endroit où nous nous trouvons dans notre programme, dés que l'aimant passe devant le capteur, une interruption est générée et un bout de code automatiquement exécuté.
Le poids de l'aimant et de l'araldite n'est pas négligeable, celà va générer un balourd. Il faudra contrebalancer de l'autre coté en collant un petit morceau de métal d'un poids équivalent à celui de l'aimant. Il faut aussi tenir compte de la perte de matière due à la découpe dans le disque dur...
Que fait ce bout de code ? Il sauvegarde le contenu d'un timer (ce timer à une fréquence fixe) et le remet à zero. Avec ce système, l'arduino peut savoir combien de temps (en unité de timer bien sur) dure un tour. Ce temps est ensuite divisé en 256 pour programmer un autre timer. Cet autre timer (avec le même prescaler que le premier, mais on s'arrangera pour que l'overflow se produise après une durée égale à 1/256 de la valeur sauvegardée de notre premier timer) va exécuter une autre interruption, 256 fois par tour, ce qui permettra de diviser la zone affichable en 256 secteurs. Le bout de code exécuté par overflow de ce deuxième timer se chargera d'allumer ou pas les leds si besoin. Comment peut il savoir si la zone doit être allumée ou non ? Simplement par la présence de données dans un tableau de 256 valeurs, représentant les 256 positions possibles et grace à un index qui s'incrémente après le passage de chaque secteur.
Normalement, cet index est stocké dans une variable de type "byte" non signée, donc il ne peut prendre que 256 valeurs et doit se remettre à zero tout seul. Cela dit, on forcera son passage à zero (ou à une valeur de votre choix, en fonction de votre réelle position 0), dans l'interruption INT0 qui est générée à chaque tour.
Les données stockées dans chaque position de ce tableau sont simplement le codage sur 3 bits des leds RVB
0 : éteint
1 : ROUGE
2 : VERT
3 : ROUGE + VERT
4 : BLEU
5 : ROUGE + BLEU
6 : VERT + BLEU
7 : ROUGE + VERT + BLEU
Pour écrire les données rapidement, on utilise pas les fonctions digitalwrite() de l'arduino. On passe directement par les registres de port, cela permet d'écrire plus rapidement, mais aussi d'écrire 3 bits d'un coup si besoin.
Bien sur, il est hors de question de piloter les leds directement par les ports de sorties de l'arduino. Il faut passer par des transistors. On utilise pour cela un ULN2003, c'est un peu du gâchis (on n'utilise que 3 transistors sur les 7) mais il possède des sorties non utilisées qui pourrait servir pour d'autres fonctions dans le futur.
Arrivé ici, nous constatons que la synchronisation se fait par interruption, que le calcul de la durée d'un tour aussi et que l'affichage des LEDS aussi. Il ne reste plus grand chose à faire.
La boucle principale va tester les positions des boutons de mise à l'heure et fait une mise à jour de l'horloge sauvegardée si besoin.
Ensuite, on regarde si notre pendule doit être rafraichie. Si un rafraichissement est nécessaire, on va lire l'heure dans l'horloge sauvegardée et en fonction de l'heure on met à jour le tableau de 256 valeurs avec les données appropriées. Pour éviter des clignotement intempestifs, il existe 2 tableaux : un d'affichage lu par la routine du timer et un de mise à jour dans lequel on stocke les données. Si un rafraichissement est nécessaire les adresses de ces 2 tableaux sont swappées. C'est tout...
Voici le schéma de mise en oeuvre.
Et voila ce que ca donne sur le veroboard.
La partie alimentation avec une diode de protection, un regulateur 5V avec 2 condensateurs.
La partie micro-controlleur. L'ATMEGA328P, la resistance de 10K du reset, le bouton de reset, à droite le connecteur FTDI pour la programmation. En haut à droite les 2 condensateurs de 22pf avec le quartz à 16mhz.
Le pilotage des leds avec l'ULN2003
L'horloge sauvegardée branchée sur le bus I2C (SDA/SCL).
Je découpé de petites pièces en chêne en forme de L pour constituer un support.
L'arrière
Dans le noir... 6h 40mn et 5 secondes...
Le code
Le code n'appelle pas de commentaire particulier. Vous le trouverez dans l'archive ci-dessous.