ARDUINO
COMMANDER UN SERVOMOTEUR

Introduction

Principe de fonctionnement

Pour commander un servomoteur, il faut lui envoyer 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 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 microsecondes. Elle permet donc de définir environ 1000 valeurs différentes (1000 à 2000) au lieu des 180 (0 à 180) avec la méthode write().

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);
}