View  Edit  Attributes  History  Attach  Print  Search

Programme GLAP-Box : L'appui sur un BP lance la capture d'une séquence d'images webcam avec annonce vocale de la séquence qui va être réalisée et attente des réponses de la GLAP-Box par Arduino.

Par X. HINAULT - Page créée le : 23/08/2012
GLAPBOX | Programmes GLAP-Box | librairie Glapbox

1.  Présentation

  • L'appui sur un BP connecté à l'Arduino lance la capture et l'enregistrement d'une séquences d'images issue de la webcam de la GLAP-Box. Un message en synthèse vocale annonce également la séquence qui va être réalisée.
  • Dans ce programme, Arduino attend la réponse de la fin d'exécution de la fonction en provenance de la librairie Glapbox avant de passer à la suite. On se base ici sur des fonctions de lecture sur le port Série que j'ai rassemblées dans une librairie Arduino personnelle.

2.  Schéma fonctionnel

3.  Arduino

3.1  Le circuit du montage

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

3.2  Explication du programme Arduino

  • L'appui sur un BP envoie sur le port série :
    • plusieurs chaines direTexte(message)
    • la chaine captureSequenceImage(chaine) qui est reconnue par le programme Processing.
    • entre chaque étape, la fonction waitForString("chaine") attend les messages de fin d'exécution renvoyé sur le port série par les fonctions de la librairie Glapbox.

3.3  Le programme complet en langage Arduino

A copier/coller directement dans l'éditeur Arduino sur la GLAP-Box.



// --- 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 : 20/8/2012.

// ------- Licence du code de ce programme : GPLv3-----

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

// -------- Que fait ce programme ? ---------
 /* L'appui sur un BP envoie une chaîne vers la GLAP-Box en vue de déclencher la capture
d'une séquence d'image avec annonce vocale de la séquence qui va tre réalisée
 */


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

// Utilise la connexion série matérielle vers le PC

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

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

// Broche 3 : Un BP connecté entre la broche et le 0V

// /////////////////////////////// 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 <Utils.h> // inclusion de ma librairie Arduino contenant des fonctions utiles ...

// --- Déclaration des constantes utiles ---
const int APPUI=LOW; // constante pour tester état BP

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

const int BP=3; // Constante pour la broche 3

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


//const int Voie[6]={0,1,2,3,4,5}; //declaration constante de broche analogique


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

String entete="glapbox:"; // l'entete doit etre la meme dans le programme Processing

int compt=0; // compte le nombre d'appui

// --- Déclaration des objets utiles pour les fonctionnalités utilisées ---
Utils utils; // déclaration d'un objet racine permettant d'accéder aux fonctions de la librairie Utils

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

// ------- Broches en entrées numériques -------  
 pinMode (BP,INPUT); // Broche BP configurée en entrée

// ------- Activation si besoin du rappel au + (pullup) des broches en entrées numériques -------  
 digitalWrite (BP,HIGH); // Rappel au + activé sur la broche BP configurée en entrée

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


if (digitalRead(BP)==APPUI) { // si BP appuyé

  int nombreImages=10;
  int delaims=500; // délai en millisecondes
  String racineNomImage="monImage";
  String flagIncrust="true";

  String reponseAttendue("direTexte=stop");

  //---- annonce vocale ----
  //direTexte(texte)
  //--- les fautes d'orthographe sont volontaires ici car elles améliorent le résultat de la synthèse vocale...
  Serial.println(entete+"direTexte(Le bouton poussoir a été appuyé!)");
  //while (utils.waitingString(true)!="direTexte=stop"); // attend tant que pas reçu chaine voulue
  utils.waitForString(reponseAttendue);

  Serial.println(entete+"direTexte(La capture dune séquence de "+ nombreImages+" images va aitre lancée !)");
   utils.waitForString(reponseAttendue);

  Serial.println(entete+"direTexte(Le délai entre chaque image sera de "+ delaims+" millisecondes !)");
  utils.waitForString(reponseAttendue);

  Serial.println(entete+"direTexte(Chaque image sera enregistrée dans un fichier nommé avec la racine  "+ racineNomImage+" suivie dun numero et lextension j pègue !)");
  utils.waitForString(reponseAttendue);

  if (flagIncrust=="true") Serial.println(entete+"direTexte(Le drapeau dincrustation ai a troue. les informations utiles seront incrustées sur chaque image.)");
  else  Serial.println(entete+"direTexte(Le drapeau dincrustation est à false. aucun message ne sera incrusté sur les images.)");
  utils.waitForString(reponseAttendue);

  Serial.println(entete+"direTexte(Prait? Souriez ! La capture va commencer !)");
  utils.waitForString(reponseAttendue);


  //------ lance capture ----
  // captureSequenceImages(nombreImages,delaims,racineNomImage,flagIncrust)

  //Serial.println(entete+"captureSequenceImages(10,1000,mon_image,true)"); // lance capture sequence d'images
  Serial.println(entete+"captureSequenceImages("+nombreImages+","+delaims+","+racineNomImage+","+flagIncrust+")"); // lance capture sequence d'images

  utils.waitForString("captureSequenceImages=stop");

  Serial.println(entete+"direTexte(La capture des images est terminée !)");
  Serial.println(entete+"direTexte(Les images se trouvent dans le répertoire Bureau slash data slash images)");

   //delay(250); // anti-rebond - inutile ici



} // fin if BP==APPUI

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

//- décommenter si vous n'utilisez pas la librairie Utils et enlever utils. devant les fonctions dans le code

/*
void waitForString(String stringToWaitIn) {

   while (waitingString(true)!=stringToWaitIn); // attend tant que pas reçu chaine voulue

} // fin waitToString

*/


/*
  String waitingString(boolean debugIn) { // fonction de réception sur le port série - renvoie la chaine reçue

    int octetReception=0; // variable de réception octet
    char caractereReception=0; // variable de réception caractère
    String chaineOut=""; // chaine renvoyée


  while (Serial.available()>0) { // si un caractère en réception

    octetReception=Serial.read(); // lit le 1er octet de la file d'attente    

    if (octetReception==10) { // si Octet reçu est le saut de ligne
          if (debugIn)Serial.print ("Saut de ligne recu : ");          
           if (debugIn)Serial.print ("Chaine = "); // affiche la chaine recue
           if (debugIn)Serial.println (chaineOut);
          delay(100); // pause
          break; // sort de la boucle while
    } // fin if

    else { // si le caractère reçu n'est pas un saut de ligne        

          caractereReception=char(octetReception);
          chaineOut=chaineOut+caractereReception;
          delay(1); // laisse le temps au caractères d'arriver

    } // fin else

   } // fin while - fin de réception de la chaine

  return(chaineOut);
}
*/


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

3.4  Test du programme Arduino

  • Pour tester le programme Arduino, il suffit :
    • d'ouvrir le Terminal Série du logiciel Arduino
    • de vérifier le débit de communication utilisé (ici 115200)
  • La chaine envoyée doit s'afficher à chaque appui du BP.

Remarquer la "robustesse" du débogage possible pour la mise au point de la communication entre Arduino et la GLAP-Box : le Terminal Série permet de s'assurer qu'Arduino envoie bien la chaine voulue, indépendemment du programme Processing, un peu à la manière d'une "sonde" sur la communication USB.

4.  Le programme Processing

4.1  Description

  • L'interface Processing :
    • reçoit la chaine série
    • appelle la fonction analyseChaine() de la librairie Glapbox, fonction qui est capable notamment :
      • de reconnaître la chaîne direTexte(chaine) et d'appeler la fonction native de la librairie glapbox direTexte("chaine")
  • La fonction glapbox direTexte("chaine") lance la synthèse vocale de la chaine.

4.2  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
// du site www.mon-club-elec.fr
// par X. HINAULT - tous droits réservés

// Programme écrit le : 23/8/2012.

// ------- Licence du code de ce programme : GPL v3-----

/////////////// Description du programme ////////////
// Utilise la librairie GSVideo de capture et lecture vidéo
// Utilise la librairie GLAP-Box qui implémente tout plein de fonctions utiles

// XXXXXXXXXXXXXXXXXXXXXX ENTETE DECLARATIVE XXXXXXXXXXXXXXXXXXXXXX

// inclusion des librairies utilisées

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

import codeanticode.gsvideo.*; // importe la librairie vidéo GSVideo qui implémente GStreamer pour Processing (compatible Linux)
// librairie comparable à la librairie native vidéo de Processing (qui implémente QuickTime..)- Voir Reference librairie Video Processing
// cette librairie doit être présente dans le répertoire modes/java/libraries du répertoire Processing (1-5)
// voir ici : http://gsvideo.sourceforge.net/

import monclubelec.glapbox.*; // importe librairie Glapbox qui comporte tout plein de fonctions utiles

// déclaration objets

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

// --- police texte ---
PFont font; // crée un objet de police texte

PImage img; // image

GSCapture cam; // déclare un objet GSCapture représentant une webcam
// L'objet GSCapture étend PImage - se comporte comme un conteneur des frames issues de la webcam

Glapbox glapbox; // Déclare objet Glapbox qui donne accès aux fonctions de la librairie

// déclaration variables globales

// variable pour la taille de la capture video
int widthCapture=320; // largeur capture
int heightCapture=240; // hauteur capture
int widthDisplay=320; // largeur affichage
int heightDisplay=240; // hauteur affichage
int fpsCapture=20; // framerate (image/secondes) pour la capture video



// XXXXXXXXXXXXXXXXXXXXXX  Fonction SETUP XXXXXXXXXXXXXXXXXXXXXX

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

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

        size(widthDisplay, heightDisplay);

                //------------- 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 de la police texte - à mettre avant série ----
        font = loadFont("ArialMT-10.vlw"); // charge le fichier police dans l'objet police texte
        // ce fichier doit être présent dans un rép <data> dans le répertoire du programme
        // pour générer un fichier de police à partir des polices système aller dans Tools > create Fonts
        // voir également http://processing.org/learning/text/

        textFont(font, 10); // Initialise la police et sa taille (en pixels)

        // text("mon texte", 50, 50);


        //======== Initialisation Objets GSVideo (capture et/ou lecture video =========

        // GSCapture(this, int requestWidth, int requestHeight, [int frameRate], [String sourceName], [String cameraName])
        // cam1 = new GSCapture(this, widthCapture, heightCapture,fpsCapture,"v4l2src","/dev/video0"); // Initialise objet GSCapture désignant webcam - avant GSVideo 1.0
        cam = new GSCapture(this, widthCapture, heightCapture,"v4l2src","/dev/video0", fpsCapture); // Initialise objet GSCapture désignant webcam - depuis GSVideo 1.0
        // largeur et hauteur doivent être compatible avec la webcam - typiquement 160x120 ou 320x240 ou 640x480...
        // Meilleurs résultats avec framerate webcam entre 20 et 30 et frameRate programme idem ou multiple plus grand (40 pour 20 par ex)
        // la liste des webcam installées sous Ubuntu (Gnu/Linux) est donnée par la commande : ls /dev/video*

        // cam1.play();  // démarre objet GSCapture = la webcam - version GSVideo avant 0.9
        cam.start();  // démarre objet GSCapture = la webcam - version GSVideo après 0.9

      // initialisation objet Glapbox
      glapbox=new Glapbox(this); // initialise objet Glapbox

      glapbox.setWebcam(cam); // configure la webcam utilisée par défaut sur la Glapbox

        glapbox.setFont(font); // configure la police utilisée par défaut par la librairie

        glapbox.setSerialPort(myPort); // configure le port Série à utiliser par défaut avec la librairie

        //glapbox.setSubDirDataImages("images_"+year()+"_"+month()+"_"+day()+"_"+hour()+"_"+minute()+"_"+second()+"/"); // sous chemin du répertoire d'enregistrement relatif à DirDataImages
        glapbox.setSubDirDataImages("sequenceImages_"+glapbox.getCurrentTime()+"/"); // sous chemin du répertoire d'enregistrement relatif à DirDataImages          
        // important : le DirDataImages est relatif au homeUser... pour pouvoir être modifié depuis Arduino

  glapbox.setEnteteSerie("glapbox:"); // l'entête utilisé doit être idem côté Arduino. "glapbox:" par défaut

} // fin fonction Setup

// XXXXXXXXXXXXXXXXXXXXXX Fonction Draw XXXXXXXXXXXXXXXXXXXX

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

// Code type capture GSVideo

  if (cam.available() == true) { // si une nouvelle frame est disponible sur la webcam

    //background(0);  // fond noir entre 2 images

    //------ gestion image webcam par GSCapture ------
    cam.read(); // acquisition d'un frame
    img=cam.get();

    image(img, 0,0,widthDisplay, heightDisplay); // affiche image
    //set(0, 0, cam); // affiche image - plus rapide

    glapbox.gestion(img, false); // fonction de gestion des fonctions capture glapbox


  } // fin if available


        // while(true); // stoppe boucle draw

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


                println("chaine reçue : "+ inString); // affiche la chaine dans la console

                glapbox.analyseChaine(inString,true); // analyse chaine reçue

                // la fonction analyseChaine reconnait de nombreuses fonctions
                // voir : http://www.mon-club-elec.fr/pmwiki_reference_lib_glapbox/pmwiki.php?n=Main.GlapboxanalyseChaine

        } // fin si chaine recue sur port série pas vide


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


//------------- Fonction d'arret de Processing ----

public void stop(){ // fonction d'arrêt de Processing

        cam.delete(); // efface l'objet GScapture

        super.stop(); // obligatoire

} // fin fonction stop()


//XXXXXXXXXXXXXXXXXX Fin du programme XXXXXXXXXXXXXXXXX

 

5.  Fonctionnement

  • L'appui sur le bouton poussoir entraîne la capture de l'image courante de la webcam dans un fichier défini par la chaine envoyée sur le port série au format captureImage(chaine)