Sur mon réseau, je voudrais commander l’éclairage et l’extinction de mes bâtiments, ainsi que l’éclairage public avec une platine Arduino. S’il pouvait aussi gèrer l’éclairage général du réseau, me faire de beaux levers de soleil et la pleine lune, ce serait magnifique. Mais pour cela, il me faudrait une horloge qui me donne le temps à l’échelle de la maquette.
C’est ce que je vais vous présenter.
Le temps à l’échelle HO
Tout d’abord, il faut mettre le temps à l’échelle :
1 journée de 24 h vaut 1440mn et au 1/87ème : 1440/87 = 16 mn donc :
1 journée est égale à 16mn.
1 heure est égale à 40 s.
1 minute est égale à 666 millisecondes (Hé oui, Arduino travaille en milliseconde)
Ces chiffres ne sont pas impératifs, si vous préférez une journée plus longue ou plus courte, il suffit de refaire le calcul.
La liste des courses
il vous faut réunir :
1 microcontrôleur ATméga328p ( le même que sur les platines Arduino Uno)
1 socket 28 broches
1 Quartz 16 Mhz
2 condensateurs de 22pf
1 résistance de 220 ohms
4 résistances de 150 ohms
1 bornier pour l’alimentation
1 Afficheur 4 digits, 7 segments (anode ou cathode commune)
et 1 plaquette de circuit imprimé percée à bande.
J’ai fait tous les tests sur une plaque d’essai avec une platine Arduino, puis, quand le programme était au point, j’ai transféré le microcontrôleur de ma platine Arduino sur mon nouveau circuit. ATTENTION : les pattes des ATméga sont fragiles, il faut agir avec précaution....
Variante : Vous pouvez aussi utiliser une platine Arduino toute faite type Uno ou Nano.
Les afficheurs 7 segments
Il en existe de toutes sortes, séparés ou d’un seul bloc, vert, rouge blanc ou bleu,
à anode ou cathode commune, prenez celui qui vous plait, tous iront.
Pour faire apparaître un chiffre sur l’afficheur, il faut alimenter les segments correspondants via la broche qu’ils ont en commun. Pour notre microcontrôleur, il doit donc gérer 7+1 broches + 1 broche supplémentaire pour le point séparateur, soit 9 broches au total. Si on multiplie par 4, cela nous fait 36 broches !!!
C’est beaucoup trop pour notre microcontrôleur... Heureusement il y a une méthode pour réduire tout cela :
Le Multiplexage.
On va relier chaque segment de chaque afficheur ensemble ( les a ensemble, les b ensemble...etc.) et on garde un commun séparé pour chaque afficheur.
Comme on travaille avec des leds, il convient de les protéger, on met en série une résistance de 150 ohms sur les communs.
Cela ne nous fait plus que 7+1 broches + 4 communs = 12 broches . C’est tout à fait acceptable pour notre petit ATméga328 !
Voilà mes branchements avec l’Arduino et mes afficheurs. Si les vôtres sont différents, il faudra modifier les branchements en conséquence.
N’hésitez pas à travailler sur le logiciel FRITZING, c’est gratuit ; très facile à prendre en main et ça rend de nombreux services.
On comprend bien que si l’on choisit un chiffre à afficher sur chaque digit et qu’on active tout ça, on va obtenir un désordre indescriptible sur les afficheurs.
Comment faire donc pour afficher des chiffres différents sur les 4 digits reliés ensemble....
En allumant et en éteignant successivement les 4 digits à tour de rôle, et suffisamment rapidement pour que l’on ne s’aperçoive de rien...
C’est ce qu’on appelle le multiplexage. Mais c’est un travail de programmation important, fastidieux et répétitif. Nous allons donc le confier à une librairie dédiée.
On en trouve plusieurs sur le Net. Moi j’ai utilisé SevSeg.h, vous pouvez la télécharger ici.
Le programme
// Créer une horloge à l'échelle HO. Une heure vaut 40 secondes,
// ce qui permet d'avoir une journée de 24h en 16mn.
#include "SevSeg.h"
//Créer une instance de l'objet.
SevSeg sevseg;
//Créer les variables globales.
unsigned long timer;
int minute=0;
// Initialisations
void setup() {
/*le premier chiffre représente anode ou cathode commune: cathode=0,anode=1.
Les chiffres 2,4,3 et 13 sont les broches de sortie de l'Arduino
pour les broches communes des afficheurs en partant de la gauche vers la droite.
Les chiffres suivants représentent les broches de sortie de l'Arduino
pour les segments a,b,c,d,e,f,g et dp des afficheurs.*/
sevseg.Begin(0,2,4,3,13,10,9,7,6,5,11,12,8);
//Régler la luminosité (0 to 100);
sevseg.Brightness(90);
// initialisation de la variable timer
timer=millis();
}
void loop() {
// Affiche les différentes sorties
sevseg.PrintOutput();
// Vérifier si la minute HO est écoulé...666 milliseconde pour 1mn.
unsigned long temps=millis();
if (temps-timer>=666) {
timer=temps;
minute++;
if (minute==1440) { // Remet à 0 après 24h*60=1440, soit une journée complète.
minute=0;
}
int x=minute/60*100;
// On divise par 60 pour avoir le nombre d'heure
int y=minute%60;
// et on le multiplie par 100 pour le positionner sur l'afficheur n°2.
int z=x+y;
//y est le modulo de la division précédente (le reste des minutes)
sevseg.NewNum(z,(byte) 2);
//z est mis sur les afficheurs, 2 représente le point.
}
}
Explications
#include "SevSeg.h" permet d’inclure la bibliothèque.
La fonction sevseg.Begin(cathode ou anode commune, les 4 communs,les broches de l’Arduino correspondants aux différents segments) est à mettre dans le setup().
Dans le setup() on initialise aussi la variable timer avec millis().
Dans la loop() on crée une variable locale de type unsigned long nommé temps et qui prend la valeur de millis() à chaque tour.
Puis on fait la différence entre temps et timer et on regarde si le résultat est supérieur ou égal à 666.
On actualise timer en ajoutant temps et on incrémente la variable minute.
Pourquoi 666 me direz-vous ? Rappelez-vous le résultat de notre calcul du début, on trouvait bien 666 millisecondes : Si vous avez fait un calcul différent, c’est ici qu’il faut mettre votre résultat.
Bon, on a une variable qui compte les minutes HO. On va la tester avec le if().
Si elle dépasse 1440 ( 24h=1440mn), elle retourne à 0 et une nouvelle journée commence !
Après, c’est le même calcul que l’on faisait en CM2 ( les trains en retard et les correspondances ratées)....
int y=minute%60 ; renvoie le reste (modulo) de la division minute/60.
La partie DIY (bricolage en français)
Sur le côté piste, les croix rouges représentent les endroits ou il faut couper les pistes.
Côté composants, on commence à souder tous les straps, puis les résistances, le bornier, le quartz et les condensateurs, le support pour le micro et enfin les afficheurs.
Quatre trous permettent de fixer la platine dans un beau boitier qui trônera sur le réseau.
N’hésitez pas à laisser vos commentaires, je me ferais un plaisir de vous répondre.
Merci pour le compliment ;
Il ne faut pas obligatoirement diviser le temps par 87, mais, sur une maquette, on aime bien, si on crée le jour et la nuit, que ça ne se produise pas que toutes les douze heures. D’où l’idée d’accélérer le temps.
Et pourquoi pas par 87.... Dans mon code, j’indique comment changer cette donnée. Plus long, moins long, c’est suivant le gout de chacun.
En théorie oui, il suffit de changer le le 666 en 60000. En pratique non, pour deux raisons :
le timer déborde au bout de 50 jours
l’Arduino a un oscillateur céramique de 0,5% de précision et de 0,2% de stabilité. C’est très insuffisant pour faire une horloge de précision suffisante.
Non, je n’ai pas dit ça. J’ai dit qu’avec le code ci dessus et un Arduino seul, c’était impossible. Pour trouver comment faire avec du matériel supplémentaire, Google est votre amis (car ça n’a rien à voir avec le train miniature).
La suite de la discussion n’étant pas instructive pour nos visiteurs et Allan ayant réussi à faire fonctionner son montage, j’ai préféré vous épargner ses entorses à l’orthographe !
bonjour,
Très intéressé par votre réalisation et dans le mème but , éclairer ou éteindre mon réseau selon un cycle géré par une horloge mais n’étant pas vraiment a l’aise avec la programmation et tout ce qui est électronique ( je suis arrivé a réaliser l’horloge sans problème)pensez vous pouvoir donner une suite a cette article expliquant comment utiliser cette horloge pour commander les différentes phases de l’éclairage du réseau ?
Bonjour,
Très heureux que vous vous intéressiez à mon petit travail.
J’ai fini depuis l’éclairage de mon réseau et je n’ai toujours pas trouvé le temps d’écrire un petit article sur la suite.
En fait, l’horloge n’est là que pour donner l’échelle de temps aux spectateurs. Un autre Arduino va se charger de la gestion des différents éclairages. La syncro des deux se fait toute seule, car mes deux Arduino démarrent en même temps et ils utilisent tous les deux la fonction millis().
Pour gérer les différents éclairages, j’ai fait une biblothèque
que j’appelle avec différentes fonctions :
allumeJour() ;
eteintJour() ;
allumeLune() ;
eteintLune() ;
sur des objets (ledRouge ; ledBlancChaud ; etc...)
Si tout cela vous intéresse, créez un sujet sur le forum, je serai ravi de vous aidez.
j’ai un problème avec le programme pourriez vous m’aider ?
Message a la vérification :"exit status 1’class SevSEg’has not member named’begin’
Avec la ligne 22 en surbrillance( sevseg.Begin(0,2,4,3,13,10,9,7,6,5,11,12,8) ;)
qu’est que j’ai mal fait ?
merci pour vos reponses .
merci, effectivement il y avait un B a begin ,erreur corrigée mais nouveau message :
S :\Documents\Arduino\Horloge_HO\Horloge_HO.ino : In function ’void setup()’ :
Horloge_HO:22 : error : no matching function for call to ’SevSeg::begin(int, int, int, int, int, int, int, int, int, int, int, int, int)’
sevseg.begin(0,2,4,3,13,10,9,7,6,5,11,12,8) ;
^
S :\Documents\Arduino\Horloge_HO\Horloge_HO.ino:22:49 : note : candidate is :
In file included from S :\Documents\Arduino\Horloge_HO\Horloge_HO.ino:4:0 :
Bon, j’ai testé ce programme en faisant un copier-coller et j’obtiens les mêmes erreurs. Je n’ai pas le temps d’approfondir et j’espère que l’auteur pourra corriger l’article.
Il est probable que la bibliothèque sevseg ait évolué : ça va s’arranger !
Merci d’avoir signalé cette anomalie.
Bonjour petitrain et merci pour cet article.
Je trouve la partie DIY très intéressante pour fabriquer l’horloge et la faire fonctionner sans la carte arduino UNO.
Pouvez-vous nous décomposer la marche à suivre pour programmer le microcontroleur ATMEGA 328 P ?
En effet j’ai à ma disposition un ATMEGA 328 P-PU que je voudrais programmer via la carte arduino UNO transformée en programmateur (comme Christian nous l’a expliqué pour les "ATtiny").
Cette explication pourrait servir a bien d’autres applications pour nos petits trains.
Merci d’avance pour votre aide.
Bonjour,
Votre demande dépasse un peu le cadre de mon tutoriel et il faudrait y passer du temps pour rédiger un nouvel article...
Faites une recherche sur internet : "programmer un atmega 328 p avec arduino", vous trouverez déjà plein de tutoriels traitant le sujet.
Le prix des platines Arduino, notamment les nanos,(2 à 4 euros) ne nécessitent plus vraiment de programmer les micro-controleurs.
Enfin , code vérifie j’ai supprimé la bibliothèque sevseg qui était dans mon dossier arduino et l’ai remplacé par la bibliothèque téléchargée a partir du lien au dessus du code .
Merci a tous .
Bonjour,
Effectivement, il faut charger la bibliothèque décrite dans l’article et utiliser le lien qui y est indiqué.
La bibliothèque a été reécrite, avec des méthodes un peu différentes...
Si vous avez compris ce que j’explique dans l’article, ce n’est pas très dur de changer les méthodes qui ne vont plus .
J’ouvre un sujet sur le forum à ce propos.
J’ai trouvé votre idée géniale ! J’aimerai bien la mettre en œuvre sur un petit écran oled 128x64 ou 128x32, pour limiter le nombre de câble brancher sur l arduino. Avez vous des idées de comment adapter votre code ?
Merci pour les compliments...
Avez-vous une bibliothèque pour l’afficheur que vous envisagez d’employer, et savez-vous vous débrouiller avec ? je vous pose ces questions car je n’ai pas sous la main un tel afficheur et je ne peux pas tester .
Le code est assez simple, il suffit de sortir tout ce qui devient inutile (
ce qui a trait à SevSeg.h) et de le remplacer par votre bibliothèque.
Ce qu’il faut garder, c’est le calcul du temps :
// Vérifier si la minute HO est écoulé...666 milliseconde pour 1mn.
unsigned long temps=millis() ;
if (temps-timer>=666)
timer=temps ;
minute++ ;
if (minute==1440) // Remet à 0 après 24h*60=1440, soit une journée complète.
minute=0 ;
int x=minute/60*100 ;
// On divise par 60 pour avoir le nombre d’heure
int y=minute%60 ;
// et on le multiplie par 100 pour le positionner sur l’afficheur n°2.
int z=x+y ;
//y est le modulo de la division précédente (le reste des minutes)
Super merci. C’est tout bon j’ai réussi à le faire. Si ça intéresse qqn n’hésitez pas à me contacter pour le code et les instructions. Au plaisir et merci pour votre réponse rapide.
Vous pouvez vous référer à la réponse que j’avais faite juste avant vous.
Bien sur, je n’ai pas écrit mon programme pour tous les afficheurs du marché.
En premier lieu, télécharger une bibliothèque pour votre afficheur et prenez le en main...
L’adaptation de mon programme ne devrait pas poser de problème.
Bonjour,
je ne pense pas que Makecode prenne en charge les Arduino, mais je peux me tromper.
En tout cas micro:bit n’est pas un Arduino, et vous n’êtes pas sur le bon forum.
Pour faire une horloge avec un micro:bit, vous pouvez partir de ces articles : https://makecode.microbit.org/pkg/m...