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 |

Positionnement servomoteur à l'aide d'une chaîne de caractère envoyée depuis Processing

Par X. HINAULT - Page créée le : 1/3/2011.

(cliquer sur l'image pour agrandir)

1.  Présentation

Un servomoteur est positionné à partir d'une chaine de caractères de la forme "servo(000)" où 000 est la valeur de l'angle sur lequel le servomoteur doit se positionner.

Ce programme utilise les fonctionnalités suivantes :

  • Utilise la connexion série vers le PC
  • Utilise un servomoteur

Ressources utiles associées à ce programme :

  • La librairie Serial - pour les communications séries entre la carte Arduino et l'ordinateur ou d'autres composants
  • La librairie Servo - pour contrôler les servomoteurs.

2.  Matériel Nécessaire

2.1  L'espace de développement Arduino

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

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

  • un servomoteur standard

3.  Instructions de montage

  • La connexion série vers le PC utilise les broches 0 et 1 (via le câble USB)
  • Connecter un servomoteur sur la broche 2
  • 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

4.  Le schéma théorique du montage

Le schéma théorique du montage (cliquer pour agrandir)

5.  Le circuit du montage

Le schéma du montage à réaliser (cliquer pour agrandir)

6.  Explication du programme

  • Le programme écoute le port série.
  • Lorsqu'une chaîne est reçue, elle est analysée et si elle est au format "servo(000)" suivi d'un saut de ligne, alors la valeur de l'angle reçue est utilisée pour positionner le servomoteur.
  • Des messages de retour sont envoyés sur le port Série, utilisables au besoin par le programme Processing côté PC.

7.  Mise en oeuvre du programme

7.1  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

7.2  Fonctionnement

  • Lancer le programme Processing : dans le champ texte, saisir texte de la forme "servo(090)" et clic sur bouton "Envoi".
  • Le servomoteur va se positionner à l'angle voulu.

(cliquer sur l'image pour agrandir)

8.  Le programme complet en langage Arduino

A copier/coller directement dans l'éditeur Arduino


// --- Programme Arduino ---
// Trame de code générée par le générateur de code Arduino
// du site www.mon-club-elec.fr

// Auteur du Programme : X. HINAULT - Tous droits réservés
// Programme écrit le : 1/3/2011.

// ------- Licence du code de ce programme -----
//  This program is free software: you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation, either version 3 of the License,
//  or any later version.
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//  You should have received a copy of the GNU General Public License
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.

// ////////////////////  PRESENTATION DU PROGRAMME ////////////////////

// -------- Que fait ce programme ? ---------
 /* Un servomoteur est positionné à partir d'une chaine de caractères de la forme "servo(000)"
 où 000 est la valeur de l'angle sur lequel le servomoteur doit se positionner.  */


// --- Fonctionnalités utilisées ---

// Utilise la connexion série vers le PC
// Utilise / fonctionne avec une interface Processing coté PC
// Utilise un servomoteur

// -------- Circuit à réaliser ---------

// La connexion série vers le PC utilise les broches 0 et 1 (via le câble USB)

// ******* ATTENTION : il est possible de connecter directement 2 ou 3 servomoteurs sur la carte Arduino
// Au-delà : utiliser une interface de puissance16
// Connecter un servomoteur sur la broche 2

// /////////////////////////////// 1. Entête déclarative ///////////////////////
// A ce niveau sont déclarées les librairies incluses, les constantes, les variables, les objets utiles...

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

// --- Inclusion des librairies ---

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

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

//--- Constantes utilisées avec le servomoteur
const int ANGLE_MIN=10; // angle position MIN en degrés
const int POS_MIN=600; // largeur impulsion pour position ANGLE_MIN degrés du servomoteur
                  // par exemple POS_MIN=600 pour ANGLE_MIN=10° avec un futaba S3003

const int ANGLE_MAX=170; // angle position MAX en degrés
int POS_MAX=2300; // largeur impulsion pour position ANGLE_MAX degrés du servomoteur
                  // POS_MAS=2300 pour ANGLE_MIN=170° pour futaba s3003

// --- Déclaration des constantes des broches E/S numériques ---

const int broche_servo=2; // Constante pour la broche 2

// --- Déclaration des constantes des broches analogiques ---


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

 int octetReception=0; // variable de stockage des valeurs reçues sur le port Série
 long nombreReception=0; // variable de stockage du nombre  reçu sur le port Série
 long nombreReception0=0; // variable de stockage du dernier nombre  reçu sur le port Série
 String chaineReception=""; // déclare un objet String vide pour reception chaine

  int valeur=0; // variable reception valeur port série
 int angleServo=0; // angle servomoteur

// --- Déclaration des objets utiles pour les fonctionnalités utilisées ---

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


// ////////////////////////// 2. 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 1 seule fois au démarrage du programme ---

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

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

//--- Initialisation Servomoteur
mon_servo.attach(broche_servo);  // attache l'objet servo à la broche de commande du servomoteur
//mon_servo.attach(broche_servo, POS_MIN, POS_MAX);  // attache l'objet servo à la broche de commande du servomoteur avec calibrage auto


// ------- Broches en sorties numériques -------  
 pinMode (broche_servo,OUTPUT); // Broche broche_servo configurée en sortie

// ------- Broches en entrées numériques -------  

// ------- Activation si besoin du rappel au + (pullup) des broches en entrées numériques -------  

// ------- Initialisation des variables utilisées -------  

Serial.println("Arduino OK"); // debug

//---- positionnement initial servomoteur
mon_servo.writeMicroseconds(angle(90)); // crée impulsion à partir valeur angle - plus précis que write()
delay(1000);


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

////////////////////////////////// 3. 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 ---

//---- code type réception valeur sur le port série ---


//---- code type réception chaine sur le port série ---
while (Serial.available()>0) { // tant qu'un octet en réception
        octetReception=Serial.read(); // Lit le 1er octet reçu et le met dans la variable

        if (octetReception==10) { // si Octet reçu est le saut de ligne
                Serial.println ("Chaine recue="+chaineReception); // affiche la chaine recue

                break; // sort de la boucle while
        }
        else { // si le caractère reçu n'est pas un saut de ligne
                chaineReception=chaineReception+char(octetReception); // ajoute le caratère au String
        }

} // fin tant que  octet réception

//----- une fois que le saut de ligne est reçu, on sort du While et on se positionne ici

// ---- analyse de la chaine recue sur le port Série ----
chaineReception=chaineReception.trim(); // enlève les espaces

if (chaineReception.substring(0,6)=="servo(") { // si reçoit l'instruction servo(000)
// nb substring : dernier caractere exclu

  Serial.print("Arduino va executer : ");

  Serial.print("servo("); // affiche

  //------------- extraction valeur angle servomoteur  ------ 3 chiffres

    //---- extraction 1er chiffre
    valeur=chaineReception.charAt(6); // extrait valeur ASCII du caractere
    valeur=valeur-48; // extrait valeur numérique du caractere
    angleServo=valeur;

     //---- extraction 2ème chiffre
    valeur=chaineReception.charAt(7); // extrait valeur ASCII du caractere
    valeur=valeur-48; // extrait valeur numérique du caractere
    angleServo=angleServo*10+valeur;

    //---- extraction 2ème chiffre
    valeur=chaineReception.charAt(8); // extrait valeur ASCII du caractere
    valeur=valeur-48; // extrait valeur numérique du caractere
    angleServo=angleServo*10+valeur;

  Serial.print(angleServo); // affiche

  if (chaineReception.substring(9,10)==")") { // si fermeture parenthèse = instruction valide

    Serial.println(")"); // affiche
    Serial.println("Instruction valide !"); // affiche

    //----- positionnement du servomoteur ----

    //angleServo=constrain(angleServo,0,180); // oblige valeur angle Servo
    mon_servo.writeMicroseconds(angle(angleServo)); // crée impulsion à partir valeur angle - plus précis que write()
    delay(1000); // laisse temps positionnement

    Serial.println("Servomoteur mis en position"); // affiche



  } // fin si fermeture parenthèse  



} // --- fin si reçoit instruction servo(000)

//------------- fin analyse chaine ---------------

chaineReception=""; //RAZ le String de réception




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


// ////////////////////////// FONCTIONS DE GESTION DES INTERRUPTIONS ////////////////////


// ////////////////////////// AUTRES FONCTIONS DU PROGRAMME ////////////////////



//------------- fonction calibrage impulsion servomoteur à partir valeur angle en degrés

int angle(int valeur_angle) {

        int impuls=0;
        impuls=map(valeur_angle,ANGLE_MIN,ANGLE_MAX,POS_MIN, POS_MAX);
        return impuls;  

} // fin fonction impulsion servomoteur

// ////////////////////////// Fin du programme ////////////////////
 

9.  Le programme Processing : Saisir une chaîne dans un champ texte et l'envoyer vers le port Série

9.1  Description

  • Ce programme permet de saisir une chaîne dans un champ texte dans une interface Processing et de l'envoyer vers le port Série à l'aide d'un bouton graphique.

9.2  Ressources utiles

  • Utilise la librairie graphique GUI controlP5

9.3  Le programme complet en langage Processing

A copier/coller directement dans l'éditeur Processing


// Programme processing
// généré avec le générateur de code Processing
// www.mon-club-elec.fr
// par X. HINAULT - Février 2011 - tous droits réservés

/////////////// Description du programme ////////////
// Utilise un/des objets String (chaîne de caractère)
// Utilise le port Serie
// Utilise la librairie GUI controlP5
// Utilise un/des bouton(s) simple(s) (Button)
// Utilise un/des champ(s) texte (Textfield)
// Ajoute un bouton et un champ pour chemin fichier

/*
Envoie vers Arduino une chaîne saisie dans un champ texte.
Reçoit la chaine renvoyée par Arduino et l'affiche dans la console.
*/


// XXXXXXXXXXXXXXXXXXXXXX ENTETE DECLARATIVE XXXXXXXXXXXXXXXXXXXXXX

// inclusion des librairies utilisées

import processing.serial.*; // importe la librairie série processing

import controlP5.*; // importe la librairie GUI controlP5
// cette librairie doit être présente dans le répertoire /libraries du répertoire Processing
// voir ici : http://www.sojamo.de/libraries/controlP5/

// déclaration objets

String str1 = "machaine"; // déclare un objet String (chaine de caractère)
String chaineEnvoi = ""; // déclare un objet String (chaine de caractère)

// --- port Série ---
Serial  myPort; // Création objet désignant le port série

ControlP5 controlP5; // déclare un objet principal de la librairie GUI controlP5


Button envoiButton; // déclare objet Button  

Textfield chaineText; // déclare des objets Textfield

// déclaration variables globales

//------ déclaration des variables de couleur utiles ----
int jaune=color(255,255,0);
int vert=color(0,255,0);
int rouge=color(255,0,0);
int bleu=color(0,0,255);
int noir=color(0,0,0);
int blanc=color(255,255,255);
int bleuclair=color(0,255,255);
int violet=color(255,0,255);


// XXXXXXXXXXXXXXXXXXXXXX  Fonction SETUP XXXXXXXXXXXXXXXXXXXXXX

void setup(){ // fonction d'initialisation exécutée 1 fois au démarrage

        // ---- initialisation paramètres graphiques utilisés
        colorMode(RGB, 255,255,255); // fixe format couleur R G B pour fill, stroke, etc...
        fill(0,0,255); // couleur remplissage RGB
        stroke (0,0,0); // couleur pourtour RGB
        rectMode(CORNER); // origine rectangle : CORNER = coin sup gauche | CENTER : centre
        imageMode(CORNER); // origine image : CORNER = coin sup gauche | CENTER : centre
        //strokeWeight(0); // largeur pourtour
        frameRate(30);// Images par seconde

        // --- initialisation fenêtre de base ---
        size(400, 130); // ouvre une fenêtre xpixels  x ypixels
        background(0,0,0); // couleur fond fenetre

// --- initialisation des objets et fonctionnalités utilisées ---

        //------------- initialisation port série ----
        println(Serial.list()); // affiche dans la console la liste des ports séries
        // Vérifier que le numéro du port série utilisé est le meme que celui utilisé avec  Serial.list()[index]
        myPort = new Serial(this, Serial.list()[0], 115200); // Initialise une nouvelle instance du port Série
        //myPort = new Serial(this, "/dev/ttyUSB0", 115200); // Initialise une nouvelle instance du port Série
        myPort.bufferUntil('\n'); // attendre arrivée d'un saut de ligne pour générer évènement série

        //======== Initialisation Objets GUI ControlP5 =========

        controlP5 = new ControlP5(this); // initialise l'objet principal de la librairie GUI controlP5

        // typeObjet nomObjet=controlP5.addObjet(paramètres); // pour info : déclaration / initialisation possible en 1 ligne
        // Textfield field = controlP5.addTextfield("myWindowTextfield",70,130,100,20); // exemple

        //======== Initialisation Objets Button =========

        //---- le bouton envoi chaine
        envoiButton=controlP5.addButton("envoiButton",0,width-60,height-40,50,24); // initialise et ajoute un Button au ControlP5
        envoiButton.setLabelVisible(true); // affichage des labels
        envoiButton.setLabel("ENVOI"); // fixe label du bouton
        envoiButton.setColorActive(color(255,0,0)); // fixe la couleur active
        envoiButton.setColorForeground(color(0,255,255)); // fixe couleur avant

        //======== Initialisation Objets Textfield =========

        //---- champ texte saisie chaine
        chaineText=controlP5.addTextfield("cheminText",10,height-40,300,20); // initialise et ajoute un Textfield au ControlP5
        chaineText.setAutoClear(false); // autoeffacement après return
        chaineText.setValue(chaineEnvoi); // initialise Texte du champ
        chaineText.setLabelVisible(true); // affichage des labels
        chaineText.setLabel("CHEMIN"); // fixe label
        chaineText.setColorActive(color(255,0,0)); // fixe la couleur active
        chaineText.setColorForeground(color(0,255,255)); // fixe couleur avant




} // fin fonction Setup

// XXXXXXXXXXXXXXXXXXXXXX Fonction Draw XXXXXXXXXXXXXXXXXXXX

void  draw() { // fonction exécutée en boucle



} // fin de la fonction draw()

// XXXXXXXXXXXXXXXXXXXXXX Autres Fonctions XXXXXXXXXXXXXXXXXXXXXX

        //------------- Fonction de gestion des évènements série ----
         void serialEvent (Serial myPort) { // fonction appelée lors de la survenue d'un évènement série

        // ******** Gestion de la valeur reçue sur le port série : **********

        String inString = myPort.readStringUntil('\n'); // chaine stockant la chaîne reçue sur le port Série
        // saut de ligne en marque de fin

        if (inString != null) { // si la chaine recue n'est pas vide


                print (inString); // affichage brut de la chaine recue


        } // fin condition chaine recue pas vide


} // fin de la fonction de gestion des évènements Série

// Gestion des évènements des objets GUI controlP5 ----

//------ fonction gestion globale des évènements GUI controlP5
public void controlEvent(ControlEvent theEvent) {
        //println(theEvent.controller().name());// affiche le nom de l'évènement
}

        //---- evenement bouton envoi chaine

void envoiButton(int theValue) { // fonction évènement Button de meme nom - reçoit la valeur

        println("Evènement envoiButton");

        myPort.write(chaineText.getText()+"\n"); // envoie la chaine suivi saut ligne sur le port Série
        print("Envoi de la chaine :");
        print(chaineText.getText()+"\n");
        chaineText.setValue(""); // vide le champ texte


} // fin evènement bouton envoi

// ------ gestion évènement Textfield ------

        //---- evenement champ texte chemin fichier

public void chaineText(String theText) { // fonction évènement Textfield de meme nom - déclenché par return - reçoit la chaine

        //println("Evènement CheminText avec valeur = "+theText);

        chaineEnvoi=theText; // mémorise le contenu du champ

        //println("Le chemin est :"+chaineEnvoi);

} // fin evènement champ texte chemin fichier


//XXXXXXXXXXXXXXXXXX Fin du programme XXXXXXXXXXXXXXXXX