Cet article a pour objectif de réaliser des décodeurs de signaux ferroviaires. L’approche se fera en trois parties.
La première consiste à réaliser ces décodeurs en se basant sur l’article de Nicolas Zin. Dans cette approche le programme reçoit un message DCC qu’il doit entièrement gérer.
La seconde approche se base sur les bibliothèques Commanders et Accessories de Thierry Paris. Les deux fournissent une grande quantité de méthodes facilitant grandement la réalisation des commandes analogiques ou DCC pour des accessoires.
Enfin la dernière solution propose une interface utilisant ces mêmes bibliothèques mais cachant leur complexité et facilitant la configuration de décodeurs de signaux ferroviaires à deux et/ou trois feux.
L’Arduino Mega 2560 peut-il alimenter 16 leds continuellement ?
16 feux tricolores à led, cela fait 48 leds. Mais dans chaque feu, une seule led est allumée et consomme moins de 10 milli-ampères.
Un Arduino Mega 2560 dispose de 54 ports, donc peut piloter 16 feux, et les 16 leds allumées en permanence ne mettent pas l’Arduino en surcharge.
Mais après croisement de nombreuses informations, il en ressort que :
La somme de tous les courants (entrant ou sortant) des ports J0-J7 (digital pins 14 et 15), G2 (digital pin 39), A0-A7 (digital pins 22 à 29) ne doit pas dépasser 200 mA.
La somme de tous les courants (entrant ou sortant) des ports C0-C7 (digital pins 30 à 37), G0-G1 (digital pins 40 et 41), D0-D7 (digital pins 18 à 21 et 38), L0-L7 (digital pins 42 à 49) ne doit pas dépasser 200 mA.
La somme de tous les courants (entrant ou sortant) des ports G3-G4 (aucune pin), B0-B7 (digital pins 10 à 13 et 50 à 53), H0-H7 (digital pins 6 à 9 et 16, 17) ne doit pas dépasser 200 mA.
La somme de tous les courants (entrant ou sortant) des ports E0-E7 (digital pins 0, 1, 2, 3, 5), G5 (digital pin 4) ne doit pas dépasser 100 mA.
La somme de tous les courants (entrant ou sortant) des ports F0-F7 (analog pins 0 à 7), K0-K7 (analog pins 8 à 15) ne doit pas dépasser 100 mA.
Au total le courant total du Mega 2560 ne doit pas dépasser 800mA (dont 80mA de consommation interne).
Donc, les leds de nos feux consommant moins de 10 mA, cela fait 160 mA maximum, répartis sur plusieurs ports. Nous sommes loin de la limite ! Ouf !
A noter que l’expression « courant entrant » (sink en anglais) signifie courant absorbé : c’est le cas quand la led est connectée au +5V par son anode (via une résistance) et à une pin de l’Arduino par sa cathode. La led s’allume quand la pin est au niveau 0V (LOW).
A l’inverse, l’expression « courant sortant » (source en anglais) signifie courant fourni : c’est le cas quand la led est connectée une pin de l’Arduino par son anode et au 0V par sa cathode (via une résistance). La led s’allume quand la pin est au niveau 5V (HIGH).
La norme DCC et les commandes d’accessoires
On trouvera dans cet article une présentation de la norme DCC, comment se présente un signal DCC sur les rails, généré par votre centrale. Mais cet article se concentre sur les commandes des locomotives avant tout.
Ici nous avons affaire aux commandes d’accessoires qui sont réalisées avec des trames DCC différentes des commandes de locos.
Le document de référence de la NMRA est RP-9.2.1-Extended packet [1] (pour ceux qui sont prêts à affronter la chose en anglais).
Nous allons maintenant tenter de vous éviter cela :-)
Les adresses correspondant aux décodeurs d’accessoires basiques (Basic Accessory) sont codées sur 9 bits d’adresses, et celles des décodeurs d’accessoires étendus (Extended Accessory) sont codées sur 11 bits d’adresse.
Ces adresses n’ont rien à voir avec les adresses des locos, du fait que les commandes DCC sont différentes. On n’a donc pas besoin de choisir des valeurs d’adresses différentes.
Curieusement, les centrales semblent utiliser les commandes d’accessoires basiques à toutes les sauces, y compris les feux, alors que ces derniers semblent devoir être commandés plutôt par des commandes étendues.
Nous allons donc nous concentrer sur les commandes basiques seulement dans l’exemple qui va suivre. Un autre article reviendra ultérieurement sur les commandes étendues.
Le format des paquets DCC pour la commande des décodeurs d’accessoires basiques
Le format d’une commande destinée à un décodeur d’accessoires est :
preambule 0 10AAAAAA 0 1AAACDDD 0 EEEEEEEE 1
L’adresse est en 2 parties AAAAAA (6 bits dans le 1er octet qui représentent les poids faibles) et AAA (3 bits dans le 2ème octet qui représentent les poids forts).
La première partie est codée simplement de 0 (000000) à 63 (111111) et la deuxième partie est codée en complément à 1 (pourquoi faire simple quand on peut faire compliqué !).
Par exemple 111 binaire vaut 000 en complément à 1 donc 0 en décimal et on a les adresses de 0 à 63 ; ensuite,
110 vaut 1 donc les adresses vont de 64 à 127 ;
101 vaut 2 donc les adresses vont de 128 à 191,
100 vaut 3 donc les adresses vont de 192 à 255,
011 vaut 4 donc les adresses vont de 256 à 319,
010 vaut 5 donc les adresses vont de 320 à 383,
001 vaut 6 donc les adresses vont de 384 à 447, et
000 vaut 7 pour les adresses de 448 à 511.
Le bit C sert à activer et désactiver un accessoire soit de façon momentanée, soit de façon permanente. L’activation ou la désactivation (si l’activation était permanente) se fait en envoyant 2 commandes, l’une avec C=1, puis une autre avec C=0, après quelques millisecondes. La durée de l’activation est déterminée par les variables de configuration CVs #515 à 518 (ce qui correspond à 4 paires de sorties).
Le décodeur peut piloter 4 paires de sorties :
Dans DDD, les DD de poids fort (à gauche) définissent quelle sortie est concernée et le dernier D de poids faible (à droite) définit l’élément dans une paire.
La combinaison de l’adresse et des bits DD de poids fort est souvent utilisée par les centrales pour simuler 4 accessoires simples comme des moteurs d’aiguilles classiques ou pour des feux ou des relais. Cette combinaison permet donc d’adresser un peu moins de 2048 accessoires (quelques unes sont réservées selon le fabricant).
Dans ce cas l’adressage indiqué dans la documentation des centrales peut prendre les formes 101/0, 101/1, 102/0, 102/1, 103/0, 103/1, 104/0, 104/1 qui correspondent toutes à l’adresse 26, paires de sorties 1, 2, 3, et 4.
On vous avait bien dit que ce n’est pas simple !
Le format des paquets DCC pour la commande des décodeurs d’accessoires étendus
Ce format est destiné à transmettre des commandes d’aspect plus particulièrement pour les décodeurs de feux ou des octets des données pour des décodeurs plus complexes. Chaque commande pilote un seul aspect à la fois d’un feu complexe.
On y retrouve les 9 bits d’adresse AAAAAA et AAA comme dans la commande basique, auxquels s’ajoutent 2 bit supplémentaires en bits 1 et 2 du 2ème octet.
XXXXX concerne un seul feu. la valeur 00000 indique un Stop absolu.
Tous les autres aspects représentés par les autres valeurs de XXXXX sont déterminés par rapport à un modèle de système de signalisation.
Les commandes de Variables de Configuration des accessoires
Chaque décodeur d’accessoires contient des paramètres programmables par des commandes DCC. Son adresse en est l’exemple typique. Celle-ci est programmée dans le CV 1 (poids faibles) et le CV 9 (poids forts).
Les CVs des décodeurs d’accessoires peuvent être configurés au même titre que les décodeurs de locomotives par des commandes DCC.
Programmation des CVs d’un décodeur d’accessoire basique :
AAAAAA AAA est l’adresse comme expliqué plus haut.
DDD indique la sortie pour laquelle les CVs sont modifiés avec C=1.
Si CDDD= 0000 alors les CVs concernent le décodeur dans sa totalité (toutes les sorties).
(1110CCVV 0 VVVVVVVV 0 DDDDDDDD) est l’instruction de configuration des CVs.
Programmation des CVs d’un décodeur d’accessoires étendu :
Notez que le bit 3 à 0 dans l’octet 2 garantit que ce paquet ne peut pas être confondu avec celui d’un accessoire basique.
La construction du décodeur
Comme indiqué au début de cet article, j’ai choisi d’utiliser un Arduino Mega 2560 qui permet de brancher les 48 Leds sans matériel extérieur (j’aurais pu utiliser un Arduino plus petit avec une carte contenant 6 x 74HC595, chacun pouvant alimenter 8 Leds, mais ça aurait fait beaucoup de câblage).
De toute façon, pour faire ce décodeur et le rendre facile à utiliser, il faut ajouter une interface DCC isolée par optocoupleur, selon ce schéma éprouvé décrit en détail à l’article Un moniteur de signaux DCC.
Ensuite, il faut ajouter des borniers à vis pour brancher les fils qui vont aux feux.
J’ai donc ajouté à mon Mega 2560 une carte d’extension imprimée à pastilles, avec la place pour les connecteurs mâles qui vont s’enficher dans les connecteurs femelles de l’Arduino :
Sur cette carte d’extension, j’ai câblé l’interface DCC ci-dessus et un régulateur de tension pour fournir le 5V nécessaire au fonctionnement de l’Arduino :
Puis j’ai réalisé une plaquette équipée de borniers à vis et l’ai reliée soigneusement aux Pins de l’Arduino sur la carte d’extension :
Il ne reste plus, ensuite, qu’à installer le programme et connecter les feux.
Le programme sans ’Accessories’
Après tout, pourquoi ne pas essayer : Je suis parti de l’article de Nicolas Zin : Un décodeur d’accessoire DCC versatile basé sur Arduino.
Voici le code qui est relativement court et facile à comprendre :
Tout d’abord, on déclare les ressources nécessaires :
#include <DCC_Decoder.h> // la bibliothèque de Minabay
#define kDCC_INTERRUPT 3 // la pin 20 du Mega2560 reçoit les interruptions du signal DCC
#define NB_FEUX 16 // 16 feux
#define NB_LEDS 3 // 3 leds par feu
Ensuite, les adresses DCC à utiliser, dans un tableau pour permettre l’usage de boucles avec index :
Maintenant, le routine Maj_Feux() qui va allumer ou éteindre les Leds en fonction de l’état DCC (sur 2 variables car associé à 2 adresses DCC) qui est converti en un état "State" compris entre 0 et 3 pour coder tout cela dans un switch :
void Maj_Feux() {
for (int i = 0; i < NB_FEUX; i++)
{
if (VALID_FEUX[i] == true)
{
// conversion des 2 etats en State compris entre 0 et 3
int State = STATE_FEUX[i*2] + STATE_FEUX[i*2+1]*2;
// positionnement des Leds
switch(State)
{
case 0: // rouge
digitalWrite(pins[i][0] , HIGH); //extinction Led verte
digitalWrite(pins[i][1] , HIGH); //extinction Led jaune
digitalWrite(pins[i][2] , LOW); //allumage Led rouge
break;
case 1: // jaune
digitalWrite(pins[i][0] , HIGH); //extinction Led verte
digitalWrite(pins[i][1] , LOW); //allumage Led jaune
digitalWrite(pins[i][2] , HIGH); //extinction Led rouge
break;
case 2: // jaune
digitalWrite(pins[i][0] , HIGH); //extinction Led verte
digitalWrite(pins[i][1] , LOW); //allumage Led jaune
digitalWrite(pins[i][2] , HIGH); //extinction Led rouge
break;
case 3: // vert
digitalWrite(pins[i][0] , LOW); //allumage Led verte
digitalWrite(pins[i][1] , HIGH); //extinction Led jaune
digitalWrite(pins[i][2] , HIGH); //extinction Led rouge
break;
}
VALID_FEUX[i] = false;
}
}
}
Puis la routine (handler en anglais) exécutée par la librairie DCC de Minabay quand une commande est arrivée :
void BasicAccDecoderPacket_Handler(int address, boolean activate, byte data)
{
// Conversion de l'adresse NMRA en adresse décodeur d'accessoire
address -= 1;
address *= 4;
address += 1;
address += (data & 0x06) >> 1;
int enable = (data & 0x01) ? HIGH : LOW;
if ((address >= DCC_CODE_START) && (address < DCC_CODE_START + NB_FEUX*2))
{
VALID_FEUX[(address - DCC_CODE_START)/2] = true;
STATE_FEUX[address - DCC_CODE_START] = enable;
Serial.print("@ ");
Serial.print(address);
Serial.print(" ");
Serial.print(STATE_FEUX[address - DCC_CODE_START]);
Serial.print(" feu ");
for (int i = 0; i < NB_FEUX; i++)
{
if (VALID_FEUX[i] == true)
{
Serial.print(i);
Serial.print(" etat ");
int State = STATE_FEUX[i*2] + STATE_FEUX[i*2+1]*2;
Serial.println(State);
}
}
}
}
A noter que la conversion d’adresse NMRA est une recette de cuisine qui fonctionne avec plusieurs centrales (heureusement). Les "Serial.print()" qui parsèment cette routine servent à voir ce qui se passe et peuvent être enlevés après la mise au point.
Maintenant le fameux SETUP qui initialise les variables tableaux, le port série, les modes de Pins et la bibliothèque DCC de Minabay :
void loop() {
static unsigned long timer=0;
////////////////////////////////////////////////////////////////
// passer le main à la bibliothèque DCC
DCC.loop();
////////////////////////////////////////////////////////////////
// on change l'etat des Leds toutes les 50 millisecondes
if (millis()-timer>50) {
Maj_Feux();
timer=millis();
}
}
Et ce programme fonctionne à merveille !
J’ai testé au départ avec ma petite MS2.
En respectant les branchements des Leds conformément à la table des Pins des Leds des Feux ci-dessus, et en programmant ces feux comme "Three Aspect Signal" avec Train Controleur :
Le résultat est immédiat via une console ESU ECOs.
On remarque qu’on a choisi d’allumer le Vert quand les 2 adresses sont au Vert, le rouge quand les 2 adresses sont au rouge et le jaune quand les 2 adresses sont différentes.
Le programme peut être téléchargé à partir d’ici :
Le programme avec Accessories
Ce code s’appuie sur la bibliothèque Commanders V1.23 du 31/12/2016 [2] et la bibliothèque Accessories V0.51 du 10/01/2017 [3].
Pour faire 16 feux, de trois leds chacun, avec une led allumée à la fois par un code Dcc, il nous faut passer par plusieurs étapes.
1 : Déclarer 16 accessoires multi leds avec trois leds chacun, en créant les ports nécessaires au fur et à mesure.
2 : Associer chaque led aux ports déclarés plus tôt.
On voit bien que le travail va être très répétitif, et peut être consommateur de mémoire programme... On a trois solutions pour parvenir au résultat :
1 : Force brute : les éléments sont tous déclarés et construits un par un. Avantage : c’est long, mais c’est le plus simple à coder, et le code est facile à comprendre. Inconvénient : il ne faut pas vouloir changer de méthode pour un feu... Parce qu’il faudra le refaire 16 fois !
2 : Boucles : le but à atteindre se prête très bien à l’utilisation de boucles. Il faut juste rendre configurable un maximum de choses, comme les pins utilisées ou le code Dcc associé à chaque feu. Avantage : si la méthode change pour un feu, elle est automatiquement appliquée à tous les feux. Inconvénient : la lisibilité devient passable...
3 : Version élégante : la voie royale consiste à créer une classe ’Feu’ qui va être instanciée 16 fois. La partie création d’un seul feu avec toutes ses implications est déporté dans cette classe. Avantage : le code principal est concis, simple à comprendre puisque pour un feu unique, et maintenable. Inconvénient : le côté C++ s’adresse à des connaisseurs... que vous êtes certainement devenus !
Le code pour un feu
Voyons le code pour un seul feu. Nous l’étendrons ensuite à plusieurs...
Nous allons commencer par une annexe, par la déclaration d’un bouton poussoir qui va servir à tester le fonctionnement, au cas où l’on soit sur un réseau analogique, ou que la centrale Dcc ne soit pas disponible, voire dans un cas extrême (et peu probable...) où l’on ait la flemme d’allumer ladite centrale !
On déclare d’abord tous les objets nécessaires : le poussoir, les trois ports utilisés, et le feu lui même :
Après l’initialisation des deux bibliothèques, on passe au begin du poussoir avec un premier identifiant, et sa broche à 1. On y ajoute ensuite deux autres identifiants avec AddEvent(). Chaque appui sur ce bouton enverra un code Dcc parmi les trois, l’appui suivant le code suivant, et ainsi de suite... J’ai choisi les codes Dcc 15/0, 15/1 et 16/0 pour chaque état du feu : vert, jaune, rouge.
Déclarons ensuite les ports sur l’Arduino, un port par Led sur les broches 9, 10 et 11.
L’accessoire feu pourrait être commandé pour tout allumer ou tout éteindre. Comme ce n’est pas le but ici, j’ai mis un identifiant volontairement excessif de 1000 pour ne pas risquer une mise en route malencontreuse...
Puis l’affectation de chaque led sur le bon port :
feu.beginLight(0, &portVert); // led verte (0)
feu.beginLight(1, &portJaune); // led jaune (1)
feu.beginLight(2, &portRouge); // led rouge (2)
Tous les éléments sont en place. Il nous faut maintenant déclarer les différents états (MovingPosition dans le jargon d’Accessories), un pour chaque led allumée tandis que les autres sont éteintes.
Le deuxième argument de la fonction AddMovingPosition() est un ’champ de bits’ sur un entier 8 bits qui représente la liste des leds de l’accessoire, avec 0 pour celles qui sont éteintes, 1 pour les allumées. Plusieurs notations sont possibles : désigner la troisième led par exemple peut se faire par trois moyens :
4 sous forme d’entier. C’est le plus évident.
0b00000100 qui représente huit bits, dont le troisième est à 1. Cette notation ne marche plus s’il y a plus de huit leds sur le feu...
1<<2 qui signifie 1 décalé deux fois vers la gauche. C’est à dire 00000001 au départ, puis 00000010, et enfin 00000100.
2 (on est en binaire) puissance 2, position du bit dans l’octet.
Résultat, si un code Dcc 15/0 est reçu, c’est la led verte qui est allumée, les autres leds seront éteintes. Pour 15/1, c’est la jaune qui va s’allumer, et pour 16/0, c’est la rouge. Si on voulait tout allumer par exemple avec le code Dcc 16/1, il faudrait ajouter une position Dcc avec 0b00000111 . Le dernier argument a un fonctionnement identique, mais pour faire clignoter certaines DELs. C’est pourquoi il est à zéro ici.
Le Setup est terminé. Le loop() est simple, il faut y faire figurer à la fois les Commanders et les accessoires :
La fonction de passage d’événement entre les deux bibliothèques doit aussi être présente avant le setup. C’est la fonction utilisée en argument du begin de Commanders :
void ReceiveEvent(unsigned long inId, COMMANDERS_EVENT_TYPE inEventType, int inEventData)
{
Accessories::ReceiveEvent(inId, (ACCESSORIES_EVENT_TYPE)inEventType, inEventData);
}
Le code pour plusieurs feux
J’ai choisi de coder une classe décrivant un seul feu, la troisième possibilité de codage vue plus haut donc. A noter que la classe doit être définie avant son utilisation, c’est pourquoi elle est en tête du fichier ino.
#include "Commanders.h"
#include "Accessories.h"
//------------------------------------------------------------------------------
// SignalArduino declaration
class SignalArduino : public AccessoryLightMulti
{
public:
void begin(byte inNbLeds, int *inpPins, int inStartingDcc);
};
//------------------------------------------------------------------------------
// SignalArduino definition
static byte counter = 0;
void SignalArduino::begin(byte inNbLeds, int *inpPins, int inStartingDcc)
{
// Je force l'appel au begin() de la classe de base AccessoryLightMulti
// pour faire ce qui est nécessaire pour un AccessoryLightMulti.
this->AccessoryLightMulti::begin(1000 + (counter++), inNbLeds, 0);
// puis j'ajoute ce qui est specifique à la classe 'SignalArduino'
for (int led = 0; led < inNbLeds; led++)
{
// Le port est créé ici et utilisé tout de suite.
// Inutile de le déclarer plus tôt ou d'en garder une trace dans une liste.
PortOnePin *port = new PortOnePin();
port->begin(inpPins[led], DIGITAL);
this->beginLight(led, port);
}
// Table de vérité sur le lien code Dcc / leds
// Led 0 1 2
// inStartingDcc / 0 on off off
// inStartingDcc / 1 off on off
// inStartingDcc+1 / 0 off off on
// inStartingDcc+1 / 1 off off off
this->AdjustMovingPositionsSize(inNbLeds);
int dcc = inStartingDcc;
bool etat = false;
for (int i = 0; i < this->GetSize(); i++)
{
if (!etat)
{
this->AddMovingPosition(DCCINT(dcc, 0), 1 << i, 0);
etat = true;
}
else
{
this->AddMovingPosition(DCCINT(dcc, 1), 1 << i, 0);
dcc++;
etat = false;
}
}
// Last moving position used to set all off.
this->AddMovingPosition(DCCINT(dcc, etat == true ? 1 : 0), 0, 0);
}
// End of class
//------------------------------------------------------------------------------
Cette classe est dérivée de AccessoriesLightMulti et ne comprend qu’une fonction : begin. En gros, c’est une factorisation du code de l’exemple précédent pour un seul feu. J’y ai ajouté des boucles pour permettre de choisir le nombre de DELs sans limitation.
Notez l’absence de valeur dans le premier crochet ’[]’ de la matrice ’pins’. En effet le compilateur déduira le nombre depuis la liste qui suit. Si cette matrice n’avait pas été initialisée tout de suite, il aurait fallu préciser le nombre de feux ! Cette notation est très pratique puisqu’elle permet de modifier le nombre de lignes de la matrice sans rien toucher d’autre. Accessoirement on est sûr de ne pas se tromper en confiant ce genre de boulot au compilateur ! Par contre le nombre d’entiers par ligne doit être fixé (NB_LEDS).
Puis les objets que nous utilisons dans les bibliothèques et les adresses DCC des 16 feux :
Initialisation du bouton de test des leds de tous les feux. ce bouton est connecté sur le port A2, la plupart des ports digitaux étant utilisés par les feux :
poussoir.begin(0, A2);
// Ce petit bouton va permettre de passer en revue tous les codes dcc des feux en séquence...
for (int feu = 0; feu < NB_FEUX; feu++)
{
poussoir.AddEvent(DCCINT(dcc_codes[feu], 0));
poussoir.AddEvent(DCCINT(dcc_codes[feu], 1));
poussoir.AddEvent(DCCINT(dcc_codes[feu] + 1, 0));
}
Initialisation des 16 feux :
for (int feu = 0; feu < NB_FEUX; feu++)
{
signaux[feu] = new SignalArduino();
signaux[feu]->begin(NB_LEDS, pins[feu], dcc_codes[feu]);
}
Comme dans l’exemple précédent ; il faut ajouter la fonction ReceiveEvent() citée plus haut.
Ce programme est simplement une adaptation de l’exemple "Signals4x3" de la bibliothèque Accessories.
Et le code est ici :
Le programme utilisant une interface avec Accessories
Cette interface permet à des personnes ne souhaitant pas entrer dans les détails informatiques de mettre en place des signaux sur une carte Arduino MEGA. Les signaux possibles peuvent être à 2 et/ou 3 feux, ce qui est le cas le plus général sur nos petits réseaux.
Le principe est le suivant :
On génère d’abord les accessoires pour les signaux à 2 feux, puis ceux pour les signaux à 3 feux. Il peut donc y avoir mixité, mais toujours les signaux à 2 feux en premier puis les signaux à 3 feux ensuite. La première broche de la première led est la broche 3. Les signaux à 2 feux correspondent à des doublons de broches (x, x+1) et des adresses y/0 et y/1, les signaux à 3 feux correspondent à des triplets de broches (x, x+1, x+2) et des adresses y/0, y/1, y+1/0. Rien n’empêche cependant de ne mettre aucun signal à 2 feux ou à 3 feux et donc de réaliser des décodeurs pour des signaux exclusivement à deux ou trois feux.
L’avantage est sa simplicité, on doit donner :
Le nombre de signaux à 2 feux (zéro possible)
Le nombre de signaux à 3 feux (zéro possible)
La première adresse DCC
La broche de la led témoin du DCC
La broche du bouton
J’ai testé avec mon ECOS et cela marche très bien. Attention cependant à la limite de courant à ne pas dépasser pour toutes les broches (voir en début d’article). Une valeur de 16 feux semble raisonnable. La bibliothèque TrafficSignal est chargeable à la fin de l’article.
Le croquis ino est très simple :
On instancie les signaux : TrafficSignal signaux ;
On fait le setup : Signaux.Setup(nbsignauxa2leds,nbSignauxa3leds, code_DCC, pinLedStatus, pinBouton) ;
Puis on boucle : Signaux.Loop()
Exemple de programme Arduino
#include <TrafficSignal.h> // la gestion des signaux
#define NB_FEUX_2 8 // nombre de signaux a 2 feux
#define NB_FEUX_3 8 // nombre de signaux a 3 feux
#define ID_DCC 40 // adresse DCC de départ du premier feu
#define LED_STATUS 53 // la broche de la led temoin DCC
#define BUTTON_PIN A15 // la broche du bouton de test
TrafficSignal signaux; // une instance des signaux
void setup()
{
signaux.Setup(NB_FEUX_2, NB_FEUX_3, ID_DCC, LED_STATUS, BUTTON_PIN);
}
void loop()
{
signaux.Loop();
}
La réalisation de décodeurs pour des signaux ferroviaires est tout à fait réalisable avec des Arduino, ce n’est que de la gestion de Led.
La première solution permet de comprendre la complexité des messages DCC, leur réception, leur décodage et les actions à entreprendre. Cependant cela impose un certain effort de programmation.
La deuxième approche basée sur Commanders et Accessories, très bien architecturée, soulage le développement mais la grande quantité de ces méthodes demande une investigation non négligeable.
Enfin la dernière approche permet rapidement de réaliser des décodeurs de signaux sans rentrer dans les détails de ces bibliothèques.
On peut donc, pour un coût très modique et rapidement, gérer 16 signaux à trois feux sur un Arduino Mega.
Cependant on peut faire quelques remarques. La première concerne l’utilisation de la bibliothèque Accessories seulement pour gérer des signaux ferroviaires est un luxe et sera beaucoup plus efficace si on l’utilise avec d’autres types d’activités comme la gestion des barrières de PN ou autres, ou cette bibliothèque montrera toute sa puissance et prendra tout son intérêt. La seconde concerne l’utilisation d’un Arduino MEGA à cause du nombre important de pins (48) utilisées pour 16 feux tricolores. Personnellement je préfère les Nano qui me permettent une meilleure répartition sur le réseau et donc d’avoir moins de câblage.
Le DCC, par sa vocation, est très efficace pour l’envoi des commandes sur le réseau et le bus CAN pour la rétro signalisation (ou la commande d’accessoires de décors). Un prochain article permettra de détailler cette approche distribuée au sein de nos réseaux !
Je voudrais d’abord m’excuser parce que j’ai détruit votre dernier message en cliquant sur le mauvais bouton... Sachez que ce n’était pas volontaire ! J’en reproduit le texte ci dessous :
’J’ai installe le programme sur mon arduino et le texte qui s’affiche c’est seulement
"DCC 16 Feux en route (V1)’ et plus rien !!!’
Au delà de cette péripétie, Dominique a raison de dire que nous ne pourrons pas vous aider si vous ne vous expliquez pas. Quelle version du programme utilisez vous, il y en a trois dans l’article ? Si vous avez lu l’article et les commentaires présents dans les codes sources, la réponse à la broche utilisée pour le Dcc est dedans, et c’est dépendant de ce que vous avez mis pour le numéro d’interruption kDCC_INTERRUPT. Quand vous dites ’un texte qui s’affiche’, il s’affiche où ? Enfin il n’a été question nulle part d’un logiciel comme Train Controller connecté à un réseau. Tous les tests ont étés effectués avec une centrale MS2 de Trix/Marklin .
En ce qui concerne la première version, je viens de voir l’heureux bénéficiaire qui s’en sert avec TrainController et ça fonctionne toujours depuis plus d’un an.
Thierry à raison, vous devez chercher ce qui diffère dans votre montage par rapport aux descriptions dans l’article, qui fonctionnent.
Bonjour, je vous remercie de vos différents conseils.
Apres avoir contrecolle le montage du 6N137, j’ai constaté la diode 1N4148 en court circuit !!!!
Je l’ai remplacée ainsi que le 6N137 par précaution, a priori je n’arrive pas a communiquer de la centrale z21 avec ARDUINO.
Aucun paquet DCC ne rentre.
Je vais continuer a persévérer.
Merci
Enfin je suis arrivé a faire fonctionner les feux !!
J’avais différents problèmes d’éléments électroniques.
Il me reste un problème, tant que les locomotives fonctionnent, je ne peut plus commander les feux.
Quand toutes les locomotives sont à l’arrêt, arduino décode les feux et ils ré-fonctionnent !?!?
Ravi de voir que votre problème avance, mais je ne peux rien pour vous si vous ne voulez pas me dire quelle version vous utilisez ! Pour affiner le problème, branchez un moniteur de paquet (article http://www.locoduino.org/spip.php?a...) et voyez si les paquets concernant les accessoires arrivent bien jusqu’à l’Arduino.
Désolé, la version pour Arduino est la 1.8, avec le moniteur de paquets je vois que les paquets passent mais je n’arrive pas à déceler lesquels correspondent aux accessoires !!!
Non, je parlais du croquis Arduino. Vous utilisez la version simple, la version objet, ou la version avec Accessories de l’article ? Demain, j’essaierai de vous faire passer mon propre moniteur qui se concentre sur les accessoires...
Bonjour, avec le programme originale pas de problème tout fonctionne bien
Avec CDMRAIL et des première adresse impaire, ça ne fonctionne pas .
J’ai changer la ligne 3 # define au lieu de 100 j’ai mis 99.
ensuite j’ai changer les adresses 99, 101,103,105 etc,,
ça fonctionne a moitié avec l’adresse 99 le rouge et l’orange fonctionne, avec l’adresse 100 le vert ne fonctionne pas le rouge et l’orange s’inverse
y a t’il une autre modification a faire
Bonjour, pourriez - vous me dire quels sont les composants pour réaliser le décodeur pour 16 signaux avec la carte proto Shield. Merci de votre réponse.
Bien à vous
ce sont les composants du schéma (dit Mynabay ou Dave Falkenburg) :
une résistance de 1K
deux résistances de 10K
un condensateur de 270 pF
une diode 1N4148
un optocoupleur 6N137
Une fois traité par ce montage, le signal DCC va à la broche 2 de l’Arduino.
Bonjour. Merci de votre réponse, mais est-il est possible d’avoir les composants pour l’Arduino méga et le schéma du câblage pour le décodeur DCC pour 16 feux tricolores pour la version simple. Merci de votre réponse. Cordialement.Bardiaux
C’est curieux, que vous manque-t-il de plus que ce qui est décrit en détail ?
Un schéma ? Le seul que j’ai est ici : https://www.locoduino.org/IMG/jpg/d...
Bonsoir, je voudrais réaliser le montage qui est dans l’article du décodeur DCC pour 16 feux tricolores, il y a une photo d’un proto shield avec ses composants et une autre avec son câblage c’est cela que je cherche rien d’autre, donc en gros le cherches les composants pour le proto Shield et le schéma de câblage pour l’autre. Merci de votre réponse. Bien à vous.
Bonjour, avez-vous une version du programme en version adresse impaire, comme pour le décodeur a 5 feux qui fonctionne très bien.
sinon pouvez-vous m’indiquer les modifications a faire dans le programme
Je m’inspire de vos nombreux articles pour réaliser plusieurs modules Arduino.
Notamment les feux de signalisation et les aiguillages.
Pour chaque module, je me rends compte qu’il faut une carte Arduino et a chaque fois un octocoupleur
Question simple et peut être bête. Peut-on n’avoir qu’un seul octocoupleur et brancher plusieurs cartes Arduino sur celui ci (une carte pour les feux de signalisation,une carte pour les aiguillages,..) ?
Bonjour , oui mais il ne faut pas exagérer sur la distance entre l’optocoupleur et les arduinos (50cm ...) ni le nombre d’arduinos ... 5
je pense qu’il n’y a cependant rien de critique , il faut tester et vérifier au moniteur que tous les messages sont bien reçus