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 le sens et la vitesse d'un moteur à courant continu (CC) par réception d'une valeur entière sur le port Série depuis une interface Processing.

Par X. HINAULT - Page créée le : 5/2/2011.

(:vimeo :)

1.  Présentation

  • Ce programme permet de contrôler le sens de rotation et la vitesse de rotation d'un moteur à courant continu (CC) par une valeur entière reçue sur le port série depuis depuis une interface Processing (un slider règle le sens et la vitesse de rotation du moteur).
  • Ce programme utilise la génération PWM : la valeur reçue devra être comprise entre 0 et 255.
  • Le signe de la valeur reçue déterminera le sens de rotation : + vers l'avant et - vers l'arrière.
  • Ce programme commande le moteur par 3 broches (1 sens AV, 1 sens AR et 1 vitesse (PWM)) et utilise une interface de puissance basée sur le CI tb6612 fng.

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é

  • une plaque d'essai pour montage sans soudures,
  • des straps,
  • un moto-réducteur CC
  • ou un moteur cc
  • une interface moteur de puissance double driver (basée sur un ci tb6612) ou équivalent

Disponible ici (6 Euros) : http://www.watterott.com/index.php?page=product&info=1339
Plus d'infos ici : Carte double driver de moteur 1A basé sur le CI tb6612fng

3.  Instructions de montage

  • La connexion série vers le PC utilise les broches 0 et 1 (via le câble USB)
  • Broche 3 : la broche PWM de l'interface moteur
  • Broche 4 : la broche IN2 de l'interface moteur
  • Broche 5 : la broche IN1 de l'interface moteur

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 fonction d'initialisation setup( ) :

  • On configure en sortie les 3 broches de commande du moteur :
    • broche de vitesse (impulsion PWM)
    • broche de marche avant
    • broche de marche arrière

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

  • on écoute le port série : si une valeur est disponible, elle est lue grâce à une fonction dédiée qui est appelée
  • Une fois la valeur reçue, en fonction de son signe, on déclenche la marche avant ou arrière, ou l'arrêt si la valeur est zéro.
  • La vitesse est modulée par impulsion PWM à l'aide de la valeur absolue de la valeur reçue, avec 255 pour une vitesse maximale.
  • Pour plus de détails, voir le programme

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  Fonctionnement

  • Lancer le programme Processing ci-dessous et régler le Slider : le moteur voit sa vitesse et le sens de rotation varier en fonction des mouvements de la souris : cool !

(:vimeo :)

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 : 5/2/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 ? ---------
 /* Ce programme permet de contrôler le sens de rotation et la vitesse de rotation d'un moteur à courant continu (CC) par une valeur entière reçue sur le port série.
Ce programme utilise la génération PWM : la valeur reçue devra être comprise entre 0 et 255.
Le signe de la valeur reçue déterminera le sens de rotation : + vers l'avant et - vers l'arrière.
Ce programme commande le moteur par 3 broches (1 sens AV, 1 sens AR et 1 vitesse (PWM)) et utilise une interface de puissance basée sur le CI tb6612 fng. */


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

// Utilise la connexion série vers le PC

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

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

// Broche 3 : la broche PWM de l'interface moteur
// Broche 4 : la broche IN2 de l'interface moteur
// Broche 5 : la broche IN1 de l'interface moteur

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

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

const int VITESSE_MOT1=3; // Constante pour la broche 3
const int AVANT_MOT1=4; // Constante pour la broche 4
const int ARRIERE_MOT1=5; // Constante pour la broche 5

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


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


// ------- Broches en sorties numériques -------  
 pinMode (VITESSE_MOT1,OUTPUT); // Broche VITESSE_MOT1 configurée en sortie
 pinMode (AVANT_MOT1,OUTPUT); // Broche AVANT_MOT1 configurée en sortie
 pinMode (ARRIERE_MOT1,OUTPUT); // Broche ARRIERE_MOT1 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 -------  

// ------- Initialisation des broches utilisées -------  
digitalWrite(VITESSE_MOT1,HIGH); // PWM haut = transparent à l'état des broches IN1/IN2

//---- +/- test des moteurs ----
//digitalWrite(AVANT_MOT1,HIGH), digitalWrite(ARRIERE_MOT1,LOW);; // Test marche avant
//delay (1000);
//digitalWrite(AVANT_MOT1,LOW), digitalWrite(ARRIERE_MOT1,HIGH);; // Test marche arriere
//delay (1000);

digitalWrite(AVANT_MOT1,LOW), digitalWrite(ARRIERE_MOT1,LOW);; // ARRET


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


//--- réception valeur sur port Série par fonction dédiée ---
        if (Serial.available()==true) nombreReception=recevoirNombre(); // si caractères présents sur port Série appel de la fonction recevoirNombre

        if (nombreReception!=nombreReception0) { // si un nombre a été reçu

                nombreReception=constrain(nombreReception,-255,255); // oblige valeurs entre -255 et +255

                Serial.print("Arduino a recu : ");
                Serial.println(nombreReception);
                nombreReception0=nombreReception; // RAZ nombreReception0


                // gestion des moteurs en fonction de la valeur recue
                if (nombreReception>0) { // si nombre positif

                  digitalWrite(AVANT_MOT1,HIGH), digitalWrite(ARRIERE_MOT1,LOW);; // Marche avant
                  analogWrite(VITESSE_MOT1,nombreReception); // impulsion PWM vitesse

                }

                if (nombreReception==0) { // si nombre =0

                  digitalWrite(AVANT_MOT1,LOW), digitalWrite(ARRIERE_MOT1,LOW);; // Arret moteur
                  digitalWrite(VITESSE_MOT1,LOW); // broche PWM au niveau bas = pas d'impulsion PWM

                }

                if (nombreReception<0) { // si nombre négatif

                  digitalWrite(AVANT_MOT1,LOW), digitalWrite(ARRIERE_MOT1,HIGH);; // Marche arriere
                  analogWrite(VITESSE_MOT1,abs(nombreReception)); // impulsion PWM vitesse - attention valeur positive

                }


        } // fin si nombreReception



} // 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 de réception valeur entière sur le port série ---

long recevoirNombre() { // fonction de reception d'un nombre sur le port série

        int octetRecu=0; // variable pour octet recu
        int compt=0; // variable locale comptage caractères reçus
        boolean signe=true; // variable locale signe nombre recu
        long nombreRecu=0; // variable locale nombre recu

        while (Serial.available()>0) { // tant qu'un octet en réception

                octetRecu=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
                        break; // sort de la boucle while
                }
                else { // si le caractère reçu n'est pas un saut de ligne

                        if ((octetRecu=='-') && (compt==0))signe=false; // si Octet reçu est le - et si c'est le 1er caractère reçu - signe négatif
                        compt=compt+1; // incrémente compt

                        octetRecu=octetRecu-48; // transfo valeur ASCII en valeur décimale

                        // calcul du nombre à partir des valeurs reçues

                        if ((octetRecu>=0)&&(octetRecu<=9)) nombreRecu = (nombreRecu*10)+octetRecu;

                } // fin else if

                delay(1); // pause pour laisser le temps à la fonction available de recevoir octet suivant

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

        if (signe==false) nombreRecu=nombreRecu*(-1); // prise en compte signe négatif

        return(nombreRecu); // renvoie le nombre calculé - type long

} // fin fonction recevoirNombre


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


// ////////////////////////// Mémo instructions ////////////////////
// ////////////////////////// Fin Mémo instructions ////////////////////

 

10.  Le programme Processing

10.1  Description

  • A l'aide d'un slider, une valeur comprise entre -255 et +255 est envoyée sur le port Série du PC. Le programme Arduino associé utilise cette valeur pour contrôler le moteur CC
  • En retour, la console Processing affiche les valeurs envoyées/recues par Arduino.

10.2  Ressources

  • Utilise la librairie GUI controlP5

10.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 le port Serie
// Utilise la librairie GUI controlP5
// Utilise un/des réglage(s) linéaire(s) (Slider)

/*
Ce programme envoie sur le port série une valeur comprise entre 0 et 255 réglée à partir d'un slider graphique ce qui permet de générer en direct une impulsion PWM de largeur voulue sur la carte Arduino.
*/


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

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

Slider s1; // déclare un/ des objet Slider

// 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(15);// Images par seconde

        // --- initialisation fenêtre de base ---
        size(400, 150); // 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 Sliders =========

        // addSlider(theName, theMin, theMax, theDefaultValue, theX, theY, theW, theH)
        s1=controlP5.addSlider("sliderPWM",-255,255,0,20,50,360,30); // ajoute un Slider au ControlP5

        // méthodes propres à l'objet Slider
        s1.setNumberOfTickMarks(511); // fixe le nombre crans - n+1 pour n valeurs
        //s1.setNumberOfTickMarks((int(s1.max())+1); // fixe le nombre crans - n+1 pour n valeurs
        s1.showTickMarks(false); // affichage des repères
        s1.setSliderMode(Slider.FIX); // fonctionnement du slider FLEXIBLE ou FIX

        // méthodes communes à tous les controles (objet Controller)
        //s1.setLabelVisible(false); // affichage des labels
        //s1.setLabel("Slider PWM"); // fixe label objet
        s1.setDecimalPrecision(0); // fixe la précision
        s1.setColorActive(color(255,0,255)); // fixe la couleur active
        s1.setColorBackground(color(255,255,0)); // fixe couleur fond  
        s1.setColorForeground(color(255,0,0)); // fixe couleur avant
        //s1.setArrayValue(new float[] {100,255} ); // fixe les valeurs min/max du Slider ?
        s1.setColorCaptionLabel(color(0,0,0)); // fixe couleur Label
        s1.setColorValueLabel(color(0,0,255)); // fixe la couleur valeur



} // fin fonction Setup

// XXXXXXXXXXXXXXXXXXXXXX Fonction Draw XXXXXXXXXXXXXXXXXXXX

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

  // tout se passe dans la fonction évènement du Slider

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

                // affichage de la chaine envoyée par la carte Arduino
                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 ----


// ------ gestion évènement Slider ------
void sliderPWM(float valeur) { // fonction évènement Slider de meme nom - reçoit la valeur

      println("Evènement Slider PWM avec valeur = "+valeur); // message console Processing - debug

      myPort.write(str(int(valeur))+"\n"); // envoie la chaine suivi saut ligne sur le port Série
      // noter la double conversion du float en int et du int en chaine texte

      delay(10); // entre 2 prises en compte
}


//XXXXXXXXXXXXXXXXXX Fin du programme XXXXXXXXXXXXXXXXX