View  Edit  Attributes  History  Attach  Print  Search

ACCUEIL | ARDUINO > S'INSTALLER > DEBUTER > APPROFONDIR | PROCESSING | MECATRONIQUE | MATERIEL | OUTILS | TESTS | Plus...|
Python > Shell > ATELIERS Python + Qt > PyQt apps > PyQt+Arduino | Mes Robots | RepRap | Mes lib'Arduino | Mes shields Arduino | Mes distros | Les Mini-PC |
ATELIERS ARDUINO| VIDEOS | COMPRENDRE | REFERENCES | CODER | TECHNIQUE | GNU/LINUX | LIENS | Rien à voir |

Contrôler la position d'un servomoteur depuis la fenêtre Terminal du logiciel Arduino

ARDUINO - EXPERT - SERIE - SERVO
Par X. HINAULT - Créé le 03/02/2010

Présentation

Ce programme bien pratique permet de saisir directement dans la fenêtre Terminal de l'IDE Arduino une valeur précise en microsecondes comprise entre 400 et 2600 pour déclencher le positionnement du servomoteur à la position correspondante. Bien pratique pour pouvoir tester notamment la largeur d'impulsion du servomoteur à 0°, à 90° et à 180°, largeur d'impulsion qui peut-être variable d'un servomoteur à l'autre...

L'utilisation des servomoteurs avec une carte Arduino est assez simple, basée sur la librairie dédiée aux servomoteurs : http://arduino.cc/en/Reference/Servo

Ce programme utilise les fonctionnalités suivantes :

  • un ou plusieurs servomoteurs

Information Technique

Qu'est-ce qu'un servomoteur ?

Un servomoteur est un moteur qui est utilisé pour maintenir un axe de rotation dans certaines positions bien précises. C'est un moteur électrique associé à une électronique de commande pilotée par une impulsion de durée variable qui va déterminer la position fixe de l'axe de sortie.

Sur un servomoteur classique, l'axe peut prendre une position comprise entre 0° et 180° selon la durée de l'impulsion reçue (1000µs pour 0°, 1500µs pour 90° et 2000µs pour 180°, ces valeurs pouvant varier d'un servomoteur à l'autre.

Dans le cas précis d'un Futaba S3003, on retrouve empiriquement 550µs pour la position extrême 0° et 2300µs pour la position 180°, le 90° étant aux alentours de 1400µs.

Brochage d'un servomoteur

Typiquement, un servomoteur présente 3 broches :

  • un fil noir à connecter à la masse
  • un fil rouge à connecter au +
  • un fil blanc à connecter à la broche de commande par impulsion.

On peut utiliser un servomoteur directement en +5V et avec une entrée numérique, ce que nous ferons ici sans aucun problème.

Ceci étant, une adaptation en tension et en intensité est parfois nécessaire, voire même un découplage des masses par optocoupleur pour éviter tout problème de reset intempestif de la carte numérique de commande. Voir rubrique MATERIEL > Interfaces » ou « COMPRENDRE » pour plus de détails sur ces sujets.

Matériel Nécessaire

L'espace de développement Arduino

  • ... pour éditer, compiler le programme et programmer la carte Arduino.

Le matériel suivant pour réaliser le montage associé

  • une plaque d'essai pour montage sans soudures,
  • des straps,
  • un servomoteur standard

Instructions de montage

  • Connecter sur la broche 2 (configurée en sortie) la broche de commande d'un servomoteur
  • Connecter les servomoteurs sur les broches de commandes utilisées
  • Dans le cas d'une carte Arduino :
    • l'intensité maximale disponible sur une broche est de 40mA
    • l'intensité maximale cumulée pour l'ensemble des broches est 200mA
    • l'instensité maximale que peut fournir l'alimentation 5V de la carte est 500mA.
  • Par conséquent, avec une carte Arduino :
    • En ce qui concerne la ligne de commande du servomoteur par la carte Arduino :
      • on pourra commander directement autant de servomoteur que l'on veut (broche de commande) avec une carte Arduino, le nombre maximal étant 200mA / I commande, soit 100 environ dans le cas du Futaba S3003, ce qui est largement supérieur au nombre de broches de la carte.
    • Il n'y aura par ailleurs pas besoin d'amplification (type ULN 2803) sur la ligne de commande du servomoteur même si l'on utilise un grand nombre de servomoteurs.
    • En ce qui concerne l'alimentation principale des servomoteurs par une carte Arduino
      • on ne peut alimenter que 3 à 4 servomoteurs simultanément par l'alimentation 5V de la carte Arduino, le nombre maximal étant 500mA / I fonctionnement = 500 / 120 = 4 servomoteurs dans le cas du Futaba S3003.
      • Une alimentation externe sera indispensable dès que l'on dépassera ce nombre pour ne pas risquer de "griller" la carte Arduino.

Pour plus de détails, voir : Principes d'utilisation des alimentations avec une carte Arduino et des servomoteurs

Le schéma théorique du montage


Le schéma théorique du montage

Le circuit du montage


Le schéma du montage à réaliser

Explication du programme

Structure globale du programme

Ce programme simple comprend :

  • une entête déclarative
  • une partie « configuration » qui ne sera exécutée qu'une fois (fonction setup( ) )
  • une partie constituée d'une boucle sans fin que le programme répètera à l'infini ( fonction loop( ) ) : c'est le coeur du programme.

Déroulement du programme

Le programme se déroule de la façon suivante :

  • Après avoir pris en compte les instructions de la partie déclarative,
  • puis après avoir exécuté la partie configuration ( fonction setup( ) ),
  • le programme bouclera sans fin ( fonction loop ( ) ), exécutant de façon répétée le code compris dans la boucle sans fin.

Le déroulement du programme

Au niveau de la partie déclarative :

Inclusion des librairies utilisées

  • On inclut les librairies des fonctionnalités utilisées :
    • Inclusion de la librairie pour les servomoteurs :
#include <Servo.h> // librairie pour servomoteur

Déclaration de constantes utiles

  • On déclare les constantes utiles dans le programme :
    • Déclaration des constantes utiles pour les servomoteurs : les constantes de positions extrêmes correspondant à la largeur d'impulsion en microsecondes de ces positions.
const int POS_MIN=550; // largeur impulsion pour position 0° servomoteur
                       // POS_MIN=550 pour futaba S3003
const int POS_MAX=2330; // largeur impulsion pour position 180° servomoteur
                                                 // POS_MAS=2330 pour futaba s3003

Déclaration des constantes de broches

  • Déclaration des constantes pour les broches utilisées dans le programme : on appelle SERVO la broche utilisée pour commander le servomoteur.
const int SERVO=2; //declaration constante de broche

Déclaration des variables globales

  • Déclaration des variables globales du programmes :
    • On déclare 2 variables utiles pour la gestion du caractère saisi sur le PC et reçu par la connexion série.
int ReceptionOctet=0; // variable de stockage des octets reçus par port série
int ReceptionNombre=0; // variable de calcul du nombre reçu par port série
  • On déclare 1 variable utilisée pour la largeur d'impulsion envoyée au servomoteur :
int impulsion=1500; // variable pour impulsion - valeur médiane initiale

Déclarations des objets utiles pour les fonctionnalités utilisées

  • Déclaration des objets utiles pour les fonctionnalités utilisées :
    • Déclaration d'un objet servomoteur appelé mon_servo
Servo mon_servo;  // crée un objet servo pour contrôler le servomoteur

Au niveau de la fonction d'initialisation setup( ) :

Initialisation des fonctionnalités utilisées :

  • On initialise les différentes fonctionnalités utilisées :
    • Initialisation du servomoteur en utilisant les constantes de positions extrêmes définies précédemment :
mon_servo.attach(broche_servo, POS_MIN, POS_MAX);  // attache l'objet servo à la broche de commande du servomoteur

configuration des broches utilisées :

  • Configuration des broches en sortie : on met en sortie la broche utilisée pour la commande du servomoteur.
pinMode(SERVO, OUTPUT); //met la broche en sortie

Au niveau de la boucle principale, la fonction loop ( ) :

  • On commence par gérer les caractères reçus sur la connexion série en provenance du PC à l'aide notamment de l'instruction .
  • L'utilisation itérative de l'instruction à l'intérieur d'un boucle permet de calculer le nombre saisi côté PC.
  • On renvoie ensuite au PC la valeur reçue pour vérification de la bonne prise en compte de la valeur saisie, à l'aide de l'instruction .

//--- lecture d'un nombre reçu par le Terminal et positionnement du servomoteur ---
if (Serial.available()>0) { // si caractère dans la file d'attente

  //---- lecture du nombre reçu
  while (Serial.available()>0) { // tant que buffer pas vide pour lire d'une traite tous les caractères reçus

    ReceptionOctet= Serial.read(); // renvoie le 1er octet présent dans la file attente série (-1 si aucun)
    ReceptionOctet=ReceptionOctet-48; // transfo valeur ASCII en valeur décimale

    if ((ReceptionOctet>=0)&&(ReceptionOctet<=9))     ReceptionNombre = (ReceptionNombre*10)+ReceptionOctet;
    // si valeur reçue correspond à un chiffre on calcule nombre

    delay(1); // pause pour laisser le temps au Serial.available de recevoir les caractères

  } // fin while

   Serial.print ("Nombre recu= ");
   Serial.println(ReceptionNombre); // affiche valeur numerique entière ou à virgule au format décimal
 
  • Ensuite, on envoie vers le servomoteur une impulsion correspondant à la valeur reçue depuis le PC, notamment grâce à l'instruction Servo.writeMicroseconds :

   //----- positionnement du servomoteur en fonction de la largeur d'impulsion demandée
   impulsion=ReceptionNombre;

    if (impulsion>2600)impulsion=2600; // pour éviter valeur supérieure à 2600 = position maxi possible servomoteur
    if (impulsion<300)impulsion=300; // pour éviter valeur inférieure à 300 = position maxi possible servomoteur

    mon_servo.writeMicroseconds(impulsion); // génère l'impulsion de la durée voulue en µs pour le servomoteur

    Serial.print ("Impulsion servomoteur = ");
    Serial.print(impulsion); // affiche valeur numerique entière
    Serial.println (" microsecondes ");

    delay (1000); //entre chaque changement de position

    ReceptionNombre=0; // réinitialisation de la variable de calcul du nombre reçu

} // end if
 
  • Le programme recommence en boucle les instructions de la fonction loop( ).

Se reporter aux commentaires présents dans le programme pour plus de détails.

Mise en oeuvre du programme

Préparation du montage et programmation de la carte Arduino :

  • Commencer par réaliser le montage indiqué sur plaque d'expérimentation
  • Ensuite, programmer la carte Arduino avec ce programme (en bas de page) selon la procédure habituelle

Préparation du Terminal côté PC dans le logiciel Arduino

  • Côté PC, il faut ouvrir la fenêtre terminal de l'IDE Arduino : pour ce faire, un simple clic sur le bouton « Sérial Monitor ».
  • La fenêtre « Terminal » s'ouvre alors :
  • Il faut alors régler le débit de communication sur la même valeur que celle utilisée par le programme avec lequel nous allons programmer la carte Arduino :

Fonctionnement

  • On commence par saisir au clavier du PC la valeur souhaitée pour la largeur d'impulsion en microsecondes (typiquement entre 500 et 2500) et « clic » sur send pour envoyer la valeur à la carte Arduino. Le servomoteur va immédiatement se positionner à la position ainsi demandée.
  • On pourra ainsi saisir plusieurs valeurs à volonté. La fenêtre affichera à chaque fois le nombre reçu par la connexion série et l'impulsion correspondante générée. Tout l'intérêt de ce programme est de pouvoir tester très simplement un servomoteur notamment au niveau des positions extrêmes (0° et 180°).

Le programme complet en langage Arduino :

A copier/coller directement dans l'éditeur Arduino


// --- Programme Arduino ---
// par X. HINAULT - 01/2010

// --- Que fait ce programme ? ---
/* Test de la position d'un servomoteur par saisie directe de la largeur d'impulsion dans le Terminal côté PC*/

// --- Fonctionnalités utilisées ---
// Utilise la connexion série vers le PC
// Utilise un servomoteur

// --- Circuit à réaliser ---
// Connexion série entre la carte Arduino et le PC (utilise les broches 0 et 1)  
// Connecter Broche de commande d'un Servomoteur sur la broche 2 (configurée en sortie)

//**************** Entête déclarative *******
// A ce niveau sont déclarées les librairies, les constantes, les variables...

// --- Inclusion des librairies utilisées ---

#include <Servo.h> // librairie pour servomoteur

// --- Déclaration des constantes ---

// --- constantes des broches ---

const int SERVO=2; //declaration constante de broche


// --- Déclaration des variables globales ---

int ReceptionOctet=0; // variable de stockage des octets reçus par port série
int ReceptionNombre=0; // variable de calcul du nombre reçu par port série
int impulsion=1500; // variable pour impulsion - valeur médiane initiale

// --- Initialisation des fonctionnalités utilisées ---

Servo mon_servo;  // crée un objet servo pour contrôler le servomoteur

//**************** FONCTION SETUP = Code d'initialisation *****
// La fonction setup() est exécutée en premier et 1 seule fois, au démarrage du programme

void setup()   { // debut de la fonction setup()

// --- ici instructions à exécuter au démarrage ---

mon_servo.attach(SERVO);  // attache l'objet servo à la broche de commande du servomoteur

Serial.begin(115200); // initialise connexion série à 115200 bauds
// IMPORTANT : régler le terminal côté PC avec la même valeur de transmission

pinMode(SERVO, OUTPUT); //met la broche en sortie



} // fin de la fonction setup()
// ********************************************************************************

//*************** FONCTION LOOP = Boucle sans fin = coeur du programme *************
// la fonction loop() s'exécute sans fin en boucle aussi longtemps que l'Arduino est sous tension

void loop(){ // debut de la fonction loop()

// --- ici instructions à exécuter par le programme principal ---


//--- lecture d'un nombre reçu par le Terminal et positionnement du servomoteur ---
if (Serial.available()>0) { // si caractère dans la file d'attente

  //---- lecture du nombre reçu
  while (Serial.available()>0) { // tant que buffer pas vide pour lire d'une traite tous les caractères reçus

    ReceptionOctet= Serial.read(); // renvoie le 1er octet présent dans la file attente série (-1 si aucun)
    ReceptionOctet=ReceptionOctet-48; // transfo valeur ASCII en valeur décimale

    if ((ReceptionOctet>=0)&&(ReceptionOctet<=9))     ReceptionNombre = (ReceptionNombre*10)+ReceptionOctet;
    // si valeur reçue correspond à un chiffre on calcule nombre

    delay(1); // pause pour laisser le temps au Serial.available de recevoir les caractères

  } // fin while

   Serial.print ("Nombre recu= ");
   Serial.println(ReceptionNombre); // affiche valeur numerique entière ou à virgule au format décimal


   //----- positionnement du servomoteur en fonction de la largeur d'impulsion demandée
   impulsion=ReceptionNombre;

    if (impulsion>2600)impulsion=2600; // pour éviter valeur supérieure à 2600 = position maxi possible servomoteur
    if (impulsion<300)impulsion=300; // pour éviter valeur inférieure à 300 = position maxi possible servomoteur

    mon_servo.writeMicroseconds(impulsion); // génère l'impulsion de la durée voulue en µs pour le servomoteur

    Serial.print ("Impulsion servomoteur = ");
    Serial.print(impulsion); // affiche valeur numerique entière
    Serial.println (" microsecondes ");

    delay (1000); //entre chaque changement de position

    ReceptionNombre=0; // réinitialisation de la variable de calcul du nombre reçu

} // end if


} // fin de la fonction loop() - le programme recommence au début de la fonction loop sans fin
// ********************************************************************************

// --- Fin programme ---