View  Edit  Attributes  History  Attach  Print  Search

EeePC-Bot : Contrôle des moteurs depuis le Terminal Série et/ou une interface Processing

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

(cliquer sur l'image pour agrandir)

1.  Présentation

  • Contrôle des moteurs et des différents mouvements (avant, arriere, stop, tourne droite, etc...) à partir d'une chaîne de caractères reçue sur le port série en provenance d'une interface Processing ou du Terminal série du logiciel Arduino.
  • Par exemple, pour que les moteurs aillent en avant, on fera enAvant(vitesse) où la vitesse sera une valeur comprise entre 0 (arrêt) et 255 (maximum). La vitesse sera exprimée sur 3 chiffres : la valeur 0 sera appliquée sous la forme enAvant(000).
  • Les fonctions disponibles sont :
    • arret()
    • tourneDroite (int vitesse)
    • tourneGauche (int vitesse)
    • enArriere (int vitesse)
    • enAvant (int vitesse)

avec :

  • vitesse de 0 à 255 (impulsion PWM)
  • sens = 0 : en arriere et sens=1 : en avant

Ce programme utilise les fonctionnalités suivantes :

  • Utilise la connexion série vers le PC

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

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é

  • des straps,

3.  Instructions de montage

  • La connexion série vers le PC utilise les broches 0 et 1 (via le câble USB)
  • Connexion de l'interface DFRobot 2A Moteur CC sur les broches de la carte Arduino :
    • Connecter broche de sens du moteur 1 sur la broche 4
    • Connecter broche de vitesse du moteur 1 sur la broche 5
    • Connecter broche de sens du moteur 2 sur la broche 7
    • Connecter broche de vitesse du moteur 2 sur la broche 6

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.  Fonctionnement du programme

6.1  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.

6.2  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

7.  Explication du programme

7.1  Au niveau de la partie déclarative :

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

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

8.  Mise en oeuvre du programme

8.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

8.2  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 :
  • Bien activer l'option Newline dans le Terminal Série.

8.3  Fonctionnement

  • Dans le Terminal Série, saisir l'instruction voulue : par exemple, enAvant(100). Le robot va avancer en avant à petite vitesse.
  • Saisir arret() : le robot s'arrete
  • etc...
  • Les fonctions disponibles sont :
    • arret()
    • tourneDroite (int vitesse)
    • tourneGauche (int vitesse)
    • enArriere (int vitesse)
    • enAvant (int vitesse)

avec :

  • vitesse de 0 à 255 (impulsion PWM)
  • sens = 0 : en arriere et sens=1 : en avant

9.  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 : 26/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 ? ---------
 /*
 Contrôle des moteurs et des différents mouvements (avant, arriere, stop, tourne droite, etc...)
 à partir d'une chaîne de caractères reçue sur le port série.
 */


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

// Utilise la connexion série matérielle vers le PC
// Utilise / fonctionne avec une interface Processing coté PC
// Utilise une carte d'interface moteurs CC DFRobot 2A

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

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

// Connexion de l'interface DFRobot 2A Moteur CC sur les broches de la carte Arduino :
// Connecter broche de sens du moteur Gauche sur la broche 4
// Connecter broche de vitesse du moteur Gauche sur la broche 5
// Connecter broche de sens du moteur Droit sur la broche 7
// Connecter broche de vitesse du moteur Droit sur la broche 6

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

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

const int AVANT=1; // constante sens moteur
const int ARRIERE=0; // constante sens moteur
const int STOP=0; // constante vitesse moteur

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

//--- moteur 1 est le moteur Gauche
const int sensMoteur1=4; // Constante pour la broche 4
const int vitesseMoteur1=5; // Constante pour la broche 5

const int sensMoteurGauche=4; // Constante pour la broche 4
const int vitesseMoteurGauche=5; // Constante pour la broche 5

//---- moteur 2 est le moteur droit
const int vitesseMoteur2=6; // Constante pour la broche 6
const int sensMoteur2=7; // Constante pour la broche 7

const int vitesseMoteurDroit=6; // Constante pour la broche 6
const int sensMoteurDroit=7; // Constante pour la broche 7

// --- 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
 String chaineReception=""; // déclare un objet String vide pour reception chaine
 String chaineTest=""; // déclare un objet String pour opération sur la chaine recue

int valeur=0; // variable utile
long param=0; // paramètre transmis

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


// ////////////////////////// 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 matérielle à 115200 bauds
// IMPORTANT : régler le terminal côté PC avec la même valeur de transmission


// ------- Broches en sorties numériques -------  
 pinMode (sensMoteur1,OUTPUT); // Broche sensMoteur1 configurée en sortie
 pinMode (vitesseMoteur1,OUTPUT); // Broche vitesseMoteur1 configurée en sortie
 pinMode (vitesseMoteur2,OUTPUT); // Broche vitesseMoteur2 configurée en sortie
 pinMode (sensMoteur2,OUTPUT); // Broche sensMoteur2 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 -------  

// ------- Codes d'initialisation utile -------  


} // 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()

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

                analyseChaine(chaineReception); // appelle la fonction d'analyse de la chaine en réception

                chaineReception=""; //RAZ le String de réception
                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


//chaineReception="";

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



//while(1); // stop loop

} // 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 d'analyse de la chaine reçue sur le port série ----

//------------ analyseChaine ---------------
void analyseChaine(String chaineRecue) { // fonction d'analyse de la chaine recue

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

  //xxxxxxxxxxxxxxxxxxx instructions sans paramètres xxxxxxxxxxxx
  if (chaineReception=="arret()") { // si instruction reçue
    arret(); // exécute instruction si valide
  }

  //xxxxxxxxxxxxxxxxxxxx instructions avec paramètres xxxxxxxxxxxxxxx

  //-------------- test instruction enAvant -----------
  if (testInstruction("enAvant(")==true) { // si instruction reçue valide
    enAvant(param); // exécute instruction
  } // fin test enAvant(xxx)

  //-------------- test instruction enArriere -----------
  if (testInstruction("enArriere(")==true) { // si instruction reçue valide
    enArriere(param); // exécute instruction
  } // fin test enArriere(xxx)

  //-------------- test instruction tourne Droite -----------
  if (testInstruction("tourneDroite(")==true) { // si instruction reçue valide
    tourneDroite(param); // exécute instruction
  } // fin test tourneDroite(xxx)

  //-------------- test instruction tourne Gauche -----------
  if (testInstruction("tourneGauche(")==true) { // si instruction reçue valide
    tourneGauche(param); // exécute instruction
  } // fin test tourneDroite(xxx)

} // ---------------- fin fonction analyse chaine ----------------------

//--------------- testInstruction : test si instruction de la forme instruction(xxx) ------------

boolean testInstruction(String chaineTest) { // reçoit chaine instruction( et renvoie true si instruction valide
// cette fonction reçoit la chaine instruction( et teste si la chaine complète est valide de la forme instruction(xxx)
// fonction utilisée dans la fonction analyse chaine

  long posRef=chaineTest.length();// position de référence pour analyse (xxx) à partir de la (

  if (chaineReception.substring(0,posRef)==chaineTest) { // si reçoit l'instruction chaineTest(
  // nb substring : dernier caractere exclu

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

    Serial.print(chaineTest); // affiche

    param=stringToLong(chaineReception.substring(posRef,posRef+3)); // extraction valeur 3 chiffres à partir caractères
    Serial.print(param); // affiche

    if (chaineReception.substring(posRef+3,posRef+4)==")") { // si fermeture parenthèse = instruction valide

      Serial.println(")"); // affiche
      Serial.println("Instruction valide !"); // affiche
      return(true); // renvoie true si instruction valide

    } // fin si fermeture parenthèse

    else {

      Serial.println("Instruction invalide !"); // affiche
      return(false); // renvoie false si instruction invalide

    } // fin else

  } // fin si reçoit l'instruction chaineTest(000)

} // fin fonction testInstruction  

//------------------- fin test instruction ------------

// ---------- fonction de conversion d'un String numérique en long

long stringToLong(String chaineLong) { // fonction conversion valeur numérique String en int

    long nombreLong=0; // variable locale
    int valeurInt=0; // variable locale

    for (int i=0; i<chaineLong.length(); i++) { // défile caractères de la chaine numérique

      valeurInt=chaineLong.charAt(i); // extrait le caractère ASCII à la position voulue - index 0 est le 1er caractère
      valeurInt=valeurInt-48; // obtient la valeur décimale à partir de la valeur ASCII  

     if (valeurInt>=0 && valeurInt<=9) { // si caractère est entre 0 et 9
       nombreLong=(nombreLong*10)+valeurInt;
     } // fin si caractère est entre 0 et 9


    } // fin for défile caractères

 return (nombreLong); // renvoie valeur numérique

} // ---------- fin stringToLong ------------


//------------- fonctions gestion moteurs robot ---------------

/* les fonctions disponibles sont :
moteurDroit(int sens, int vitesse)
moteurGauche(int sens, int vitesse)
arret()
tourneDroite (int vitesse)
tourneGauche (int vitesse)
enArriere (int vitesse)
enAvant (int vitesse)
vitesse (int vitesse)

avec :
- vitesse de 0 à 255 (impulsion PWM)
- sens = 0 : en arriere et sens=1 : en avant

*/


//--- fonction controle moteur Droit
void moteurDroit(int sens, int vitesse) { // sens = 0 en arriere, sens = 1 en avant,

  analogWrite(vitesseMoteurDroit,vitesse); // génère une impulsion PWM sur la broche de vitesse du moteur
  digitalWrite(sensMoteurDroit,sens); // Marche arriere

}

//--- fonction controle moteur Gauche
void moteurGauche(int sens, int vitesse) { // sens = 0 en arriere, sens = 1 en avant,

  analogWrite(vitesseMoteurGauche,vitesse); // génère une impulsion PWM sur la broche de vitesse du moteur
  digitalWrite(sensMoteurGauche,sens); // Marche arriere

}

//--- fonction stop = arret complet
void arret() {

  analogWrite(vitesseMoteurGauche,STOP); // génère une impulsion PWM sur la broche de vitesse du moteur
  analogWrite(vitesseMoteurDroit,STOP); // génère une impulsion PWM sur la broche de vitesse du moteur

}

//---- fonction tourne à Droite
void tourneDroite (int vitesse) {

  moteurGauche(AVANT, vitesse);
  moteurDroit(ARRIERE, vitesse);

}

//---- fonction tourne à Gauche
void tourneGauche (int vitesse) {

  moteurGauche(ARRIERE, vitesse);
  moteurDroit(AVANT, vitesse);

}

//---- fonction en arriere
void enArriere (int vitesse) {

  moteurGauche(ARRIERE, vitesse);
  moteurDroit(ARRIERE, vitesse);

}

//---- fonction en avant
void enAvant (int vitesse) {

  moteurGauche(AVANT, vitesse);
  moteurDroit(AVANT, vitesse);

}

//---- vitesse
void vitesse (int vitesse) { // modifie la vitesse sans modifier le sens

   analogWrite(vitesseMoteurGauche,vitesse); // génère une impulsion PWM sur la broche de vitesse du moteur
   analogWrite(vitesseMoteurDroit,vitesse); // génère une impulsion PWM sur la broche de vitesse du moteur
}
// ////////////////////////// Fin du programme ////////////////////

 

10.  Pour aller plus loin...

  • On peut exécuter ce programme sur le eeePC embarqué et prendre la commande à distance depuis un PC fixe en utilisant un simple accès au bureau à distance par VNC du PC embarqué. Voir ici : Configurer un accès bureau distant entre 2 PC sous Ubuntu
  • En activant la webcam, on a également le retour vidéo du PC embarqué : sympa !