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 |

Ethernet en mode serveur : Serveur réseau de datalogging avec stockage dans une SD-Card et accès distant dans une interface Processing

ARDUINO - EXPERT - ETHERNET
Par X. HINAULT - Créé le 01/10/2010

1.  Présentation

  • Ce programme réalise un serveur de datalogging sur un réseau ethernet, accessible éventuellement depuis le web si votre routeur le permet.
  • On utilise ici une carte Arduino couplée à un module ethernet :
    • Toutes les n secondes, une valeur (résultat de mesure, etc...) est mémorisée dans la carte SD.
    • Le programme Arduino reçoit des instructions via le réseau pour accéder à la carte SD à distance, notamment :
      • lecture du contenu du fichier sur la carte micro-SD
      • activation du mode "live" qui permet la réception en direct via le réseau à intervalle réguliers de la valeur courante depuis la carte Arduino
      • effacement des données sur la carte SD
      • vérification, initialisation de la carte SD
      • modification de l'intervalle de mesure
  • Les messages utiles sont émis simultanément sur le réseau et sur le port série afin de faciliter test et mise au point.
  • Toute la force de cette application réside dans le fait de disposer d'un serveur réseau de datalogging autonome, accessible à tout moment par le réseau depuis un PC, sans interruption du flux de mesure et sans manipulation physique de la carte SD. Mis sur un réseau avec bloc CPL, cette solution permet de disposer d'un serveur distant du PC sans câblage supplémentaire.

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é

  • un module Arduino Ethernet
  • une carte mémoire micro-SD de 2Go ou plus...

3.  Le réseau utilisé :

  • Voici le réseau local utilisé :
  • A noter : la connexion USB en pointillé sur le schéma pour montrer que l'on peut utiliser, au moins en phase de mise au point et de test, la communication série pour afficher les messages en provenance de l'Arduino.
  • Dans mon cas :
    • le routeur DHCP (Livebox) a une plage d'adresse entre .10 et .50
    • le shield Ethernet sera initialisé avec l'adresse IP .70, une adresse statique en dehors de la plage du routeur.
    • la passerelle du réseau est le routeur avec l'adresse .1
  • Pour plus de détails, voir : Arduino : Expert : Shield Ethernet : Les différentes architectures de réseau utilisables.

4.  Instructions de montage

  • Le montage à réaliser est très simple : il suffit d'enficher le module Arduino Ethernet sur la carte Arduino UNO ou Duemilanove.
  • Il faut également mettre en place une carte micro-SD dans l'emplacement prévu à cet effet sur le shield Ethernet.
  • Ensuite, on connecte la carte Arduino au port USB
  • On connecte également le module Arduino au PC à l'aide d'un câble Ethernet au réseau (connecté à un bloc CPL dans mon cas).

5.  Le circuit du montage


Le schéma du montage à réaliser

6.  Explication du programme

  • Ce programme écoute le réseau et analyse les chaines reçues pour exécuter les actions voulues
  • Une valeur est par ailleurs enregistrée à intervalle régulier dans la carte micro-SD.
  • Les messages sont émis simultanément sur le réseau et le port Série pour faciliter test et mise au point.

7.  Fonctionnement

  • Programmer la carte Arduino.
  • Lancer ensuite le programme Processing sur le PC connecté au réseau.
  • Dans la fenêtre qui apparait, saisir l'une des instructions suivantes et cliquer sur le bouton graphique :
    • lireSD : renvoie la lecture du fichier SD
    • clearSD : efface la carte SD
    • modeLive : active le mode "Live"
    • stopLive : stoppe le mode Live
    • fixDelay(xxxx) : fixe le delai de mesure en ms
    • verifSD : vérification SD fonctionne bien et taille du fichier
    • valueLive : renvoie la valeur courante

8.  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 : 20/11/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 ? ---------
 /* Serveur Ethernet renvoyant contenu SD-Card lors requete  */
 // Une ligne de donnée est ajoutée dans un fichier de la SD-CARD à intervalle régulier


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

// Utilise le module Ethernet Arduino
// en mode serveur HTTP
// Utilise la SD Card

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

// Le module Ethernet est à enficher broche à broche sur la carte Arduino
// Connecter broche SCLK du module Ethernet sur la broche 13
// Connecter broche MISO du module Ethernet sur la broche 12
// Connecter broche MOSI du module Ethernet sur la broche 11
// Connecter broche Select Ethernet du module Ethernet sur la broche 10
// Connecter broche Select SD Card du module Ethernet sur la broche 4
// Le module Ethernet est compatible avec la carte Mega via le connecteur ICSP


// /////////////////////////////// 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 <SPI.h>
#include <Ethernet.h>
#include <Server.h>
#include <Client.h>
#include <SD.h> // crée automatiquement un objet racine SD représentant la carte mémoire SD


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

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

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

boolean flagSerial=true; // pour activation message série
boolean flagNetwork=true; // pour activation message réseau


//=============== SD CARD ================

File myFile; // objet file

char dirName[]="/monrep"; // tableau de caracteres pour le nom du répertoire sur la SD Card

// nom du fichier court (8 caractères maxi . 3 caractères maxi) (dit format DOS 8.3)
char fileName[] = "test.txt"; // tableau de caractères pour le nom du fichier

char pathFile[] = "/monrep/test.txt"; // tableau de caractères pour le nom du fichier

int test; //variable mémorisation résultat renvoyé par fonctions

long millis0=millis(); // mémorise dernier millis() pris en compte
int intervalle=1000; // intervalle en milliseconde entre 2 mesures

boolean flagLive=false; // drapeau mode "live" = envoie en temps réel des valeurs
boolean flagLiveSent=true; // variable témoin envoi valeur Live

boolean flagInit=false, flagVerif=false, flagClear=false;

//=============== ETHERNET ==================

//--- déclaration du tableau d'adresse MAC ---
//--- ne pas utiliser la meme adresse MAC si on utilise plusieurs module ethernet
//--- utiliser adresse MAC indiquée sur étiquette du module
//byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0x1A, 0x71 };


//---- tableau de l'adresse IP de la carte Arduino
byte ipLocal[] = { 192,168,1,70 }; // le réseau local a numéro 192.168.1.x
//---- ATTENTION : aucun élément du réseau ne doit avoir la meme adresse IP

// nb : si on utilise un routeur DHCP sur le réseau, il faut simplement que l'adresse statique
// soit "hors" de la plage des adresses dynamiques DHCP

//----- tableau de l'adresse de la passerelle ---
byte passerelle[] = { 192, 168, 1, 1 }; // l'adresse du PC de connexion à internet ou de la box

//----- tableau du masque de sous réseau
byte masque[] = { 255, 255, 255, 0 }; // idem masque sous-réseau du PC ou de la box : 255.255.255.0


String requeteRecue=""; // variable stockage requete client

//-- variables utiles pour la réception des trames de téléinformation
String chaineRecue=""; // déclare un string vide global
int comptChar=0; // variable de comptage des caractères reçus
char charIn=0; // variable de mémorisation du caractère courant en réception

int delayRecept=10; // delai en µs pour laisser temps réception caractères à 1200 bauds (débit lent...)
// on utilise delaymicroseconds dans ce programme pour les pauses afin d'éviter problème interruption avec delay()
// NB : à 1200 bauds, un caractère sur 10 bits mets théoriquement 1/120 = 8.33ms pour arriver...  

boolean debug=true; // drapeau activation messages debug

String chaineHtml="";

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

//--- création de l'objet serveur ----
// Server serveurHTTP(80); // crée un objet serveur utilisant le port 80 = port HTTP
EthernetServer serveurHTTP(80); // préfixe Ethernet devant Client et Server à partir Arduino 1.0


//Client client;

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

//---- initialise la connexion Ethernet avec l'adresse MAC du module Ethernet, l'adresse IP Locale
//---- l'adresse IP de la passerelle internet et le masque du réseau local
Ethernet.begin(mac, ipLocal, passerelle, masque);
delay(1000); // donne le temps à la carte Ethernet de s'initialiser

//---- initialise le serveur HTTP----
serveurHTTP.begin(); //---- initialise le serveur HTTP

//--- initialise connexion série
Serial.begin(115200); // réinitialise communication série

// ------- Broches en sorties numériques -------  

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


//--- gestion initiale de la SD Card ---

initSDCard(true, false); // initialisation de la SDCard - crée le fichier de stockage - n'efface pas fichier existant
// la fonction reçoit un drapeau pour begin et un drapeau pour efface - voir ci-dessous



} // 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 pour une connexion d'un client distant au serveur local ---

// crée un objet client basé sur le client connecté au serveur HTTP
// Client client = serveurHTTP.available();
EthernetClient client = serveurHTTP.available(); // préfixe Ethernet devant Client et Server à partir Arduino 1.0


////////////////// Connexion au client ///////////////////

  if (client) { // si l'objet client n'est pas vide

    if (client.connected()) { // si le client est connecté

////////////////// Reception de la requete Client ///////////////////

      requeteRecue=""; // initialise chaine reception requete

      while (client.available()) { // tant que des octets sont disponibles en lecture

                char c = client.read(); // lit l'octet suivant reçu du client (pour vider le buffer au fur à mesure !)
                requeteRecue=requeteRecue+c; //

      } // --- fin while client.available

    // si plus de caractères disponibles = requete client terminée

////////////////// Analyse de la requete client ///////////////////

         Serial.println ("Requete =");
         Serial.println (requeteRecue);

        //=================== requete initSD ============================

        if (requeteRecue.startsWith("initSD")) { // si initialisation de la SDCard demandée - efface pas fichier

            flagInit=false;

            initSDCard(true, false); // initialise SD sans effacer fichier et sans begin

        } // fin requete mode live

        //=================== requete verifSD ============================

        if (requeteRecue.startsWith("verifSD")) { // si vérification de la SDCard demandée - efface pas fichier

            initSDCard(false, false); // initialise SD sans effacer fichier et sans begin

            flagVerif=false;

            if ((flagNetwork)||(flagVerif)) {
              client.println ("Carte SD Verifiee!");
               client.print("Taille Fichier=");
                client.print(myFile.size());
                client.println("Octets");
            }

            flagVerif=false;

        } // fin requete mode live


        //=================== requete clearSD ============================

        if (requeteRecue.startsWith("clearSD")) { // si effacement de la SDCard demandée - vide fichier

            flagClear=false;

            initSDCard(false,true); // vide le fichier sans initialiser SD

            if ((flagNetwork)||(flagClear)) client.println ("Carte SD Effacee!");

            flagClear=false;


        } // fin requete mode live

        //=================== requete fixDelay(0000) =======================

        if (requeteRecue.startsWith("fixDelay(") ) { // si requete fixDelay( reçue

         if (flagSerial) Serial.println ("Modification du delai de mesure :");
         if (flagNetwork) client.println ("Modification du delai de mesure :");

         if (requeteRecue.substring(requeteRecue.length()-2,requeteRecue.length()-1)==")") { // si la chaine se termine par )

         intervalle=stringToLong(requeteRecue.substring(9,requeteRecue.length()-2)); // récupère la valeur entre les ( )
         }

         if (flagSerial) {
           Serial.print("Nouvel intervalle=");
           Serial.print (intervalle);
           Serial.println ("ms");
         }

         if (flagNetwork) {
           client.print("Nouvel intervalle=");
           client.print (intervalle);
           client.println ("ms");
         }



        }        

        //=================== requete stop live ============================

        if (requeteRecue.startsWith("stopLive")) { // si arret du mode live demandé

          flagLive=false; // activation du mode live

         if (flagSerial) Serial.println ("Mode live inactif !");
         if (flagNetwork) client.println ("Mode live inactif !");


        } // fin requete stop live


        //=================== requete mode live ============================

        if (requeteRecue.startsWith("modeLive")) { // si debut du mode live demandé

              flagLive=true; // activation du mode live

         if (flagSerial) Serial.println ("Mode live actif !");
         if (flagNetwork) client.println ("Mode live actif !");


        } // fin requete mode live

        //===================== requete getLive ================================
        // Mode Live : envoi de la dernière valeur mémorisée sur le réseau
        // lorsque le modeLive est activé, Processing envoie une requete à intervalles réguliers
        // pour obtenir un renvoi à intervalle régulier

        if (requeteRecue.startsWith("valueLive")) { // si demande de valeur live

            if ((flagLive) && (!flagLiveSent)) { // si mode live activé et que dernière valeur pas envoyée

                Serial.println(millis0);        
                client.println(millis0); // envoie la dernière valeur prise en compte
                flagLiveSent=true; // témoin envoi dernière valeur


              } // fin si flagLive

        } // fin si requete getLive


        //=================== requete lecture carte SD ============================
        if (requeteRecue.startsWith("lireSD")) { // si lecture de la SDCard demandée

          //--- mettre ici code à exécuter pour cette commande

          //-- on envoie tous les caractères du fichier de la SDCard sur le réseau et/ou le port Série
          //-- l'analyse du contenu sera faite coté PC dans Processing (plus robuste pour analyse contenu du fichier)

         //--- ouverture du fichier en lecture ---
          myFile=SD.open(pathFile,FILE_READ); // ouvre le fichier en lecture

         if (flagSerial) Serial.println ("Ouverture du fichier en lecture");
         if (flagNetwork) client.println ("Ouverture du fichier en lecture");

         for (int i=0; i<myFile.size(); i++ ) {

           myFile.seek(i); // se positionne à la position i

           if (flagSerial) Serial.print(char(myFile.peek())); // affiche le caractère courant
           if (flagNetwork) client.print(char(myFile.peek())); // affiche le caractère courant            
         }


       myFile.close(); // fermeture du fichier

       if (flagSerial) Serial.println ("Fermeture fichier effectuee!");
       if (flagNetwork) client.println ("Fermeture fichier effectuee!");

        } // fin if si "lireSD"


        //=================== requete lecture cart SD format HTML ============================

      if (requeteRecue.startsWith("GET")) { // si requete GET = renvoi d'une réponse HTML

/* décommenter si on veut une réponse HTML -- attention fait déborder RAM = utiliser mémoire FLASH au besoin

        // ----- envoi d'une entete standard de réponse http
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connection: close"); // pour connexion non persistante client
          client.println();

        // ----- envoi du code HTML de la page

             //---- debut de la page HTML ---
             client.println("<html>");

             // ---- Entete de la page HTML ----
             client.println("<head>");

               client.println("<meta content=\"text/html; charset=ISO-8859-1\" http-equiv=\"Content-Type\">");

               client.println("<title>Connexion au Serveur Arduino</title>");

               // balise meta pour réactualisation automatique de la page Web toutes les n secondes
               client.println("<META HTTP-EQUIV=\"Refresh\" CONTENT=\"5\">");

             client.println("</head>");

             //----- Corps de la page HTML ---
             client.println("<body>");

             client.println("<br>");
             client.println("****** Contenu du fichier de la SD-CARD ****");
             client.println("<br>");


          //-- on envoie tous les caractères du fichier de la SDCard sur le réseau et/ou le port Série
          //-- l'analyse du contenu sera faite coté PC dans Processing (plus robuste pour analyse contenu du fichier)

         //--- ouverture du fichier en lecture ---
          myFile=SD.open(pathFile,FILE_READ); // ouvre le fichier en lecture

         if (flagSerial) Serial.println ("Ouverture du fichier en lecture");
         if (flagNetwork) client.println ("Ouverture du fichier en lecture");

         for (int i=0; i<myFile.size(); i++ ) {

           myFile.seek(i); // se positionne à la position i

           if (myFile.peek()==13) { // si saut de ligne = on remplace par <br>

             if (flagSerial) Serial.println("<br>"); // affiche le caractère courant
             if (flagNetwork) client.println("<br>"); // affiche le caractère courant            

           }
           else { // si pas de saut de ligne = on affiche le caractère lui-meme

             if (flagSerial) Serial.print(char(myFile.peek())); // affiche le caractère courant
             if (flagNetwork) client.print(char(myFile.peek())); // affiche le caractère courant  

           } // fin else        

       } // fin for i



       myFile.close(); // fermeture du fichier

       if (flagSerial) Serial.println ("Fermeture fichier effectuee!");
       if (flagNetwork) client.println ("Fermeture fichier effectuee!");

             client.println("<br>");


             client.println("</body>");

             //---- fin de la page HTML
             client.println("</html>");

*/

      } // fin if GET




    } // --- fin if client connected

    delay(1);
    // on donne au navigateur le temps de recevoir les données


////////////////// Fermeture de la connexion client ///////////////////

     client.stop(); // ferme le client distant une fois réponse envoyée
    delay(10); // laisse temps fermeture

  } //---- fin if client existe ----


//------ écriture d'une valeur dans la SD-card à intervalle régulier ------

if ((millis()-millis0)>intervalle) { // si intervalle écoulé : écriture dans la SDCARD

  millis0=millis(); // mémorise nouveau millis()

      //----- ouverture du fichier pour écriture ---


    myFile=SD.open(pathFile,FILE_WRITE); // ouvre le fichier en écriture et crée fichier si existe pas


     if (myFile!=true) Serial.println ("Echec ouverture fichier !");  // si échec ouverture
     else { // si ouverture réussie

       //Serial.println ("Ouverture fichier reussie !");

       myFile.seek(myFile.size()); // positionnement à la fin du fichier

       //Serial.println ("Positionnement a la fin du fichier!");

        //myFile.println(); // ajoute un saut de ligne

      //myFile.println("------ Debut nouvel enregistrement -------"); // ajoute une ligne

       myFile.print("millis=");  myFile.println(millis());  
       //--- mettre ici toute valeur voulue à écrire en SD CARD      

       myFile.close(); // fermeture du fichier

       //Serial.println ("Fermeture fichier effectuee!");
       Serial.print ("."); // temoin enregistrement d'une valeur

       //--- gestion drapeau du mode live --

       if (flagLive) { // si mode live activé

          flagLiveSent=false; // valeur pas envoyée          

       }// si flagLive

     } // fin else     = ouverture réussie

} // fin if millis()

delay(10); // entre 2 passages loop

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



//================ Fonctions SD CARD ===============================

//--------------- Initialisation de la SDCard ---------

void initSDCard(boolean flagBegin, boolean flagErase) {
  // la fonction reçoit un drapeau pour begin et un drapeau pour efface
  // reçoit en paramètre drapeau pour activation begin (seulement première fois
 // reçoit en paramètre true/false pour effacement fichier

  pinMode(10, OUTPUT); // laisser la broche SS en sortie - obligatoire avec librairie SD

  if (flagBegin==true) { // si flag Begin==true

   //----- initialisation de la carte SD -----
  Serial.println("Initialisation de la SD card...");

    test=SD.begin(4); // initialisation de la carte SD avec broche 4 en tant que CS - renvoie true/false

    if (test!=true) { // si initialisation n'est pas réussie
      Serial.println("Echec initialisation!"); // message port Série
    }
    else { // si nitialisation réussie
      Serial.println("Initialisation reussie !"); // message port Série
    } // fin si SD.begin
  }

  //----- test de l'existence d'un fichier


 test=SD.exists(pathFile); // test si le fichier existe - renvoie true/false

 Serial.print ("Test="); Serial.println(test);

 if (test!=true) { // si le fichier n'existe pas

   Serial.println ("Le fichier n'existe pas !");

       //----- création du fichier ---


    myFile=SD.open(pathFile,FILE_WRITE); // ouvre le fichier en écriture et crée fichier si existe pas


     if (myFile!=true) Serial.println ("Echec ouverture fichier !");  // si échec ouverture
     else { // si ouverture réussie

       Serial.println ("Ouverture fichier reussie !");

       myFile.println("Test fichier");

       myFile.close(); // fermeture du fichier

       Serial.println ("Fermeture fichier effectuee!");

     }    // fin ouverture réussie      

      //---- Vérification existence du fichier

       test=SD.exists(pathFile); // test si le fichier existe - renvoie true/false

       Serial.print ("Test="); Serial.println(test);

       if (test!=true)   Serial.println ("Le fichier existe pas !"); // si fichier existe pas
       else { // si fichier existe

         Serial.println ("Creation fichier OK !");

     } // fin else = fichier existe

 } // fin si rép existe pas

 else { // si le fichier existe

     Serial.println ("Le fichier existe !");

     if (flagErase==true) { // si flagErase==true : le fichier est effacé
       SD.remove(pathFile); // efface le fichier  
       Serial.println ("Fichier efface !");  
       flagClear=true; // drapeau témoin
     }
     else { // si flagErase false = le fichier n'est pas effacé
       Serial.print("Taille Fichier=");
       Serial.print(myFile.size());
       Serial.println("Octets");
       flagVerif=true; // drapeau témoin

     } // fin si flagErase false  



 }// fin else si fichier existe pas


} // ------------- fin initSD ------------



//--------------- Lecture SD CARD ------

// void lectureSDCard(boolean flagSerial, boolean flagNetwork, Client clientIn) {
void lectureSDCard(boolean flagSerial, boolean flagNetwork, EthernetClient clientIn) {
// préfixe Ethernet devant Client et Server à partir Arduino 1.0


      //---- lecture du fichier

/*      
       test=SD.exists(pathFile); // test si le fichier existe - renvoie true/false

       Serial.print ("Test="); Serial.println(test);

       if (test!=true)   Serial.println ("Le fichier existe pas !"); // si fichier existe pas
       else { // si fichier existe

         Serial.println ("Le fichier existe !");
 */


         //--- ouverture du fichier en lecture ---
          myFile=SD.open(pathFile,FILE_READ); // ouvre le fichier en lecture

         if (flagSerial) Serial.println ("Ouverture du fichier en lecture");
         if (flagNetwork) clientIn.println ("Ouverture du fichier en lecture");

         for (int i=0; i<myFile.size(); i++ ) {

           myFile.seek(i); // se positionne à la position i

           if (flagSerial) Serial.print(char(myFile.peek())); // affiche le caractère courant
           if (flagNetwork) clientIn.print(char(myFile.peek())); // affiche le caractère courant            
         }


       myFile.close(); // fermeture du fichier

       if (flagSerial) Serial.println ("Fermeture fichier effectuee!");
       if (flagNetwork) clientIn.println ("Fermeture fichier effectuee!");

       //} // fin else si fichier existe


} // --- fin lecture SDCard


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

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

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

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

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

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


    } // fin for défile caractères

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

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


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

9.  Le programme Processing

9.1  Explications :

  • Ce programme crée un "client réseau" qui se connecte au serveur Arduino.
  • Lors de l'appui sur le bouton envoie sur le réseau la chaine de caractère présente dans le champ texte.

9.2  Ressources

  • La librairie controlP5
  • Processing 1-5

9.3  Le programme complet en langage Processing :

A copier/coller directement dans l'éditeur Processing


// Programme processing
// généré avec le générateur de code Processing
// www.mon-club-elec.fr
// par X. HINAULT - Avril - Novembre 2011 - tous droits réservés

/////////////// Description du programme ////////////
// Utilise un/des objets String (chaîne de caractère)
// Utilise le port Serie
// Utilise un Client réseau : ce programme nécessite un serveur réseau accessible

// Utilise la librairie GUI controlP5
// Utilise un/des bouton(s) simple(s) (Button)
// Utilise un/des champ(s) texte (Textfield)
// Ajoute un bouton et un champ pour chemin fichier

/*
Envoi une chaine de caractère vers le serveur réseau
à partir champ texte et bouton (libriairie GUI controleP5)
*/


// XXXXXXXXXXXXXXXXXXXXXX ENTETE DECLARATIVE XXXXXXXXXXXXXXXXXXXXXX

// inclusion des librairies utilisées

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

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

boolean flagModeLive=false; // drapeau de mode live

int rate=30; // frame/seconde
int nbSec=1; // nombre de secondes
int nbFrame; // nombre de frames à prendre en compte =rate*nbSec

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

//---- librairie GUI controlP5 ----
ControlP5 controlP5; // déclare un objet principal de la librairie GUI controlP5

Button networkButton; // déclare objet Button  

Textfield networkText; // déclare des objets Textfield

// 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.1.70"; // 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=80; // port pour réseau wifi
//int portNetwork=80; // port pour réseau http

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

        nbFrame=rate*nbSec; // valeur utilisée pour modulo avec framecount pour intervalle régulier dans draw

        // --- initialisation fenêtre de base ---
        size(400, 130); // ouvre une fenêtre xpixels  x ypixels
        background(vert); // couleur fond fenetre

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

        //------------- initialisation de la police texte - à mettre avant série ----
        //fontA = loadFont("Arial-Black-14.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(fontA, 14); // Initialise la police et sa taille (en pixels)

        //text("Client Processing actif !", 10, 60);


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


        //---- le bouton envoi chaine vers client réseau Processing
        networkButton=controlP5.addButton("networkButton",0,110,35,200,24); // initialise et ajoute un Button au ControlP5
        networkButton.setLabelVisible(true); // affichage des labels
        networkButton.setLabel("==> ENVOI reseau vers serveur " + ipServeur); // fixe label du bouton
        networkButton.setColorActive(color(255,0,0)); // fixe la couleur active
        networkButton.setColorForeground(color(0,255,255)); // fixe couleur avant

        //======== Initialisation Objets Textfield =========


        //---- champ texte saisie chaine
        networkText=controlP5.addTextfield("networkText",10,10,300,20); // initialise et ajoute un Textfield au ControlP5
        networkText.setAutoClear(false); // autoeffacement après return
        networkText.setValue(chaineEnvoiNetwork); // initialise Texte du champ
        networkText.setLabelVisible(true); // affichage des labels
        networkText.setLabel("Saisir chaine"); // fixe label
        networkText.setColorLabel(bleu); // fixe la couleur label
        networkText.setColorActive(color(255,0,0)); // fixe la couleur active
        networkText.setColorForeground(color(0,255,255)); // fixe couleur avant


//------------- initialisation objet Client réseau ----
  // 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("Client : Connexion du client Processing.....");



} // fin fonction Setup

// XXXXXXXXXXXXXXXXXXXXXX Fonction Draw XXXXXXXXXXXXXXXXXXXX

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

     if (clientNetwork.available() > 0) { // si des caractères sont disponibles en provenance du réseau
     //while (clientNetwork.available() > 0) { // si des caractères sont disponibles en provenance du réseau
        inStringFromServerNetwork= clientNetwork.readString();
       //inStringFromServerNetwork= clientNetwork.readStringUntil(10);
       if (inStringFromServerNetwork!=null) {
         //println("10.Réception client Processing <== serveur réseau : ");
         print( inStringFromServerNetwork);
       } // fin si inStringFromServer!=null

      } // fin if client avalaible>0


    //---- code à exécuter à intervalle régulier = envoi requete valueLive si mode Live Actif
    if ((frameCount%nbFrame)==0) { // pour exécution à intervalle régulier

      if(flagModeLive) { // si mode live actif

          clientNetwork = new Client(this, ipServeur, portNetwork); // pour réseau local sur port 5905

          //----- envoie la chaine vers le Serveur Réseau ----
          clientNetwork.write("valueLive\n"); //--- envoie une chaine vers le Serveur  suivie d'un saut de ligne
          print("?");

        } // if flagModeLive

    } // if frameCount%nbFrame

} // fin de la fonction draw()

// XXXXXXXXXXXXXXXXXXXXXX Autres Fonctions XXXXXXXXXXXXXXXXXXXXXX


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

//---- evenement bouton envoi chaine

void networkButton(int theValue) { // fonction évènement Button de meme nom - reçoit la valeur

        println("Client : Evènement envoiButton");

        //--- réinitialiser connexion avant chaque envoi ++
        clientNetwork = new Client(this, ipServeur, portNetwork); // pour réseau local sur port 5905
        println("Client : Connexion du client Processing....au serveur");

        //----- envoie la chaine vers le Serveur Réseau ----
        clientNetwork.write(networkText.getText()+"\n"); //--- envoie une chaine vers le Serveur  suivie d'un saut de ligne
        print("3. Envoi Client Processing ==> Serveur Réseau : ");
        print(networkText.getText()+"\n");
        delay(100); // entre deux envois

       //networkText.setValue(""); // vide le champ texte

        //--- active le mode live
        if (match(networkText.getText(),"modeLive")!=null) {
        flagModeLive=true;
        }

        //--- désactive le mode live
        if (match(networkText.getText(),"stopLive")!=null) {
        flagModeLive=false;
        }

} // fin evènement bouton envoi


// ------ gestion évènement Textfield ------

//---- evenement champ texte network

public void networkText(String theText) { // fonction évènement Textfield de meme nom - déclenché par return - reçoit la chaine

        //println("Evènement CheminText avec valeur = "+theText);

        chaineEnvoiNetwork=theText; // mémorise le contenu du champ

        //println("Le chemin est :"+chaineEnvoi);

} // fin evènement champ texte chemin fichier



//XXXXXXXXXXXXXXXXXX Fin du programme XXXXXXXXXXXXXXXXX