L’Arduino c’est à la fois une carte équipée d’un microcontrôleur et un environnement logiciel qui fournit à l’utilisateur des fonctions pour manipuler le matériel de manière plus simple que s’il devait mettre en œuvre le micro-contrôleur à partir de rien.
L’Arduino se programme en langage C et quelques fois en C++. Le C est un langage de programmation très populaire, notamment sur les systèmes embarqués, c’est à dire les systèmes informatiques intégrés dans un procédé dans le but de le piloter.
Un programme minimum pour Arduino
Le programme minimum pour l’Arduino est constitué de deux fonctions. Une fonction regroupe une série d’instructions et remplit un rôle. Voici ces deux fonctions, setup()
et loop()
. La fonction setup()
est exécutée 1 seule fois au début de programme. La fonction loop()
est exécutée répétitivement.
/*
* La fonction setup() est exécutée 1 fois
* au démarrage du programme
*/
void setup()
{
}
/*
* La fonction loop() est exécutée
* répétitivement
*/
void loop()
{
}
en langage C, une fonction retourne une valeur dont le type est indiqué juste à gauche du nom de la fonction. Il existe plusieurs types de données en C, les nombres entiers positifs et négatif (int
), ceux qui sont seulement positif (unsigned int
) etc. Nous verrons les types au fur et à mesure des besoins. Ici le type est void
, il s’agit d’un type spécial qui signifie « rien » ou « vide » et qui indique que les fonctions setup()
et loop()
ne retournent aucune valeur.
Une fonction peut prendre des arguments. Les arguments sont donnés entre les parenthèses juste après le nom de la fonction. Ici les deux fonctions n’ont aucun argument.
Les instructions qui constituent la fonction sont données entre les accolades. Ici les deux fonctions sont vides et par conséquent elle ne font strictement rien.
Au dessus des fonctions il y a du texte. Il s’agit de commentaires. Un commentaire commence par /*
et termine par */
. C’est une bonne habitude de commenter abondamment ses programmes. En effet, quelques semaines plus tard, il est difficile de se rappeler de ce que l’on a voulu faire dans un programme et les commentaires explicatifs sont bienvenus.
Mise en œuvre d’un servo-moteur
La mise en œuvre d’un servo-moteur avec l’Arduino est aisée. Il y a une bibliothèque pour ça !
Une bibliothèque est un jeu de fonctions optionnelles que l’on peut ou non employer dans le programme. Pour utiliser la bibliothèque permettant de piloter des servo-moteurs, il suffit d’inclure, au début du programme la directive suivante
#include <Servo.h>
Il faut ensuite pouvoir manipuler le servo-moteur. Il faut pour cela créer une variable de type Servo
. On dit aussi instancier une variable. Le type Servo
est un peu spécial, on entre là sur le terrain du C++. Servo
est une classe et créer une variable de ce type donne un objet. En plus de contenir une valeur comme une variable de type nombre entier, un objet possède des fonctions qui agissent sur lui. Dans le monde de l’objet on appelle communément ces fonctions des méthodes. Nous n’avons pas besoin d’en connaître plus pour utiliser un objet de type Servo
. Voici comment on crée une variable, que nous appelons monServo
de type Servo
.
Servo monServo;
Notez le « ; » qui termine la ligne, il est nécessaire et termine la directive. Notez aussi que le respect des majuscules et des minuscules est important car le langage C fait la différence entre s
et S
par exemple. Par conséquent appeler la variable monServo
n’est pas la même chose que de l’appeler monservo
.
La variable monServo
est instanciée, il faut maintenant l’accrocher à une des sorties numériques de l’Arduino. Nous allons choisir la sortie 2 car les sorties 0 et 1 ont un rôle particulier : elles permettent d’envoyer des messages qui seront affichés sur votre ordinateur hôte. Il s’agit d’une aide irremplaçable qui se révèle nécessaire pour comprendre ce qui se passe quand le programme ne fait pas ce que l’on attend.
Accrocher la variable à une sortie se fait avec la méthode attach
et, évidemment, dans la fonction setup()
car il est inutile de le faire plus d’une fois.
void setup()
{
monServo.attach(2); /* accroche monServo à la pin 2 de l'Arduino */
}
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. À savoir un mouvement lent. Le mouvement a bien lieu toutes les secondes mais il est très rapide, quasi instantané.
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.
Programme 2
#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 (plus d’informations sont données dans l’article « La carte de commande 6 servo-moteurs, le matériel », une autre mise en œuvre utilisant une conception matérielle personnelle). Cette impulsion a donc la forme suivante.
La valeur médiane est donc de 1500µs et les valeurs minimum et maximum pour les angles que nous avions fixés deviennent respectivement et approximativement 1250 et 1750. 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.
Programme 3
#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.
Voici qui conclut cette prise en main des servo-moteurs. Le prochain article portera sur l’ajout d’un bouton permettant de commander le mouvement du servo-moteur.
Messages
30 décembre 2015, 22:14, par Simon
Bonjour,
Avec le même servo j’ai besoin de lui faire faire un aller-retour mais une seule fois, pour actionner un bouton poussoir.
Est-ce possible ?
Dans l’attente je vous remercie et champion votre site !!
André
5 janvier 2016, 14:16, par Jean-Luc
Bonjour,
Merci :-)
Je ne comprends pas ce que vous voulez faire. Pourquoi ne pas remplacer le bouton par un dispositif (transistor, relai, que sais-je) commandé par l’Arduino ?
Quel est le rôle de ce bouton
18 janvier 2016, 23:11, par Simon
Bonjour
Meilleurs vœux.
Tout simplement pour lever un levier commandé par une LDR. Sans plus.
Comme l’arduino commande directement le servo-moteur, je pensais le faire avec. sans ajouter de composant supplémentaire.
Merci pour votre éventuelle réponse.
André
18 janvier 2016, 23:30
Bonsoir,
Meilleurs vœux également.
Pour faire un allez-retour lent et un seul, c’est assez simple. Le servo est à son angle initial avec une vitesse de 0. Sur un événement, pression d’un bouton par exemple, la vitesse est mise à 1. Le servo commence son mouvement, quand il atteint son angle maximum, la vitesse est mise à -1, il revient. Quand l’angle atteint l’angle minimum, la vitesse passe à 0 et le servo s’arrête. Le programme serait le suivant :
20 janvier 2016, 20:38, par Simon
Bonsoir,
Merci beaucoup pour votre aide qui m’a été précieuse et je peux continuer mon projet en le modifiant légèrement.
Merci encore c’est super sympa
André
30 janvier 2016, 14:32, par Serge
Bonjour,
J’avance pas à pas, en prenant le temps de la compréhension, je commence à maîtriser les bases mais je suis confronté à un problème que je ne peux résoudre.
J’alimente un seul servo avec la carte arduino
A la mise sous tension de l’Arduino, avec le bon sketch téléchargé, il y a un mouvement assez brutal du servo, notamment dans une position où il dépasse largement l’angle maxi.
Je peux contourner le problème en alimentant d’abord l’arduino puis en branchant le +5v sur le servo. Cela peut très bien se concevoir ainsi mais n’existe-t’il pas de méthode soft pour régler ce problème, ou comment le contournez-vous ?.
Merci pour tout ce travail et pour votre réponse
30 janvier 2016, 15:38
Bonjour Serge,
Mettez une résistance de 10kΩ entre le signal de commande du servo et le +5V
30 janvier 2016, 17:20, par Serge
Merci pour cette astuce... l’essayer c’est l’adopter...!!!
Bon week end