Mon réseau T-Trak comportant maintenant 13 aiguillages, le pilotage de ces accessoires via la Multimaus n’est pas vraiment simple. De plus mon module de dépôt doit participer à une exposition et sera donc exploité par de nombreux modélistes différents. Pour faciliter les manipulations j’ai donc cherché à faire un TCO.

J’ai trouvé sur le net plusieurs sources d’informations pour réaliser un TCO qui se branche comme une « souris esclave » sur la centrale ROCO en étant connecté au bus Xpressnet. Pour réaliser ceci un arduino mega 2560 est utilisé.
Voici donc pour commencer mes sources de travail:

C’est sur ce dernier site que j’ai trouvé le document  .pdf le plus compréhensible pour réaliser le TCO et le programme .ino pour l’arduino avec seulement quelques variables à modifier.

En recherchant un Max485 pour réaliser le montage de l’interface série j’ai trouvé sur le net des petits modules RS-485 tout prêt pour arduino.

J’en ai donc acheté un et ai décidé de l’utiliser pour ce TCO afin de simplifier encore plus le montage.
On peut trouver de la documentation sur ce module assez facilement par exemple ici.

Je vous propose de vous faire part de mon expérience. En effet j’ai réalisé un petit schéma de câblage de l’arduino mega 2560 avec ce module RS485 TTL directement utilisable avec le programme de l’UAICF.

J’ai utilisé une rallonge RJ12 de chez Leroy Merlin sur laquelle j’ai coupé une des prises. Après avoir branché ce câble sur la centrale allumée, j’ai repéré les fils de masse et de +12v en provenance de la prise slave de la centrale ROCO grâce à un multimètre.

Voici le détail des branchements pour la communication entre la centrale ROCO et l’Arduino:

  • Masse du câblage RJ12 sur borne GND du module
  • +12V du câblage RJ12 sur borne VIN de l’arduino mega
  • Fils de données A et B du câblage branchés sur le bornier vert à vis en A et B (intervertir l’ordre si la communication avec la centrale ne se fait pas. On peut aussi ajouter une résistance de 120 Ohm entre les bornes pour déparasiter le signal.)
  • Borne RO du module connectée à la pin 19 (RX1) de l’arduino
  • Borne DI du module connectée à la pin 18 (TX1) de l’arduino
  • Bornes DE et RE reliées ensemble vers la pin 3 de l’arduino conformément au programme del’UAICF (une résistance de 470 Ohm et une diode branchés entre le +5v et le fil permettent de contrôler la bonne connexion de la sortie avec l’arduino)

Connexion des interrupteurs de commande:

Pour le contrôle des différents aiguillages j’ai choisi d’utiliser des interrupteurs à leviers ON-ON (mais on peut aussi utiliser 2 boutons poussoirs par aiguille). Ces interrupteurs sont montés avec une résistance de 10KOhm en mode PULL-UP sur les entrées de l’arduino:

  • Un coté de la résistance est connecté au +5v
  • l’autre coté sur une des bornes de l’interrupteur.
  • cette même borne est connecté à une pin d’entrée de l’arduino
  • la deuxième borne de l’inter est relié à la masse de l’arduino

Voici le schema ci-dessus au format fritzing:

Le programme pour l’arduino

Dans le programme on définit les adresses DCC des aiguilles et les entrées correspondantes des inter sur l’arduino. Il faut aussi installer la librairie Xpressnet.

                //**************************************************//
                //                                                  //
                //         Programme pour réaliser le TCO           //
                //                du pupitre DEMO                   //
                //          avec carte Arduino MEGA 2560            //
                //                                                  //
                //         TCO pour module Demo Aiguillage          //
                //                                                  //
                //             UAICF Nevers-Vauzelles               //
                //          http://modelisme58.free.fr              //
                //                                                  //
                //            Novembre 2015 - Vers 1.3              //
                //                                                  //
                //**************************************************//

//-------------------------------------------------------------------------
// Bibliothèques nécessaires

//----------------------------------------------------------------------------
#include <XpressNet.h> 
XpressNetClass XpressNet;

#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  #define SerialDEBUG 1  //For Serial Port Debugging (Arduino Mega only)
#endif 

#if SerialDEBUG
  #include <SoftwareSerial.h>
  SoftwareSerial Debug(0, 1); // RX, TX - Mettre sur 0 et 1 pour MEGA 2560
#endif

//-------------------------------------------------------------------------
// /|\ Variables à modifier ----------------------------------------------- /|\
// Définition des adresses des aiguillages et entrées utilisés sur la carte Arduino MEGA

int Aig[]          = { 0,1};  // Adresse DCC des aiguillages, la premiere adresse 0 correspond arret d'urgence
int Bt[]           = {23,24};  // Bornes de la carte ARDUINO

int NbreBoutons = 0;	       // Nbre total de boutons
int NbrePoussoirs = 0;         // Nbre d'aiguillages commandés par Bouton Poussoir
int NbreLevier = 1;            // Nbre d'aiguillages commandés par Bouton Levier

#define XNetAddress 15        // Adresse de la souris XpressNet : 2 souris Xpressnet ne pourront pas avoir la même adresse
                              // Valeur entre 1 et 31

// /|\ Fin des variables à modifier --------------------------------------- /|\
//-------------------------------------------------------------------------

//-------------------------------------------------------------------------
// Définition des variables et constantes

int BtEtat[100] ;  
int BtEtatAncien[100] ; 

byte Led = 13;
int DCCEtat;
long previousMillis = 0;

#define XNetSRPin 3       // Max485 Bus du driver relié à la borne de l'Arduino

//-------------------------------------------------------------------------
// Initialisation du programme
void setup() {                

  delay(1000);

  NbreBoutons = NbrePoussoirs + NbrePoussoirs + NbreLevier + 1;
  
for (int i=0; i < NbreBoutons; i++)
{
  BtEtat[i] = 2;
  BtEtatAncien[i] = 1;
  pinMode(Bt[i], INPUT_PULLUP); 
}
  pinMode(Led, OUTPUT);
  
  delay(100);
  
  Serial.begin(9600);
  Serial.println("UAICF Nevers-Vauzelles - http://modelisme58.free.fr");
  Serial.println("Octobre 2015 - Vers 1.2");

  XpressNet.start(XNetAddress, XNetSRPin);
  XpressNet.setPower(csNormal);

  Serial.print("  --> Etat Centrale DCC = ");
  Serial.println(XpressNet.getPower());
  Serial.println("");
  
  for (int i=0; i < NbreBoutons; i++)
    {
    BtEtat[i] = digitalRead(Bt[i]);
    Serial.print(" Borne Arduino : "); Serial.print(Bt[i]); Serial.print(" | Etat = "); Serial.println(BtEtat[i]);
    delay (10);
    }

  XpressNet.receive();
  
  Serial.println("--- Initialisation des positions des Aiguillages avec bouton a levier uniquement ---");
  // Uniquement pour les aiguillages commandés par un bouton à levier  
  for (int i = NbrePoussoirs*2 +1; i < NbrePoussoirs*2 + NbreLevier +1; i++)
    {
    if (BtEtat[i] != BtEtatAncien[i])
      {
        Serial.print("   Aiguillage ayant l'adresse DCC "); Serial.print(Aig[i]);
        Serial.print(" (Borne "); Serial.print(Bt[i]);
        BtEtatAncien[i] = BtEtat[i] ;
        XpressNet.setTrntPos (0x0, Aig[i]-1, BtEtat[i] );
        delay (200);
        XpressNet.setTrntPos (0x0, Aig[i]-1, BtEtat[i] );
        delay (750);
      }
    }
  Serial.println("--- Fin Initialisation des positions des Aiguillages ---");
  Serial.println("--- Fin initialisation du programme ---");   Serial.println(" ");
  digitalWrite(Led, HIGH);

}

//-------------------------------------------------------------------------
// Programme fonctionnant en boucle

void loop() {

  // Récupére l'état des entrées  
  for (int i=0; i < NbreBoutons; i++)
    {
    BtEtat[i] = digitalRead(Bt[i]);
    delay (1);
    }

  XpressNet.receive();

  unsigned long currentMillis = millis();

  // --- Commande pour Arret d'Urgence --------------------------------------------

  if (BtEtat[0] == 0 && DCCEtat == 0)
      {
      XpressNet.setHalt();
      delay (500);
      if (DCCEtat == 0)
          {
          digitalWrite(Led, LOW);
          Serial.println(" ");
          Serial.println(" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ");
          Serial.println(" !!! --- Arret d'Urgence --- !!! ");
          delay (1000);
          previousMillis = currentMillis;
          }
      }

  if (BtEtat[0] == 0 && DCCEtat > 0 && (currentMillis - previousMillis > 5000) )
      {
      XpressNet.setPower(csNormal);
      delay (500);
      if (DCCEtat > 0)
        {
        digitalWrite(Led, HIGH);
        Serial.println(" ");
        Serial.println(" --- DCC Ok --- ");
        previousMillis = currentMillis;
        }
      }

  // Envoie de la commande DCC pour accessoires si changement de l'état des entrées  

if (DCCEtat ==0)  // Si pas d'arrêt d'urgence d'enclenché
{
  // --- Commande pour Boutons à levier --------------------------------------------
  for (int i = NbrePoussoirs*2 +1; i < NbrePoussoirs*2 + NbreLevier +1; i++)
    {
    if (BtEtat[i] != BtEtatAncien[i])
      {
        Serial.print("Aiguillage ayant l'adresse DCC "); Serial.print(Aig[i]);
        Serial.print(" (Arduino "); Serial.print(Bt[i]);
        BtEtatAncien[i] = BtEtat[i] ;
        XpressNet.setTrntPos (0x0, Aig[i]-1, BtEtat[i] );
        delay (10);
      }
    }
    

  // --- Commande pour Boutons Poussoirs --------------------------------------------
  // Commande Position 1
  for (int i=1; i < NbrePoussoirs*2 +1; i=i+2)
    {
    if (BtEtat[i] != BtEtatAncien[i] && BtEtat[i] == 0 && BtEtat[i+1] == 1)
      {
        Serial.print("Aiguillage ayant l'adresse DCC "); Serial.print(Aig[i]);
        Serial.print(" (Arduino "); Serial.print(Bt[i]);
        BtEtatAncien[i] = 0;
        BtEtatAncien[i+1] = 1;
        XpressNet.setTrntPos (0x0, Aig[i]-1, 0 );
        delay (1);
      }
    }
    
  // Commande Position 2
  for (int i=2; i < NbrePoussoirs*2 +2; i=i+2)
    {
    if (BtEtat[i] != BtEtatAncien[i] && BtEtat[i] == 0 && BtEtat[i-1] == 1)
      {
        Serial.print("Aiguillage ayant l'adresse DCC "); Serial.print(Aig[i]);
        Serial.print(" (Arduino "); Serial.print(Bt[i]);
        BtEtatAncien[i] = 0;
        BtEtatAncien[i-1] = 1;
        XpressNet.setTrntPos (0x0, Aig[i]-1, 1 ); 
        delay (10);
      }
    }
}
  // Fin de l'envoi de la commande DCC pour accessoires si changement de l'état des entrées  

}
//-------------------------------------------------------------------------
// Message pour débogage

void notifyTrnt(uint8_t Adr_High, uint8_t Adr_Low, uint8_t Pos)
{
  Serial.print(") ---> Position = "); 
  Serial.println(Pos, DEC); 
}

//-------------------------------------------------------------------------
void notifyXNetPower (uint8_t State)
{
  Serial.print("  --> Etat Centrale DCC = ");
  Serial.println(State, HEX);
  DCCEtat = State;
  
}
TCO Xpressnet

 

Il y a quelques paramètres à modifier qui sont clairement expliqués dans le code et dans le fichier pdf édité par l’UAICF. Voici ceux correspondant à mes besoins pour exemple:

//-------------------------------------------------------------------------
// /|\ Variables à modifier ----------------------------------------------- /|\
// Définition des adresses des aiguillages et entrées utilisés sur la carte Arduino MEGA

int Aig[]          = { 0,10,12,20,21,22,23,24,25,30,31,32,33,34};  // Adresse DCC des aiguillages
int Bt[]           = {23,24,25,26,27,28,29,30,31,32,33,34,35,36};  // Bornes de la carte ARDUINO

int NbreBoutons = 0;	       // Nbre total de boutons
int NbrePoussoirs = 0;         // Nbre d'aiguillages commandés par Bouton Poussoir
int NbreLevier = 13;            // Nbre d'aiguillages commandés par Bouton Levier

#define XNetAddress 15        // Adresse de la souris XpressNet : 2 souris Xpressnet ne pourront pas avoir la même adresse
                              // Valeur entre 1 et 31

// /|\ Fin des variables à modifier --------------------------------------- /|\
//-------------------------------------------------------------------------
variables à modifier

Réalisation du T.C.O

J’ai trouvé chez Cultura une boite à thé en bois avec 6 compartiments parfaitement adaptée à mon projet. Elle a la taille d’une feuille A5. J’ai donc dessiné mon TCO au format vectoriel avec l’emplacement des interrupteurs.
Une fois la feuille imprimée je l’ai collée avec un vernis colle pour papier.
Ensuite j’ai percé l’emplacement des leviers.

J’ai enfin pût m’atteler au câblage de mes 15 interrupteurs ce qui m’a pris une bonne après-midi !!

Lors des essais du TCO, si la position d’un interrupteur est inversée par rapport à la position de l’aiguillage souhaitée, il suffit de changer le fil de masse sur l’autre borne de l’interrupteur étant donné que j’ai câblé les +5v sur la borne centrale des interrupteurs.

Il me reste un dernier détails qui ne fonctionne pas, en effet impossible d’actionner un aiguillage kato relié à un décodeur digitrax DS51K1. J’arrive à changer l’adresse du décodeur via le TCO, mais l’aiguillage n’est pas actionné !!
Si quelqu’un a une idée à me soumettre cela serait bien.

Pour finir voici une petite vidéo de présentation: