Les différents types de mouvements d’un servomoteur

. Par : Dominique, Guillaume, Jean-Luc. URL : https://www.locoduino.org/spip.php?article80

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.