ModelleisenbahN

Accueil > La technologie > Arduino > Manœuvre des aiguilles avec des servo-moteurs > Mise en œuvre d’un servo-moteur

Manœuvre des aiguilles en analogique avec des servo-moteurs

Mise en œuvre d’un servo-moteur

publié par Jean-Luc, le dimanche 10 novembre 2013

Tags aiguille - arduino - servo

L’Arduino c’est à la fois une carte équipée d’un microcontrôleur et un environnement logiciel qui fournit à l’utilisateur des fonctions pour manipuler le matériel de manière plus simple que s’il devait mettre en œuvre le micro-contrôleur à partir de rien.

L’Arduino se programme en langage C et quelques fois en C++. Le C est un langage de programmation très populaire, notamment sur les systèmes embarqués, c’est à dire les systèmes informatiques intégrés dans un procédé dans le but de le piloter.

Un programme minimum pour Arduino

Le programme minimum pour l’Arduino est constitué de deux fonctions. Une fonction regroupe une série d’instructions et remplit un rôle. Voici ces deux fonctions, setup() et loop(). La fonction setup() est exécutée 1 seule fois au début de programme. La fonction loop() est exécutée répétitivement.

  1. /*
  2.  * La fonction setup() est exécutée 1 fois
  3.  * au démarrage du programme
  4.  */
  5. void setup()
  6. {
  7. }
  8.  
  9. /*
  10.  * La fonction loop() est exécutée
  11.  * répétitivement
  12.  */
  13. void loop()
  14. {
  15. }

Télécharger

en langage C, une fonction retourne une valeur dont le type est indiqué juste à gauche du nom de la fonction. Il existe plusieurs types de données en C, les nombres entiers positifs et négatif (int), ceux qui sont seulement positif (unsigned int) etc. Nous verrons les types au fur et à mesure des besoins. Ici le type est void, il s’agit d’un type spécial qui signifie « rien » ou « vide » et qui indique que les fonctions setup() et loop() ne retournent aucune valeur.

Une fonction peut prendre des arguments. Les arguments sont donnés entre les parenthèses juste après le nom de la fonction. Ici les deux fonctions n’ont aucun argument.

Les instructions qui constituent la fonction sont données entre les accolades. Ici les deux fonctions sont vides et par conséquent elle ne font strictement rien.

Au dessus des fonctions il y a du texte. Il s’agit de commentaires. Un commentaire commence par /* et termine par */. C’est une bonne habitude de commenter abondamment ses programmes. En effet, quelques semaines plus tard, il est difficile de se rappeler de ce que l’on a voulu faire dans un programme et les commentaires explicatifs sont bienvenus.

Mise en œuvre d’un servo-moteur

La mise en œuvre d’un servo-moteur avec l’Arduino est aisée. Il y a une bibliothèque pour ça !

Une bibliothèque est un jeu de fonctions optionnelles que l’on peut ou non employer dans le programme. Pour utiliser la bibliothèque permettant de piloter des servo-moteurs, il suffit d’inclure, au début du programme la directive suivante

  1. #include <Servo.h>

Il faut ensuite pouvoir manipuler le servo-moteur. Il faut pour cela créer une variable de type Servo. On dit aussi instancier une variable. Le type Servo est un peu spécial, on entre là sur le terrain du C++. Servo est une classe et créer une variable de ce type donne un objet. En plus de contenir une valeur comme une variable de type nombre entier, un objet possède des fonctions qui agissent sur lui. Dans le monde de l’objet on appelle communément ces fonctions des méthodes. Nous n’avons pas besoin d’en connaître plus pour utiliser un objet de type Servo. Voici comment on crée une variable, que nous appelons monServo de type Servo.

  1. Servo monServo;

Notez le « ; » qui termine la ligne, il est nécessaire et termine la directive. Notez aussi que le respect des majuscules et des minuscules est important car le langage C fait la différence entre s et S par exemple. Par conséquent appeler la variable monServo n’est pas la même chose que de l’appeler monservo.

La variable monServo est instanciée, il faut maintenant l’accrocher à une des sorties numériques de l’Arduino. Nous allons choisir la sortie 2 car les sorties 0 et 1 ont un rôle particulier : elles permettent d’envoyer des messages qui seront affichés sur votre ordinateur hôte. Il s’agit d’une aide irremplaçable qui se révèle nécessaire pour comprendre ce qui se passe quand le programme ne fait pas ce que l’on attend.
Accrocher la variable à une sortie se fait avec la méthode attach et, évidemment, dans la fonction setup() car il est inutile de le faire plus d’une fois.

  1. void setup()
  2. {
  3. monServo.attach(2); /* accroche monServo à la pin 2 de l'Arduino */
  4. }

Télécharger

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.

  1. void loop()
  2. {
  3. /* positionne le servo à 70° */
  4. monServo.write(70);
  5. /* attend 1000 ms */
  6. delay(1000);
  7. /* positionne le servo à 110° */
  8. monServo.write(110);
  9. /* attend 1000 ms */
  10. delay(1000);
  11. }

Télécharger

Cette première application ne remplit pas le cahier des charges. À savoir un mouvement lent. Le mouvement a bien lieu toutes les secondes mais il est très rapide, quasi instantané.

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.

Programme 2

  1. #include <Servo.h>
  2.  
  3. Servo monServo;
  4. int vitesse;
  5. int angle;
  6.  
  7. const int angleMin = 70;
  8. const int angleMax = 110;
  9.  
  10. /*
  11.  * La fonction setup() est exécutée 1 fois
  12.  * au démarrage du programme
  13.  */
  14. void setup()
  15. {
  16. monServo.attach(2);
  17. angle = angleMin;
  18. vitesse = 1;
  19. }
  20.  
  21. /*
  22.  * La fonction loop() est exécutée
  23.  * répétitivement
  24.  */
  25. void loop()
  26. {
  27. monServo.write(angle);
  28. /* calcule le nouvel angle */
  29. angle = angle + vitesse;
  30.  
  31. if (angle > angleMax) {
  32. /*
  33.   * le nouvel angle dépasse le maximum
  34.   * on le recale au maximum et on inverse la vitesse
  35.   */
  36. angle = angleMax;
  37. vitesse = -1;
  38. }
  39. else if (angle < angleMin) {
  40. /*
  41.   * le nouvel angle dépasse le minimum
  42.   * on le recale au minimum et on inverse la vitesse
  43.   */
  44. angle = angleMin;
  45. vitesse = 1;
  46. }
  47. delay(25);
  48. }

Télécharger

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 (plus d’informations sont données dans l’article « La carte de commande 6 servo-moteurs, le matériel », une autre mise en œuvre utilisant une conception matérielle personnelle). Cette impulsion a donc la forme suivante.

PNG - 9.2 ko
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.

La valeur médiane est donc de 1500µs et les valeurs minimum et maximum pour les angles que nous avions fixés deviennent respectivement et approximativement 1250 et 1750. 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.

Programme 3

  1. #include <Servo.h>
  2.  
  3. Servo monServo;
  4. int vitesse;
  5. int angle;
  6.  
  7. const int angleMin = 1250;
  8. const int angleMax = 1750;
  9.  
  10. /*
  11.  * La fonction setup() est exécutée 1 fois
  12.  * au démarrage du programme
  13.  */
  14. void setup()
  15. {
  16. monServo.attach(2);
  17. angle = angleMin;
  18. vitesse = 1;
  19. }
  20.  
  21. /*
  22.  * La fonction loop() est exécutée
  23.  * répétitivement
  24.  */
  25. void loop()
  26. {
  27. monServo.writeMicroseconds(angle);
  28. /* calcule le nouvel angle */
  29. angle = angle + vitesse;
  30.  
  31. if (angle > angleMax) {
  32. /*
  33.   * le nouvel angle dépasse le maximum
  34.   * on le recale au maximum et on inverse la vitesse
  35.   */
  36. angle = angleMax;
  37. vitesse = -1;
  38. }
  39. else if (angle < angleMin) {
  40. /*
  41.   * le nouvel angle dépasse le minimum
  42.   * on le recale au minimum et on inverse la vitesse
  43.   */
  44. angle = angleMin;
  45. vitesse = 1;
  46. }
  47. delay(2);
  48. }

Télécharger

Le résultat est meilleur avec un mouvement plus fluide.

Voici qui conclut cette prise en main des servo-moteurs. Le prochain article portera sur l’ajout d’un bouton permettant de commander le mouvement du servo-moteur.

Mise en œuvre des 3 programmes présentés

8 Messages

  • Mise en œuvre d’un servo-moteur 30 décembre 2015 22:14, par Simon

    Bonjour,

    Avec le même servo j’ai besoin de lui faire faire un aller-retour mais une seule fois, pour actionner un bouton poussoir.
    Est-ce possible ?

    Dans l’attente je vous remercie et champion votre site !!

    André

    repondre message

    • Mise en œuvre d’un servo-moteur 5 janvier 2016 14:16, par Jean-Luc

      Bonjour,

      Merci :-)

      Je ne comprends pas ce que vous voulez faire. Pourquoi ne pas remplacer le bouton par un dispositif (transistor, relai, que sais-je) commandé par l’Arduino ?

      Quel est le rôle de ce bouton

      repondre message

      • Mise en œuvre d’un servo-moteur 18 janvier 2016 23:11, par Simon

        Bonjour
        Meilleurs vœux.

        Tout simplement pour lever un levier commandé par une LDR. Sans plus.

        Comme l’arduino commande directement le servo-moteur, je pensais le faire avec. sans ajouter de composant supplémentaire.

        Merci pour votre éventuelle réponse.

        André

        repondre message

        • Mise en œuvre d’un servo-moteur 18 janvier 2016 23:30

          Bonsoir,

          Meilleurs vœux également.

          Pour faire un allez-retour lent et un seul, c’est assez simple. Le servo est à son angle initial avec une vitesse de 0. Sur un événement, pression d’un bouton par exemple, la vitesse est mise à 1. Le servo commence son mouvement, quand il atteint son angle maximum, la vitesse est mise à -1, il revient. Quand l’angle atteint l’angle minimum, la vitesse passe à 0 et le servo s’arrête. Le programme serait le suivant :

          1. #include <Servo.h>
          2.  
          3. const int angleMin = 70;
          4. const int angleMax = 110;
          5.  
          6. const byte pinServo = 2;
          7. const byte pinBouton = 3;
          8.  
          9. Servo monServo;
          10. int vitesse;
          11. int angle;
          12.  
          13. /*
          14.  * La fonction setup() est exécutée 1 fois
          15.  * au démarrage du programme
          16.  */
          17. void setup()
          18. {
          19. pinMode(pinBouton, INPUT_PULLUP);
          20. monServo.attach(pinServo);
          21. angle = angleMin;
          22. vitesse = 0;
          23. }
          24.  
          25. /*
          26.  * La fonction loop() est exécutée
          27.  * répétitivement
          28.  */
          29. void loop()
          30. {
          31. if (digitalRead(pinBouton) == LOW && vitesse == 0) {
          32. vitesse = 1;
          33. }
          34.  
          35. monServo.write(angle);
          36. /* calcule le nouvel angle */
          37. angle = angle + vitesse;
          38.  
          39. if (angle > angleMax) {
          40. /*
          41.   * le nouvel angle dépasse le maximum
          42.   * on le recale au maximum et on inverse la vitesse
          43.   */
          44. angle = angleMax;
          45. vitesse = -1;
          46. }
          47. else if (angle < angleMin) {
          48. /*
          49.   * le nouvel angle dépasse le minimum
          50.   * on le recale au minimum et on inverse la vitesse
          51.   */
          52. angle = angleMin;
          53. vitesse = 0;
          54. }
          55. delay(25);
          56. }

          Télécharger

          repondre message

          • Mise en œuvre d’un servo-moteur 20 janvier 2016 20:38, par Simon

            Bonsoir,

            Merci beaucoup pour votre aide qui m’a été précieuse et je peux continuer mon projet en le modifiant légèrement.

            Merci encore c’est super sympa

            André

            repondre message

  • Mise en œuvre d’un servo-moteur 30 janvier 2016 14:32, par Serge

    Bonjour,

    J’avance pas à pas, en prenant le temps de la compréhension, je commence à maîtriser les bases mais je suis confronté à un problème que je ne peux résoudre.

    J’alimente un seul servo avec la carte arduino
    A la mise sous tension de l’Arduino, avec le bon sketch téléchargé, il y a un mouvement assez brutal du servo, notamment dans une position où il dépasse largement l’angle maxi.

    Je peux contourner le problème en alimentant d’abord l’arduino puis en branchant le +5v sur le servo. Cela peut très bien se concevoir ainsi mais n’existe-t’il pas de méthode soft pour régler ce problème, ou comment le contournez-vous ?.

    Merci pour tout ce travail et pour votre réponse

    repondre message

Répondre à cet article

Les thèmes

Archives

Informations

ModelleisenbahN | publié sous licence Creative Commons by-nc-nd 2.0 fr | généré dynamiquement par SPIP & Blog'n Glop