XX. Projet 12 : utiliser un servomoteur▲
Les servomoteurs, souvent abrégés en « servo » tout court par leurs utilisateurs, sont des moteurs d'un type particulier, très appréciés pour faire tourner quelque chose jusqu'à une position bien précise et capable de maintenir cette position jusqu'à l'arrivée d'une nouvelle instruction. Ils sont très utilisés dans le modélisme (direction des voitures télécommandées, commande des gouvernes de dérive et de profondeur sur les avions, etc.), mais ont aussi leur place dans la robotique et l'industrie par exemple dans des vannes pour réguler des flux de liquides.
Dans ce chapitre, nous allons apprendre à utiliser le plus répandu des servomoteurs en modélisme et dans la petite électronique, il s'agit des modèles dits 9 g, pour 9 grammes. Extérieurement, il se présente sous la forme d'un petit rectangle, avec deux petits rebords sur les côtés pour le fixer solidement et un axe décentré sur lequel on peut fixer des bras interchangeables pour assurer la liaison mécanique avec la pièce qui doit bouger. Même s'il existe de servomoteurs à rotation continue, l'immense majorité des modèles sont capables de bouger leur bras sur 180° seulement.
Vu de l'intérieur, un servomoteur est un peu plus complexe qu'il n'en a l'air :
Un petit moteur à courant continu est relié à un potentiomètre (résistance variable) par l'intermédiaire d'un circuit électronique ce qui permet de contrôler finement le moteur en fonction de la position du potentiomètre. Sur l'axe de sortie du moteur, une série d'engrenages permet d'augmenter son couple (sa force utile) en réduisant sa vitesse de rotation.
Quand le moteur tourne, les engrenages s'animent, le bras bouge et entraîne dans son mouvement le potentiomètre. Si le mouvement s'arrête, le circuit électronique ajuste en continu la vitesse du moteur pour que le potentiomètre et donc par extension le bras du moteur reste toujours au même endroit. C'est ce qui permet par exemple à un bras d'un robot de ne pas retomber sous l'effet de son propre poids lorsque le mouvement s'arrête !
Utilisation d'un servomoteur avec l'Arduino
Pour commander un servomoteur, il faut lui envoyer un train d'impulsions dont la période (intervalle de temps entre chaque impulsion) est toujours de 20 ms (millisecondes). Ce qui va varier et qui finalement déterminera la position du bras n'est pas la période, mais bien la durée de l'impulsion :
- pour une impulsion de 1 ms, le servomoteur se met en position 0° ;
- pour une impulsion de 1,5 ms, le servomoteur se met en positon 90° ;
- pour une impulsion de 2 ms, le servomoteur se met en position 180°.
Ce schéma rappelle le PWM que l'on a utilisé pour faire varier l'intensité d'une LED par exemple, le principe en est effectivement très semblable, avec un train d'ondes rectangulaires puisque les données transmises sont digitales (HIGH ou LOW) sans valeurs intermédiaires.
La connexion d'un servomoteur ne pose pas de difficulté. Le fil rouge se connecte à l'alimentation (5 V), le fil noir se connecte au ground (GND) et le fil jaune (attention parfois blanc ou orange ou… suivant le matériel dont dispose le fabricant chinois ?) à n'importe quelle sortie numérique de l'Arduino (pin 0 à 13).
XX-A. Code 23 : faire bouger le bras d’un servomoteur dans les deux sens▲
L'objectif des trois codes ci-dessous est de se familiariser avec l'utilisation des servomoteurs.
Pour les trois codes, nous aurons besoin de la bibliothèque Servo qui fait partie d'office du logiciel Arduino, mais qui n'est pas installée par défaut.
Menu : Croquis → Inclure une bibliothèque → Servo.
Attention, pour que la bibliothèque nouvellement installée soit utilisable, il faut quitter puis relancer Arduino.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
/*
Code 23 - Edurobot.ch, destiné à l'Arduino
Objectif : Faire bouger le bras d'un servomoteur dans un sens puis dans l'autre, indéfiniment
*/
//*****EN-TÊTE DECLARATIF*****
#include
<Servo.h>
// on inclut la bibliothèque pour piloter un servomoteur
Servo monServo; // on crée l'objet monServo
void
setup()
{
monServo.attach(9
); // on définit le Pin utilisé par le servomoteur
}
void
loop()
{
for
(int
position =
0
; position <=
180
; position ++
){
// on crée une variable position qui prend des valeurs entre 0 à 180 degrés
monServo.write(position); // le bras du servomoteur prend la position de la variable position
delay
(15
); // on attend 15 millisecondes
}
for
(int
position =
180
; position >=
0
; position --
){
// cette fois la variable position passe de 180 à 0°
monServo.write(position); // le bras du servomoteur prend la position de la variable position
delay
(15
); // le bras du servomoteur prend la position de la variable position
}
}
Une fois votre code fonctionnel, n'hésitez pas à tester des délais d'attente différents, de demander des parcours de 90° seulement ou d'autres valeurs, de varier le pas des incréments utilisés, par exemple de 5° en 5°, etc. Et observez à chaque fois le nouveau résultat.
Nous avons dit en parlant des servomoteurs qu'une fois une position atteinte, le moteur, grâce aux informations maintenant le bras dans la position demandée jusqu'à ce qu'un nouvel ordre lui parvienne. Cette fonction de maintien est primordiale aussi bien en modélisme qu'en robotique. Si un bras robotisé saisit quelque chose par exemple, il ne faut pas qu'il retombe juste sous l'effet du poids de la pièce saisie et de son bras. Pour cela le servomoteur doit donc continuer d'ajuster la position à maintenir. La petite variation de code ci-dessous nous prouvera d'une part que la position demandée est maintenue même quand on demande à l'Arduino d'effectuer une autre tâche (ici, allumer la diode 13) et vous pouvez aussi essayer de tourner le servo à la main (sans forcer !) pour sentir la résistance à la rotation qu'exerce le servo qui tente de maintenir sa position.
XX-B. Code 24 : servomoteur et gestion des tâches▲
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
/*
Code 24 - Edurobot.ch, destiné à l'Arduino
Objectif : prouver que la bibliothèque Servo permet au servomoteur d'agir et de se maintenir
en position même lorsque l'Arduino effectue une autre tâche.
*/
//*****EN-TÊTE DECLARATIF*****
#include
<Servo.h>
// on inclut la bibliothèque pour piloter un servomoteur
Servo monServo; // on crée l'objet monServo
void
setup()
{
monServo.attach(9
); // on définit le Pin utilisé par le servomoteur
pinMode
(13
,OUTPUT
); // la Pin13 est mise en mode OUTPUT
}
void
loop()
{
monServo.write(0
); // on dit à l'objet de mettre le servo à 0°
diode13(); // appel de la fonction diode13 qui est définie plus bas
monServo.write(180
); // on dit à l'objet de mettre le servo à 180°
diode13(); // appel de la fonction diode13
}
void
diode13() //on va faire clignoter 15 fois la diode 13
{
for
(int
t=
0
;t<
15
;t++
){
digitalWrite
(13
,HIGH
);
delay
(100
);
digitalWrite
(13
,LOW
);
delay
(100
);
}
}
À vous de faire aussi varier les angles demandés, le nombre de clignotements de la LED 13, le temps d'attente…
Et pour en terminer avec le pilotage des servomoteurs, voici un code qui ne manque pas de provoquer son petit effet, vous allez ajouter un potentiomètre à votre montage et c'est la position du potentiomètre que vous tournerez qui servira à positionner le bras du servomoteur.
Pour vous aider, voici le schéma du montage :
XX-C. Code 25 : commander un servomoteur avec un potentiomètre▲
Ce code tout simple permet, à l'aide d'un mappage, de lier les 1024 paliers d'un potentiomètre aux 180° de rotation d'un servo.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
/*
Code 25 - Edurobot.ch, destiné à l'Arduino
Objectif : commander un servomoteur avec un potentiomètre
*/
//*****EN-TÊTE DECLARATIF*****
#include
<Servo.h>
// on inclut la bibliothèque pour piloter un servomoteur
Servo monServo; // on crée l'objet monServo
int
pinmonServo =
9
; // on définit la Pin9 liée à la commande du servomoteur
int
pinPotar =
A0; // on définit la Pin analogique A0 pour la lecture du potentiomètre
void
setup()
{
monServo.attach(pinmonServo); // on lie l'objet monServo au pin de commande
}
void
loop()
{
int
valeurPotar=
analogRead
(pinPotar); // on lit la valeur du potentiomètre
int
angle=
map
(valeurPotar, 0
,1023
,0
,180
); // on transforme la valeur analogique lue en valeur d'angle entre 0 et 180°
monServo.write(angle); // on met le bras du servomoteur à la position angle
}