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 |

Arduino'Live : contrôle en live de l'état des broches de la carte Arduino configurées en sortie à partir d'une interface processing

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

Cliquer sur l'image pour agrandir

1.  Présentation

1.1  Programme Arduino

A partir d'une interface Processing qui envoie des codes de caractères, ce programme assure le décodage des codes reçus et met les broches de la carte Arduino dans l'état voulu. Utilise la nouvelle classe String du langage Arduino.

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

1.2  Programme Processing

  • Le programme Processing crée une interface graphique regroupant 20 bouton graphique de type inverseur ayant l'aspect d'une LED, chaque bouton contrôlant une des 20 broches de la carte Arduino (sauf les broches 0 et 1 qui sont utilisées par le port série-USB)
  • Lorsque l'un des boutons est modifié, l'état de l'ensemble des boutons est analysé et le code au format pin00H ou pin00L est envoyé sur le port série. Ce code est décodé par le programme Arduino qui allume/éteint la LED correspondante.

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,
  • jusqu'à 20 LEDs 5mm,
...
  • et autant de résistances 1/4w de 200 Ohms environ,
...

3.  Instructions de montage

  • La connexion série vers le PC utilise les broches 0 et 1 (via le câble USB)
  • Connecter une LED en série avec sa résistance sur toutes les broches voulues.

4.  Le schéma théorique du montage

Ici le schéma pour 8 LEDs, extensible à volonté jusqu'à 20 LEDs...

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

5.  Le circuit du montage

Voici le montage à réaliser pour 8 LEDs rouges, extensible jusqu'à 20 LEDs si besoin.

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 met les 20 broches en sortie à l'aide d'une boucle

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

  • A l'aide d'une boucle While(), on assure la réception des chaînes reçues sur le port série. La fonction d'analyse des chaînes reçues est appelée dès qu'un saut de ligne est reçu.

7.3  Autres fonctions utilisées

  • Ce programme repose en grande partie sur une fonction d'analyse des chaînes reçues. A l'aide des fonctions de l'objet String, on s'assure que la chaîne reçue est bien au format pin00H ou pin00L et on allume la broche correspondante.
  • Voir les commentaires du programme pour plus de détails

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
  • Ensuite lancer le programme Processing ci-dessous et cliquer sur les boutons : les LEDs s'allument/s'éteignent à volonté. Cool !

Cliquer sur l'image pour agrandir

8.2  Fonctionnement

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 : 30/1/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 ? ---------
 /* A partir d'une interface Processing qui envoie des codes de caractères,
 ce programme assure le décodage des codes reçus
 et met les broches de la carte Arduino dans l'état voulu.
Utilise la nouvelle classe String du langage Arduino.  */


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


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


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


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

//----- on met toutes les broches en sortie numérique ----

for (int i=0; i<20; i++) { // fait défiler les broches 0 à 19

  pinMode(i,OUTPUT); // met la broche i 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 -------  

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

                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

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

void analyseChaine(String chaineRecue) { // analyse validité de la chaine recue au format pin00H

  //--- variables locales
  int broche=0; // variable pour le numéro de broche
  int valeur=0; // variable utile

  //analyse des 3 premiers caractères
  if (chaineRecue.startsWith("pin")) { // si la chaine débute bien par pin

    Serial.println("La chaine debute par pin");

    //analyse du numéro de la broche
    chaineTest=chaineRecue.substring(3,4); // extraction du 4ème caractère - le 1er est à index=0

    //--- extraction du 4ème caractère
    //valeur=chaineRecue.charAt(3); // extrait le caractère ASCII à la position voulue - index 0 est le 1er caractère
    //valeur=valeur-48; // obtient la valeur décimale à partir de la valeur ASCII
    //Serial.print("valeur="), Serial.println(valeur);

    //if ( (valeur==0) || (valeur==1) ) { // si 4ème caractère est 0 ou 1
    if ( (chaineTest=='0') || (chaineTest=='1') ) { // si 4ème caractère est 0 ou 1

       Serial.println ("Le premier chiffre est 0 ou 1");

       //chaineTest=chaineRecue.substring(4,5); // extrait le caractère ASCII à la position voulue - index 0 est le 1er caractère
       valeur=chaineRecue.charAt(4); // extrait le caractère ASCII à la position voulue - index 0 est le 1er caractère
       valeur=valeur-48; // obtient la valeur décimale à partir de la valeur ASCII
       Serial.print("valeur="), Serial.println(valeur);


       if (valeur>=0 && valeur<=9) { // si 5ème caractère est entre 0 et 9

         Serial.println("Cinquieme caractere est un chiffre"); // debug

         //--- calcul du numero de broche correspondant
         if (chaineTest=="0") broche=valeur;
         if (chaineTest=="1") broche=10+valeur;

         Serial.print("Broche choisie ="), Serial.println(broche); // debug


         chaineTest=chaineRecue.substring(5,6); // extraction du 6ème caractère - le 1er est à index=0

           if ( chaineTest=="H" || chaineTest=="L") { // si le dernier caractère est H ou L

             Serial.println("Chaine recue valide !");

             Serial.print("La broche "), Serial.print(broche), Serial.print(" est mise au niveau "); // debug

             if (chaineTest=="H") { // si niveau caractère H

               Serial.print("HAUT");
               digitalWrite(broche, HIGH); // met la broche au niveau HAUT

             }

             if (chaineTest=="L") { // si niveau caractère H

               Serial.print("BAS");
               digitalWrite(broche, LOW); // met la broche au niveau HAUT

             }


           } // fin si 6ème car = L ou H

         } // fin si 2ème chiffre entre 0 et 9

    } // fin si 4ème car est 0 ou 1

  } // fin si début chaine = pin

} // fin fonction analyse chaine

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


 

10.  Le programme Processing associé

10.1  Description

  • L'interface graphique repose sur l'utilisation de l'objet Toggle fournit par la librairie controlP5. On utilise ici 20 Toggles, un par broche.
  • Le coeur du programme se trouve dans la fonction controlEvent() qui est appelée à chaque fois d'un Toggle est modifié. On réalise alors l'analyse de l'ensemble des Toggles et on envoie le code vers l'Arduino au format pin00L ou pin00H.

10.2  Ressources utiles :

  • La librairie controlP5
  • Les images suivantes à mettre dans le répertoire du programme :

10.3  Le code 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
// X. HINAULT - Janvier 2011 - tous droits réservés
// www.mon-club-elec.fr

/////////////// Description du programme ////////////
// Utilise un/des objets String (chaîne de caractère)
// Utilise le port Serie
// Utilise la librairie GUI controlP5
// Utilise un bouton inverseur (Toggle)
// Utilise un groupe de boutons inverseurs (Toggle) à choix multiple (CheckBox)

/*
Ce programme crée une interface graphique de controle en "live"
de l'état des broches de la carte Arduino configurées en sortie.
Un bouton graphique contrôle chaque broche.  
*/


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


PImage img1; // déclare un objet image

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

Toggle [] t= new Toggle[20]; // crée un tableau de 20 toggle - 1er indice est 0

Textlabel [] tl= new Textlabel[20]; // crée un tableau de 20 Textlabel - 1er indice est 0

// déclaration variables globales
int espace=3; // espace entre les Toggle
int hauteur=25; // hauteur des Toggle
int Xcolonne1=400; // X de la colonne 1
int Xcolonne2=100; // X de la colonne 2


//------ 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
        imageMode(CORNER); // origine image : CORNER = coin sup gauche | CENTER : centre
        frameRate(30);// Images par seconde

        // --- initialisation fenêtre de base ---
        size(600, 500); // ouvre une fenêtre xpixels  x ypixels
        background(blanc); // 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()[1], 115200); // Initialise une nouvelle instance du port Série
        myPort = new Serial(this, "/dev/ttyACM0", 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

        //--- chargement de l'image de fond - carte Arduino UNO
        img1 = loadImage("monimage.gif"); // charge un fichier image dans l'objet PImage (conteneur d'image)
        // ce fichier doit être présent dans le répertoire du programme ou à l'emplacement indiqué
        image(img1, 120, height-400, 275, 350);// affiche l'image

        //======== Initialisation Objets Toggle =========

        // addToggle(String theName, boolean theDefaultValue, float theX, float theY, int theWidth, int theHeight)

       //---- broches 0-1 ----
       for (int i=1; i>=0; i--) { // crée toggle pour les broches 0-1 - parcourt à l'envers

         t[i]=controlP5.addToggle("Broche "+i,false,Xcolonne1,height-50-(i*(hauteur+espace)),20,20); // initialise et ajoute un Button au ControlP5

         // setImages(PImage theImageDefault,PImage theImageOver, PImage theImageActive,PImage theImageHighlight)
          // les images doivent etre de la meme taille que bouton, dans rép prog, type .jpg .png ..
          // un toggle n'utilise que image Default et Active
          // les broches 0 et 1 ne sont pas utilisables car utilisées par la connexion série
          t[i].setImages(loadImage("imageDefault.png"),loadImage("imageDefault.png"), loadImage("imageDefault.png"),loadImage("imageDefault.png"));
          t[i].setLabelVisible(true); // affichage des labels

          tl[i]=controlP5.addTextlabel("Label "+i, "Broche "+i +" (non dispo)",Xcolonne1+(hauteur+espace),height-50+5-(i*(hauteur+espace)));
          tl[i].setColorValueLabel(color(noir)); // fixe couleur texte label

       } // fin for broche 0-1

        //----- les broches 2-13 ------
        for (int i=13; i>=2; i--) { // crée toggle pour les broches 2 à 13 - parcourt à l'envers

          t[i]=controlP5.addToggle("Broche "+i,false,Xcolonne1,height-50-(i*(hauteur+espace)),20,20); // initialise et ajoute un Button au ControlP5

         // setImages(PImage theImageDefault,PImage theImageOver, PImage theImageActive,PImage theImageHighlight)
          // les images doivent etre de la meme taille que bouton, dans rép prog, type .jpg .png ..
          // un toggle n'utilise que image Default et Active
          t[i].setImages(loadImage("imageDefault.png"),loadImage("imageDefault.png"), loadImage("imageActive.png"),loadImage("imageDefault.png"));
          t[i].setLabelVisible(true); // affichage des labels

          tl[i]=controlP5.addTextlabel("Label "+i, "Broche "+i,Xcolonne1+(hauteur+espace),height-50+5-(i*(hauteur+espace)));
          tl[i].setColorValueLabel(color(noir)); // fixe couleur texte label


        }

        //----- toggle des broches 14-19 (A0 à A5 utilisées en numériques) ------
        for (int i=19; i>=14; i--) { // crée toggle pour les broches 2 à 13 - parcourt à l'envers


           t[i]=controlP5.addToggle("Broche "+i,false,Xcolonne2,height-50-((19-i)*(hauteur+espace)),20,20); // initialise et ajoute un Button au ControlP5

         // setImages(PImage theImageDefault,PImage theImageOver, PImage theImageActive,PImage theImageHighlight)
          // les images doivent etre de la meme taille que bouton, dans rép prog, type .jpg .png ..
          // un toggle n'utilise que image Default et Active
          t[i].setImages(loadImage("imageDefault.png"),loadImage("imageDefault.png"), loadImage("imageActive.png"),loadImage("imageDefault.png"));
          t[i].setLabelVisible(true); // affichage des labels

          tl[i]=controlP5.addTextlabel("Label "+i, "Broche "+i+" (A"+(i-14)+")",Xcolonne2+(hauteur+espace)-100,height-50+5-((19-i)*(hauteur+espace)));
          tl[i].setColorValueLabel(color(noir)); // fixe couleur texte label


        }

} // fin fonction Setup

// XXXXXXXXXXXXXXXXXXXXXX Fonction Draw XXXXXXXXXXXXXXXXXXXX

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

  // tout se passe dans la fonction controlEvent

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

        // tout se passe dans la fonction controlEvent


      } // 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) { // fonction appelée dès qu'un évènement survient dans le controlP5

     String testString= theEvent.controller().name(); // crée un String à partir du nom de l'évènement

     println(); // saut ligne propreté
     println("*** Gestion évènement Toggle par Processing ***"); // titre - debug
     println ("Nom évènement déclencheur = " + theEvent.controller().name());// affiche le nom de l'évènement - debug


    if (match(testString,"Broche")!=null) { // si le nom de l'évènement contient Broche

      println ("Un évènement Broche est survenu ");

     for (int i=2; i<20; i++) { // parcourt les 20 broches  

        print ("Nom Toggle = "+ t[i].name()); // debug
        print (" / "); // slash séparation
        print("Etat Toggle = "+ t[i].getState()); // debug
        print (" / "); // slash séparation


        // if (theEvent.controller().name()==t[i].name()) { //--- si évènement Toggle t[i]  - si prise en compte que du Toggle déclencheur

          if (t[i].getState()==true) { // si état du Toggle[i] est vrai

            if (i<10) { // si i<10, ajoute 0 pour format 00
              print ("Envoi sur le port Série de la chaine : pin"+"0"+i+"H"); // debug
              myPort.write("pin"+"0"+i+"H\n"); // envoi code pour éteindre broche vers Arduino au format pin00H
            } // fin if i<10

            if (i>=10) { // si i>10, on n'ajoute pas 0 pour format 00
              print ("Envoi sur le port Série de la chaine : pin"+i+"H"); // debug
              myPort.write("pin"+i+"H\n"); // envoi code pour éteindre broche vers Arduino au format pin00H
            } // fin if i<10

           }// fin si état Toggle[i] est vrai  

          if (t[i].getState()==false) { // si état du Toggle[i] est faux

            if (i<10) { // si i<10, ajoute 0 pour format 00
              print ("Envoi sur le port Série de la chaine : pin"+"0"+i+"L"); // debug
              myPort.write("pin"+"0"+i+"L\n"); // envoi code pour éteindre broche vers Arduino au format pin00L
            } // fin if i<10

            if (i>=10) { // si i>10, on n'ajoute pas 0 pour format 00
              print ("Envoi sur le port Série de la chaine : pin"+i+"L"); // debug
              myPort.write("pin"+i+"L\n"); // envoi code pour éteindre broche vers Arduino au format pin00L
            } // fin if i<10

           }// fin si état Toggle[i] est vrai  

        //} // fin si prise en compte que du Toggle déclencheur


       println();

     } // fin for

    } // fin if nom évènement = Broche

}


//XXXXXXXXXXXXXXXXXX Fin du programme XXXXXXXXXXXXXXXXX