LOCODUINO

Les différents types de mouvements d’un servomoteur

.
Par : Dominique, Guillaume, Jean-Luc

DIFFICULTÉ :

Dans La bibliothèque Servo, nous avons vu comment fonctionnait la librairie Servo et les différentes fonctions permettant d’animer le servo-moteur. Voyons maintenant comment mettre en pratique ces commandes afin d’imiter au plus proche le mouvement d’une aiguille, c’est-à-dire le code dans loop().
Nous allons donc faire des essais et nous passerons donc du mouvement d’un moteur d’aiguillage type électro-aimant (ex : PECO) à un moteur lent d’aiguillage (ex : tortoise).
Nous verrons plusieurs types de mouvements qui ne correspondent pas uniquement à ceux d’une aiguille. Ils pourront correspondre à un signal mécanique, mouvement de barrière...

Article mis à jour le 13 août 2023 pour ajouter un lien vers l’article SlowMotionServo.
Les angles donnés sont à titre d’exemple, ils ne refléteront pas ceux de votre réseau. Les valeurs limites seront à trouver avec une application dédiée.

Aller-retours

La première application est très simple, il s’agit de faire faire au servo des aller-retours de part et d’autre de la position médiane. La méthode write(...) permet de donner l’angle auquel le servo doit se positionner. L’argument est une valeur comprise entre 0 et 180°. L’angle minimum choisi est donc de 70° et l’angle maximum de 110°. On fixe la pause entre 2 changements de position à 1s. La fonction loop() est donc la suivante.

void loop()
{
    /* positionne le servo à 70° */
    monServo.write(70);
    /* attend 1000 ms */
    delay(1000); 
    /* positionne le servo à 110° */
    monServo.write(110);
    /* attend 1000 ms */
    delay(1000); 
}

Cette première application ne remplit pas le cahier des charges du mouvement réaliste, à savoir un mouvement lent. Le mouvement a bien lieu toutes les secondes mais il est très rapide, quasi instantané comme un électro-aimant.

Aller-retours lents

Pour obtenir un mouvement lent, il faut faire varier l’angle du servo progressivement. Pour cela, il faut changer l’angle très très peu et le faire plus souvent. Fixons par exemple un changement d’angle de 1°. Si l’on veut que le mouvement, passer de 70° à 110° soit accompli en 1s, il faut augmenter l’angle de 1° toutes les 1000ms / (110 - 70). soit une pause de 25ms. Quand l’angle atteint 110°, il faut inverser le mouvement. Quand l’angle atteint 70°, il faut de nouveau inverser le mouvement. Nous avons donc besoin de deux variables, angle qui contient l’angle courant du servo et vitesse qui contient 1 si on augmente l’angle et -1 si on le diminue. Pour faciliter la programmation, on va placer 70 et 110 dans deux constantes. Le programme est le suivant.

#include <Servo.h>
 
Servo monServo;
int vitesse;
int angle;
 
const int angleMin  = 70;
const int angleMax = 110;
 
/*
 * La fonction setup() est exécutée 1 fois
 * au démarrage du programme
 */
void setup()
{
    monServo.attach(2);
    angle = angleMin;
    vitesse = 1;
}
 
/*
 * La fonction loop() est exécutée
 * répétitivement
 */
void loop()
{
    monServo.write(angle);
    /* calcule le nouvel angle */
    angle = angle + vitesse;
 
    if (angle > angleMax) {
        /* 
         * le nouvel angle dépasse le maximum
         * on le recale au maximum et on inverse la vitesse
         */
        angle = angleMax;
        vitesse = -1;
    }
    else if (angle < angleMin) {
        /*
         * le nouvel angle dépasse le minimum
         * on le recale au minimum et on inverse la vitesse
         */
        angle = angleMin;
        vitesse = 1;
    }
    delay(25);
}

Le mouvement est bien lent comme on le désire mais avec une variation de l’angle par degré, le mouvement est un peu saccadé. Une autre méthode permet un positionnement plus précis. Il s’agit de la méthode writeMicroseconds(...). L’argument de cette méthode n’est plus un angle mais la durée de l’impulsion de commande du servo-moteur en micro-secondes. En effet, le signal de commande du servo-moteur est une impulsion dont la largeur détermine la position du servo. Cette impulsion a donc la forme suivante.

La PWM de commande d’un servo
Seuls les durées extrêmes de l’impulsion et la durée médiane sont montrées mais toutes les valeurs entre 0,5 ms et 2,5 ms sont possibles.

Dans La bibliothèque Servo, nous avons vu que les valeurs extrèmes dépendent des paramètres optionnels de la méthode attach(...). Sans spécifier ces valeurs, 544 est la valeur inférieure et 2400 la supérieure.
1472 µs est la valeur médiane.

Pour comprendre correctement le code, la valeur médiane est approximativement de 1500µs et les valeurs minimum et maximum pour les angles que nous avions fixés deviennent respectivement et approximativement 1250 et 1750.
Pour avoir les valeurs exactes, il faudra faire les bons calculs.
On va conserver une vitesse de 1 ou -1 et pour avoir un mouvement d’1s alors que l’on franchi 500 pas d’angle on va désormais faire une pause de 2ms. Le programme est donc le suivant.

#include <Servo.h>
 
Servo monServo;
int vitesse;
int angle;
 
const int angleMin  = 1250;
const int angleMax = 1750;
 
/*
 * La fonction setup() est exécutée 1 fois
 * au démarrage du programme
 */
void setup()
{
    monServo.attach(2);
    angle = angleMin;
    vitesse = 1;
}
 
/*
 * La fonction loop() est exécutée
 * répétitivement
 */
void loop()
{
    monServo.writeMicroseconds(angle);
    /* calcule le nouvel angle */
    angle = angle + vitesse;
 
    if (angle > angleMax) {
        /* 
         * le nouvel angle dépasse le maximum
         * on le recale au maximum et on inverse la vitesse
         */
        angle = angleMax;
        vitesse = -1;
    }
    else if (angle < angleMin) {
        /*
         * le nouvel angle dépasse le minimum
         * on le recale au minimum et on inverse la vitesse
         */
        angle = angleMin;
        vitesse = 1;
    }
    delay(2);
}

Le résultat est meilleur avec un mouvement plus fluide. Il remplit donc son office de mouvement lent.

Nous avons donc vu différents types de mouvements possibles avec un servo-moteur. A nous de trouver son utilisation, notamment dans le mouvement des aiguilles avec le mouvement réaliste du dernier programme.

Les valeurs d’angles en degrés et en µs dans l’article sont mis pour les exemples. Chaque utilisation que vous en ferez nécessitera une connaissance des angles limites afin que le code soit adapté et fasse ce que vous lui ordonnerez.

La bibliothèque SlowMotionServo

Cette bibliothèque a été écrite pour reproduire des mouvements lents avec un servomoteur et aussi pour définir des trajectoires de mouvements. Par exemple, lorsqu’on ouvre les portes d’une remise, celles-ci ont tendance à rebondir légèrement en butant sur le taquet de fin de course. Ou bien encore, les barrières de passage à niveau actionnées manuellement par une garde-barrière, rebondissaient légèrement en arrivant à leur position fermée. L’article La bibliothèque SlowMotionServo décrit cette bibliothèque et comment l’utiliser. Bien évidemment, ces rebonds n’existent pas dans le positionnement de lames d’aiguilles ou bien avec les barrières des passages à niveau actuels.

36 Messages

  • Les différents types de mouvements d’un servo-moteur 30 août 2016 22:31, par Serge NORBERT

    Bonjour

    Je suis presque débutant sur arduino et j’essaie d’adapter ce programme à mon cas particulier.(commande lente d’aiguilles donc avec writeMicroseconds()
    Je suis arrivé au résultat souhaité mais je constate lorsque je commande deux aiguilles simultanément, un ralentissement important de la rotation des deux servos pendant la phase où ils sont tous les deux en rotation... si un décalage entre les deux commandes on voit nettement la variation de vitesse
    Ce n’est pas un problème d’alimentation (à priori) puisque les deux servos sont alimentés par une alim 5v indépendante 1A
    Peut-on expliquer ce phénomène par une boucle loop qui met deux fois plus de temps à s’éxécuter et dans ce cas peut on améliorer le résultat car dans mon installation je pourrai commander jusqu’à 5 aiguilles simultanément

    Merci de vos réponses

    Répondre

  • Les différents types de mouvements d’un servo-moteur 30 août 2016 23:11, par Serge NORBERT

    Il n’y a que les ... qui ne reconnaissent pas leur erreur...
    En fait j’ai crée des fonctions...."Commande Aig1 à G... Commande Aig2 à Gauche...etc.... que je lance en fonction du bouton correspondant...
    Mais le delay(2) qui détermine la vitesse de translation de l’aiguille doit rester dans le loop...1 fois... et non dans chaque fonction comme j’avais fait.
    C’est dans l’erreur qu’on progresse le plus... il faut bien se consoler !!!!
    Bonne soirée

    Répondre

  • programme de16 servo-moteurs avec bouton pousoir 15 décembre 2016 11:28, par Etienne 59

    bonjour,
    Je suis dans la difficulté pour programmer mon arduino mega 2560. je débute et il faut que je commande 16 servos par boutons poussoir pour mes aiguillages et jevoudrais utiliser mes entrees A0, A1,... pour chaque boutons poussoir.
    Merci d’avance.
    Etienne 59

    Répondre

    • programme de16 servo-moteurs avec bouton pousoir 15 décembre 2016 12:21, par Dominique

      Bonjour,

      J’ai écrit ce programme pour 10 servos, commandés par 10 inverseurs : je pense que vous pouvez l’adapter à votre cas :

      programme pour 10 servos lents

      Il y a une procédure de réglage de la course des servos (valeurs minimales et maximales) avec enregistrement en EEPROM, vous verrez, c’est bien pratique.

      D’autres pourrons vous orienter vers d’autres solutions

      Bon courage

      Répondre

      • programme de16 servo-moteurs avec bouton pousoir 20 décembre 2016 18:59, par etienne59

        Merci pour votre réponse,
        Mais malheureusement je n’ai pas d’EEPROM car j’ai un Arduino Méga2560 et je ne suis pas très bon sur la logique Arduino.
        Pour que tout fonctionne comme je le désire, il faudrait que mes boutons poussoirs soient branchés sur chacune des entrées de l’Arduino.
        Et que l’action sur un BP puisse amener le mouvement d’un servo et après son relachement qu’il puisse finir son déplacement.
        Et que lorsque je réutilise ce même BP, le servo reprenne sa position initiale.

        Répondre

  • Les différents types de mouvements d’un servo-moteur 20 décembre 2016 19:47, par Dominique

    Bonsoir Etienne,

    C’est justement ce que fait mon programme :

    • tout d’abord le Mega2560 a bien une EEPROM (comme les autres Arduino, sauf le Due) et mon programme tourne sur un Mega, donc plus de problème de ce coté là.
    • remplacer un inverseur par un bouton poussoir est facile, si vous associez une variable "etat" à chaque bouton et que cette variable passe de TRUE à FALSE (et vice versa) à chaque appui sur le bouton.
    • regardez les articles sur les entrées-sorties et les boutons poussoirs dans Locoduino, et aussi, si cela ne suffit pas, sur les nombreux cours de programmation Arduino qui fleurissent partout sur la toile.
    • je pense que vous allez réussir à modifier le programme en conséquence, ce qui vous aura fait progresser.
      Bon courage

    Répondre

    • Les différents types de mouvements d’un servo-moteur 22 décembre 2016 17:59, par etienne59

      Bonsoir Dominique,
      J’ai essayé de télécharger le programme sur l’arduino Mega mais il me dit qu’il est incompatible.
      Comment puis-je faire ?
      Je pensais qu’en regardant ce qui été fait avec cet appareil, j’aurais pu le faire aussi mais le langage C pour moi veut dire Chinois.
      j’ai eu les yeux plus gros que le cerveau.
      joyeuses fêtes

      Répondre

      • Les différents types de mouvements d’un servo-moteur 22 décembre 2016 18:19, par Dominique

        Etienne,

        Le programme que je vous ai proposé a été écrit pour et testé sur un Mega2560.
        Donc ça doit forcément marcher.

        Maintenant si vous pensez que c’est du chinois, ne vous découragez pas du tout. Commencez par lire et faire les exercices qui sont décrits dans les articles "Pour débuter" et "Programmation, les bases".

        Vous avez aussi l’excellent Hors Serie N° 1 de Hackable qui se trouve en librairie en ce moment : ne le ratez pas !

        Il est indispensable de passer par les étapes d’initiation et d’apprentissage avant d’aborder un projet ferroviaire avec succès. Plein d’autres y sont arrivés avec un peu de patience.

        Bon courage
        Dominique

        Répondre

  • Les différents types de mouvements d’un servo-moteur 22 décembre 2016 18:35, par etienne59

    On me conseille d’utiliser une boucle de scrutation mais je ne vois pas comment m’en servir
    j’ai acheté le grand livre d’arduino mais je ne trouve pas comment enregistrer tout les BP pour la même action sur leur propre servo.
    un petit coup de pouce pour le début m’arrangerai.

    Répondre

    • Bonjour Etienne59,

      Vous m’avez envoyé aujourd’hui un mail direct à ce sujet.
      Cela ne me pose aucun problème d’aider mon prochain, bien évidemment, sauf que je ne peux répondre autre chose que ce que Dominique vous a dit le 22/12 :
      Il faut d’abord avoir un certain nombre de bases (dont les boucles) en commençant par des choses nettement plus simples que des commandes de servos via la PWM.
      Locoduino a aussi des programmes simples (case "Les programmes" dans l’accueil)

      Répondre

        • Les différents types de mouvements d’un servo-moteur 25 décembre 2016 17:38, par etienne59

          Merci pour votre réponse rapide,
          Puis je vous soumettre le programme que j’ai commencé ?
          Actuellement, j’ai des messages d’erreurs mais je voudrais savoir si il y a un début de compréhension du système.
          Aussi je n’ai pas beaucoup d’équipement électronique pour réaliser les montages.
          Et je voudrais finir la commande de mes aiguillages assez rapidement car il me restera le cantonnement que je prévois sur un autre Arduino avec la signalisation.
          bien amicalement
          Etienne

          Répondre

          • Les différents types de mouvements d’un servo-moteur 25 décembre 2016 18:42, par Dominique

            La cause des messages d’erreur est écrite en rouge en bas de l’IDE.

            Chacun doit apprendre à corriger ses erreurs : c’est le seul moyen de progresser.

            Vous n’irez pas jusqu’au bout de votre projet si vous ne maîtrisez pas cette pratique qui n’est pas de notre domaine ferroviaire mais de la programmation en général.

            "Et je voudrais finir la commande de mes aiguillages assez rapidement car il me restera le cantonnement que je prévois sur un autre Arduino avec la signalisation."  : C’est ambitieux mais n’oubliez pas que Locoduino est un site de partage de projets et d’expériences. Nous ne réalisons aucune prestation de programmation.

            Répondre

          • Les différents types de mouvements d’un servo-moteur 26 décembre 2016 00:43, par Jean-Luc

            Bonsoir,

            vous pouvez poster votre programme cote forum, ça sera plus adapté. Ici par exemple : http://forum.locoduino.org/index.ph...

            Répondre

  • Les différents types de mouvements d’un servo-moteur 22 décembre 2016 21:17, par Dominique

    Pourquoi ne commencez-vous pas par des choses simples comme je vous l’ai suggéré dans ma réponse précédente ?

    Rien ne sert de courir ; il faut partir à point.

    Répondre

  • Les différents types de mouvements d’un servo-moteur 11 janvier 2017 11:09, par Patrice

    Bonjour, je suis assidument depuis quelques temps vos réalisations et vous félicite pour cette aide que vous nous apportez dans le modélisme ferroviaire. J’ai téléchargé le programme pour 10 aiguilles permettant le pilotage via un inverseur, il fonctionnait très bien jusqu’à une manipulation qui n’a fait passer en mode programmation EEPROM (je suppose puisque maintenant le terminal affiche ;
    Version 0
    0 :-1,-1
    1 :-1,-1
    2 :-1,-1
    3 :-1,-1
    4 :-1,-1
    5 :-1,-1
    6 :-1,-1
    7 :-1,-1
    8 :-1,-1
    9 :-1,-1
    comment j’ai fait ceci, je n’en sait rien maintenant mes servo sont bloqués sur la course -1.
    j’ai cru voir une démo avec une carte fakir qui permet via une pin de faire la programmation des courses des différents servo (que je ne retrouve plus sur youtube) . Pouvez m’indiquer ou trouver ces informations et explications sur cette procédure me permettant de refaire une programmation correcte des courses des servo sur EEPROM.
    Vous en remerciant par avance.
    Cordialement
    Patrice

    Répondre

    • Les différents types de mouvements d’un servo-moteur 11 janvier 2017 11:56, par Dominique

      Bonjour Patrice,

      Si vous jetez un coup d’oeil au sketch que j’ai donné plus haut, vous verrez que lorsque le moniteur est connecté à 115200 b/s, le fait d’envoyer "0" (zéro) entraine une réécriture de l’EEPROM avec les valeurs Min et Max des servos, plus un compteur qui s’incrémente en face de "Version".

      Mon conseil donc est de recharger le sketch dans votre Arduino puis d’ouvrir le moniteur et de taper "0"

      C’est justement fait pour sauvegarder les réglages des butées qui sont comprises entre 1500 et 1600 au départ.

      Si vous ne comprenez pas comment fonctionne ces réglages, dites le moi.

      Pour info ce programme ultra simple est là :
      programme pour 10 servos lents

      Répondre

      • Bonjour Dominique,
        J’aimerai votre aide pour répondre à 1 questions et résoudre un problème en lien avec l’eeprom.
        Q1 : Pour quelle raison les numéros des pines servos dans votre programme ne correspondent pas aux pines des sorties PWM des mega ?
        Problème :
        Je rencontre un problème similaire à celui de Patrice en 2017, Il m’est impossible de rentrer dans l’eeprom les angles min et max des servos qui sont dans le tableau tablePos[MaxAig][2].
        j’ai bien tapé 0 dans le champ de saisie du moniteur, le programme m’indique bien ENREGISTREMENT EEPROM. Mais lorsque je retourne sur le moniteur, les données restent toujours les mêmes.
        15:28:44.206 -> Version 17
        15:28:44.206 -> 0:1500,1600
        15:28:44.206 -> 1:1500,1600
        15:28:44.206 -> 2 :-1,-1
        15:28:44.206 -> 3 :-1,-1
        15:28:44.206 -> 4 :-1,-1
        15:28:44.206 -> 5 :-1,-1
        15:28:44.206 -> 6 :-1,-1
        15:28:44.206 -> 7 :-1,-1
        15:28:44.206 -> 8 :-1,-1
        15:28:44.206 -> 9 :-1,-1
        15:28:55.106 -> Enregistrement EEPROM

        Pour "apprivoiser" et déterminer les paramètres, j’ai câblé mon mega avec 1 seul servo et un seul interrupteur-pas de LED pour le moment. Mon but est de commander 15 servos en utilisant toutes les sorties PWM du Mega 2560.
        Ci apprès le sketch qui est une copie du votre dans lequel j’ai choisi la pin2 pour le servo et 22 pour l’interrupteur.
        Cela fait plusieurs soirées que je bute sur ce problème d’angle mini et maxi qui ne sont pas enregistrés dans l’eeprom.
        Je profite de message pour vous remercier pour le fantastique travail de vulgarisation et d’aide que toutes les personnes de Locoduino offrent.

        Sketch qui ne fonctinne pas bien :

        // VERSION 1.1 du 1 Decembre 2016
        
        #include <Arduino.h>
        #include <Servo.h>
        #include <Bounce2.h>
        #include <EEPROM.h>
        #include "Dix_aiguilles.h"
        
        
        #define MaxAig 10                   // nombre d'ensembles Aiguille+Inter+2leds
        
        
        const int tablePins[MaxAig][4] = { // pour chaque aiguille il faut renseigner les No de pins :
          {02, 22, 16 ,17},                // pin Servo, pin Inter, pin Led Directe, pin led Déviée
          {18, 19, 20, 21},                // c'est geroupé par blocs de quatre
          {14, 23, 23, 25},                // correspondant au groupes de 4 connecteurs 
          {26, 27, 28, 29},                // sur la carte fakir
          {30, 31, 32, 33},
          {34, 35, 36, 37},
          {38, 39, 40, 41},
          {42, 43, 44, 45},
          {46, 47, 58, 49},
          {50, 51, 52, 53} 
        };
        
        int tablePos[MaxAig][2] = { // butées Min et Max en globales
          {1200, 1800},
          {1500, 1600},
          {1500, 1600},
          {1500, 1600},
          {1500, 1600},
          {1500, 1600},
          {1500, 1600},
          {1500, 1600},
          {1500, 1600},
          {1500, 1600}  
        };
        
        CommandeAiguille*  aiguille0=new CommandeAiguille();
        CommandeAiguille*  aiguille1=new CommandeAiguille();
        CommandeAiguille*  aiguille2=new CommandeAiguille();
        CommandeAiguille*  aiguille3=new CommandeAiguille();
        CommandeAiguille*  aiguille4=new CommandeAiguille();
        CommandeAiguille*  aiguille5=new CommandeAiguille();
        CommandeAiguille*  aiguille6=new CommandeAiguille();
        CommandeAiguille*  aiguille7=new CommandeAiguille();
        CommandeAiguille*  aiguille8=new CommandeAiguille();
        CommandeAiguille*  aiguille9=new CommandeAiguille();
        
        CommandeAiguille* tableAiguille[MaxAig] {
          aiguille0, aiguille1, aiguille2, aiguille3, aiguille4, 
          aiguille5, aiguille6, aiguille7, aiguille8, aiguille9
        };
        
        /////////// variable globales ///////////
          byte V0, V1;
          int val;
          int numServo, encoursServo;
          bool minmax; // min = false, max = true
        
        
        /////////////////////////////////////////////////////////
        void setup() 
        {
          int numServo;
        
          Serial.begin(115200);
          while (!Serial) {
            ; // wait for serial port to connect. Needed for native USB port only
          }
          V0 = EEPROM.read(0);
          V1 = EEPROM.read(1);
          if ((V0!=0xFF)&&(V1!=0xFF)) {
            val = V0;
            val = val << 8;
            val = val | V1;
            Serial.print("Version ");Serial.println(val);
            EEPROM.get( 2, tablePos );  //lecture de la table des min et max.
            for( int j = 0 ; j < MaxAig ; j++ ){
              Serial.print( j ); 
              Serial.print( ':' ); 
              Serial.print( tablePos[ j ][ 0 ]);
              Serial.print( ',' ); 
              Serial.print( tablePos[ j ][ 1 ]);
              Serial.println(); 
            }
          } else {
            Serial.println("EEPROM vierge");
            val = 0;
          }
            for (numServo = 0; numServo < MaxAig; numServo++) {
            tableAiguille[numServo]->SetpinServo(tablePins[numServo][0]);
            tableAiguille[numServo]->SetpinInter(tablePins[numServo][1]);
            tableAiguille[numServo]->SetpinLedDirecte(tablePins[numServo][2]);
            tableAiguille[numServo]->SetpinLedDeviee(tablePins[numServo][3]);
            tableAiguille[numServo]->SetPosMinMax(tablePos[numServo][0], tablePos[numServo][1]);
            tableAiguille[numServo]->InitCommandeAiguille();
          } 
        
        }
        
        //////////////////////////////////////////////////////
        void loop() 
        {
        
          for (numServo = 0; numServo < MaxAig; numServo++) {
            tableAiguille[numServo]->ServoUpdate();
            tableAiguille[numServo]->InterUpdate();
          }
          
          while (Serial.available() > 0) 
          {
            int commande = Serial.parseInt();  // lecture entier
            if (Serial.read() == '\n') 
            {
              switch (commande) {
                case 0:
                val = val + 1;
                V1 = val;
                V0 = val >> 8;
                EEPROM.update(0, V0);
                EEPROM.update(1, V1);
                Serial.println("Enregistrement EEPROM");
                EEPROM.put( 2, tablePos );  //Write array data.
                break;
                
                case 1:
                encoursServo = commande - 1;
                Serial.print("Servo "); Serial.print(encoursServo+1); Serial.print(" : ");
                Serial.print(tablePos[encoursServo][0]);Serial.print("->");
                minmax = false;
                break;
                case 2:
                encoursServo = commande - 1;
                Serial.print("Servo "); Serial.print(encoursServo+1); Serial.print(" : ");
                Serial.print(tablePos[encoursServo][0]);Serial.print("->");
                minmax = false;
                break;
                case 3:
                encoursServo = commande - 1;
                Serial.print("Servo "); Serial.print(encoursServo+1); Serial.print(" : ");
                Serial.print(tablePos[encoursServo][0]);Serial.print("->");
                minmax = false;
                break;
                case 4:
                encoursServo = commande - 1;
                Serial.print("Servo "); Serial.print(encoursServo+1); Serial.print(" : ");
                Serial.print(tablePos[encoursServo][0]);Serial.print("->");
                minmax = false;
                break;
                case 5:
                encoursServo = commande - 1;
                Serial.print("Servo "); Serial.print(encoursServo+1); Serial.print(" : ");
                Serial.print(tablePos[encoursServo][0]);Serial.print("->");
                minmax = false;
                break;
                case 6:
                encoursServo = commande - 1;
                Serial.print("Servo "); Serial.print(encoursServo+1); Serial.print(" : ");
                Serial.print(tablePos[encoursServo][0]);Serial.print("->");
                minmax = false;
                break;
                case 7:
                encoursServo = commande - 1;
                Serial.print("Servo "); Serial.print(encoursServo+1); Serial.print(" : ");
                Serial.print(tablePos[encoursServo][0]);Serial.print("->");
                minmax = false;
                break;
                case 8:
                encoursServo = commande - 1;
                Serial.print("Servo "); Serial.print(encoursServo+1); Serial.print(" : ");
                Serial.print(tablePos[encoursServo][0]);Serial.print("->");
                minmax = false;
                break;
                case 9:
                encoursServo = commande - 1;
                Serial.print("Servo "); Serial.print(encoursServo+1); Serial.print(" : ");
                Serial.print(tablePos[encoursServo][0]);Serial.print("->");
                minmax = false;
                break;
                case 10:
                encoursServo = commande - 1;
                Serial.print("Servo "); Serial.print(encoursServo+1); Serial.print(" : ");
                Serial.print(tablePos[encoursServo][0]);Serial.print("->");
                minmax = false;
                break;
                
                default:
                if ((commande > 1400) && (commande < 1700)) {
                  Serial.print(commande);
                  if (!minmax) {
                    tablePos[encoursServo][0] = commande;
                    minmax = true;
                    Serial.print(", ");
                    Serial.print(tablePos[encoursServo][1]);Serial.print("->");
                  } else {
                    tablePos[encoursServo][1] = commande;
                    Serial.println();
                    Serial.print("Aiguille "); Serial.print(encoursServo+1); Serial.print(" : ");
                    Serial.print(tablePos[encoursServo][0]);Serial.print(", ");
                    Serial.println(tablePos[encoursServo][1]);
                  }
                }
                break;
              }
              
            }
          }
        
        }

        Répondre

        • Bonjour Gilles,
          Il est fortement conseillé de poser ce genre de question sur le forum (à l’endroit indiqué), votre question étant hors sujet par rapport à l’article. De plus, il manque le fichier .h qui contient les objets et les fonctions. Sans ce fichier on ne peut pas vous répondre et c’est sans doute la cause de votre problème. Pensez à décrire votre question complètement. N’étant pas chez moi sans matériel de test, je ne pourrai pas vous répondre dans l’immédiat.

          Répondre

  • Les différents types de mouvements d’un servomoteur 20 octobre 2018 19:42, par hognon emmanuel

    j’ai trouvé, sur la revue, loco revue N°855

    comment faire fonctionner un servo, pour l’ouverture et la fermeture d’un passage à niveau avec deux servos

    mais, je ne sais pas comment écrire le programme, avec deux servos.

    Voir en ligne : loco revue LR page 99 N)855

    Répondre

  • Bonjour,
    J’ai un programme pour un allez et retour

    Programme de test pour servomoteur de positionnement angulaire
    Traduction en français, ajout de variables
    Code original de BARRAGAN <http://barraganstudio.com>
    et Scott Fitzgerald http://www.arduino.cc/en/Tutorial/Sweep

    www.projetsdiy.fr - 19/02/2016
    public domain
    */

    #include <Servo.h>

    Servo myservo ; // création de l’objet myservo

    int pin_servo = 9 ; // Pin 9 sur lequel est branché le servo sur l’Arduino si vous utilisez un ESP32 remplacez le 9 par 4 et si vous utilisez un ESP8266 remplacez le 9 par 2

    int pos = 0 ; // variable permettant de conserver la position du servo
    int angle_initial = 0 ; //angle initial
    int angle_final = 150 ; //angle final
    int increment = 1 ; //incrément entre chaque position
    bool angle_actuel = false ;//Envoi sur le port série la position courante du servomoteur

    void setup()
    Serial.begin(9600) ;
    while(!Serial) ;
    myservo.attach(pin_servo) ; // attache le servo au pin spécifié sur l’objet myservo

    void loop()
    for (pos = angle_initial ; pos <= angle_final ; pos += increment) // Déplace le servo de 0 à 180 degréespar pas de 1 degrée
    myservo.write(pos) ; // Demande au servo de se déplacer à cette position angulaire
    delay(60) ; // Attend 30ms entre chaque changement de position
    if (angle_actuel)
    Serial.println(myservo.read()) ;


    for (pos = angle_final ; pos >= angle_initial ; pos -= increment) // Fait le chemin inverse
    myservo.write(pos) ;
    delay(60) ;
    if (angle_actuel)
    Serial.println(myservo.read()) ;



    mais je voudrai faire une pose de 2 ou 3 secondes entre chaque mouvement.Si je rajoute une ligne delay (2000) ;cela fait varié la vitesse de déplacement du moteur et in ne fait pas de pose ?
    Je suis perdu

    Répondre

    • Les différents types de mouvements d’un servomoteur 25 juillet 2020 21:27, par Dominique

      Ça dépend de l’endroit où vous insérez le delay(2000) : dites nous tout !

      Répondre

      • Merci de votre réponse rapide
        Je place "delay (2000) ;"
        void loop()

        for (pos = angle_initial ; pos <= angle_final ; pos += increment) // Déplace le servo de 0 à 180 degréespar pas de 1 degrée
        myservo.write(pos) ; // Demande au servo de se déplacer à cette position angulaire
        delay(60) ; // Attend 30ms entre chaque changement de position
        if (angle_actuel)
        Serial.println(myservo.read()) ;

        delay (2000) ;

        for (pos = angle_final ; pos >= angle_initial ; pos -= increment) // Fait le chemin inverse
        myservo.write(pos) ;
        delay(60) ;
        if (angle_actuel)
        Serial.println(myservo.read()) ;

        Répondre

  • Voila le programme complet

    */

    #include <Servo.h>

    Servo myservo ; // création de l’objet myservo

    int pin_servo = 9 ; // Pin 9 sur lequel est branché le servo sur l’Arduino si vous utilisez un ESP32 remplacez le 9 par 4 et si vous utilisez un ESP8266 remplacez le 9 par 2

    int pos = 0 ; // variable permettant de conserver la position du servo
    int angle_initial = 0 ; //angle initial
    int angle_final = 150 ; //angle final
    int increment = 1 ; //incrément entre chaque position
    bool angle_actuel = false ;//Envoi sur le port série la position courante du servomoteur

    void setup()
    Serial.begin(9600) ;
    while(!Serial) ;
    myservo.attach(pin_servo) ; // attache le servo au pin spécifié sur l’objet myservo

    void loop()
    for (pos = angle_initial ; pos <= angle_final ; pos += increment) // Déplace le servo de 0 à 180 degréespar pas de 1 degrée
    myservo.write(pos) ; // Demande au servo de se déplacer à cette position angulaire
    delay(60) ; // Attend 30ms entre chaque changement de position
    if (angle_actuel)
    Serial.println(myservo.read()) ;

    delay (2000) ;

    for (pos = angle_final ; pos >= angle_initial ; pos -= increment) // Fait le chemin inverse
    myservo.write(pos) ;
    delay(60) ;
    if (angle_actuel)
    Serial.println(myservo.read()) ;

    Répondre

  • Mise hors tension d’un servo 29 juillet 2020 11:35, par JPM06

    Bonjour,
    Je n’ai pas trouvé dans ces pages comment on peut mettre un servo hors tension après utilisation. Je sais bien qu’il faut cesser de lui envoyer des impulsions, mais les exemples de programme donnés ne semblent pas le faire (?).
    Y a-t-il une commande dans les bibliothèques pour faire ça ?
    J-P.

    Répondre

    • Mise hors tension d’un servo 29 juillet 2020 11:52, par trimarco232

      Je sais bien qu’il faut cesser de lui envoyer des impulsions

      Bonjour,
      intéressant, tu as une source pour ça ?

      Répondre

      • Mise hors tension d’un servo 29 juillet 2020 12:47

        C’est le fonctionnement standard des servos : les fameuses 20ms. Si on n’envoie plus d’impulsion au servo, après 20ms il cesse d’asservir, ne commande plus son moteur, et reste dans sa dernière position... à condition que le couple résistant ne soit pas trop important.
        Dans bien des cas, il n’est pas nécessaire que le servo conserve un couple important à l’arrêt. Un signal mécanique, une animation quelconque, ou même un moteur d’aiguille s’il est bien conçu, ne le nécessitent pas.
        Une source ? Tu dois en trouver sur le net, mais en cherchant bien. En fait ce détail est rarement abordé parce qu’en aéromodélisme - le monde d’origine des servos- cette possibilité n’est pas utilisée. Mais tous les servos qui me sont passés entre les mains fonctionnent comme ça.

        Répondre

    • Mise hors tension d’un servo 29 juillet 2020 15:07, par Jean-Luc

      Bonjour,

      Oui, il suffit d’appeler la fonction detach(). C’est pris en charge dans SlowMotionServo et c’est documenté dans l’article.

      Cordialement

      Répondre

  • Les différents types de mouvements d’un servomoteur 23 février 2021 19:56, par Hervé

    Bonsoir.
    Simple question d’un néophyte !
    n’est-il pas plus simple de démultiplier la vitesse mécaniquement à l’aide d’engrenages ?

    Voir en ligne : http://www.locoduino.org/spip.php++cs_INTERRO++a...

    Répondre

    • Les différents types de mouvements d’un servomoteur 25 février 2021 14:30, par Jean-Luc

      Bonjour.

      Non ☺️

      Les raisons sont les suivantes :

      • j’ai 76 aiguillages sur mon réseau et je préfère écrire le programme 1 fois plutôt que de construire 76 réducteurs.
      • les servomoteurs que j’utilise ont une vitesse à vide de 60° pour 90ms. Si je veux tourner un axe de 10° en 1s par exemple pour manœuvrer un aiguillage, il faudra une réduction de 6 x 1/90 x 1000 = 66. Construire un tel réducteur augmenterait significativement le prix d’un moteur d’aiguillage sachant qu’un servomoteur coûte 2€ chez Hobbyking.

      Répondre

Réagissez à « Les différents types de mouvements d’un servomoteur »

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 « Matériel »

Les derniers articles

Les articles les plus lus