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 la rotation de 2 servomoteurs (tourelle pan/tilt) à partir d'une interface Processing à distance via un réseau wifi à l'aide du shield RedFly (Watterott)

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

1.  Présentation

  • Deux servomoteurs connectés à la carte Arduino sont contrôlés à l'aide de sliders (contrôles linéaires réglables) dans une interface Processing basique.
  • L'interface Processing envoie sur le réseau wifi, en tant que client réseau, une chaine de caractères sous la forme servoPan(000) où 000 est la valeur de l'angle de positionnement du servomoteur.
  • Cette chaîne de caractères réceptionnée par le shield wifi RedFly configuré en serveur réseau wifi.
  • La chaine est ensuite transférée par communication série du shield wifi RedFly vers la carte Arduino.
  • Le programme Arduino analyse la chaine reçue et en extrait la valeur d'angle reçue
  • Le servomoteur est positionné dans la position voulue
  • La vitesse est également réglable
  • On pourra ainsi contrôler à distance et sans fil, par réseau wifi, une tourelle dite "pan/tilt" (pan - axe panoramique et tilt - inclinaison) permettant de contrôler la position d'un capteur de distance, une webcam, etc...

On réalise ici une connexion en mode "attribution automatique" des adresses ip par le routeur (mode DHCP). Il est tout à fait possible de réaliser une configuration manuelle également, sous réserve d'adapter le programme à votre cas particulier.

Ce programme utilise les fonctionnalités suivantes :

  • Utilise deux servomoteurs
  • Utilise la connexion série vers le PC
  • Utilise le stockage des variables en mémoire Flash Programme

Ressources utiles associées à ce programme :

  • La librairie Flash - pour mettre simplement les chaînes de caractères et constantes de vos programmes dans la mémoire Flash programme de votre carte Arduino. Attention : nécessite une petite modification du fichier print.h, à faire une fois pour toute.
  • La librairie RedFly - pour le contrôle du shield Arduino wifi RedFly de chez Watterott.

Ressources utiles associées à ce programme :

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é

3.  Instructions de montage

Le shield wifi RedFly est sensible aux décharges électro-statiques : éviter de toucher directement les pattes du shield avec les doigts !

  • Connecter le servomoteur "pan" (rotation panoramique) sur la broche 8 du Shield EasyCard
  • Connecter le servomoteur "tilt" (rotation inclinaison) sur la broche 9 du Shield EasyCard
  • 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.  Note technique concernant la communication série avec le module wifi RedFly

  • Le module wifi RedFly communique avec la carte Arduino en utilisant le port série matériel, c'est à dire le même que celui qui est utilisé pour programmer et communiquer avec la carte Arduino, à savoir les broches 0 et 1 de la carte Arduino (Uno ou Duemilanove).
  • A première vue, ceci empêche la communication série entre le PC et la carte Arduino pendant l'exécution du programme. En fait, cette communication est possible sous réserve de quelques contraintes à savoir :
    • le débit utilisé doit être le même que celui utilisé par la communication série entre le module wifi RedFly et la carte Arduino, à savoir 9600 bauds.
    • avant toute utilisation de la communication série pendant l'exécution du programme entre le PC et la carte Arduino, il faudra désactiver puis réactiver la communication série avec le module, ce qui se fait à l'aide de 2 fonctions dédiées de la librairie pour le module RedFly, les fonctions enable() et disable().
  • Au sein des programmes Arduino, il faudra cependant veiller à ne pas utiliser la communication série entre la carte Arduino et le PC lorsque le module wifi et la carte Arduino communiquent entre-eux, sous peine d'obtenir une perte de données issues du module wifi.
  • A noter que l'utilisation du Terminal série configuré en 9600 bauds permettra de visualiser les messages de communication entre le module wifi et la carte Arduino.

7.  Mise en place du réseau wifi : étape préparatoire

  • Ce programme nécessite un réseau wifi local opérationnel entre le PC utilisé, un routeur Wifi en mode d'attribution automatique des adresses (DHCP) et la carte wifi RedFly.

Pour ce programme, vous avez besoin de connaître les éléments suivants :

  • le nom du réseau ou SSID ( se connecter depuis le PC à l'interface du routeur - 192.168.1.1 dans mon cas)
  • le numéro du réseau (chiffres en xxx.xxx.xxx. de l'adresse ip - en rouge sur le schéma)
  • connaître d'adresse ip du PC (sous Ubuntu, ifconfig dans un terminal)

Vous devez vérifier notamment :

  • que le sous-masque du réseau est bien 225.255.255.0 au niveau du routeur. A modifier le cas échéant.
  • Concrètement :
    • 1. vous branchez votre routeur wifi, qui peut être votre Box ou un routeur wifi acheté exprès (configuré en mode DHCP (=attribution automatique d'adresse) par défaut normalement). La connexion à internet n'est pas nécessaire ici.
    • 2. vous connectez votre PC au réseau wifi comme vous le feriez d'habitude (pas de clé wep nécessaire normalement - si on vous en demande une, elle doit être fournie par le fabricant ou FAI). Connectez-vous en mode "infra-structure", le mode "ad-hoc" correspondant à une connexion directe entre 2 éléments du réseau)
    • 3. Une fois la connexion faite, récupérer et noter l'adresse ip attribuée à votre PC (sous Ubuntu, faire $ ifconfig dans une console)
    • 3. vous ouvrez un navigateur et vous connectez à l'adresse de votre routeur (de la forme http://192.168.1.1 - le numéro est fourni par la documentation fabricant / FAI) : vous arrivez dans l'interface du routeur. Noter les éléments voulus : le SSID, le numéro réseau, le masque, ... et modifier le sous-masque réseau au besoin.
    • 4. Mettez le module RedFly sur la carte Arduino et connecter la carte au port Série : vous devez avoir une LED verte et une rouge qui s'allument sur le shield RedFly.
    • 5. Vous pouvez passer à la suite...

Voir également :

8.  Explication du programme

8.1  Fonctionnement général

  • L'interface Processing envoie sur le réseau wifi, en tant que client réseau, une chaine de caractères sous la forme servoPan(000) où 000 est la valeur de l'angle de positionnement du servomoteur.
  • Cette chaîne de caractères réceptionnée par le shield wifi RedFly configuré en serveur réseau wifi.
  • La chaine est ensuite transférée par communication série du shield wifi RedFly vers la carte Arduino.
  • Le programme Arduino analyse la chaine reçue et en extrait la valeur d'angle reçue
  • Le servomoteur est positionné dans la position voulue
  • La vitesse est également réglable
  • voir les commentaires détaillés du programme pour plus de détails.

8.2  Etapes types de la connexion au réseau wifi

Les étapes types de la connexion du module RedFly à un réseau wifi sont les suivantes :

  • 1. initialisation du module avec la fonction init()
  • 2. Détection du/des réseaux avec la fonction scan()
  • 3. connexion au réseau wifi à l'aide de son identifiant (ssid), en mode ouvert ou crypté (WEP, WAP..), à l'aide de la fonction join()
  • 4. configuration des paramètres du réseau (ip, passerelle, ..) avec la fonction begin()
  • 5. ouverture de la ligne réseau, en fixant le protocole (UDP ou TCP) et le port, avec la fonction socketListen
  • 6. lecture/écriture des données sur la ligne réseau avec les fonctions socketRead() et socketSend()
  • Pour plus d'informations sur les fonctions, voir : librairie RedFly

9.  Mise en oeuvre du programme

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

9.2  Lancement

  • 1. Allumer le routeur et connecter le PC au réseau wifi du routeur. Noter l'adresse IP attribuée au PC. Sous Ubuntu, çà donne dans un terminal :

Dans mon cas, l'ip du PC est 192.168.0.4

  • 2. Mettre sous tension le montage et programmer la carte Arduino. A noter qu'il est possible de lancer une fenêtre Terminal pour s'assurer de la bonne initialisation du module wifi (Utiliser dans ce cas obligatoirement un debit de 9600 bauds). Je vous conseille de le faire au moins juste après la programmation, pour être sûr que votre shield wifi détecte bien le réseau. Vous devez obtenir dans ce cas :
  • 3. Une fois fait, depuis le PC, je vous conseille également de faire un ping vers le routeur puis vers shield wifi. Dans mon cas, le routeur est à l'adresse 192.168.0.1 (numéro du réseau et 1 généralement), le shield wifi est à l'adresse 192.168.0.3 (essayer plusieurs numéros autour de l'ip de votre pc si le ping ne marche pas - moi le pc a l'ip 192.168.0.4) ce qui doit donner, sous Ubuntu (dans une fenêtre Terminal) :
  • 4. Corrigez le programme Processing avec l'IP de votre shield et lancer l'interface Processing : le client réseau est activé et se connecte :

9.3  Fonctionnement

  • Le servomoteur "pan" se positionne en fonction de la position du slider PAN.
  • Le servomoteur "tilt" se positionne en fonction de la position du slider TILT.
  • Des messages dans la console de Processing témoignent également du bon déroulement de la connexion du client au serveur réseau et de l'envoi de la chaine du client Processing vers le serveur réseau

10.  Le programme complet en langage Arduino

A copier/coller directement dans l'éditeur Arduino

  • Adapter les paramètres réseaux à votre cas particulier, notamment le nom du réseau.

// --- 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 : 23/05/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 réalise un simple serveur wifi (port 5905) à l'aide du shield Arduino wifi RedFly de chez Watterott.

  ce serveur reçoit chaine caractères en provenance client réseau wifi

Deux servomoteurs connectés à la carte Arduino sont contrôlés
à partir du PC (interface Processing

Controle par chaine de la forme : servoPan(000) avec 000 = angle en degrés

*/


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

// Utilise la connexion série matérielle vers le PC
// Utilise le stockage des variables en mémoire Flash Programme
// Utilise 2 servomoteurs pour tourelle Pan/Tilt (Panoramique/inclinaison)
// Utilise le shield RedFly pour connexion Wifi (par Watterott)

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

// La connexion série matérielle vers le PC utilise les broches 0 et 1 (via le câble USB)
// Module wifi Redfly de chez Watterott connecté broche à broche sur la carte Arduino
// utilise les broches 0 et 1 (communication série matérielle) + broches 3 et 4

// ******* ATTENTION : il est possible de connecter directement 2 ou 3 servomoteurs sur la carte Arduino
// Connecter un servomoteur PAN sur la broche 8
// Connecter un servomoteur TILT sur la broche 9

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

#include <Flash.h> // Inclusion librairie pour stockage en mémoire Flash Programme
// Avant utilisation, il faut installer manuellement cette librairie
// dans le dossier <Libraries> du dossier Arduino
// infos : www.mon-club-elec.fr/pmwiki_reference_arduino/pmwiki.php?n=Main.LibrairieFlashProgramme

#include <RedFly.h> // inclusion de la librairie pour shield Arduino wifi RedFly (watterott)
// Avant utilisation, il faut installer manuellement cette librairie
// dans le dossier <Libraries> du dossier Arduino
// infos : www.mon-club-elec.fr/pmwiki_reference_arduino/pmwiki.php?n=Main.LibrairieRedFly

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

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

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

// pour étalonner un servomoteur, voir la page :
//http://www.mon-club-elec.fr/pmwiki_mon_club_elec/pmwiki.php?n=MAIN.ArduinoExpertSerieDepuisPCPositionServomoteur

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

const int broche_servoPan=8; // Constante pour la broche 8
const int broche_servoTilt=9; // Constante pour la broche 8


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


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

//------ variables pour le réseau wifi avec le module RedFly ----
byte ip[]      = { 192,168,  2, 10 }; //tableau contenant adresse ip du shield wifi RedFly (serveur) - 4 octets
byte netmask[] = { 255,255,255,  0 }; // tableau contenant le masque de sous-réseau - 4 octets

byte mac[]= {0,0,0,0,0,0}; //tableau contenant l'adresse mac du module wifi - 6 octets

//unsigned int port=80; // port utilisé pour la connexion
unsigned int port=5905; // port utilisé pour la connexion

byte ligneReseau=0xFF; // identifiant de ligne réseau
int ligneReseau_len=0; // réception len
char ligneReseau_buf[100]; // buffer de réception

//----- debug - tableau de la variable rd où est stocké la valeur renvoyée par la fonction socketRead()
//String mem_rd=""; // Pour mémoriser les valeurs de la variable rd
char mem_rd[100]; // pour mémoriser les valeurs de la variable rd
int compt_rd=0; // pour comptage nombre valeur de la variable rd

char ssid[32]; // tableau pour stocker ssid (nom du réseau)
byte mode; // variable pour stocker mode du réseau (0=Open, 1=WPA, 2=WPA2, 3=WEP)
byte rssi; // variable pour stocker rssi (la force du signal réseau)

//--------- pour la chaine reçue par le réseau ----

String chaineIn=""; // déclare un objet String vide pour reception chaine

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

int angleServoPan=90; // variable de position du servo  Pan en degrés
int angleServoTilt=90; // variable de position du servo  Tilt en degrés

int angleServoPan0=90; // variable de la dernière position du servo  Pan en degrés
int angleServoTilt0=90; // variable de la dernière position du servo  Tilt en degrés

int vitesse=10; // variable utilisée pour délai entre 2 lecture port Série

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

Servo mon_servoPan;  // crée un objet servo pour contrôler le servomoteur 1
Servo mon_servoTilt;  // crée un objet servo pour contrôler le servomoteur 2

// l'objet RedFly est automatiquement créé lors de l'inclusion de la librairie
// toutes les fonctions de la librairie RedFly s'appliquent à cet objet sous la forme RedFly.fonction()

// ////////////////////////// 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(9600); // initialise connexion série matérielle à 9600 bauds
// IMPORTANT : régler le terminal côté PC avec la même valeur de transmission
// Module RedFly : la communication série avec le module se fait à 9600 Bauds

delay(100); // delai avant communication avec module wifi

//--- Initialisation Servomoteur
mon_servoPan.attach(broche_servoPan);  // attache l'objet servo à la broche de commande du servomoteur Pan
mon_servoTilt.attach(broche_servoTilt);  // attache l'objet servo à la broche de commande du servomoteur Tilt


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

//------------ initialisation du module wifi RedFly ----

initialisationRedFly(); // appelle fonction initialisation

//---- positionnement initial servomoteur
mon_servoPan.writeMicroseconds(angle(angleServoPan)); // crée impulsion à partir valeur angle - plus précis que write()
mon_servoTilt.writeMicroseconds(angle(angleServoTilt)); // 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()



//--------------- Wifi : gestion des connexions clients entrantes -----------------

  //uint8_t sock, buf[32];
  byte sock, buf[32]; // sock = numéro de ligne en écoute - buf = buffer réception

  //uint16_t rd, len;
  int unsigned rd, len; // rd = mémorise retour de socketRead()=taille des données lues ? - len : taille totale des données disponibles


  if(ligneReseau == 0xFF) // si il n'y a pas de ligne réseau ouverte - cf socketListen()

  {

    debugoutln("Pas de ligne ouverte"); // affiche message
    return; // sort de la fonction

  }



  sock = 0xff; //pour renvoi des données de toutes les lignes réseau
  // paramètre passé à la fonction socketRead()

  rd = RedFly.socketRead(&sock, &len, 0, 0, buf, sizeof(buf));
  // la fonction socketRead renvoie le nombre de données lues = mises dans le buffer destination


  if(sock == ligneReseau) // si la ligne lue est la ligne Réseau obtenue avec SocketListen (port défini)

  {

/*    //--------- éviter les messages pendant la lecture des données en réception car çà perturbe la communication entre redfly et Arduino
     //-------- affiche message -----
  if (rd!=0) { // si des données ont été lues --
    RedFly.disable();
    Serial.print("rd =");
    Serial.println(rd);
    RedFly.enable();
  }

*/


    if((rd != 0) && (rd != 0xffff)) // si la fonction socketRead() n'a pas renvoyé 0 (= des données ont été lues)
    // et n'a pas renvoyé 0xFFFF (= connexion interrompue)
    // il semble que la fonction socketRead() renvoie 1 à chaque passage --

    {

      //---------- pour éviter débordement buffer réception ligne réseau -----------

      if((ligneReseau_len+rd) > sizeof(ligneReseau_buf)) // si la longueur données déjà présente dans buffer + taille données lues > taille buffer

      {

        rd = sizeof(ligneReseau_buf)-ligneReseau_len; // la taille données lues est réduite à la place restante dans buffer ligne Reseau

      }

      //--------- récupération données reçues par réseau dans buffer réception ligne réseau

      memcpy(&ligneReseau_buf[ligneReseau_len], buf, rd); // copie dans http buffer le contenu de buf longueur rd (?)

      ligneReseau_len += rd; // incrémente longueur données présentes dans http buffer de la quantité données rd


      //--- mémorisation valeur rd pour affichage --
      //mem_rd=mem_rd+rd; // ajoute la valeur de rd au String
      //mem_rd[compt_rd]=rd+48; // mémorise valeur ascii de rd
      if (compt_rd<(sizeof(mem_rd)-1)) mem_rd[compt_rd]=rd+48; // mémorise valeur ascii de rd tant que compt_rd < taille tableau mem_rd
      compt_rd ++; // incrémente compt_rd

    } // fin si (rd != 0) && (rd != 0xffff)



    if((rd == 0xffff)  || (len == 0)) // si la connexion est fermée ou si toutes les données sont lues
    // une fois que la chaine est reçue donc...

    {

      //ferme la ligne réseau si connexion fermée - sinon laisse ouvert pour nouvelle réception
      if (rd == 0xffff) {

        debugoutln("La ligne est fermee"); // affiche message
        RedFly.socketClose(sock); // ferme la ligne

        ecouteLigneReseau(); //------------- ré-ouverture de la ligne réseau en écoute ------------



      } // fin si ligne fermée

      //affiche le contenu du http buffer
      ligneReseau_buf[sizeof(ligneReseau_buf)-1] = 0; // met 0 dans la dernière case de http buffer (une chaine de caractère se termine par 0)

      //debugoutln(ligneReseau_buf); // affiche le contenu du http buffer - possible une fois communication entre Redfly et Arduino finie

      mem_rd[sizeof(mem_rd)-1]=0; // met 0 dans dernière case du tableau (une chaine de caractère se termine par 0)

      //debugout("Valeurs rd : "); // affiche message      
      //debugoutln (mem_rd); // affiche liste valeur des rd

      RedFly.disable();
      //Serial.print(F("comptage rd : "));
      //Serial.println(compt_rd);
      RedFly.enable();

//----- une fois que la chaine est reçue

      RedFly.disable(); // désactive le wifi pendant toute la procédure pour messages

      chaineIn=ligneReseau_buf; // met le buffer dans le String...

      analyseChaine(chaineIn); //appel fonction analyse chaine


      RedFly.enable(); // réactive wifi

//------------- fin analyse chaine ---------------
      chaineIn=""; //RAZ le String de réception

      //-------- réinitialise réception nouvelle chaine par wifi -----------
      compt_rd=0; // RAZ compt_rd

      for (int i=0; i<ligneReseau_len; i++) ligneReseau_buf[i]=' '; // RAZ des caractères utilisés du buffer ligneReseau

      ligneReseau_len=0; // RAZ ligneReseau_len

    } // fin si len==0

  } // fin si sock == ligneReseau

   //delay(vitesse); // fixe la vitesse de mouvement du servo - entre 2 lecture analogique
  // delay perturbe 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 ////////////////////

//--------- fonctions pour affichage Terminal série avec shield RedFly ---
//---- chacune de ces fonctions désactive/active la communication série et utilise fonction Serial.print ou Serial.println
void debugout(char *s)  { RedFly.disable(); Serial.print(s);   RedFly.enable(); }
void debugoutln(char *s){ RedFly.disable(); Serial.println(s); RedFly.enable(); }


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

//--------------- initialisation module RedFly ----------------------

void initialisationRedFly() {

  byte ret; // variable pour stockage valeur renvoyées par fonctions utilisées

  //initialisation du module wifi intégré sur le shield RedFly
  ret = RedFly.init(HIGH_POWER); // initialise le module wifi avec niveau HAUT série = 5V - valeur renvoyée stockée dans ret
  //valeurs possibles : LOW_POWER MED_POWER HIGH_POWER

  if(ret!=0) { // si la fonction init() n'a pas renvoyé 0  

    debugoutln("Echec initialisation module wifi"); // affiche message

  } // si échec initialisation module wifi

  else { // si la fonction init a renvoyé 0 càd si initialisation réussie

    debugoutln("Initialisation module wifi OK"); // affiche message

    //récupération de l'adresse MAC du module wifi
    RedFly.getmac(mac); // récupère l'adresse mac et la met dans le tableau reçu par la fonction


    //------------ affiche adresse MAC au format xx:xx:xx:xx:xx:xx
    RedFly.disable(); // désactive communication série avec module wifi avant utilisation Serial.print

    Serial.print(F("Adresse MAC du module : ")); // affiche message

    for (int i=0; i<6; i++) { // défile les 6 octets

      if (mac[i]<10) Serial.print(0,HEX),Serial.print(mac[i],HEX), Serial.print(":"); // affiche message
      else Serial.print(mac[i],HEX), Serial.print(":");

    } // fin for

    Serial.println(); // saut de ligne
    Serial.println(); // saut de ligne

    RedFly.enable(); // ré-active communication série avec module wifi après utilisation Serial.print

    //------------- détection réseau sans fil disponible ----------

    RedFly.disable(),Serial.println(F("---- recherche reseau wifi disponible ----")), RedFly.enable(); // affiche message

    //on commence par rechercher un réseau sans fil disponible -- à faire avant join()
    //RedFly.scan(); // recherche réseau sans récupérer infos

    //scan(char ssid[], uint8_t *mode, uint8_t *rssi)
    ret=RedFly.scan( ssid, &mode, &rssi); // recherche réseau et récupère infos dans variables reçues par la fonction

    //-- affichage des valeurs récupérées --
    RedFly.disable(); // désactivation série module wifi

//    Serial.print("Valeur renvoyee = "), Serial.println(int(ret)); // affiche valeur de ret
    Serial.print(F("Nom reseau detecte : ")), Serial.println(ssid);
    Serial.print(F("Mode reseau (0=Open, 1=WPA, 2=WPA2, 3=WEP) = ")), Serial.println(int(mode));
    Serial.print(F("Force du signal = ")), Serial.print(int(rssi)), Serial.println("%");
    Serial.println(); // saut de ligne

    RedFly.enable(); // ré-activation série module wifi

    //---- recherche plusieurs réseaux disponibles ---
    // --- nextscan() semble devoir etre précéde de scan()
/*
    RedFly.disable(), Serial.println("---- recherche des 5ers reseaux wifi disponibles ----"), Serial.println(), RedFly.enable(); // affiche message

    for (int i=0; i<5; i++) { // détecte les 5 premiers réseaux trouvés

    ret=RedFly.nextscan( ssid, &mode, &rssi); // recherche réseau et récupère infos dans variables reçues par la fonction

    //-- affichage des valeurs récupérées --
    RedFly.disable(); // désactivation série module wifi

//  Serial.print("Valeur renvoyee = "), Serial.println(int(ret)); // affiche valeur de ret
    Serial.print("Nom reseau detecte : "), Serial.println(ssid);
    Serial.print("Mode reseau (0=Open, 1=WPA, 2=WPA2, 3=WEP) = "), Serial.println(int(mode));
    Serial.print("Force du signal = "), Serial.print(int(rssi)), Serial.println("%");
    Serial.println(); // saut de ligne

    RedFly.enable(); // ré-activation série module wifi

    } // fin for i détection n premiers réseaux trouvés
*/
   

    //------------- Connexion au réseau détecté ---------------
    //ret = RedFly.join("belkin54g", "ADB48F70E9B9B2733C2FA8D90E",INFRASTRUCTURE); //"wlan" (SSID=nom), "12345678" (clé wep ou wap), INFRASTRUCTURE or IBSS_JOINER
    //ret = RedFly.join("Livebox-f0c2", "FAD994A61922743DA3DC1933F5",INFRASTRUCTURE); //"wlan" (SSID=nom), "12345678" (clé wep ou wap), INFRASTRUCTURE or IBSS_JOINER
    //ret = RedFly.join("NETGEAR", "",INFRASTRUCTURE); //"wlan" (SSID=nom), "12345678" (clé wep ou wap), INFRASTRUCTURE or IBSS_JOINER
    ret = RedFly.join("NETGEAR"); //"wlan" (SSID=nom) - connexino sur réseau non sécurisé par clé wep = le plus simple

    if(ret!=0) { // si valeur renvoyée par join n'est pas nulle = erreur de connexion

      debugoutln("Erreur de connexion au reseau wifi !");

    } // fin if

    else { // si valeur renvoyée par join nulle = connexion au réseau wifi réussie

       debugoutln("Connexion au reseau wifi : OK !");

      //configuration de l'adresse IP du module wifi
      ret = RedFly.begin(); //attribution automatique - avec un routeur en mode DHCP - le plus simple

      //ret = RedFly.begin(ip);
      //ret = RedFly.begin(ip, gateway);
      //ret = RedFly.begin(ip, gateway, netmask);
      //ret = RedFly.begin(ip, 0, netmask);

        if(ret!=0) { // si la valeur renvoyée par la fonction begin n'est pas nulle = en cas d'erreur de configuration

          debugoutln("Erreur de configuration initiale parametres reseau");
          RedFly.disconnect();
          debugoutln("Deconnexion du reseau wifi");

        }// fin if

        else {

          debugoutln("Configuration initiale parametres reseau : OK !");

          ecouteLigneReseau(); //------------- ouverture de la ligne réseau en écoute - voir fonction ------------


        } // fin else

    } // fin else


  } // fin si Initialisation module OK


} // -------- fin initialisation module wifi Redfly -------------



//------------- fonction ouverture de la ligne réseau RedFly en écoute ------------

void ecouteLigneReseau (void) {  

  ligneReseau = RedFly.socketListen(PROTO_TCP, port); //lance écoute sur le port  en utilisant le protocole TCP = serveur sur port défini
          // socketListen renvoie 0xFF si erreur... sinon, renvoie le numéro de la ligne en écoute

          if(ligneReseau == 0xFF) { // la fonction socketListen renvoie 0xFF si erreur... sinon, renvoie le numéro de la ligne en écoute

            debugoutln("Erreur de connexion ligne reseau");

              RedFly.disconnect();
              debugoutln("Deconnexion du reseau wifi");

            }// fin if

          else { // si pas d'erreur

            //debugoutln("Ecoute ligne reseau TCP sur port 80 : OK !");

            RedFly.disable();
            Serial.print(F("Ecoute ligne reseau TCP sur port "));
            Serial.print(port);
            Serial.println(F(" : OK !"));
            RedFly.enable();

          }// fin else ligne reseau

} // fin fonction ouverture de la ligne réseau RedFly en écoute ------------


//---------------------- fonction analyse chaine -------------------

void analyseChaine (String chaineReception) {

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

//----- gestion servomoteur PAN ----
if (chaineReception.substring(0,9)=="servoPan(") { // si reçoit l'instruction servoPan(000)
// nb substring : dernier caractere exclu

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

  //Serial.print(F("servoPan(")); // affiche

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

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

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

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

  //Serial.print(angleServoPan); // affiche

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

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

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

    angleServoPan=constrain(angleServoPan,ANGLE_MIN,ANGLE_MAX); // oblige valeur angle Servo
    mon_servoPan.writeMicroseconds(angle(angleServoPan)); // crée impulsion à partir valeur angle - plus précis que write()
    //angleServoPan0=angleServoPan; // mémorise dernière valeur angle prise en compte

    //delay(1000); // laisse temps positionnement

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



  } // fin si fermeture parenthèse  



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

//--------------------- gestion servomoteur Tilt -------------------------------

//----- gestion servomoteur TILT ----
if (chaineReception.substring(0,10)=="servoTilt(") { // si reçoit l'instruction servoPan(000)
// nb substring : dernier caractere exclu

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

  //Serial.print(F("servoTilt(")); // affiche

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

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

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

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

  //Serial.print(angleServoTilt); // affiche

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

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

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

    angleServoTilt=constrain(angleServoTilt,ANGLE_MIN,ANGLE_MAX); // oblige valeur angle Servo
    mon_servoTilt.writeMicroseconds(angle(angleServoTilt)); // crée impulsion à partir valeur angle - plus précis que write()
    //angleServoTilt0=angleServoTilt; // mémorise dernière valeur angle prise en compte

    //delay(1000); // laisse temps positionnement

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



  } // fin si fermeture parenthèse  



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

//---------------- gestion vitesse ------------------------

//----- gestion servomoteur Vitesse ----
if (chaineReception.substring(0,8)=="Vitesse(") { // si reçoit l'instruction Vitesse
// nb substring : dernier caractere exclu

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

  //Serial.print(F("Vitesse(")); // affiche

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

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

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

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

  Serial.print(vitesse); // affiche

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

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


  } // fin si fermeture parenthèse  



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


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


 

11.  Le programme Processing

11.1  Description

  • Ce programme réalise un client réseau qui se connecte au réseau wifi au serveur constitué par le shield wifi RedFly
  • 2 réglages linéaires graphiques (sliders) permettent de régler :
    • la valeur de l'angle du servomoteur PAN (rotation panoramique)
    • la valeur de l'angle du servomoteur TILT (rotation inlinaison)
  • un 3ème slider permet de régler la vitesse de rotation utilisée
  • une chaine de caractères au format servoTilt(000) est envoyée sur le port série et affichée dans la console lorsque le réglagle des sliders change.

11.2  Ressources utiles

  • Librairie GUI controlP5
  • Librairie Network

11.3  Le programme complet en langage Processing

A copier/coller directement dans l'éditeur Processing

  • Adapter les paramètres réseaux à votre cas particulier, notamment l'adresse ip du module wifi serveur (si configuration manuelle) et le port utilisé qui doit être le même que le programme Arduino.
  • Noter que le port (="ligne réseau" à l'intérieur de la connexion wifi) utilisé doit également être ouvert sur le routeur utilisé. Ici, on utilise le port 5905 (libre).

// Programme processing
// généré avec le générateur de code Processing
// www.mon-club-elec.fr
// par X. HINAULT - Mai 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)
// Utilise un Client réseau : ce programme nécessite un serveur réseau accessible

/*
Envoi une chaine de caractère vers le serveur réseau
en fonction de la position des sliders
pour controle pan/tilt servomoteurs
*/



// XXXXXXXXXXXXXXXXXXXXXX ENTETE DECLARATIVE XXXXXXXXXXXXXXXXXXXXXX

// inclusion des librairies utilisées

import processing.net.*; // importe la librairie pour connexion réseau Client/Serveur

//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 chaineEnvoiNetwork = ""; // déclare un objet String (chaine de caractère)

// --- objet Client Réseau ---
Client clientNetwork; // déclaration d'un objet client réseau
String inStringFromServerNetwork; // pour réception chaine en provenance Serveur Réseau
String inStringFromClientBoard; // pour réception chaine en provenance carte Arduino Client

// --- 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 sPan, sTilt, sVitesse; // 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);

//String ipServeur="192.168.2.5"; // ip du serveur sur réseau wifi local
String ipServeur="192.168.0.3"; // ip du serveur sur réseau wifi local
//String ipServeur="127.0.0.1"; // ip du serveur sur boucle locale

//int portNetwork=12345; // port pour boucle locale
int portNetwork=5905; // port pour réseau wifi
//int portNetwork=80; // port pour réseau http

int valeurPan0; // variable globale pour mémoriser dernier valeur Tilt envoyee sur le reseau
int valeurTilt0; // variable globale pour mémoriser dernier valeur Tilt envoyee sur le reseau

// 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(450, 400); // 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 objet Client réseau ---- A FAIRE AVANT controlP5 ++
  // Connexion du Client au serveur ayant l'adresse indiquée et sur le port indiqué
  // 127.0.0.1 pour connexion en local sur la machine
  //clientNetwork = new Client(this, ipServeur, portNetwork); // Remplacer avec l'adresse IP du serveur et le numéro de port utilisé
  clientNetwork = new Client(this, ipServeur, portNetwork); // pour réseau local sur port 5905
  // info : le port utilisé doit être ouvert sur le PC client et le PC serveur ainsi que sur le routeur du réseau

  println("Connexion du client Processing au serveur "+ ipServeur +" sur le port "+portNetwork+"...");

//////////////////////// Faire les initialisations fonctionnalités AVANT la création des controles GUI controlP5
// car la création appelle les fonctions évènements ...

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

        //------------ slider Pan ----------------
        // addSlider(theName, theMin, theMax, theDefaultValue, theX, theY, theW, theH)
        sPan=controlP5.addSlider("sPan",0,180,90,40,height-50,350,25); // ajoute un Slider au ControlP5
        //s1 = (Slider)controlP5.controller("MonSlider1"); // initialise l'objet Slider déclaré

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

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

        //------------ slider Tilt ----------------
        // addSlider(theName, theMin, theMax, theDefaultValue, theX, theY, theW, theH)
        sTilt=controlP5.addSlider("sTilt",0,180,90,10,10,25,350); // ajoute un Slider au ControlP5
        //s1 = (Slider)controlP5.controller("MonSlider1"); // initialise l'objet Slider déclaré

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

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

        //------------ slider Vitesse ----------------
        // addSlider(theName, theMin, theMax, theDefaultValue, theX, theY, theW, theH)
        sVitesse=controlP5.addSlider("sVitesse",1,20,10,10,height-15,400,10); // ajoute un Slider au ControlP5
        //s1 = (Slider)controlP5.controller("MonSlider1"); // initialise l'objet Slider déclaré

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

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



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

// ------ gestion évènement Slider ------

void sPan(float valeur) { // fonction évènement Slider de meme nom - reçoit la valeur
        //println("Evènement Slider Pan avec valeur = "+valeur);

        //println("Envoi sur port série = "+int(valeur));


  int valeurNetwork=int(valeur); // convertit valeur reçue en int

if ( valeurPan0!=valeurNetwork) { // si la valeur Pan0 a été modifiée - pour éviter envoi répété inutile sur réseau

      if (valeurNetwork>=100){ // si valeur sup à 100
          clientNetwork.write("servoPan("+str(valeurNetwork)+")\n"); //--- envoie une chaine vers le Serveur  suivie d'un saut de ligne
          //print("Envoi Client Processing ==> Serveur Réseau : ");
          print("servoPan("+str(valeurNetwork)+")\n");
        }



      if ((valeurNetwork<=99) && (valeurNetwork>=10)){ // si valeur entre 10 et 99
          clientNetwork.write("servoPan(0"+str(valeurNetwork)+")\n"); //--- envoie une chaine vers le Serveur  suivie d'un saut de ligne
          //print("Envoi Client Processing ==> Serveur Réseau : ");
          print("servoPan(0"+str(valeurNetwork)+")\n");
        }


        if (valeurNetwork<=9){ // si valeur sup à 9
          clientNetwork.write("servoPan(00"+str(valeurNetwork)+")\n"); //--- envoie une chaine vers le Serveur  suivie d'un saut de ligne
          //print("Envoi Client Processing ==> Serveur Réseau : ");
          print("servoPan(00"+str(valeurNetwork)+")\n");
        }

    } // fin if valeurPan0!=valeur

        valeurPan0=valeurNetwork; //mémorise dernière valeur Pan

        //delay(100); // entre deux envois


}

// ------ gestion évènement Slider ------
void sTilt(float valeur) { // fonction évènement Slider de meme nom - reçoit la valeur
        //println("Evènement Slider Tilt avec valeur = "+valeur);
        //println("Envoi sur port série = "+int(valeur));


  int valeurNetwork=int(valeur); // convertit valeur reçue en int

if ( valeurTilt0!=valeurNetwork) { // si la valeur Pan0 a été modifiée - pour éviter envoi répété inutile sur réseau

      if (valeurNetwork>=100){ // si valeur sup à 100
          clientNetwork.write("servoTilt("+str(valeurNetwork)+")\n"); //--- envoie une chaine vers le Serveur  suivie d'un saut de ligne
          //print("Envoi Client Processing ==> Serveur Réseau : ");
          print("servoTilt("+str(valeurNetwork)+")\n");
        }



      if ((valeurNetwork<=99) && (valeurNetwork>=10)){ // si valeur entre 10 et 99
          clientNetwork.write("servoTilt(0"+str(valeurNetwork)+")\n"); //--- envoie une chaine vers le Serveur  suivie d'un saut de ligne
          //print("Envoi Client Processing ==> Serveur Réseau : ");
          print("servoTilt(0"+str(valeurNetwork)+")\n");
        }


        if (valeurNetwork<=9){ // si valeur sup à 9
          clientNetwork.write("servoTilt(00"+str(valeurNetwork)+")\n"); //--- envoie une chaine vers le Serveur  suivie d'un saut de ligne
          //print("Envoi Client Processing ==> Serveur Réseau : ");
          print("servoTilt(00"+str(valeurNetwork)+")\n");
        }

    } // fin if valeurPan0!=valeur

        valeurTilt0=valeurNetwork; //mémorise dernière valeur Pan


        //delay(100); // entre deux envois



}

// ------ gestion évènement Slider ------
/*void sVitesse(float valeur) { // fonction évènement Slider de meme nom - reçoit la valeur
        println("Evènement Slider Vitesse avec valeur = "+valeur);

        valeurNetwork=int(valeur); // utilise variable globale
        println("Envoi sur port série = "+valeurNetwork);

        //if (valeur>100)myPort.write("Vitesse("+int(valeur)+")\n"); // envoie la valeur suivie d'un saut de ligne sur le port Série
        if ((valeur<100) && (valeur>9))myPort.write("Vitesse(0"+int(valeur)+")\n"); // envoie la valeur suivie d'un saut de ligne sur le port Série
        if (valeur<=9)myPort.write("Vitesse(00"+int(valeur)+")\n"); // envoie la valeur suivie d'un saut de ligne sur le port Série

}
*/

//XXXXXXXXXXXXXXXXXX Fin du programme XXXXXXXXXXXXXXXXX