ARDUINO
COMMANDER UN SERVOMOTEUR

Introduction

Principe de fonctionnement

Un servomoteur se commande en lui envoyant un train d'impulsions électriques, aux caractéristiques suivantes :

Câblage

Attention à respecter les couleurs pour le câblage. Une erreur... risque de détruire la carte Arduino!

Exemples de programmes

Fonctionnement autonome

Bien de l'utilisation de la bibliothèque Servo.h ne soit pas indispensable, elle simplifie l'écriture du code. L'exemple ci-dessous permet d'obtenir un aller et retour répétitif.

#include <Servo.h>    // on importe la bibliothèque Servo
Servo leServo;        // on crée l’objet leServo issu de la classe Servo

void setup() {
  leServo.attach(9);  // la commande du servomoteur est reliée à son connecteur
}

void loop() {
  leServo.write(20);  // axe du servomoteur mis à la position -50°
  delay(2000);        // on attend que la position angulaire soit atteinte
  leServo.write(170); // position angulaire à 50°
  delay(2000);        // nouvelle attente
}

Diminution de la vitesse angulaire

Il est possible de ralentir la vitesse angulaire de l'axe du servomoteur, à l'aide d'une boucle et de la fonction delay().

for (int i=0;i<180;i+=1) {
  leServo.write(i);
  delay(20);
}

Solution sans bibliothèque

L'utilisation de bibliothèques présente quelques inconvénients :

Il est donc toujours utile de savoir s'en passer.

int pinServo=9;

void placer(int angle) {   // angle allant de 0 à 180
  int impulsion=(int)(5.55*angle+1000);
  for (int t=0;t<80;t++) { // boucle laissant au servo le temps d'atteindre sa position
    digitalWrite(pinServo,HIGH);
    delayMicroseconds(impulsion);
    digitalWrite(pinServo,LOW);
    delay(20);
  }
}

void setup() {
  pinMode(pinServo, OUTPUT);
}

void loop() {
  placer(20);  // position angulaire à -50°
  delay(2000);
  placer(170); // position angulaire à 50°
  delay(2000);
}

Remarque

La fonction map() modifie la plage de variation d’une variable. On écrit ainsi plus simplement :

int impulsion=map(angle, 0, 180, 1000, 2000);

Complément

La méthode writeMicroseconds()

La méthode writeMicroseconds() définit directement la largeur des impulsions en μs. Elle permet donc de définir environ 1000 valeurs différentes (1000 à 2000) au lieu des 180 (0 à 180) avec la méthode write().

Réglage selon le servomoteur

Pour s'adapter aux différents servomoteurs, la méthode attach() prend deux paramètres optionnels, les largeurs minimale et maximale des impulsions en μs. Les valeurs par défaut sont respectivemeent 544 et 2400.

leServo.attach(9, 1000, 2000);

Servomoteur à rotation continue

Un servomoteur à rotation continue, ou servomoteur treuil, se commande de la même manière qu'un servomoteur classique, avec un train d'impulsions :

Exemple de code, avec la méthode writeMicroseconds() :

#include <Servo.h>
Servo leServo;

void setup() { 
  leServo.attach(9);
}

void loop() {
  leServo.writeMicroseconds(1700); // rotation dans un sens
  delay(2000);
  leServo.writeMicroseconds(1500); // stop
  delay(1000);
  leServo.writeMicroseconds(1300); // rotation dans l'autre sens
  delay(2000);
  leServo.writeMicroseconds(1500); // stop
  delay(1000);
}

Le programme ci-dessous permet d'obtenir l'arrêt, les rotations dans les sens horaire ou trigonométrique en envoyant les caractères a, h et t depuis le moniteur série :

#include <Servo.h>
Servo leServo;

void setup() {
  leServo.attach(9);
  Serial.begin(9600);
}

void loop() {
  if (Serial.available()) { // si des caractères sont envoyés
    char caractere = Serial.read();
    if (caractere == 'a') {
      leServo.writeMicroseconds(1500);
    }
    if (caractere == 'h') {
      leServo.writeMicroseconds(1300);
    }
    if (caractere == 't') {
      leServo.writeMicroseconds(1700);
    }
    Serial.print(caractere);
  }
}

La méthode detach()

Quelques difficultés surviennent parfois. Par exemple :

Ces difficultés peuvent se lever avec la méthode detach(). Par exemple :

#include <Servo.h>
Servo servo1, servo2;
int pos;

void setup() { }

void loop() { 
  servo1.attach(9);
  servo2.attach(10);
  for(pos=10; pos<=170; pos++) {
    servo1.write(pos);
    servo2.write(180-pos);
    delay(15);
  }
  for(pos=170; pos>=10; pos--) {
    servo1.write(pos);
    servo2.write(180-pos);
    delay(15);
  }
  servo1.detach();
  servo2.detach();
  delay(2500);
}