LOCODUINO

Aide
Forum de discussion
Dépôt GIT Locoduino
Flux RSS

mardi 19 mars 2024

Visiteurs connectés : 19

Décodeur pour aiguillage à solénoïdes sur Arduino

.
Par : JPClaude

DIFFICULTÉ :

Nous proposons dans cet article la réalisation d’un décodeur d’ aiguillages à solénoïdes sur une base d’Arduino NANO aussi bien en mode TCO (et oui on peut s’amuser sans avoir le DCC) pour quatre aiguillages avec leurs boutons et leurs leds de positionnement, qu’en mode DCC pour huit aiguillages et une extension avec la bibliothèque de Thierry pour Arduino MEGA qui permet d’avoir jusqu’à 32 aiguillages. On présente d’abord de façon rapide le principe des aiguillages à solénoïdes, puis les interfaces possibles de commande de ces derniers, enfin les réalisations de ces décodeurs et des idées de réalisation de cartes. En fin d’article vous trouverez également un petit circuit qui permet de protéger les bobines en cas de dysfonctionnement (bouton coincé ou circuit intégré qui dégénère), cela m’est arrivé avec un ULN2803A qui a maintenu ses sorties du fait d’une mauvaise soudure (adieu pour la bobine concernée).

<

Principe des aiguillages à solénoïdes

Ces aiguillages sont basés sur des moteurs à deux bobines avec un barre en fer doux attirée d’un côté ou de l’autre en fonction de l’alimentation d’une des bobines. Le principe est donc simple, si on alimente une bobine l’aiguille se déplace dans un sens, si on alimente l’autre elle se déplace dans l’autre sens. Ces bobines demandent un fort courant (500mA à 2A pour certain modèle) mais sur un laps de temps très court sous peine de voir griller les bobines. Il existe plusieurs types d’aiguillage, les simples à deux directions, les triples à trois directions et les TJD (Traversée Jonction Double) à quatre positions. Un aiguillage simple est composé d’un moteur, les aiguillages triples de deux moteurs, on peut aller jusqu’à quatre moteurs pour des TJD. Dans tous les cas il suffit de savoir générer la bonne impulsion pour faire varier un des moteurs.
Par exemple dans le cas d’un simple aiguillage il suffit d’envoyer l’impulsion sur une des bobines pour faire varier la position de l’aiguillage. Il suffit de deux broches (une pour chaque sens) et une adresse DCC (DCC/0 et DCC/1).
Dans le cas d’aiguillage triple il faut commander deux moteurs. Il faut donc 4 broches et deux adresses DCC. N’ayant que trois directions, il faut faire attention au mouvement des aiguilles. Par exemple dans le cas des aiguillages PECO type SL99 il faut respecter la table de vérité suivante :

Il y donc une position interdite. Il faut faire attention lorsque l’on branche les points A, B, C et D sur les broches de l’Arduino.

La commande des aiguillages à solénoïdes

Nous ne parlons ici que des aiguillages à solénoïdes. Ces aiguillages demandent une impulsion entre 500mA et 2A pour les plus gros mais avec une courte durée de 50 à 300ms généralement. Il y a donc deux aspects à prendre en compte, le premier est la durée, c’est à l’Arduino de gérer cette durée, le second est de générer un courant suffisant, que l’Arduino ne peut fournir, par une interface en sortie des broches de l’Arduino.

Durée de l’impulsion

Elle ne pose aucun problème puisque prise en compte dans la bibliothèque UAD, il suffit donc de déterminer la durée en ms et de fournir cette valeur au programme.

Génération du courant d’impulsion

Il existe plusieurs possibilités pour réaliser cette génération, les relais, l’interface L298N, le L9110 ou l’interface ULN2803A. On trouve l’ensemble de ces composants pour quelques Euros. Je souligne que je n’ai pas utilisé le L293D car il monopolise trop de broches sur le MEGA.

Les relais

On trouve des interfaces qui vont de 2 à 16 relais à 1RT. Ce qui veut dire qu’un seul relais ne peut commander qu’une seule bobine, il faut donc deux relais pour un moteur d’aiguillage. Chaque broche INx est reliée à une broche de l’Arduino. Lorsque la broche est haute (HIGH) le relais est au repos et lorsqu’elle est basse (LOW) le relais travaille.

Les bornes du relais sont les suivantes :

  • GND : la masse de l’Arduino
  • VCC : le 5V de l’Arduino
  • IN1 à INx : les broches de commande des relais, connectées aux broches digitales de l’Arduino, actives quand LOW.
  • STRAP : si le strap est mis on utilise le 5v de l’Arduino, les optocoupleurs sont shuntés, si on enlève le strap il faut fournir une tension (5V ou 12V suivant le type de relais), dans ce cas les optocoupleurs agissent et isolent l’Arduino.
  • COMMUN : alimentation du relais (jusqu’à 220V et 10A !!), le commun des bobines.
  • Permanent : sortie permanente du relais (position repos)
  • Commuté : sortie commutée du relais (position travail), l’entrée d’une bobine

Les relais permettent d’avoir de forte puissance et donc de s’adapter à tout type d’aiguillage, mais ont l’inconvénient d’être bruyants et consommateurs d’énergie. La consommation est de 70mA par relais actionné.

Voici la connexion pour un aiguillage

L’interface L298N

Cette interface contient un double pont H, il peut contrôler deux moteurs CC ou un moteur pas à pas. Ce module supporte des courants de 3A max (2A en fonctionnement continu). La puissance maximale est de 25W. Il possède des diodes de protection rapide pour le pont en H et une grande capacité de filtrage. Ce module coûte moins de 5€.

Les bornes sont les suivantes :

  • 1 : - de la bobine 1 du moteur 1
  • 2 : - de la bobine 2 du moteur 1
  • 3 : strap 12V, il faut l’enlever si on utilise une tension supérieure à 12V (35V max)
  • 4 : tension du moteur (enlever le strap si supérieur à 12V), le + commun des moteurs
  • 5 : GND, relier les masses de l’Arduino et de l’alimentation externe
  • 6 : sortie 5V si le strap est mis (peut alimenter l’Arduino)
  • 7 : enable jumper pour le moteur 1 (à connecter dans le cas PWM), laisser le strap ici
  • 8, 9, 10, 11 : les entrées de commande de l’Arduino, actives quand LOW
  • 12 : enable jumper pour le moteur 2 (à connecter dans le cas PWM), laisser le strap ici
  • 13 : - de la bobine 1 du moteur 2
  • 14 : - de la bobine 2 du moteur 2

Ce petit module est très intéressant car d’un coût très faible et permettant de gérer des aiguilles à forte demande d’intensité, comme les moteurs PECO. Il ne demande que 36mA au maximum par broche.

Voici la connexion pour un aiguillage

L’interface L9110

Ce composant permet de contrôler un moteur CC (c’est un pont en H). Il admet des tensions entre 2,5V et 12V pour une intensité de 800mA par sortie en continu. (Je remercie Denis qui m’a fait connaitre ce composant). Le schéma est le suivant :

IA et IB sont les commandes des sorties OA et OB respectivement, actives quand LOW.
et le schéma de connection est le suivant :

La bobine 1 est activée quand IA est LOW et la bobine 2 quand IB est LOW.

L’interface ULN2803A

Ce composant offre 8 sorties en Darlington pour une tension de 50V max et 500mA par sortie (attention pas de mélange de tension en sortie). Sa structure est simple comme le montre le schéma suivant :

Les connections sont des plus faciles, il faut relier les entrées 1 à 8 aux broches de commande de l’Arduino, actives quand HIGH, les sorties 1 à 8 aux moins des bobines et la broche 10 au plus des moteurs (diodes anti-retour).
Afin d’avoir plus d’intensité on peut relier deux sorties entre elles ce qui permet d’avoir 1A, mais attention pas plus sinon ça chauffe !!.

Voici la connexion pour un aiguillage

Un méga relié à un moteur à solénoïde via un driver ULN2803

Conclusion

On a donc à notre disposition un panel large pour gérer nos aiguillages que l’on peut résumer de la manière suivante :

Réalisation d’un décodeur pour 4 aiguillages à solénoïdes en mode TCO (sans DCC)

Dans ce mode 4 aiguillages peuvent être contrôlés par 4 boutons et 8 leds qui fournissent au TCO la position des aiguilles. Les commandes des moteurs pour cet exemple sont faites via des ULN2803A qui ont l’avantage d’être simple à mettre en place et qui fournissent un courant d’un ampère pour une tension max de 35V. Le schéma de principe est le suivant :

Chaque bouton est une bascule qui change la position d’un aiguillage et allume la led correspondante. Les leds sont commandées par 4 ports de l’Arduino, une partie des leds (bobine1) sont commandées au plus, l’autre partie (bobine2) est commandé au moins. Pour ceux qui le souhaitent voici une idée de carte à réaliser. Les borniers d’aiguillages permettent de connecter les bobines des aiguillages, les borniers leds permettent de connecter les leds du TCO (en tenant compte des polarités) et les borniers boutons pour les boutons du TCO en mode PULLUP :

Le programme INO est le suivant (fichier cde_aiguillage_Nano_TCO) :

/*
 * commande de 4 aiguillages sur Arduino UNO/NANO sans DCC avec bouton et led pour TCO
* les boutons sont traites avec anti-rebond
 * Les leds indiquent la position de l'aiguillage sur le TCO
 * Configuration :
 * aiguillage 1 : bobine1 : broche 3, bobine2 : broche 4
 * aiguillage 2 : bobine1 : broche 5, bobine2 : broche 6
 * aiguillage 3 : bobine1 : broche 7, bobine2 : broche 8
 * aiguillage 4 : bobine1 : broche 9, bobine2 : broche 10
 * led aiguillage 1 : broche 11
 * led aiguillage 2 : broche 12
 * led aiguillage 3 : broche 13
 * led aiguillage 4 : broche A0
 * bouton aiguillage 1 : broche A1
 * bouton aiguillage 2 : broche A2
 * bouton aiguillage 3 : broche A3
 * bouton aiguillage 4 : broche A4
 * 
 */

/******************************************************************************************
 * 
 * LES PARAMETRES DE CONFIGURATION a definir par l'utilisateur
 * CONSOLE : pour avoir le deroulement du programme, si pas necessaire supprimer la ligne
* *********************************************************************************************/
 
 #define CONSOLE                         // sortie console du deroulement
 #define DEBIT_CONSOLE    115200         // le debit de la console
 #define ACTIVATION        250           // duree d'activation des bobines en ms ( a modifier si necessaire) 

 /***********************************************************************************************
  * 
  * LES PARAMETRES INTERNES
  * 
  * ************************************************************************************************/
#define TRAVAIL   LOW         // LOW pour Relais, L298N, L9110; HIGH pour ULN2803A
#define REPOS     HIGH        // HIGH pour Relais, L298N, L9110; LOW pour ULN2803A
#define BOBINE1   HIGH        // position sur bobine1
#define BOBINE2   LOW         // position sur bobune2

#define DELAI_ANTI_REBOND  50

/////////////////// LES AIGUILLAGES  ///////////////////////////////////////////////////////

#define FIRST_PIN         3             // broche de depart des aiguillages

//// STRUCTURE D'UN AIGUILLAGE ////

struct TurnOut {
  int position_actuelle;                    // etat, bobine1 ou bobine2
  int bobine1;                              // broche bobine 1
  int bobine2;                              // broche bobine 2
  int bouton;                               // broche du bouton TCO a bascule
  int etat_bouton;
  int ledBobine;                            // broche de la Led TCO pour les bobines
  boolean demande_activation;     // demande d'activation, bouton bascule
};
#define NB_TURNOUT        4       // le nombre  d'aiguillages
TurnOut turnout[NB_TURNOUT];      // l'ensemble des aiguillages

/********************************************************************
 * 
 * METHODE APPELEE SI UNE DEMANDE DE MISE A JOUR PAR LE BOUTON
 * Determine periodiquement les bobines a activer
 * 
 *******************************************************************/
 
void activation_aiguillage(int i) {
    int etat = turnout[i].position_actuelle;
    if (turnout[i].demande_activation == true)         // si l'aiguillage i est en attente d'activation
    {
      if (turnout[i].position_actuelle==BOBINE1){                   // bobine 1  --> bobine 2
                      digitalWrite(turnout[i].bobine2,TRAVAIL);     // activation
                      delay(ACTIVATION);                         // duree de l'activation
                      digitalWrite(turnout[i].bobine2,REPOS);      // arret de l'activation
                      digitalWrite(turnout[i].ledBobine, LOW);
                      etat = BOBINE2;
                      #ifdef CONSOLE
                        Serial.print("activation -> aiguillage");Serial.print(i);Serial.println(" : bobine2");
                      #endif
                      }
        else{                                                      // bobine 2 --> bobine 1
                      digitalWrite(turnout[i].bobine1,TRAVAIL);      // activation
                      delay(ACTIVATION);                          // duree de l'activation
                      digitalWrite(turnout[i].bobine1,REPOS);       // arret de l'activation
                      digitalWrite(turnout[i].ledBobine, HIGH);
                      etat = BOBINE1;
                      #ifdef CONSOLE
                        Serial.print("activation -> aiguillage");Serial.print(i);Serial.println(" : bobine1");
                      #endif
              }
    }
   turnout[i].position_actuelle = etat;                 // etat de la bascule
  turnout[i].demande_activation = false;                // l'aiguillage a etait traite
 }


/************************************************************************************* 
 *  
 *  METHODE de test des boutons avec anti rebond 
 *  determine si un aiguillage est concerne par l'appui d'un bouton
 *  
 ***********************************************************************************/

boolean boutonTest(int i)
{   turnout[i].demande_activation = false;
    int etat = digitalRead(turnout[i].bouton);
    int tempo = millis();
    while ((millis() - tempo) < DELAI_ANTI_REBOND) {}
    if (etat == LOW){turnout[i].demande_activation = true;}
  return turnout[i].demande_activation;
}

/**********************************************************************************************
 * 
 * le setup
 * initialise les aiguillages 
* 
******************************************************************************************/

void setup() {
  int decal = 0;
  for (int i=0; i<NB_TURNOUT; i++){             // pour tous les aiguillages
    turnout[i].demande_activation = false;          // pas de demande d'activation
    turnout[i].position_actuelle = BOBINE1;            // par defaut sur bobine 1
    
    turnout[i].bobine1 = decal+FIRST_PIN;           // numero de broche de la bobine 1
    pinMode(turnout[i].bobine1, OUTPUT);            // bobine 1   en sortie 
    digitalWrite(turnout[i].bobine1, REPOS);          // bobine 1 au repos
   
    
    turnout[i].bobine2 = 1+decal+FIRST_PIN;         // numero de la broche de la bobine 2
    pinMode(turnout[i].bobine2, OUTPUT);            // bobine 2  en sortie  
    digitalWrite(turnout[i].bobine2, REPOS);          // bobine 2 au repos
    
    
    turnout[i].ledBobine = FIRST_PIN + i +8;           // les led du TCO
    pinMode(turnout[i].ledBobine, OUTPUT);
    digitalWrite(turnout[i].ledBobine,HIGH);        // bobine 1 allumee par defaut
    delay(ACTIVATION);
     digitalWrite(turnout[i].ledBobine,LOW);
     delay(ACTIVATION);
     digitalWrite(turnout[i].ledBobine,HIGH);
          
    turnout[i].bouton = FIRST_PIN + i +12;          // le bouton du TCO
    pinMode(turnout[i].bouton,INPUT_PULLUP);
    turnout[i].etat_bouton = HIGH;
   
    decal+=2;                                   // on passe aux aiguillages suivants  
  }
  
  #ifdef CONSOLE
   Serial.begin(DEBIT_CONSOLE);
   for (int i=0; i<NB_TURNOUT; i++){
    Serial.print("aiguillage");Serial.println(i); 
    Serial.print("\t bobine 1 sur broche : ");Serial.println(turnout[i].bobine1);
    Serial.print("\t bobine 2 sur broche : ");Serial.println(turnout[i].bobine2);
    Serial.print("\t bouton TCO sur broche : ");Serial.println(turnout[i].bouton);
    Serial.print("\t Led TCO sur broche : ");Serial.println(turnout[i].ledBobine);
  }
  #endif
}

/*************************************************************************
 * boucle
 * 
 ******************************************************************/
 
void loop() {
  for (int i = 0;i<NB_TURNOUT;i++) {if (boutonTest(i))  activation_aiguillage(i);}

Un exemple de séquence :

aiguillage0
bobine 1 sur broche : 3
bobine 2 sur broche : 4
bouton TCO sur broche : 15
Led TCO sur broche : 11
aiguillage1
bobine 1 sur broche : 5
bobine 2 sur broche : 6
bouton TCO sur broche : 16
Led TCO sur broche : 12
aiguillage2
bobine 1 sur broche : 7
bobine 2 sur broche : 8
bouton TCO sur broche : 17
Led TCO sur broche : 13
aiguillage3
bobine 1 sur broche : 9
bobine 2 sur broche : 10
bouton TCO sur broche : 18
Led TCO sur broche : 14
activation -> aiguillage0 : bobine2
activation -> aiguillage0 : bobine1
activation -> aiguillage1 : bobine2
activation -> aiguillage1 : bobine1
activation -> aiguillage2 : bobine2
activation -> aiguillage2 : bobine1
activation -> aiguillage3 : bobine2
activation -> aiguillage3 : bobine1

Réalisation d’un décodeur pour 8 aiguillages à solénoïdes en mode DCC

Si on utilise le mode DCC, on récupère les ports utilisés par les boutons et les leds pour augmenter les possibilités à 8 aiguillages. Le schéma de principe devient le suivant :

Et une idée de carte à réaliser :

decodeur 8 aiguillages DCC sur NANO

et sa réalisation :

Le programme INO est le suivant (fichier cde_aiguillage_Nano_DCC) :

/*
 * decodeur de 8 aiguillages sur Arduino UNO/NANO
 * Les aiguillages sont commandes par des sorties sur les broches a partir de la broche 3 par paire (aiguillage 1 =  (3,4) etc...)
 * ces sorties peuvent etre utilisees directement pour commander des ULN2803 ou les inputs de relais ou L298N 
 * 
 */

/******************************************************************************************
 * 
 * LES PARAMETRES DE CONFIGURATION a definir par l'utilisateur
 * CONSOLE : pour avoir le deroulement du programme, si pas necessaire supprimer la ligne
 * FIRST_ID_DCC : premiere adresse DCC de depart, premier aiguillage (FIRST_ID_DCC sur broche 3), second aiguillage (FIRST_ID_DCC+1 sur broche 4, etc..)
 * NB_TURNOUT : le nombre d'aiguillages = 8
 * 
 *********************************************************************************************/
 
 #define CONSOLE                         // sortie console du deroulement
 #define DEBIT_CONSOLE    115200         // le debit de la console
 #define FIRST_ID_DCC      40            // ID DCC de départ
#define ACTIVATION        250           // duree d'activation des bobines en ms ( a modifier si necessaire)
#define NB_TURNOUT        8             // le nombre  d'aiguillages 
 /***********************************************************************************************
  * 
  * LES PARAMETRES INTERNES
  * 
  * ************************************************************************************************/
 
//////////////////// LE DCC  /////////////////////////////////////////////////////////////////

#include <DCC_Decoder.h>                 // la bibliothèque de Minabay
#define kDCC_INTERRUPT    0             // la pin 2 qui recoit les interruptions du signal DCC
int adresse_precedente = 0;             // evite les commandes multiples DCC
int ancienne_position = 2;
volatile boolean MAJ_activation;        // si des MAJ a faire apres controle du DCC

/////////////////// LES AIGUILLAGES  ///////////////////////////////////////////////////////

#define FIRST_PIN         3             // broche de depart des aiguillages
#define BOBINE1           0             // adresse DCC/0
#define BOBINE2           1             // adresse DCC/1 

//// STRUCTURE D'UN AIGUILLAGE ////

struct TurnOut {
  int adresse;                    // son adresse DCC
  int position_actuelle;          // directe / deviee
  int bobine1;                    // broche bobine 1
  int bobine2;                    // broche bobine 2
  boolean demande_activation;     // demande d'activation
};
TurnOut turnout[NB_TURNOUT];      // l'ensemble des aiguillages

/********************************************************************
 * 
 * METHODE APPELEE SI UNE DEMANDE DE MISE A JOUR PAR LE DCC
 * Determine periodiquemùent les bobines a activer
 * 
 *******************************************************************/
 
void activation_aiguillage() {
 
  for (int i = 0; i < NB_TURNOUT; i++)                 // on balaie tous les aiguillages
  {
    if (turnout[i].demande_activation == true)         // si l'aiguillage i est en attente d'activation
    {
      switch(turnout[i].position_actuelle)            // on regarde la position demandee
      { 
        case BOBINE1 :{                                           // si bobine 1
                      digitalWrite(turnout[i].bobine1,HIGH);     // activation
                      delay(ACTIVATION);                         // duree de l'activation
                      digitalWrite(turnout[i].bobine1,LOW);      // arret de l'activation
                      #ifdef CONSOLE
                        Serial.print("activation -> aiguillage");Serial.print(i);Serial.println(" : bobine1");
                      #endif
                      break;}
        case BOBINE2 : {                                          // si bobine 2
                      digitalWrite(turnout[i].bobine2,HIGH);      // activation
                      delay(ACTIVATION);                          // duree de l'activation
                      digitalWrite(turnout[i].bobine2,LOW);       // arret de l'activation
                      #ifdef CONSOLE
                        Serial.print("activation -> aiguillage");Serial.print(i);Serial.println(" : bobine2");
                      #endif
                     break;}
           }
       turnout[i].demande_activation = false;                // l'aiguillage a etait traite
      }
    }
  MAJ_activation = false;                                   // on a fait toutes les MAJ
}

/************************************************************************************* 
 *  
 *  METHODE APPELEE A CHAQUE IT DU DCC
 *  determine si un aiguillage est concerne par la commande DCC
 *  
 ***********************************************************************************/

void BasicAccDecoderPacket_Handler(int address, boolean activate, byte data)
{  
  address -= 1; address *= 4; address += 1; address += (data & 0x06) >> 1;    // decodage adresse DCC
  int bobine = (data & 0x01) ? BOBINE1 : BOBINE2;             // quelle bobine est concernee DCC/bobine
  // si on change d'adresse ou de position, evite les commandes repetitives
  if ((address != adresse_precedente) | ((bobine != ancienne_position)&(address == adresse_precedente))){
    if ((address >= FIRST_ID_DCC) && (address < FIRST_ID_DCC + NB_TURNOUT))  // si une de nos adresses
    {turnout[address - FIRST_ID_DCC].demande_activation =  true;            // aiguillage en demande d'activation
    turnout[address - FIRST_ID_DCC].position_actuelle = bobine;            // etat demande (n° de bobine)
    MAJ_activation = true;                                                // MAJ demandee 
    }
   adresse_precedente = address; ancienne_position = bobine;            // evite de traiter plusieurs fois la meme commande DCC
  }
}
/**********************************************************************************************
 * 
 * le setup
 * initialise le DCC et les aiguillages
 * 
 ******************************************************************************************/

void setup() {
  int decal = 0;
  for (int i=0; i<NB_TURNOUT; i++){              // pour tous les aiguillages
    turnout[i].adresse = FIRST_ID_DCC + i;          // son ID DCC
    turnout[i].demande_activation = false;          // pas de demande d'activation
    turnout[i].bobine1 = decal+FIRST_PIN;           // numero de broche de la bobine 1
    pinMode(turnout[i].bobine1, OUTPUT);            // bobine 1   en sortie (ID DCC/0)
    digitalWrite(turnout[i].bobine1, LOW);          // bobine 1 au repos
    turnout[i].bobine2 = 1+decal+FIRST_PIN;         // numero de la broche de la bobine 2
    pinMode(turnout[i].bobine2, OUTPUT);            // bobine 2  en sortie  (ID DCC/1)
    digitalWrite(turnout[i].bobine2, LOW);          // bobine 2 au repos
    decal+=2;                                   // on passe aux aiguillages suivants  
  }

 /***********************************************************
* La methode appellee par le DCC
******************************************/

DCC.SetBasicAccessoryDecoderPacketHandler(BasicAccDecoderPacket_Handler, true);     // le DCC
  DCC.SetupDecoder( 0x00, 0x00, kDCC_INTERRUPT );                                     // son IT
  MAJ_activation = false;                                  // pas de MAJ a priori
  #ifdef CONSOLE
   Serial.begin(DEBIT_CONSOLE);
   for (int i=0; i<NB_TURNOUT; i++){
    Serial.print("aiguillage");Serial.print(i);Serial.print(" , code DCC : ");Serial.println(turnout[i].adresse); 
    Serial.print("\t bobine 1 sur broche : ");Serial.println(turnout[i].bobine1);
    Serial.print("\t bobine 2 sur broche : ");Serial.println(turnout[i].bobine2);
  }
  #endif
}

/*************************************************************************
 * boucle
 * 
 ******************************************************************/
 
void loop() {
  DCC.loop();                                             // demande DCC ?
  if (MAJ_activation) {activation_aiguillage();}          // si oui activation des aiguillages
}

Et un exemple de séquences :

aiguillage0 , code DCC : 40
bobine 1 sur broche : 3
bobine 2 sur broche : 4
aiguillage1 , code DCC : 41
bobine 1 sur broche : 5
bobine 2 sur broche : 6
aiguillage2 , code DCC : 42
bobine 1 sur broche : 7
bobine 2 sur broche : 8
aiguillage3 , code DCC : 43
bobine 1 sur broche : 9
bobine 2 sur broche : 10
aiguillage4 , code DCC : 44
bobine 1 sur broche : 11
bobine 2 sur broche : 12
aiguillage5 , code DCC : 45
bobine 1 sur broche : 13
bobine 2 sur broche : 14
aiguillage6 , code DCC : 46
bobine 1 sur broche : 15
bobine 2 sur broche : 16
aiguillage7 , code DCC : 47
bobine 1 sur broche : 17
bobine 2 sur broche : 18
activation -> aiguillage0 : bobine2
activation -> aiguillage0 : bobine1
activation -> aiguillage1 : bobine2
activation -> aiguillage1 : bobine1
activation -> aiguillage2 : bobine2
activation -> aiguillage2 : bobine1
activation -> aiguillage3 : bobine2
activation -> aiguillage3 : bobine1

Réalisation d’un décodeur pour Arduino MEGA en mode DCC avec la bibliothèque UAD

Avec l’utilisation d’un Arduino MEGA le nombre d’aiguillages explose et peut aller jusqu’à 32 !!!
Nous utilisons ici la bibliothèque UAD de Thierry qui va nous faciliter la configuration du décodeur.
Comme on a pu le voir précédemment, suivant les interfaces il faut envoyer des commandes soit en mode « HIGH » soit en mode « LOW ». Pour cela le programme fournit deux méthodes de setup l’une pour des commandes en mode « HIGH » l’autre pour des commandes en mode « LOW » soit en mode TCO (SetupDigital, SetupDigital_Inverted) soit en mode DCC (SetupDccDigital, SetupDccDigital_Inverted) . Dans notre cas particulier la méthode SetupDigital s’applique uniquement à l’interface avec les ULN2803A, dans les autres cas (relais, ULN298N) la méthode SetupDigital_Inverted doit être appelée, ce qui veut dire qu’il peut y avoir mélange de relais et d’ULN298N mais pas d’ULN2803A. Le programme INO se base sur une classe turnOut donnée en fin d’article (fichier turnOut).

Voici un schéma de principe pour contrôler 16 aiguillages à base d’ULN2803A :

Au centre les 16 pins allant vers les broches de l’Arduino.

Et une idée de carte à réaliser :
JPEG - 1.4 Mio

En mode TCO il y a un bouton par aiguillage, deux leds pour les positions d’un aiguillage et ses deux bobines, soit 5 broches par aiguillage. Pour la première commande d’aiguillage on obtient donc :
Bouton sur la broche 3,
led bobine1 sur la broche 4,
led bobine2 sur la broche 5,
bobine1 sur la broche 6,
et bobine2 sur la broche 7,
et ainsi de suite.
En mode DCC il n’y a qu’un bouton de test (par défaut sur la broche A15) et une led témoin sur la broche 53, on obtient donc la séquence suivante :
Bobine1 sur broche 3,
Bobine2 sur broche 4,
Et ainsi de suite.

Le programme INO en mode TCO

/*
 * decodeur pour des aiguilles à solenoide et a 2 positions sur Arduino MEGA
 * en mode TCO
 * bouton : pin x
 * led bobine 1 : pin x + 1
 * led bobine 2 : pin x + 2
 * bobine 1 : pin x + 3
 * bobine 2 : pin x + 4
 * 
 */

/********************************************************************
 * PARAMETRES DE CONFIGURATION
 * 
 *********************************************************************/
 #define NB_TURN_OUT 4      // nombre d'aiguillages
#define ACTIVATION 250    // activation des bobines de 250 ms


/**********************************************************************
 * LES PARAMETRES INTERNES
 * 
 *************************************************************************/
 
#include <UniversalAccessoryDecoder.h>  // la biliotheque UAD
#include "TurnOut.h"                    // la classe des aiguillages

TurnOut aiguilles;      // une instance des aiguillages

/*
 * pour le setup il faut donner :
 *  le nombre d'aiguille
 *  la duree d'activation de l'aiguille
 *  par defaut la tension est MAX = 255
 *  on peut modifier cette valeur comme troisieme argument du setup
 *  
 */
void setup() {
  aiguilles.SetupDigital(NB_TURN_OUT,ACTIVATION);   // commande = HIGH
  //aiguilles.SetupDigital_Inverted(NB_TURN_OUT,ACTIVATION);  // ou commande = LOW
  }

/*
 * la boucle se limite a une methode
 */
void loop() {aiguilles.Loop();}

et le même en mode DCC :

/*
 * decodeur pour des aiguilles à solenoide et a 2 positions sur Arduino MEGA
 * en mode DCC
 * base sur le project: <DCC Accessory Decoder> de Thierry PARIS
 * 
 * aiguille y : bobine1 pin x (IdDccy/0), bobine2 pin x+1 (IdDccy/1)
 * nombre max d'aiguille y
 * 
 * interruption int0 pour le DCC sur pin 2
 * 
 */

/********************************************************************
 * PARAMETRES DE CONFIGURATION
 * 
 *********************************************************************/
 #define NB_TURN_OUT 4      // nombre d'aiguillages
#define ID_DCC 40                 // adresse DCC de depart du premier aiguillage
#define ACTIVATION 250    // activation de 250ms


/**********************************************************************
 * LES PARAMETRES INTERNES
 * 
 *************************************************************************/
 
#include <UniversalAccessoryDecoder.h>  // la biliotheque UAD
#include "TurnOut.h"                    // la classe des aiguillages

TurnOut aiguilles;      // une instance des aiguillages

/*
 * pour le setup il faut donner :
 *  le nombre d'aiguille
 *  l'adresse de debut DCC
 *  la duree d'activation de l'aiguille
 *  par defaut la tension est MAX = 255
 *  on peut modifier cette valeur comme quatrieme argument du setup
 *  par defaut la broche de la led de test DCC est a la broche 53, 
 *  on peut modifier cette valeur comme cinquieme argument du setup
 *  la broche du bouton est par defaut en A15,
 *  on peut modifier cette valeur en sixieme argument du setup
 *  
 */
void setup() {
  aiguilles.SetupDccDigital_Inverted(NB_TURN_OUT,ID_DCC,ACTIVATION);  // commande = LOW
  //aiguilles.SetupDccDigital(NB_TURN_OUT,ID_DCC,ACTIVATION);          // ou commande = HIGH
  }

/*
 * la boucle se limite a une methode
 */
void loop() {aiguilles.LoopDcc();}

et un exemple de séquences

Universal Accessories Decoder V4.14.
Developed by Thierry Paris.

*** Setup started.
ButtonsCommander Setup
*** Setup Finished. Memory used = 545 bytes

Avec le bouton de test

DCCToggle : Accessory 0 DccId 40 / 0
AccessoryMotor MoveToggle() : DriverPortArduino 3 MoveLeftDir() at speed 255
255
DriverPortArduino 3 MoveStop()
DCCToggle : Accessory 1 DccId 40 / 1
AccessoryMotor MoveToggle() : DriverPortArduino 4 MoveLeftDir() at speed 255
255
DriverPortArduino 4 MoveStop()

Avec des commandes DCC

DCCToggle : Accessory 1 DccId 40 / 1
AccessoryMotor MoveToggle() : DriverPortArduino 4 MoveRightDir() at speed 255
DriverPortArduino 4 MoveStop()

DCCToggle : Accessory 0 DccId 40 / 0
AccessoryMotor MoveToggle() : DriverPortArduino 3 MoveRightDir() at speed 255
DriverPortArduino 3 MoveStop()

Circuit de protection des solénoïdes

Le circuit suivant permet de protéger l’alimentation des bobines en fournissant une décharge capacitive lors de l’appel et en protégeant les bobines par la durée de recharge du condensateur de l’ordre de 100 ms en laissant un courant de fuite limité à 13,5 mA admissible par les bobines.

Circuit de protection des bobines

L’entrée consiste en une alimentation continue entre 12 et 20 V (ajouter un pont de diode en cas d’alimentation alternative).
En sortie, il faut relier la borne positive au commun des aiguillages et la borne négative au GND de l’Arduino.

Conclusion

Pour un très faible coût et des interfaces de puissance simples il est possible de créer des décodeurs d’aiguillages à solénoïdes. Les programmes sont simples et permettent de réaliser rapidement ces décodeurs sans rentrer dans la complexité de la réalisation logicielle. L’ensemble des possibilités présentées ont été testées sur une console ECOS pour le DCC et fonctionnent parfaitement... Vous trouverez ici bas les programmes et une idée de typons pour réaliser les cartes.

commande aiguillages NANO TCO
commande aiguillages NANO DCC
commande aiguillages MEGA
idées de typons
schemas en pdf

111 Messages

Réagissez à « Décodeur pour aiguillage à solénoïdes sur Arduino »

Qui êtes-vous ?
Votre message

Pour créer des paragraphes, laissez simplement des lignes vides.

Lien hypertexte

(Si votre message se réfère à un article publié sur le Web, ou à une page fournissant plus d’informations, vous pouvez indiquer ci-après le titre de la page et son adresse.)

Rubrique « Projets »

LaBox, Une Centrale DCC polyvalente et abordable (1)

LaBox, Une Centrale DCC polyvalente et abordable (2)

LaBox, Une Centrale DCC polyvalente et abordable (3)

Comment piloter trains et accessoires en DCC avec un Arduino (1)

Comment piloter trains et accessoires en DCC avec un Arduino (2)

Comment piloter trains et accessoires en DCC avec un Arduino (3)

Comment piloter trains et accessoires en DCC avec un Arduino (4)

SGDD : Système de Gestion DD (1)

SGDD : Système de Gestion DD (2)

SGDD : Système de Gestion DD (3)

La PWM : Qu’est-ce que c’est ? (1)

La PWM : Qu’est-ce que c’est ? (2)

La PWM : Qu’est-ce que c’est ? (3)

La PWM : Qu’est-ce que c’est ? (4)

Mise en oeuvre du Bus CAN entre modules Arduino (1)

Mise en oeuvre du Bus CAN entre modules Arduino (2)

Un gestionnaire en C++ pour votre réseau (1)

Un gestionnaire en C++ pour votre réseau (2)

Un gestionnaire en C++ pour votre réseau (3)

Un gestionnaire en C++ pour votre réseau (4)

Réalisation de centrales DCC avec le logiciel libre DCC++ (1)

Réalisation de centrales DCC avec le logiciel libre DCC++ (2)

Réalisation de centrales DCC avec le logiciel libre DCC++ (3)

Contrôleur à télécommande infrarouge pour centrale DCC++

Gestion d’une gare cachée (1)

Gestion d’une gare cachée (2)

Gestion d’une gare cachée (3)

La carte Satellite V1 (1)

La carte Satellite V1 (2)

La carte Satellite V1 (3)

La carte Satellite V1 (4)

La carte Satellite V1 (5)

Chenillard de DEL

Enseigne de magasin

Feux tricolores

Multi-animations lumineuses

L’Arduino et le système de commande numérique DCC

Un décodeur d’accessoire DCC versatile basé sur Arduino

Un moniteur de signaux DCC

Une barrière infrarouge

Un capteur RFID

Un TCO xpressnet

Une animation sonore

L’Arduino au coeur des systèmes de pilotage analogiques ou numériques

Calcul de la vitesse d’un train miniature avec l’Arduino

La génèse d’un réseau 100% Arduino

Une horloge à échelle H0

Simulateur de soudure à arc

Un automatisme de Passage à Niveau

Automatisation du pont FLEISCHMANN 6152 (HO) avec un ESP32 (1)

Identifier et localiser vos trains avec le RFID/NFC et un bus CAN.

Etude d’un passage à niveau multivoies

La rétro-signalisation sur Arduino

Décodeur pour aiguillage à solénoïdes sur Arduino

Un décodeur DCC pour les signaux à deux ou trois feux sur Arduino NANO/UNO

Etude d’un passage à niveau universel

Réalisation pratique d’un système de mesure de vitesse à l’échelle N

Une Passerelle entre le bus S88 et le bus CAN pour la rétro signalisation

Un décodeur DCC pour 16 feux tricolores

Block Automatique Lumineux avec la carte shield "Arduino 4 relays"

Réalisation d’un affichage de gare ARRIVEE DEPART

Ménage à trois (Ordinateur, Arduino, réseau)

Réalisation d’un va-et-vient automatique et réaliste

Souris et centrale sans fil

Communications entre JMRI et Arduino

Annonces en gare avec la RFID

Une croix de pharmacie animée avec Arduino UNO

Réalisation d’un wagon de mesure (distance et vitesse)

Passage à niveau géré par Arduino (1)

Passage à niveau géré par Arduino (2)

Passage à niveau géré par Arduino (3)

Passage à niveau géré par Arduino (4)

Passage à niveau géré par Arduino (5)

Une manette simple et autonome pour LaBox

Éclairer le réseau (1)

Éclairer le réseau (2)

Block Automatique Lumineux à 8 cantons analogiques

Un décodeur DCC pour les plaques tournantes Fleischmann et Roco

Éclairer le réseau (3)

Éclairer le réseau (4)

Éclairer le réseau (5)

JMRI pour Ma première centrale DCC

Rocrail pour Ma première centrale DCC

CDM-Rail pour Ma première centrale DCC (1)

CDM-Rail pour Ma première centrale DCC (2)

Banc de test pour les décodeurs DCC

Ma première manette pour les aiguillages DCC

Mon premier décodeur pour les aiguillages DCC

Boitier 3D pour la station DCC minimale

Va-et-vient pour deux trains

Un programme pour régler facilement les servos moteurs avec un ESP32

Affichage publicitaire avec Arduino (1)

Affichage publicitaire avec Arduino (2)

TCO Web interactif avec des ESP32 et des ESP8266 (1)

TCO Web interactif avec des ESP32 et des ESP8266 (2)

TCO Web interactif avec des ESP32 et des ESP8266 (3)

TCO Web interactif avec des ESP32 et des ESP8266 (4)

TCO Web interactif avec des ESP32 et des ESP8266 (5)

Les derniers articles

LaBox, Une Centrale DCC polyvalente et abordable (3)


Thierry

LaBox, Une Centrale DCC polyvalente et abordable (1)


Thierry

LaBox, Une Centrale DCC polyvalente et abordable (2)


Dominique, msport, Thierry

Un programme pour régler facilement les servos moteurs avec un ESP32


bobyAndCo

TCO Web interactif avec des ESP32 et des ESP8266 (5)


utpeca

TCO Web interactif avec des ESP32 et des ESP8266 (4)


utpeca

TCO Web interactif avec des ESP32 et des ESP8266 (3)


utpeca

TCO Web interactif avec des ESP32 et des ESP8266 (2)


utpeca

TCO Web interactif avec des ESP32 et des ESP8266 (1)


utpeca

Affichage publicitaire avec Arduino (2)


catplus, Christian

Les articles les plus lus

Réalisation de centrales DCC avec le logiciel libre DCC++ (3)

La PWM : Qu’est-ce que c’est ? (1)

Mon premier décodeur pour les aiguillages DCC

La rétro-signalisation sur Arduino

Comment piloter trains et accessoires en DCC avec un Arduino (1)

Réalisation de centrales DCC avec le logiciel libre DCC++ (1)

Chenillard de DEL

Mise en oeuvre du Bus CAN entre modules Arduino (2)

LaBox, Une Centrale DCC polyvalente et abordable (1)

Décodeur pour aiguillage à solénoïdes sur Arduino