Page 1 sur 1

Commande d'aiguillage par servo moteur

Posté : 19 avr. 2025, 09:18
par herwat
Bonjour,

à la demande d'Olivier, je vais faire un petit descriptif de mes montages à base de servo pour commander mes aiguillages .

Mais d'abord, un peu d'histoire .
Sur mon premier réseau, je voulais déjà mettre des moteurs lents pour piloter mes aiguillages mais j'ai vite renoncé vu le prix des modèles proposés !
Je me suis donc rabattu sur les moteurs Conrad :
.
Mot_conrad.JPG
Mot_conrad.JPG (10.35 Kio) Vu 798 fois
.
C'était pas mal, fiables, pas cher, avec des contacts auxiliaires, mais trop bruyants à mon gout .
.
Petit à petit, je me suis intéressé aux servo moteurs pilotés par module ESU :
.
IMG_1249.jpg
IMG_1249.jpg (119.73 Kio) Vu 798 fois
.
Mais les modules ESU sont chers et la mise en œuvre des servo n'était pas simple . Bref, j'ai plus ou moins lâché l'affaire .
Et puis le temps a passé, j'ai du démonter mon réseau , mais j'ai également découvert l'impression 3D et j'ai commencé un peu la programmation arduino . . .
Alors quand j'ai commencé mon réseau actuel, j'ai décidé de commandé tous les aiguillages avec des servo piloté par arduino .
Dans un premier temps, j'ai fait ce montage :
.
Montage.jpg
Montage.jpg (61.96 Kio) Vu 798 fois
.
Mais le réglage par rapport à l'aiguillage n'était pas facile pour, à mon avis, deux raisons :
D'abord, la tige de commande n'est pas toujours perpendiculaire au plan de voie et ensuite, si le servo est même légèrement de travers par rapport à la tirette de commande de l'aiguillage, ça force et l'aiguille se positionne souvent mal .
J'ai donc fait ce montage qui corrige les deux problèmes :
.
IMG_2349.jpg
IMG_2349.jpg (149.41 Kio) Vu 798 fois
.
Facile à poser et ça c'est avéré être d'une grande fiabilité .
Avec le temps et les besoins, tout ça a évolué :
Modèle sous table :
.
IMG_3278.jpg
IMG_3278.jpg (70 Kio) Vu 798 fois
.
Mosèle sur table :
.
IMG_3277.jpg
IMG_3277.jpg (62.63 Kio) Vu 798 fois
.
Et j'en passe . :hhhaaaa:
Bilan : on a un moteur lent , silencieux et pas cher . En effet, si on prend un servo de qualité, on s'en sort à moins de 10 € l'unité et si on fait le choix de servo bon marché (ce que je n'ai pas fait ) , à moins de 5 € . . . Qui dit mieux !

Voilà pour la partie mécanique . La partie pilotage suit .
Bien évidemment si les fichiers stl intéresse quelqu'un pour impression , il suffit de demander .

Re: Commande d'aiguillage par servo moteur

Posté : 19 avr. 2025, 09:53
par C2Vues-BricoTrain
Bonjour Hervé,

Belles progressions dans l'étude d'un meilleur fonctionnement pour commander mécaniquement des moteurs d'aiguillages.

:bienv: :bienv: :bienv: :bienv:

Re: Commande d'aiguillage par servo moteur

Posté : 19 avr. 2025, 10:07
par TrainDoly
Bonjour Hervé.
Merci beaucoup d'avoir répondu à ma demande de manière aussi précise. C'est vraiment super! :cooooool:

Je suis en train d'en installer sur mon réseau mais je me demande si c'est une bonne idée de mettre la tige en direct entre le servo et l'aiguillage.
Ne faudrait-il pas faire une ou deux boucles ressort sur la tige pour compenser la différence de course du servo et la course de l'aiguillage?

Re: Commande d'aiguillage par servo moteur

Posté : 19 avr. 2025, 13:02
par herwat
ça dépend de ton montage .
Il faut qu'il y ai un minimum de distance entre le bras du servo et l'aiguillage pour que la tige fasse ressort . quelle est le diamètre de la tige ?

Perso, vu mon montage , j'ai à peu prés 10 mm de tige et c'est de la corde à piano de 1 mm . J'ai essayé avec de la 0.8 mm , c'est trop souple .

Maintenant, je ne sais pas ce que tu utilise pour piloter le servo, mais normalement tu peux régler l'amplitude de la course du bras .

Re: Commande d'aiguillage par servo moteur

Posté : 20 avr. 2025, 09:57
par likiki
Reste a détailler le programme. :siffle:

Superbe sujet Hervé. :cooooool:

Re: Commande d'aiguillage par servo moteur

Posté : 20 avr. 2025, 11:30
par TrainDoly
herwat a écrit : 19 avr. 2025, 13:02 ça dépend de ton montage .
Il faut qu'il y ai un minimum de distance entre le bras du servo et l'aiguillage pour que la tige fasse ressort . quelle est le diamètre de la tige ?

Perso, vu mon montage , j'ai à peu prés 10 mm de tige et c'est de la corde à piano de 1 mm . J'ai essayé avec de la 0.8 mm , c'est trop souple .

Maintenant, je ne sais pas ce que tu utilise pour piloter le servo, mais normalement tu peux régler l'amplitude de la course du bras .
La tige est de la baguette de brasure TIG pour l'inox.
Elle est souple mais résistante et surtout elle se travaille facilement. J'ai essayé avec de la corde à piano mais je n'arrivais pas à la façonner correctement.

Mon moteur est à environ 8cm de l'aiguillage.

Re: Commande d'aiguillage par servo moteur

Posté : 21 avr. 2025, 13:07
par herwat
C'est à toi de voir si ça force sur la tirette de l'aiguillage ou non . Difficile d'en dire plus . . . :siffle:

Re: Commande d'aiguillage par servo moteur

Posté : 21 avr. 2025, 15:44
par herwat
Bon, passons à l'électronique .

Tous mes servo sont pilotés par des arduino nano .
vu le nombre d'aiguillage, j'ai standardisé la chose ! :hhhaaaa:
Tout d'abord le support :
.
IMG_3282.jpg
IMG_3282.jpg (61.49 Kio) Vu 753 fois
.
Que je pourrai coller soit horizontalement soit verticalement sous la table .
Ensuite, tous les module ont la même taille est fait avec des plaquettes d’essai à bande
en voilà un en construction :
.
IMG_3283.jpg
IMG_3283.jpg (71.32 Kio) Vu 753 fois
.
et dand le support :
.
IMG_3284.jpg
IMG_3284.jpg (69.19 Kio) Vu 753 fois
.
Pour des raisons pratiques, je me suis limité à commander 4 servo maximum par arduino .
Ensuite, bien sûr, chaque module est fait selon les besoins du moment .
Commande par impulsion ou par niveau logique donné par bouton poussoir , par interrupteur ou par signal venant d'un autre arduino . . . .Y en a pour tous les goût . :siffle:

Par exemple, voici celui que j'ai fait dernièrement pour commander l'aiguillage triple qui dessert les trois voies de garage :
.
IMG_3286.jpg
IMG_3286.jpg (81.45 Kio) Vu 753 fois
.
Il pilote deux servo qui fonctionnent en simultanés .
Il y a 3 entrés pour boutons poussoir pour sélectionner la voie
Il y a 3 sorties supplémentaire pour commander 3 relais d'alimentation DCC des voies .
Et bien s^r les sorties pour la signalisation par leds .

Et voilà ce que ça donne comme programme :
.

Code : Tout sélectionner

             /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
              * * * * *      Sélection de trois voies marchandise       * * * * *
              * * * * *    BP1 pour les aiguillages RP 09 et RP 10      * * * * *
              * * * * *         BP2 pour l' aiguillages RP 11           * * * * *
              * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

              * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
              *      Nano 13 avec ajout de sorties relais pour alim voies       *
              * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

     * Programme opérationnel
     * Deux servo pour actionner un aiguillage triple 
     * Commande par trois boutons poussoirs
     * entree : changement d'état par impulsion
     
                                                        1
                                                   -----O-----            SV1   SV2
                                            SV1  /               Voie 1    1     1
                                                /       2        Voie 2    1     0
                              --------------------------O-----   Voie 3    0     0
                                                \
                                                 \SV2   3
                                                   -----O------

     */ 

    #include <Servo.h>
    
    const byte pinServo1 = 3;   //  Servo commandant l'aiguillage SV 1
    const byte pinServo2 = 4;   //  Servo commandant l'aiguillage SV 2

    const byte pinEntree1 = A3;   //  Entrée pour le bouton poussoir Voie 1
    const byte pinEntree2 = A4;   //  Entrée pour le bouton poussoir voie 2
    const byte pinEntree3 = A5;   //  Entrée pour le bouton poussoir voie 3
    const byte PinLedVoie [3] = {5,6,7};
    const byte PinRelai [3] = {9,10,11};
    int Voie ;
          
    int MiniMax1[2]  = {700,1000} ;  //   défini l'amplitude du mouvement
    int MiniMax2[2]  = {650,1050} ;
    int vitesse[2]  = {-1,1} ;

    int AllumLed [3][3] = { 
                           {1,0,0},   //  Eclairage voie 1
                           {0,1,0},   //  Eclairage voie 2
                           {0,0,1},   //  Eclairage voie 3
                          };
    int AllRelais [3][3]= { 
                           {0,1,1},   //  Relai alim voie 1
                           {1,0,1},   //  Relai alim voie 2
                           {1,1,0},   //  Relai alim voie 3
                          };
    int y ;

 //*************    Configuration des mouvements servo selon plan de voie    ***********
 //                          ( inutilisé dans ce programme )
 
    boolean Inverse = false ;   // false : le sens de rotation des 2 servo est le même
                                // true  : le sens de rotation est inverse .
                                // Commutation par inverseur sur A2
    const byte pinInvers = 2;
    
 //*************************************************************************************

    Servo monServo1;
    int Avance1;
    int angle1;
    int angleFinal1;
    boolean Sens1;

    Servo monServo2;
    int Avance2;
    int angle2;
    int angleFinal2;
    boolean Sens2;

    boolean Etat1;
    boolean Etat1lu;
    boolean Etat2;
    boolean Etat2lu;
    boolean Mvt1;
    boolean Mvt2;
    boolean Mvt;

    void setup()
      {
        pinMode (pinEntree1, INPUT);
        pinMode (pinEntree2, INPUT);
        pinMode (pinEntree3, INPUT);
        pinMode (pinInvers, INPUT);
        for (y=0 ; y <= 2 ; y++){ pinMode(PinLedVoie [y], OUTPUT); }
        for (y=0 ; y <= 2 ; y++){ pinMode(PinRelai [y], OUTPUT); }
        for (y=0 ; y <= 2 ; y++){ digitalWrite(PinRelai [y], HIGH);}
        Inverse = digitalRead(pinInvers);

        monServo1.attach(pinServo1);
        monServo1.writeMicroseconds(780);
        delay(500);
        angle1 = 850;
        Etat1lu = true ;   // 
        Etat1 = true ;     //  ces 3 valeurs déterminent la position initiale du
        Sens1 = true;      //  servo  : "true" dans un sens, "false" dans l'autre.
        Mvt1 = true;
        
        Avance1 = vitesse[Sens1]; angleFinal1 = MiniMax1[Sens1];
        
        monServo2.attach(pinServo2);
        monServo2.writeMicroseconds(850);
        delay(500);
        angle2 = 850;
        Etat2lu = false ;   //
        Etat2 = false ;     //  même chose que pour le servo 1 .
        Sens2 = false ;     //
        Mvt2 = true;

        Avance2 = vitesse[Sens2]; angleFinal2 = MiniMax2[Sens2];

        Voie = 0 ;
      }

    void loop()
      {
         if(!Mvt1)
              { if( digitalRead(pinEntree1)){ Etat1lu = true  ;
                                              Etat2lu = false  ; Voie=0; }
                if( digitalRead(pinEntree2)){ Etat1lu = true  ;
                                              Etat2lu = true ; Voie=1; }
                if( digitalRead(pinEntree3)){ Etat1lu = false ;
                                              Etat2lu = true ; Voie=2; }

                if (Etat1lu == Etat1 ) { }
                else{ 
                    Etat1 = Etat1lu ;
                    Sens1 = Etat1;
                    monServo1.attach(pinServo1);
                    Mvt1 = true;
                  
                    Avance1 = vitesse[Sens1]; angleFinal1 = MiniMax1[Sens1];
                    }
               }
              
          if(!Mvt2) 
               { 
                if (Etat2lu == Etat2 ) { }
                else{ 
                    Etat2 = Etat2lu ;
                    Sens2 = Etat2;
                    monServo2.attach(pinServo2);
                    Mvt2 = true;
                  
                    Avance2 = vitesse[Sens2]; angleFinal2 = MiniMax2[Sens2];
                    }
               }

         if(Mvt1) { 
                  angle1 = angle1 + Avance1;      
                  monServo1.writeMicroseconds(angle1);

                  if (angle1 == angleFinal1)
                     {
                        Avance1 = 0;
                        monServo1.detach();
                        Mvt1 = false;
                     } 
                  }

         if(Mvt2) {
                  angle2 = angle2 + Avance2;      
                  monServo2.writeMicroseconds(angle2);

                  if (angle2 == angleFinal2)
                     {
                        Avance2 = 0;
                        monServo2.detach();
                        Mvt2 = false;
                     }
                  }

        Mvt = Mvt1 || Mvt2  ;
        if(Mvt){ for (y=0 ; y <= 2 ; y++)
                     { digitalWrite(PinLedVoie [y], LOW);
                       digitalWrite(PinRelai [y], HIGH);  }
               }

        else   { for (y=0 ; y <= 2 ; y++)
                     { digitalWrite(PinLedVoie [y], AllumLed [Voie][y]);
                       digitalWrite(PinRelai [y], AllRelais [Voie][y]);   }
               }

        delay(6);    // conditionne la vitesse de rotation des servo
      }
Ou bien celui que je suis en train de faire et qui est en cours d'essai :
.
IMG_3285.jpg
IMG_3285.jpg (73.49 Kio) Vu 753 fois
.
Il pilote deux servo indépendamment et par niveau logique .
et voilà le programme

Code : Tout sélectionner

             /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
              * * * * *                                                 * * * * *
              * * * * *   Commande des 2 aiguillages  GM 12 et GM 13    * * * * *
              * * * * *                par niveau logique               * * * * *
              * * * * *                                                 * * * * *
              * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *


     * Programme en cours
     */ 

    #include <Servo.h>
    
    const byte pinServo1 = 3;   //  Servo commandant l'aiguillage GM 12
    const byte pinServo2 = 4;   //  Servo commandant l'aiguillage GM 13

    const byte pinEntree1 = A3;   //  Entrée pour l'aiguillage GM 12
    const byte pinEntree2 = A4;   //  Entrée pour l'aiguillage GM 13
    const byte pinMvt = 13 ;      //  Sortie témoin de mouvement
           
    int MiniMax1[2]  = {700,1000} ;  //   défini l'amplitude du mouvement
    int MiniMax2[2]  = {700,1000} ;
    int vitesse[2]  = {-1,1} ;

    int y ;

 //*************  Configuration des mouvements servo selon niveau logique   ***********
 //                               et positio initiale
 
    boolean Posini1 = true ;
    boolean Posini2 = false ;
    
 //*************************************************************************************

    Servo monServo1;
    int Avance1;
    int angle1;
    int angleFinal1;
    boolean Sens1;

    Servo monServo2;
    int Avance2;
    int angle2;
    int angleFinal2;
    boolean Sens2;

    boolean Etat1;
    boolean Etat1lu;
    boolean Etat2;
    boolean Etat2lu;
    boolean Mvt1;
    boolean Mvt2;
    boolean Mvt;

    void setup()
      {
        pinMode (pinEntree1, INPUT);
        pinMode (pinEntree2, INPUT);
        pinMode (pinMvt, OUTPUT);

        monServo1.attach(pinServo1);
        monServo1.writeMicroseconds(850);
        delay(500);
        angle1 = 850;
        Etat1lu = Posini1 ;
        Etat1 = Posini1 ;
        Sens1 = Posini1;
        Mvt1 = true;
        
        Avance1 = vitesse[Sens1]; angleFinal1 = MiniMax1[Sens1];
        
        monServo2.attach(pinServo2);
        monServo2.writeMicroseconds(850);
        delay(500);
        angle2 = 850;
        Etat2lu = Posini2 ;
        Etat2 = Posini2 ;
        Sens2 = Posini2 ;
        Mvt2 = true;

        Avance2 = vitesse[Sens2]; angleFinal2 = MiniMax2[Sens2];

      }

    void loop()
      {
         if(!Mvt1)
              { if( digitalRead(pinEntree1)){ Etat1lu = !Posini1 ; }
                else { Etat1lu = Posini1 ; }

                if (Etat1lu == Etat1 ) { }
                else{ 
                    Etat1 = Etat1lu ;
                    Sens1 = Etat1;
                    monServo1.attach(pinServo1);
                    Mvt1 = true;
                  
                    Avance1 = vitesse[Sens1]; angleFinal1 = MiniMax1[Sens1];
                    }
               }
              
          if(!Mvt2) 
               { if( digitalRead(pinEntree2)){ Etat2lu = !Posini2 ; }
                 else { Etat2lu = Posini2 ; }
                 
                if (Etat2lu == Etat2 ) { }
                else{ 
                    Etat2 = Etat2lu ;
                    Sens2 = Etat2;
                    monServo2.attach(pinServo2);
                    Mvt2 = true;
                  
                    Avance2 = vitesse[Sens2]; angleFinal2 = MiniMax2[Sens2];
                    }
               }

         if(Mvt1) { 
                  angle1 = angle1 + Avance1;      
                  monServo1.writeMicroseconds(angle1);

                  if (angle1 == angleFinal1)
                     {
                        Avance1 = 0;
                        monServo1.detach();
                        Mvt1 = false;
                     } 
                  }

         if(Mvt2) {
                  angle2 = angle2 + Avance2;      
                  monServo2.writeMicroseconds(angle2);

                  if (angle2 == angleFinal2)
                     {
                        Avance2 = 0;
                        monServo2.detach();
                        Mvt2 = false;
                     }
                  }

        Mvt = Mvt1 || Mvt2  ;
        if(Mvt){ digitalWrite(pinMvt, HIGH); }
        else { digitalWrite(pinMvt, LOW); }

        delay(6);    // conditionne la vitesse de rotation des servo
      }

.
Ce module sera piloté par l'arduino MEGA qui gère le TCO marchandise . Il va faloir que je modifie ce tableau pour la circonstance et ça, ça va être un peu galère . Mais bon . . . :siffle: :siffle: :siffle:

pour info , je rappelle que j'ai fait ici une description de mes TCO . ça date un peu, les images sont dégradées , mais ça donne une idée .
voili voilou . . .

Re: Commande d'aiguillage par servo moteur

Posté : 21 avr. 2025, 15:54
par herwat
Je ne sais pas pourquoi, une image c'est incrustée en bas du message, impossible de l'enlever . :hurt4: :hurt4: :hurt4:

Re: Commande d'aiguillage par servo moteur

Posté : 21 avr. 2025, 16:17
par likiki
Parce que tu as mis deux fois l'image 3283 et que tu n'utilise qu'une des deux (c'est celle du bas que tu n'utilise pas). :siffle:

Re: Commande d'aiguillage par servo moteur

Posté : 21 avr. 2025, 19:06
par TrainDoly
Supers explications!

Merci Hervé.

Re: Commande d'aiguillage par servo moteur

Posté : 01 mai 2025, 18:54
par TrainDoly
Hervé,
voilà ce que j'utilise pour faire mes tringles.
C'est pas ici que je l'ai acheté mais c'est un exemple...

-*- Tringles -*-


J'ai mis deux moteurs pour le moment. Ils fonctionnent très bien dans mon "train qui en chasse un autre V2" mais je ne suis pas très fier de l'installation de la commande.
Je te montre deux photos très moches pour que tu me dises comment j'aurais dû faire une connexion propre entre la tringle et l'aiguillage.
Pour le trou dans la planche, je ferais mieux... :-|

IMG_20250501_180122410.jpg




IMG_20250501_180106897.jpg

C'est pas beau.... hein?
Merci!

Re: Commande d'aiguillage par servo moteur

Posté : 01 mai 2025, 19:44
par herwat
TrainDoly a écrit : 01 mai 2025, 18:54
C'est pas beau.... hein?
Merci!
Oh . . .. ça pourrait être pire ! :hhhaaaa: :hhhaaaa: :hhhaaaa:
et ça peut facilement être repris .

Je ne fais pas mieux mais ça ce voit moins car j'utilise des aiguillages PECO qui ont un trou au mieux de la tirette .
.
IMG_3294.jpg
IMG_3294.jpg (80.26 Kio) Vu 640 fois
.
le trou dans le bois est donc sous les rails ! :cooooool:
et en plus, la corde à piano va directement dedans .

à moins de faire un petit trou dans la tirette de tes aiguillages, je ne vois pas ce que tu peux faire de mieux .
Le trou, tu pourrais le faire avec un foret de 1 mm ou le faire avec un clou chauffé . Mais c'est risqué ! . . . .

Re: Commande d'aiguillage par servo moteur

Posté : 01 mai 2025, 21:12
par ramasoft
Moi, je ne critiquerai pas le trou car je fais bien pire ... :hhhaaaa:

Re: Commande d'aiguillage par servo moteur

Posté : 08 mai 2025, 18:15
par patrice_b
Tres intéressant cet article Hervé. :merciiii:

Vous êtes vraiment des bons messieurs, bravo ! :tirechap: :tirechap: :bienv: :bienv:

Voila un exemple de plus qui donne envie d'acheter une imprimante 3D, et de vraiment bucher l'Arduino... Je vais attaquer mon réseau quand je serai dans le trou :hhhaaaa: :hhhaaaa:

Re: Commande d'aiguillage par servo moteur

Posté : 08 mai 2025, 18:35
par likiki
Mais non, tu commence ton réseau et après tu adaptera.

:siffle: