LOCODUINO

La bibliothèque SlowMotionServo

.
Par : Jean-Luc

DIFFICULTÉ :

Mouvoir lentement un organe mécanique revient fréquemment en modélisme ferroviaire. On peut citer les aiguillages, les signaux mécaniques, les passages à niveau ou bien encore les portes de remises. Parmi les actionneurs possibles, on trouve les moteurs à courant continu, les moteurs pas à pas et les servomoteurs. Ces derniers sont les plus simple à commander avec un Arduino car ils ne nécessitent aucune électronique supplémentaire. Les servomoteurs ont fait l’objet de plusieurs articles sur Locoduino, principalement « Les différents types de mouvements d’un servomoteur » et « La bibliothèque Servo ». Nous vous présentons maintenant une nouvelle bibliothèque réalisée par l’auteur et permettant de déplacer lentement plusieurs servomoteurs selon des trajectoires précises.

Après la réalisation du logiciel de pilotage de servomoteurs destiné à la commande d’actionneurs d’aiguillages, voir « Manœuvre des aiguilles avec des servomoteurs » j’ai voulu m’attaquer à la manœuvre de portes de remises et de barrières de passage à niveau. Les mouvements à accomplir sont plus complexes mais aussi plus visuels. La technique doit donc être différente.

Le mouvement du servomoteur pour actionner un aiguillage est linéaire, c’est à dire que l’évolution de l’angle du palonnier au cours du temps est une droite. Cela convient tout à fait dans ce cas mais pour animer le reseau, d’autres mouvements sont nécessaires. Par exemple, l’ouverture d’une porte de remise aura une phase d’accélération, la porte est poussée, une phase de décélération, la porte continue sur son erre et les frottements la ralentisse puis une phase de rebond où la porte revient en arrière avec un mouvement amorti. Il est donc nécessaire de définir le mouvement du servomoteur comme une trajectoire. De cette manière tout est permis.

La bibliothèque SlowMotionServo est construite pour cela. Elle permet de piloter plusieurs servomoteurs simultanément et, pour chacun de ces servomoteurs, de définir une trajectoire, en fait deux trajectoires, une pour le mouvement du palonnier dans le sens trigonométrique et une pour le mouvement dans le sens horaire. La vitesse de parcours de ces deux trajectoires est également réglable.

La position du servomoteur est normalisée sous forme d’un nombre à virgule entre 0.0 et 1.0, 0.0 correspond à la largeur d’impulsion de commande minimum et 1.0 à la largeur maximum.

Installer la bibliothèque

SlowMotionServo est disponible via le gestionnaire de bibliothèque de l’IDE. Dans le menu Croquis, sélectionnez Inclure une bibliothèque puis Gérer les bibliothèques. Dans la case de recherche en haut à droite de la fenêtre qui apparaît, tapez SlowMotionServo.

Mise en œuvre rapide

Commençons par une utilisation simple. Nous n’avons qu’un seul servomoteur à piloter. Commençons par un simple mouvement linéaire. Tout d’abord, comme pour tout autre bibliothèque, il faut inclure SlowMotionServo et Servo, bibliothèque sur laquelle repose SlowMotionServo. Sélectionner dans le menu Croquis puis Inclure une bibliothèque puis SlowMotionServo ajoutera ces deux inclusions dans votre sketch.

#include <Servo.h>
#include <SlowMotionServo.h>

Ensuite, nous allons créer un objet de la classe SMSLinear.

SMSLinear monServo;

Dans setup, nous spécifions la broche par laquelle le servo est commandé, ici la broche 2.

void setup()
{
  monServo.setPin(2);
}

Il nous faut également une variable qui va contenir alternativement 0.0 et 1.0 pour fixer la position cible du servomoteur. Nous initialisons cette variable à 0.0.

float positionCible = 0.0;

Dans loop, nous devons appeler la fonction qui assure l’actualisation de la position du servo et, quand le servo est à l’arrêt, c’est à dire que sa position cible est atteinte, nous changeons cette position cible.

void loop()
{
  SlowMotionServo::update(); /* actualisation de la position */
  if (monServo.isStopped()) {
    positionCible = 1.0 - positionCible;
    monServo.goTo(positionCible);
  }
}

Trois trajectoires sont livrées, une trajectoire linéaire, SMSLinear, qui convient pour les aiguillages :

PNG - 41.1 kio

une trajectoire avec une phase d’accélération et de décélération, SMSSmooth :

PNG - 40.7 kio

et une trajectoire avec dans une direction une phase d’accélération et de décélération suivi d’un amorti, la courbe rouge, et dans l’autre direction une phase d’accélération et de décélération seule, la courbe bleue sur le graphe qui suit, SMSSmoothBounce :

PNG - 46.2 kio

Cette dernière trajectoire convient pour les portes de remise. Il est bien évidemment possible de définir ses propres trajectoires.

Changer les positions minimum et maximum

Nous avons vu que 0.0 correspond à la position minimum et que 1.0 correspond à la position maximum. Par défaut, ces positions correspondent respectivement à des largeurs d’impulsion de 1000µs et 2000µs, c’est à dire les valeurs minimum et maximum recommandées par la bibliothèque Servo. Il est bien évidemment possible de les changer mais faites attention de rester dans les limites permises par vos servomoteurs.

setMin (min)

Définit l’angle minimum du servo. L’angle est exprimé en son équivalent en microsecondes. La valeur peut varier de 544 à 2400. Une valeur inférieure à 544 sera ramenée à 544 et une valeur supérieure à 2400 sera ramenée à 2400. Si la valeur est inférieure à l’angle minimum, elle est ramenée à l’angle minimum.

setMax (max)

Définit l’angle maximal du servo. L’angle est exprimé en son équivalent en microsecondes. La valeur peut aller de 544 à 2400. Une valeur inférieure à 544 sera ramenée à 544 et une valeur supérieure à 2400 sera ramenée à 2400. Si la valeur est supérieure à l’angle maximum, elle est ramenée à l’angle maximum.

setMinMax (min, max)

Définit les angles minimum et maximum du servo. L’angle est exprimé en son équivalent en microsecondes. La valeur peut varier de 544 à 2400. Une valeur inférieure à 544 sera ramenée à 544 et une valeur supérieure à 2400 sera ramenée à 2400. Si l’angle minimum est supérieur à l’angle maximal, les deux angles sont définis sur la valeur moyenne . Par exemple, si vous définissez l’angle minimum sur 2000 et l’angle maximal sur 1000, les deux angles seront définis sur 1500, ce qui se traduira par une impossibilité de mouvement.

Changer la vitesse du mouvement et le sens du mouvement

Par défaut, quelques soient les angles minimum et maximum, les trajets de l’angle minimum à l’angle maximum et inversement sont effectués en 10s. Les vitesses peuvent être réglées via les fonctions suivantes.

setMinToMaxSpeed(vitesse)

Règle la vitesse du servo lorsqu’il se déplace de l’angle minimum à l’angle maximum. la vitesse est un nombre à virgule. Une vitesse de 1.0 correspond à une durée de 10s.

setMaxToMinSpeed(vitesse)

Règle la vitesse du servo lorsqu’il se déplace de l’angle maximum à l’angle minimum. la vitesse est un nombre à virgule. Une vitesse de 1.0 correspond à une durée de 10s.

setSpeed(vitesse)

Règle la vitesse du servo lorsqu’il se déplace de l’angle minimum à l’angle maximum et de l’angle maximum à l’angle minimum. la vitesse est un nombre à virgule flottante. Une vitesse de 1.0 correspond à un 10s en déplacement.

setReverted(sens)

Par défaut, sens, un booléen, est false et les trajectoires correspondent aux graphiques ci-dessus. Si sens est mis à true, le mouvement est inversé selon un axe de symétrie situé à t=0.5. Par exemple, la trajectoire SMSSmoothBounce devient :

PNG - 47 kio

Déclenchement du mouvement

Les fonctions suivantes permettent de mouvoir le servomoteur.

setInitialPosition(position)

Définit la position initiale du servo. La position est un nombre à virgule flottante allant de 0.0 à 1.0. Si la valeur est supérieure à 1.0, elle est ramenée à 1.0 et si elle est inférieure à 0.0, elle est ramenée à 0.0

goTo(position)

Va à la position spécifiée en suivant la trajectoire. La position est un nombre à virgule flottante allant de 0.0 à 1.0. Si la valeur est supérieure à 1.0, elle est ramenée à 1.0 et si elle est inférieure à 0.0, il est ramenée à 0.0

goToMin()

Équivalent à goTo(0.0)

goToMax()

Équivalent à goTo(1.0)

setDetachAtMin(detache)

detache est un booléen. Si true, le servo est détaché lorsque la position minimum est atteinte. Le servo n’est plus piloté. Ceci est utile lorsque le servo doit pousser contre une force de rappel élastique. Si false, le servo continue à être piloté.

setDetachAtMax(detache)

detache est un booléen. Si true, le servo est détaché lorsque la position maximum est atteinte. Le servo n’est plus piloté. Ceci est utile lorsque le servo doit pousser contre une force de rappel élastique. Si false, le servo continue à être piloté.

setDetach(detache)

detache est un booléen. Si true, le servo est détaché lorsque la position minimum ou maximum est atteinte. Le servo n’est plus piloté. Ceci est utile lorsque le servo doit pousser contre une force de rappel élastique. Si false, le servo continue à être piloté.

isStopped()

retourne truesi le servo est arrêté, false si il est en mouvement.

Les autres fonctions

setPin(pin)

Spécifie la broche à laquelle le servo est branché.

SlowMotionServo::setDelayUntilStop(delai)

Cette fonction de classe définit le délai entre le moment où les servos atteignent leur position minimum ou maximum et le moment où ils sont détachés. Comme la mécanique est toujours en retard par rapport au programme, détacher immédiatement les servos les empêcherait d’atteindre leur position mécanique. Ceci est défini une fois pour tous les servos et utilisé uniquement pour les servos et les positions pour lesquelles setDetach(true) est spécifié.

SlowMotionServo::update()

Met à jour les positions de tous les servos. Cette fonction de classe doit être appelée dans loop(). Il ne faut pas que le temps d’exécution de loop() soit trop long sinon le mouvement du ou des servomoteurs se fera par à-coups [1]. Il faut notamment et absolument bannir delay().

Comment définir ses propres trajectoires

Pour ce faire, vous devez hériter de la classe SlowMotionServo et redéfinir les fonctions membres slopeUp et slopeDown. Prenons la classe SMSSmooth comme exemple :

class SMSSmooth : public SlowMotionServo
{
public:
  virtual float slopeUp(float time);
  virtual float slopeDown(float time);
  float slope(float time) { return (1.0 - cos(time * PI))/2.0; }
};

Comme les trajectoires sont les mêmes de min à max et max à min, nous définissons une nouvelle fonction membre, slope, qui définit la trajectoire. Cette fonction est appelée par slopeUp et slopeDown :

float SMSSmooth::slopeUp(float time)
{
  return slope(time);
}

float SMSSmooth::slopeDown(float time)
{
  return slope(time);
}

Un exemple concret

Pour aller plus loin que le petit exemple déjà présenté, je vous propose une petite application permettant de gérer les portes d’une remise à locomotives au moyen d’un bouton poussoir. Le comportement est simple : si les portes sont toutes les deux fermées, une pression sur le bouton les ouvre. Si les portes sont toutes les deux ouvertes, une pression sur le bouton les ferme. Si au moins l’une est en mouvement une pression sur le bouton est sans effet.

Afin de permettre une réutilisation facile et une réplication des double-portes, nous allons définir une class Remise va regrouper les deux servos et le bouton ainsi que la fonction les initialisant et la fonction faisant fonctionner le système. Il s’agit en fait de l’encapsulation du code de l’exemple PushButton2Servos livré avec la bibliothèque. Voici la classe Remise :

class Remise {
  private: SMSSmoothBounce mPorteDroite;
  private: SMSSmoothBounce mPorteGauche;
  private: Bounce mBoutonOverture;
  private: bool mPosition; /* false = fermé, true = ouvert */

  public: void demarre(const byte pinBouton, const byte pinServoPorteDroite, const byte pinServoPorteGauche);
  public: void gereRemise();
};

On y trouve nos deux servos de type SMSSmoothBounce et le bouton [2]. On a également une variable booléenne, mPosition permettant de mémoriser si les portes sont en position ouverte ou fermée. Enfin, la fonction demarre permet d’initialiser tout ce petit monde et la fonction gereRemise gère le bouton et lance le mouvement si il est enfoncé et que les portes sont stoppées.

La fonction demarre

Cette fonction procède donc aux intialisations. La broche du bouton est programmée en entrée avec résistance de tirage à 5V, l’objet mBouton est accroché à sa broche et son intervalle de rafraichissement est fixé. Les valeurs minimum et maximum des deux portes sont fixées avec une ouverture légèrement supérieure à 90°. Les valeurs sont à affiner selon vos servos. La vitesse est fixée à 1.7, cette valeur est à régler selon vos goûts. Le mouvement de la porte gauche est inversé par rapport au mouvement de la porte de droite. Les positions initiales sont fixées à 0.1 afin qu’il y ait un mouvement au démarrage pour fermer les portes (les deux goTo(0.0) à la fin de demarre). En effet, il faut que la position initiale soit différente du premier mouvement demandé, sinon aucun mouvement n’aura lieu. Enfin, les deux servos sont accrochés à leur broche respectives.

void Remise::demarre(const byte pinBouton, const byte pinServoPorteDroite, const byte pinServoPorteGauche)
{
  pinMode(pinBouton, INPUT_PULLUP);
  mBoutonOverture.attach(pinBouton);
  mBoutonOverture.interval(5); /* rafraichissement toutes les 5ms */
  mPorteDroite.setMin(700);
  mPorteDroite.setMax(1800);
  mPorteDroite.setSpeed(1.7);
  mPorteGauche.setMin(1100);
  mPorteGauche.setMax(2200);
  mPorteGauche.setSpeed(1.7);
  mPorteGauche.setReverted(true); /* La porte gauche a un mouvement inverse */
  mPorteDroite.setInitialPosition(0.1);
  mPorteGauche.setInitialPosition(0.1);
  mPorteDroite.setPin(pinServoPorteDroite);
  mPorteGauche.setPin(pinServoPorteGauche);
  mPosition = false;
  /* ferme les porte au démarrage */
  mPorteDroite.goTo(0.0);
  mPorteGauche.goTo(0.0);
}

La fonction gereRemise

Cette fonction lit le bouton et, si aucune des portes n’est en mouvement et si le bouton a été enfoncé, fixe une position cible en fonction de la position courante. Voici cette fonction :

void Remise::gereRemise()
{
  mBoutonOverture.update(); /* met à jour l'état du bouton */
  if (mPorteDroite.isStopped() && mPorteGauche.isStopped())
  {
    /* si un mouvement était en cours, il est terminé */
    if (mBoutonOverture.fell()) {
      /* appui sur le bouton, on démarre le mouvement */
      if (mPosition) {
        /* la remise est ouverte, la cible pour la fermer est 0.0 */
        mPorteDroite.goTo(0.0);
        mPorteGauche.goTo(0.0);
        mPosition = false;
      }
      else {
        /* la remise est fermée, la cible pour l'ouvrir est 1.0 */
        mPorteDroite.goTo(1.0);
        mPorteGauche.goTo(1.0);
        mPosition = true;
      }
    }
  }
}

Le sketch

Tout d’abord, nous créons un objet de type Remise :

Remise remise1;

Ensuite nous déclarons des constantes correspondant aux broches où sont connectés le bouton et les servos :

const byte pinServoDroitRemise1 = 4;
const byte pinServoGaucheRemise1 = 3;
const byte pinBoutonRemise1 = 5;

Dans setup, nous initialisons la remise :

void setup()
{
  remise1.demarre(pinBoutonRemise1, pinServoDroitRemise1, pinServoGaucheRemise1);
}

Enfin dans loop, nous appelons SlowMotionServo::update() pour actualiser la position des servos et nous appelons gereRemise() pour saisir les ordres de l’utilisateur et lancer le mouvement des portes :

void loop()
{
  SlowMotionServo::update();

  remise1.gereRemise();
}

Voici le sketch à télécharger :

Sketch de démonstration pour une remise double-porte

Et une vidéo de démonstration de ce sketch :

Et si j’ai plusieurs double-portes ?

C’est assez simple :

  1. Déclarez toutes les constantes des numéros de broches pour tous les servos et les boutons ;
  2. Instanciez autant d’objets Remise que vous avez de double-portes. Par exemple, remise1, remise2, remise3, etc.
  3. Appelez demarre dans setup pour chacun des objets Remise.
  4. Appelez gereRemise dans loop pour chacun des objets Remise. Notez que l’appel de SlowMotionServo::update() reste en un seul exemplaire.

[1Par exemple, pour un movement linéaire, si le servomoteur parcoure 90° en 5s, ceci correspond à une variation de durée d’impulsion de 1000µs en 5s environ. La résolution de la durée d’impulsion imposé par la bibliothèque Servo étant de 4µs, update doit être appelée au moins toutes les 20ms.

[2Comme pour l’exemple PushButton2Servos, on utilise la bibliothèque Bounce2.

66 Messages

  • génial et limpide
    merci

    Répondre

  • La bibliothèque SlowMotionServo 13 avril 2019 10:56, par Luc DE VLEESCHOUWER

    Bonjour,
    Malheureusement, je n’obtiens pas le résultat escompté. En effet, la rotation des servomoteurs se fait pas à pas au lieu d’une rotation de 90°. J’ai vérifié le montage. J’ai ajouté la librairie "Bounce2" dans le programme. Merci pour votre réponse.

    Répondre

  • La bibliothèque SlowMotionServo 14 avril 2019 17:32, par Luc DE VLEESCHOUWER

    Oui, j’ai rajouté la bibliothèque Bounce 2 comme indiqué dans une réponse.Voir ci-dessous :
    Comme pour l’exemple PushButton2Servos, on utilise la bibliothèque Bounce2.

    Répondre

    • La bibliothèque SlowMotionServo 15 avril 2019 08:27, par Jean-Luc

      Il ne s’agit pas à proprement parler d’une modification du sketch. Je parlais de l’ajout de code comme par exemple quelques delay(...). Si le sketch n’a pas été modifié, une cause possible est une consommation excessive des servos qui effondre l’alimentation.

      Répondre

      • La bibliothèque SlowMotionServo 15 juillet 2020 09:58, par Luc De Vleeschouwer

        J’ai repris mon problème après une longue absence due à des problèmes de santé.
        Vous aviez raison, c’était une consommation trop importante des servos.
        J’ai ajouté un condensateur de 100µF à chaque servo ainsi qu’une résistance de 10 kΩ à la masse du bouton poussoir.
        Cela fonctionne parfaitement.
        Je vous suggère de l’indiquer dans votre note explicative pour les débutants comme moi.
        Encore merci pour vos conseils.

        Répondre

  • La bibliothèque SlowMotionServo 15 avril 2019 09:48, par Luc DE VLEESCHOUWER

    Merci.
    Je vais en parler à mon fournisseur de servos.

    Répondre

  • La bibliothèque SlowMotionServo 16 avril 2019 10:19, par Luc DE VLEESCHOUWER

    Bonjour.
    Ce sont des servos SG90 alimentés en 4 à 6 V.

    Par contre, il y a une phrase dans le texte "exemple concret" qui me préoccupe.

    " Il s’agit en fait de l’encapsulation du code de l’exemple PushButton2Servos livré avec la bibliothèque."

    Faut-il installer la bibliothèque "PushButton2Servos" ?
    Je ne l’ai pas trouvée dans le programme Arduino après avoir été dans "Croquis" "Gérer les bibliothèques".
    Merci pour votre réponse.

    Répondre

    • La bibliothèque SlowMotionServo 18 avril 2019 20:29, par Jean-Luc

      Bonsoir,

      PushButton2Servos est un des exemples de la bibliothèque SlowMotionServo. Je reviens sur ce que vous observez : « En effet, la rotation des servomoteurs se fait pas à pas au lieu d’une rotation de 90° ». Ce n’est pas très clair. Qu’entendez vous exactement ? le mouvement est haché ? discontinu ?

      Répondre

  • La bibliothèque SlowMotionServo 19 avril 2019 10:01, par Luc DE VLEESCHOUWER

    Bonjour,
    En effet, je l’ai retrouvé dans les exemples.
    La rotation ne se fait pas complètement. Elle s’arrête à 30°. Mais les deux servos fonctionnent en même temps.
    Mais, une chose m’a préoccupé. Dans le sketch, au début, il y a les deux "include" (Servo et SlowMotionServo).
    Quand j’ai vérifié dans l’Arduino, il y avait un message d’erreurs au niveau de la ligne "private : Bounce mBoutonOverture". J’ai, donc, rajouter la librairie Bounce2. Ce qui est curieux, c’est qu’elle s’affiche en noir alors que les deux autres sont en rouge. Est-ce une ancienne version ?
    Ne dois-je pas changer les chiffres dans le SetMin et SetMax ?
    Les servos sont des TP SG90.
    Je ne vois vraiment pas où se situe le problème. Merci pour votre réponse.

    Répondre

    • La bibliothèque SlowMotionServo 19 avril 2019 19:42, par Jean-Luc

      Bonsoir,
      Normalement 180° correspond à des valeurs min de 544 et max de 2400. Soit à une vache près 2000 pour 180°. Dans le sketch, les valeurs sont celles que j’ai utilisées pour la vidéo, avec une différence max-min de 1100, ce qui correspond à 100° environ. C’est surprenant que vous ayez 30°. Essayer avec les valeurs maximum permises pour voir ce que ça donne.

      Répondre

  • La bibliothèque SlowMotionServo 24 avril 2019 11:07, par Luc DE VLEESCHOUWER

    Merci pour vos bons conseils mais cela ne fonctionne toujours pas. Je vous transmets les messages d’erreurs que je reçois lors de la vérification.

    Arduino : 1.8.9 (Windows 7), Carte : "Arduino/Genuino Uno"
    Remise:12:12 : error : ’Bounce’ does not name a type
    private : Bounce mBoutonOverture ;
    C :\Users\Luc\Documents\Arduino\Remise\Remise.ino : In member function ’void Remise::demarre(byte, byte, byte)’ :
    Remise:22:3 : error : ’mBoutonOverture’ was not declared in this scope
    mBoutonOverture.attach(pinBouton) ;
    C :\Users\Luc\Documents\Arduino\Remise\Remise.ino : In member function ’void Remise::gereRemise()’ :
    Remise:43:3 : error : ’mBoutonOverture’ was not declared in this scope
    mBoutonOverture.update() ; /* met à jour l’état du bouton */
    exit status 1
    ’Bounce’ does not name a type

    Répondre

    • La bibliothèque SlowMotionServo 24 avril 2019 11:54, par Jean-Luc

      Bonjour,
      Vous n’avez sans doute pas installé la bonne bibliothèque. Bounce2 s’installe via le gestionnaire de bibliothèques.

      Répondre

  • La bibliothèque SlowMotionServo 26 avril 2019 10:28, par Luc DE VLEESCHOUWER

    Bonjour,
    J’avais déjà ajouté la librairie "Bounce2" (voir mon message du 13 avril) sans succès.

    Répondre

    • La bibliothèque SlowMotionServo 26 avril 2019 18:44, par Jean-Luc

      Le message d’erreur explique que le compilateur ne sait pas ce qu’est Bounce .
      la seule explication possible est que l’include #include <Bounce2.h> A sauté du sketch ou à été déplacé.

      Répondre

  • La bibliothèque SlowMotionServo 27 avril 2019 12:04, par Luc DE VLEESCHOUWER

    Un tout grand merci à tous pour votre aide.

    Répondre

  • La bibliothèque SlowMotionServo 26 novembre 2019 22:11, par Xavier

    Bonsoir,

    Très bien cette bibliothèque ... Je compte l’utiliser en lien avec la bibliothèque NmraDcc pour des décodeurs d’accessoires divers et variés, inspirés du SmartSwitch de Peco.
    J’aurais besoin de quelques précisions sur la plage de valeur acceptées pour les vitesses (setMinToMaxSpeed, setMaxToMinSpeed, setSpeed) qui irait de 0.0 à ???.
    Pour les positions (setInitialPosition, GoTo) elles vont de 0.0(défini par setMin) à 1.0(défini par setMax)

    De plus, si j’ai bien suivi, dans le setup de l’exemple, la séquence
    mPorteDroite.setMin(700) ;
    mPorteDroite.setInitialPosition(0.1) ;
    mPorteDroite.setPin(pinServoPorteDroite) ;
    mPorteDroite.goTo(0.0) ;

    permet de positionner la porte droite comme défini par setMin

    Merci

    Répondre

    • La bibliothèque SlowMotionServo 29 novembre 2019 00:26, par Jean-Luc

      Bonsoir,

      Il n’y a pas de limite pour la vitesse max excepté la valeur maximum qu’il est possible de stocker dans un nombre flottant d’une part et les débordements de capacité qui pourraient se produire lors des calculs d’autre part. Ceci dépend de l’intervalle de temps entre deux updates et de la trajectoire. En pratique, une vitesse de 1.0 se traduira par un temps de parcours de 10s et une vitesse de 10.0 par un temps de parcours d’une seconde. A vous de choisir ce qui vous convient.

      la réponse est oui pour les deux autres questions.

      cordialement.

      Répondre

  • La bibliothèque SlowMotionServo 29 novembre 2019 20:41, par Xavier

    Bonsoir,
    Merci pour cette réponse précise que je vais m’empresser d’essayer.
    Mon projet avance a grands pas. Je dois encore

    • Valider le décodeur DCC
    • Inclure la gestion de 2 PCF8574, l’un pour visualiser la position des accessoires, le second pour pouvoir les commander soit par des boutons poussoirs, soit par des interrupteurs.
      J’ai remplacé le double afficheur 7 segments par un LCD 2*16 en I2C
      Cordialement,

    Répondre

  • La bibliothèque SlowMotionServo 15 décembre 2019 20:09, par Fantasio

    Bonsoir Jean-Luc.

    Tout d’abord un grand merci pour votre travail.

    J’utilise des attiny85 pour la plupart des animations au profit de mon club.
    Quelques entrées sorties sont suffisantes et l’utilisation d’un Uno serait vraiment de la gourmandise...
    Bien évidemment du fait de son timer à 8 bits, l’attiny n’accepte pas la bibliothèque Servo...Est ce également le cas pour SlowMotionServo ?

    Merci par avance pour votre aide.

    Répondre

  • La bibliothèque SlowMotionServo 15 décembre 2019 21:45, par msport

    Peut-être lire :
    Le microcontrôleur ATtiny45 (1)commande servo 4 décembre 2018 14:56, par christian

    Toutes les bibliothèques écrites pour Arduino ne fonctionnent pas avec les puces ATtiny. C’est notamment le cas de la bibliothèque Servo car elle utilise le Timer 16 bits absent de l’ATtiny45.
    Et du coup SlowMotionServo non plus !
    Attention à ce genre de réponse qui paraît évident mais ne l’est absolument pas. Ce n’est pas pour rien si, dans l’article, nous avons reconstitué le signal au lieu d’employer une bibliothèque.

    Le microcontrôleur ATtiny45 (1)commande servo 5 décembre 2018 09:28, par Jean-Luc

    Effectivement, essais faits, c’est la bibliothèque Servo qui ne compile pas faute de support matériel. Il existe une bibliothèque nommée Servo8bit pour les ATTiny 45 et 85 : https://github.com/fri000/Servo8Bit

    Répondre

  • La bibliothèque SlowMotionServo 16 décembre 2019 00:37, par Fantasio

    Merci pour votre réponse.

    Dommage que cette bibliothèque très intéressante ne puisse être utilisée avec l’attiny. Ce microcontrôleur, il est vrai, est limité et ce n’est pas la première fois qu’une application développée sur l’Arduino ne peut être transférée sur l’attiny...

    Bonne continuation et félicitation pour ce site

    Répondre

    • La bibliothèque SlowMotionServo 16 décembre 2019 12:04, par msport

      Je n’ai pas utilisé SlowMotionServo sur ATTiny, mais je comprends de la réponse citée de Christian, qu’en utilisant la bibliothèque nommée Servo8bit, SlowMotionServo devrait fonctionner sur ATTiny.
      Dites nous si vous essayez.

      Répondre

      • La bibliothèque SlowMotionServo 16 décembre 2019 14:39, par Fantasio

        Je viens juste de modifier le programme en incluant Servo8bit et en modifiant les numéros des pins por l’adapter à l’attiny85.

        La compilation me retourne ces erreurs :
        Arduino : 1.8.6 (Windows 10), Carte : "ATtiny25/45/85, ATtiny85, Internal 8 MHz"

        C :\Users\Dominique\Documents\Arduino\libraries\Servo\src\avr\Servo.cpp : In function ’void __vector_3()’ :

        C :\Users\Dominique\Documents\Arduino\libraries\Servo\src\avr\Servo.cpp:82:44 : error : cannot convert ’volatile uint8_t* aka volatile unsigned char*’ to ’volatile uint16_t* aka volatile unsigned int*’ for argument ’2’ to ’void handle_interrupts(timer16_Sequence_t, volatile uint16_t*, volatile uint16_t*)’

        handle_interrupts(_timer1, &TCNT1, &OCR1A) ;
        ^
        C :\Users\Dominique\Documents\Arduino\libraries\Servo\src\avr\Servo.cpp : In function ’void initISR(timer16_Sequence_t)’ :

        C :\Users\Dominique\Documents\Arduino\libraries\Servo\src\avr\Servo.cpp:129:5 : error : ’TCCR1B’ was not declared in this scope

        TCCR1B = _BV(CS11) ; // set prescaler of 8

        ^

        C :\Users\Dominique\Documents\Arduino\libraries\Servo\src\avr\Servo.cpp:136:5 : error : ’TIFR1’ was not declared in this scope

        TIFR1 |= _BV(OCF1A) ; // clear any pending interrupts ;

        ^

        C :\Users\Dominique\Documents\Arduino\libraries\Servo\src\avr\Servo.cpp:137:5 : error : ’TIMSK1’ was not declared in this scope

        TIMSK1 |= _BV(OCIE1A) ; // enable the output compare interrupt

        ^

        Plusieurs bibliothèque trouvées pour "Servo.h"
        Utilisé : C :\Users\Dominique\Documents\Arduino\libraries\Servo
        Non utilisé : D :\arduino\arduino-1.8.6\libraries\Servo
        exit status 1

        Répondre

        • La bibliothèque SlowMotionServo 16 décembre 2019 16:00, par msport

          Manifestement, il y a d’autres références à la version 16 bits de Servo qu’il faudrait remplacer par la version 8 bits.
          Servo.cpp -> Servo8Bits.cpp
          Les concepteurs pourront certainement en dire plus mais un message de 2018 n’a pas eu de suite.
          https://www.locoduino.org/spip.php?...

          Répondre

          • La bibliothèque SlowMotionServo 16 décembre 2019 16:07, par msport

            En attendant vous pouvez tenter de modifier SlowMotionServo.h dans vos "libraries" : Servo.h -> Servo8Bits.h (ne fonctionnera plus pour les Arduino)

            Répondre

            • La bibliothèque SlowMotionServo 16 décembre 2019 17:54, par Fantasio

              Merci pour votre aide.

              Au point où j’en suis, triturer SlowMotionServo me parait difficile vu mon niveau actuel. Mais bon je vais essayer...

              Répondre

              • La bibliothèque SlowMotionServo 16 décembre 2019 19:16, par Jean-Luc

                Bonsoir.

                L’IDE détermine la bibliothèque à utiliser en examinant les includes situés le sketch. Ici il essaye de compiler Servo, pas Servo8bits. Avez vous remplacé le include de Servo.h par Servo8bits.h dans le sketch en plus de l’avoir remplacé dans SlowMotionServo.h ? Si non, il faut le faire.

                cordialement.

                Répondre

  • La bibliothèque SlowMotionServo 16 décembre 2019 13:25, par Fantasio

    Pas de problème, je vous tiendrai informé du résultat que j’espère positif.

    Répondre

  • La bibliothèque SlowMotionServo 17 décembre 2019 01:16, par Fantasio

    Suite à votre message j’ai effectivement remplacé dans le sketch le include de Servo.h par Servo8Bit.h et même manip dans le SlowMotionServo.h

    La compilation me retourne désormais uniquement les erreurs suivantes :

    In file included from C:\Users\Dominique\Documents\Arduino\attiny_remise8bit\attiny_remise8bit.ino:10:0:
    qui correspondrait à #include <SlowMotionServo.h>

    C:\Users\Dominique\Documents\Arduino\libraries\SlowMotionServo-master\src/SlowMotionServo.h:28:1: error: expected class-name before '{' token
    
     {
    
     ^
    
    exit status 1
    Erreur de compilation pour la carte ATtiny25/45/85

    Répondre

    • La bibliothèque SlowMotionServo 17 décembre 2019 07:25, par Jean-Luc

      C’est à cause de la ligne 27 où il y a :

      class SlowMotionServo : public Servo

      Il faudrait également remplacer Servo par Servo8bit

      Répondre

      • La bibliothèque SlowMotionServo 17 décembre 2019 12:18, par Fantasio

        Je viens de remplacer public Servo par public Servo8Bit, la compilation me retourne maintenant les erreurs suivantes :

        Arduino : 1.8.6 (Windows 10), Carte : "ATtiny25/45/85, ATtiny85, Internal 8 MHz"
        
        In file included from C:\Users\Dominique\Documents\Arduino\libraries\SlowMotionServo-master\src/SlowMotionServo.h:23:0,
        
                         from C:\Users\Dominique\Documents\Arduino\libraries\SlowMotionServo-master\src\SlowMotionServo.cpp:19:
        
        C:\Users\Dominique\Documents\Arduino\libraries\Servo8Bit-master/Servo8Bit.h: In member function 'unsigned int SlowMotionServo::normalizePos(unsigned int)':
        
        C:\Users\Dominique\Documents\Arduino\libraries\Servo8Bit-master/Servo8Bit.h:83:9: error: 'long int Servo8Bit::map(long int, long int, long int, long int, long int)' is private
        
            long map(long x, long in_min, long in_max, long out_min, long out_max);
        
                 ^
        
        C:\Users\Dominique\Documents\Arduino\libraries\SlowMotionServo-master\src\SlowMotionServo.cpp:177:22: error: within this context
        
           return mReverted ? map(inPos, mMinPulse, mMaxPulse, mMaxPulse, mMinPulse) : inPos;
        
                              ^
        
        In file included from C:\Users\Dominique\Documents\Arduino\libraries\SlowMotionServo-master\src/SlowMotionServo.h:23:0,
        
                         from C:\Users\Dominique\Documents\Arduino\libraries\SlowMotionServo-master\src\SlowMotionServo.cpp:19:
        
        C:\Users\Dominique\Documents\Arduino\libraries\Servo8Bit-master/Servo8Bit.h:83:9: error: 'long int Servo8Bit::map(long int, long int, long int, long int, long int)' is private
        
            long map(long x, long in_min, long in_max, long out_min, long out_max);
        
                 ^
        
        C:\Users\Dominique\Documents\Arduino\libraries\SlowMotionServo-master\src\SlowMotionServo.cpp:177:75: error: within this context
        
           return mReverted ? map(inPos, mMinPulse, mMaxPulse, mMaxPulse, mMinPulse) : inPos;

        Répondre

        • La bibliothèque SlowMotionServo 17 décembre 2019 19:00, par Jean-Luc

          Allez savoir pourquoi, l’auteur de Servo8bit a cru bon de définir sa propre fonction map qui fait pourtant partie du logiciel Arduino de base. Manque de pot il l’a mise privée. Comme Servo utilise cette fonction et que celle du logiciel Arduino est masquée par celle déclarée dans Servo8bit et que cette dernière est privée, on a cette erreur de compilation.

          Donc essayez à la ligne 177 de SlowMotionServo.cpp de remplacer map par ::map ce qui forcera l’appel du map du scope global, c’est à dire celui du logiciel Arduino.

          Répondre

  • La bibliothèque SlowMotionServo 17 décembre 2019 22:40, par msport

    Bibliothèque modifiée et renommée en 8 bits.
    Compile, mais à tester sur ATTiny.

    Voir en ligne : bibliothèque SlowMotionServo modifiée 8 bits

    Répondre

  • La bibliothèque SlowMotionServo 18 décembre 2019 18:27, par Fantasio

    Merci pour votre aide et du temps consacré pour répondre à ma sollicitation....

    Effectivement la compilation se fait désormais sans signaler d’erreur.

    Je testerai le programme prochainement au sein de mon club...

    Bonne continuation

    Répondre

  • La bibliothèque SlowMotionServo comportement erratique avec MQTT 12 février 2020 14:25, par Régis Saint Girons

    Bonjour,Je dois contrôler des clapets de ventilation avec un ESP8266 et un servo. J’utilise les librairies ESP8266WiFi.h et PubSubClient.h pour faire des liaisons MQTT wifi entre l’ESP8266 et un thermomètre zigbee.

    Je fais tourner sans problème votre exemple RightLeft.ino sur l’ESP8266 mais lorsque je l’intègre dans mon projet avec le wifi et mqtt je n’arrive pas à avoir un fonctionnement cohérent du servo.

    Dans mon projet lorsque je reçois un message mqtt j’extrais la payload qui est la position voulu pour le clapet (0 fermée, 1 ouvert). Je la transforme en float et j’utilise votre code :

      SlowMotionServo::update(); /* actualisation de la position */
      if (servo.isStopped()) {
         servo.goTo(position);
      }

    J’ai pris soin de faire les setup recommandés min, max, speed, pin SMSLinear...

    après reset le servo se déplace à la position voulu mais sans effet slow motion puis il réagit de façon aléatoire aux ordres suivants. Je ne sais pas trop quoi faire pour debugger cela et vos conseils me seront précieux ?

    Répondre

  • La bibliothèque SlowMotionServo 12 février 2020 19:50, par Jean-Luc

    Bonsoir,

    il est probable que slowMotionServo::Update() ne soit pas appelé suffisamment souvent. Il est également probable que la gestion de MQTT soit fautive car trop longue. Pour en avoir le coeur net, enregistrez la valeur de millis() dans un tableau à chaque fois que vous appelez slowMotionServo::Update() puis au bout d’un nombre d’échantillons suffisamment important imprimez la différence entre deux valeurs successive du tableau. Ça vous donnera un indication.

    Répondre

  • La bibliothèque SlowMotionServo 6 avril 2020 20:31, par paul laurence

    bonsoir et encore merci pour votre excellent tuto ca ma permis d’apprendre pas mal de chose et surtout me débloquer sur certain projet que j’ai en ce moment. par contre j’aurai une petit question pratique que je n’arrive pas a faire( je suis débutant dans l’arduino). J’ai 2 paire de porte je souhaiterai que une de mes paire s’ouvre qu’il y ai un temps d’attente et que l’autre paire s’ouvre puis inversement. Excuser moi pour cette question un peu bête mais ça fait quelque jour que je me creuse la tête et que j’y arrive pas

    en vous remerciant d’avance

    Répondre

    • La bibliothèque SlowMotionServo 7 avril 2020 09:49, par Jean-Luc

      Bonjour,
      il faut que vous fassiez une machine à états avec les états FERMEES, PREMIERE_SOUVRE, SECONDE_SOUVRE, OUVERTES, SECONDE_SE_FERME, PREMIERE_SE_FERME avec des transitions s’effectuant sur le passage du temps. Allez lire l’article « Comment concevoir rationnellement votre système.

      Répondre

      • La bibliothèque SlowMotionServo 8 avril 2020 14:23, par paul laurence

        bonjour, merci pour votre aide mais je ne comprend pas ce qu’il faut faire j’essai de refaire le void remise pour que la porte 1 s’ouvre avant la porte 2 mais je ne comprend pas comment faire (l’arduino doit pas être fait pour moi).j’ai bien lu votre article que vous m’avez mis en lien mais je ne comprend pas ce qu’il faut faire.

        Répondre

        • La bibliothèque SlowMotionServo 8 avril 2020 15:38, par Jean-Luc

          Bonjour,
          J’essaye de vous expliquer ça quand j’ai deux minutes (étant donné que je vais en avoir besoin pour ma remise, autant en faire profiter les autres :-)) mais le format des messages à la suite des articles n’est pas idéal. J’ouvrirai un fil sur le forum.
          Cordialement.

          Répondre

  • La bibliothèque SlowMotionServo 9 septembre 2020 20:23, par henri_oul

    Bonjour, je voulais vous remercier pour cette bibliothèque, elle m’a permis enfin de faire fonctionner mes servos sans bloqué le reste de mon programme
    J en profite aussi pour vous dire qu elle fonctionne bien sur esp32 après modification de la bibliothèque servo par esp32_servo
    J’ai pas tout testé mais je suis arrivé à faire fonctionner 3 servos suivant les différents modes

    Cédric

    Répondre

  • La bibliothèque SlowMotionServo 17 octobre 2020 11:15, par Antoine (tony04)

    Bonjour Jean Luc,
    j’utilise cette librairie depuis qu’elle existe et te félicite pour le travail réalisé.

    Par contre j’ai eu la surprise de voir l’un de mes montages ne plus fonctionner suite à la dernière mise à jour.
    Voici la différence que j’ai pu constater :
    Pour des raisons de commodité j’utilisais la fonction setMin et setMax pour le tarage de mes servos et cela même en dehors du setup du sketch, c.a.d. dans le loop.
    Sur la nouvelle version il semblerait qu’il ne soit plus possible d’utiliser ces fonctions dans le loop, peux-tu me confirmer ce comportement ?
    En attendant j’utilise une ancienne version de cette librairie.

    Merci par avance pour ta réponse et très bon Week-end.

    Bien cordialement
    Antoine

    Répondre

    • La bibliothèque SlowMotionServo 20 octobre 2020 14:16, par Jean-Luc

      Bonjour Antoine,

      Effectivement dans la dernière version, pour permettre le réglage « live », j’ai ajouté une machine d’états interne qui distingue les modes de fonctionnement. Je vais regarder mais il se pourrait que ça soit dû à ça.

      Bien cordialement

      Répondre

  • La bibliothèque SlowMotionServo 9 novembre 2021 18:04, par Didier

    Bonjour j’aimerais trouver un programme qui commande 4 servomoteur en même temps,le même mouvement de 0 à 90 et 90 à 0 en continu merci beaucoup
    C’est parceque j’ai 64 ans et je n’y connais rien merci beaucoup cordialement Didier

    Répondre

  • La bibliothèque SlowMotionServo 9 novembre 2021 21:18, par msport

    Bonsoir,

    potentiellement pas besoin de programme spécifique :

    vous câblez les quatre servos en parallèle, ils exécuteront le même mouvement si ils sont identiques.

    Si besoin vous utilisez quatre sorties qui prennent la même valeur en même temps.

    Cordialement

    Répondre

  • La bibliothèque SlowMotionServo 10 décembre 2021 11:19, par Didier

    Bonjour j’ai un projet avec servomoteur un bûcheron qui abat un arbre le bûcheron arrête et l’arbre tombe reste coucher x seconde ce releve et le bûcheron recommence si quelqu’un pouvait m’aider car j’ai 64 ans et je ni connais rien en programmation merci beaucoup cordialement Didier

    Répondre

    • La bibliothèque SlowMotionServo 10 décembre 2021 21:49, par msport

      Bonsoir,
      sauf intérêt particulier, Locoduino ne réalise pas de programmes tout faits. Voyez via le forum si quelqu’un a le même projet. En tout état de cause, pour ce type de réalisation simple, vous pouvez vous inspirer de l’exemple Sweep de la bibliothèque Servo facilement modifiable pour un 2e servo.
      Cordialement.

      Voir en ligne : Comment piloter un servomoteur avec un Arduino

      Répondre

  • La bibliothèque SlowMotionServo 12 janvier 2023 12:03, par Jean François

    Bonjour,
    j’ai voullu utiliser le programme remise en le modifiant pour une seule porte.Dans le programme j’ai donc supprimé toutes les instructions contenant Porte Droite
    La compilation se passe assez bien mais le televersement s’arrete et j’ai des messages d’erreurs du type
    avrdude:st500_getsync()attempt 0 of 10:not_in sync:resp=0x1c
    avrdude:st500_rec()programer is not responding
    Ce message va de 0 a 10
    a droite un autre message d’erreur indique
    upload error:failed reploading:uploading error:exit status1
    que dois je faire pour arriver a ouvrir et fermer une seule porte
    cordialement

    Répondre

    • La bibliothèque SlowMotionServo 12 janvier 2023 17:27, par Jean-Luc

      Bonjour,
       
      Il est peu probable que les problèmes de téléversement du sketch soit dûs à vos modifications. Pouvez vous téléverser un autre sketch dans cet Arduino, Blink par exemple ?
       
      Sinon, il est inutile de modifier le sketch pour ne manœuvrer qu’une seule porte car il suffit de ne pas brancher le second servo, voilà tout ☺️

      Répondre

  • La bibliothèque SlowMotionServo 15 janvier 2023 11:43, par Jean François

    Bonjour, merci pour votre réponse
    J’ai televersé Blink comme vous me l’avez suggéré.
    Cela ne marche pas j’ai toujour une indiquation d’erreur
    Il faut que je regle ça avant de recharger "remise"
    Concernant la porte unique c’est tellement evident que je n’y ai même pas pensé
    Cordialement

    Répondre

  • Où et comment demander de l’aide ? 15 janvier 2023 13:43, par msport

    Bonjour,

    votre problème est basique et n’a rien à voir avec l’article.
    Voyez comment le présenter sur le forum.
    https://www.locoduino.org/spip.php?...
    Et avant relisez les articles d’initiation :
    https://www.locoduino.org/spip.php?...

    Si vous utilisez le bon port, vous n’avez peut-être pas choisi le bon Nano ...

    Cordialement

    Répondre

  • La bibliothèque SlowMotionServo application "remise" 15 janvier 2023 15:04, par Besseyre Guy

    Bonjour à tous
    après de nombreux essais, je n’arrive pas à rajouter au programme "remise"
    le clignotement d’une led quand les portes sont FERMEES ;
    merci de votre aide

    Répondre

  • La bibliothèque SlowMotionServo 2 avril 2023 18:33, par Francois Constant

    Bonjour, comment introduire cette fonction dans le code du PN décrit dans les 5 articles

    Répondre

  • La bibliothèque SlowMotionServo 2 avril 2023 21:21, par msport

    Bonjour,
    vous pouvez utiliser le sketch de démonstration pour une remise double-porte remise.ino en remplaçant le bouton poussoir par des ILS ou des détecteurs FC-51 en parallèle.
    Cordialement

    Répondre

  • La bibliothèque SlowMotionServo 13 septembre 2023 18:42, par Pépito

    Pour info, afin de pouvoir disposer de la fonction delay() ou d’avoir un programme conséquent qui va impacter la fonction SlowMotionServo::update()
    Il est possible de placer cette fonction dans une boucle while qui va permettre un rafraichissement très rapide de l’état du servo.
    ici le booléen Départ permet de rentrer la première fois dans la boucle puis c’est la fin du mouvement du servo qui permet d’en sortir :

    bool Depart = 1;
    while(Depart == 1 || monServo.isStopped() == 0){
      Depart = 0;
      if (monServo.isStopped()) {
        positionCible = 1 - positionCible;
        monServo.goTo(positionCible);
      }
      SlowMotionServo::update(); /* actualisation de la position */ 
    }
    delay(5000);

    Répondre

  • La bibliothèque SlowMotionServo 30 octobre 2023 17:09, par CHAUVIN Patrick

    bonjour Jean-Luc,
    tout d’abord merci pour ces explications précises et ce sketch de mouvement de portes de remises.
    Je l’ai adapté pour une remise de 5 garages à 2 portes soit 10 portes en tout avec un déclenchement d’ouverture par des ILS. Tout fonctionne très bien sauf qu’à la mise sous tension de l’Arduino Uno, tous les servomoteurs se mettent à faire un soubresaut très violent et ne retrouvent pas leur position d’origine, portes ouvertes ou fermées, les portes se retrouvent à mi chemin. J’utilise des petits servos SG90. Je ne vois pas du tout d’où peut provenir ce problème, auriez vous une idée ?
    Merci d’avance pour l’aide que vous m’apporterez.
    Bien cordialement
    Patrick

    Répondre

    • La bibliothèque SlowMotionServo 30 octobre 2023 17:29, par Jean-Luc

      Bonjour Patrick,
       
      À priori, ce problème survient car, à la mise sous tension, l’électronique du servo interprète le signal (qui est alors flottant) conjointement avec la montée de l’alimentation, comme un pulse qui fixe alors une position du servo.
       
      Normalement, ce problème peut être réglé en mettant une résistance de quelque kΩ (essayez 10 kΩ) entre le signal et le 5V.

      Répondre

      • La bibliothèque SlowMotionServo 30 octobre 2023 17:43

        Merci Jean-Luc pour cette réponse ultra rapide ! Je ne suis pas sur place mais je ferai cette modification dès la semaine prochaine et vous tiendrai au courant
        Bonne soirée
        Bien cordialement

        Répondre

  • La bibliothèque SlowMotionServo 8 juin 18:22, par jacques filippi

    Magnifique travail (comme toujours) pour la mise au point de cette bibliothèque.

    j’ai pu m’apercevoir en écrivant mon programme ( barrières de PN ) qu’elle avait de nombreuses méthodes que vous n’abordez pas dans article. C’est normal il serait bien trop long.

    Cependant existe il une documentation qui les liste, car en général leur nom est suffisamment explicite pour comprendre leur utilité ?

    Merci d’avance et félicitations pour votre travail, j’ai tout appris sur Locoduino pour la mise en œuvre des arduinos sur mon réseau

    Répondre

Réagissez à « La bibliothèque SlowMotionServo »

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 « Bibliothèques »

Les derniers articles

Les articles les plus lus