Le EeePC-Bot est un projet innovant qui permet de contrôler des moteurs par joystick via un réseau wifi entre un eeePC embarqué et un PC fixe. Ce projet offre une solution pratique et abordable pour les applications robotiques et autres projets de contrôle à distance. Il permet aux utilisateurs de contrôler leurs robots à distance et de les programmer pour effectuer des tâches spécifiques. Grâce à ce projet, les utilisateurs peuvent facilement contrôler leurs robots à distance et leur donner des instructions précises.
EeePC-Bot : Commande des moteurs par Joystick via réseau wifi entre eeePC embarqué et PC fixe.
Intro
- Sur cette page, je vous propose de réaliser une chaine de 4 programmes qui vont permettre de commander le robot à l’aide d’un Joystick par wifi. Le joystick envoie une valeur fixe pour la vitesse. Le but de cette page est surtout de faire la « preuve du concept » et donne un résultat sympa puisque l’on contrôle le robot sans fil à distance tout en ayant un retour vidéo de ce que voit le robot.
- Le robot utilise également la synthèse vocale et les bruitages sonores qui sont donc également déclenchés par le joystick par wifi ! Un point intéressant : on utilise ici la capacité d’exprimer la valeur de la variable vitesse par synthèse vocale : « vitesse à 39 pour cent »… sympa !
- Pour mettre en place la chaîne des 4 programmes nécessaires à la mise en place de cette connexion par réseau wifi, il faut procéder par étape et avec un minimum de rigueur. Pour autant, çà n’est pas très compliqué.
Etapes préalables à la mise en place du réseau wifi entre les 2 cartes Arduino.
La mise en place du réseau wifi entre les 2 PC nécessite :
- 2 PC (ou eeePC) avec la distribution Gnu/Linux Ubuntu installée. Pour plus d’info, voir ici : http://doc.ubuntu-fr.org/installation et/ou http://doc.ubuntu-fr.org/asus_eee_pc Même si je ne l’ai pas testée, il n’y a pas de raison pour que la procédure ne fonctionne pas sous les autres OS.
- la mise en place d’une connexion des 2 PC sur un routeur wifi configuré en DHCP (attribution automatique des adresses ip). Le routeur peut être une Livebox ou tout autre routeur wifi, avec ou sans accès internet (pas utilisé ici).
- de tester le réseau entre les 2 PC et de récupérer les adresses ip du PC serveur et du PC client. On s’est assuré notamment que le réseau fonctionne bien en réalisant un ping entre les 2 PC utilisés.
- d’ouvrir sur chaque PC le port utilisé pour communiquer entre les PC ainsi que sur le routeur.
Ici, nous utilisons le port 5905.
Une connaissance minimale en structure de réseau est nécessaire ici :
- savoir ce qu’est une adresse ip, un sous-masque réseau, un réseau
- savoir ce qu’est un port
- savoir ce qu’est un routeur, ce qu’est l’attribution des adresses ip en DHCP.
Rien d’inaccessible cependant !
Le schéma fonctionnel de la chaîne de connexion à réaliser
- Voici le schéma fonctionnel de la chaine globale de programmes utilisée :
Ce que nous allons faire ici…
- la carte Arduino « serveur » va :
- interpréter la chaine reçue en provenance du réseau,
- va réaliser l’action demandée et réémettre en réponse à la chaine reçue une chaine de caractère vers le « serveur » Processing pour génération du son voulu en synthèse vocale, via le port série côté « serveur ».
- l’interface Processing « serveur » va :
- envoyer la chaine reçue vers la carte Arduino « serveur » via le port série côté « serveur »
- interpréter les chaines reçues sur le port série pour déclencher la synthèse vocale ou la lecture des fichiers sons voulus.
- le « client » Processing va envoyer la chaine reçue vers l’interface Processing « serveur » via le réseau wifi. Le rôle de ce programme est essentiellement un rôle de relais.
- la carte Arduino « client » va émettre en fonction de la position du Joystick une chaine de caractères vers le « client » Processing via le port Série côté client.
- A chaque étape, les consoles des interfaces Processing afficheront des messages attestant du parcours de la chaine de caractère entre les 4 programmes.
- On rappelle qu’il faut :
- que le réseau wifi soit opérationnel entre les 2 PC (voir ci-dessus – étapes préalables ou ici : Etapes préalables à la mise en place du réseau wifi entre les 2 cartes Arduino.)
- connaître l’adresse ip du serveur (via ifconfig dans une console sur le PC serveur).
- ouvrir sur chaque PC et sur le routeur wifi le port utilisé pour communiquer entre les PC. Ici, nous utilisons le port 5905.
Etape 1 : le programme Arduino « serveur » (sur la carte Arduino distante)
Ce que fait ce programme
- Ce programme :
- reçoit une chaine de caractère sur le port série correspondant à l’action à exécuter et interprète cette chaine.
- envoie une chaine de caractères vers le eeePC du robot pour synthèse vocale et bruitages sonores voulus
Code du programme Arduino « serveur »
- Ce code est le même que celui de la page : Commande des moteurs par chaine de caractères via Terminal série e/o Processing + annonce sonore des actions par synthèse vocale et bruitages sonores
- Programmer ce code dans votre carte Arduino « serveur » (carte Arduino distante) :
// 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 : 11/4/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 ? ———
/*
Contrôle des moteurs et des différents mouvements (avant, arriere, stop, tourne droite, etc…)
à partir d’une chaîne de caractères reçue sur le port série.
Déclenche des messages vocaux en synthèse vocale
Déclenche des bruitages sonores par lecture de fichier son
*/
// — Fonctionnalités utilisées —
// Utilise la connexion série matérielle vers le PC
// Utilise / fonctionne avec une interface Processing coté PC
// Utilise une carte d’interface moteurs CC DFRobot 2A
// ——– Circuit à réaliser ———
// La connexion série matérielle vers le PC utilise les broches 0 et 1 (via le câble USB)
// Connexion de l’interface DFRobot 2A Moteur CC sur les broches de la carte Arduino :
// Connecter broche de sens du moteur 1 sur la broche 4
// Connecter broche de vitesse du moteur 1 sur la broche 5
// Connecter broche de sens du moteur 2 sur la broche 7
// Connecter broche de vitesse du moteur 2 sur la broche 6
// /////////////////////////////// 1. Entête déclarative ///////////////////////
// A ce niveau sont déclarées les librairies incluses, les constantes, les variables, les objets utiles…
// — Déclaration des constantes —
// — Inclusion des librairies —
// — Déclaration des constantes utiles —
const int AVANT=1; // constante sens moteur
const int ARRIERE=0; // constante sens moteur
const int STOP=0; // constante vitesse moteur
// — Déclaration des constantes des broches E/S numériques —
//— moteur 1 est le moteur Gauche
const int sensMoteur1=4; // Constante pour la broche 4
const int vitesseMoteur1=5; // Constante pour la broche 5
const int sensMoteurGauche=4; // Constante pour la broche 4
const int vitesseMoteurGauche=5; // Constante pour la broche 5
//—- moteur 2 est le moteur droit
const int vitesseMoteur2=6; // Constante pour la broche 6
const int sensMoteur2=7; // Constante pour la broche 7
const int vitesseMoteurDroit=6; // Constante pour la broche 6
const int sensMoteurDroit=7; // Constante pour la broche 7
// — Déclaration des constantes des broches analogiques —
// — Déclaration des variables globales —
int octetReception=0; // variable de stockage des valeurs reçues sur le port Série
String chaineReception=« »; // déclare un objet String vide pour reception chaine
String chaineTest=« »; // déclare un objet String pour opération sur la chaine recue
int valeur=0; // variable utile
long param=0; // paramètre transmis
// — Déclaration des objets utiles pour les fonctionnalités utilisées —
// ////////////////////////// 2. FONCTION SETUP = Code d’initialisation //////////////////////////
// La fonction setup() est exécutée en premier et 1 seule fois, au démarrage du programme
void setup() { // debut de la fonction setup()
// — ici instructions à exécuter 1 seule fois au démarrage du programme —
// ——- Initialisation fonctionnalités utilisées ——-
Serial.begin(115200); // initialise connexion série matérielle à 115200 bauds
// IMPORTANT : régler le terminal côté PC avec la même valeur de transmission
// ——- Broches en sorties numériques ——-
pinMode (sensMoteur1,OUTPUT); // Broche sensMoteur1 configurée en sortie
pinMode (vitesseMoteur1,OUTPUT); // Broche vitesseMoteur1 configurée en sortie
pinMode (vitesseMoteur2,OUTPUT); // Broche vitesseMoteur2 configurée en sortie
pinMode (sensMoteur2,OUTPUT); // Broche sensMoteur2 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 ——-
} // 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()
//— fichiers sons espeaker disponibles :
// test_des_moteurs.wav
// stop_moteur.wav
// moteur_gauche_en_marche_avant.wav
// moteur_droit_en_marche_avant.wav
// moteur_gauche_en_marche_arriere.wav
// moteur_droit_en_marche_arriere.wav
// je_tourne_a_droite.wav
// je_recule.wav
// j_avance.wav
// — ici instructions à exécuter par le programme principal —
//—- code type réception chaine sur le port série —
while (Serial.available()>0) { // tant qu’un octet en réception
octetReception=Serial.read(); // Lit le 1er octet reçu et le met dans la variable
if (octetReception==10) { // si Octet reçu est le saut de ligne
Serial.println (« Chaine recue= »+chaineReception); // affiche la chaine recue
analyseChaine(chaineReception); // appelle la fonction d’analyse de la chaine en réception
chaineReception=« »; //RAZ le String de réception
break; // sort de la boucle while
}
else { // si le caractère reçu n’est pas un saut de ligne
chaineReception=chaineReception+char(octetReception); // ajoute le caratère au String
}
} // fin tant que octet réception
//—– une fois que le saut de ligne est reçu, on sort du While et on se positionne ici
//chaineReception= » »;
//————- fin analyse chaine —————
//while(1); // stop loop
} // fin de la fonction loop() – le programme recommence au début de la fonction loop sans fin
// ********************************************************************************
// ////////////////////////// FONCTIONS DE GESTION DES INTERRUPTIONS ////////////////////
// ////////////////////////// AUTRES FONCTIONS DU PROGRAMME ////////////////////
//————- fonction d’analyse de la chaine reçue sur le port série —-
//————— testInstruction : test si instruction de la forme instruction(xxx) ————
boolean testInstruction(String chaineTest) { // reçoit chaine et renvoie true si instruction valide
long posRef=chaineTest.length();// position de référence pour analyse (xxx)
if (chaineReception.substring(0,posRef)==chaineTest) { // si reçoit l’instruction chaineTest(000)
// nb substring : dernier caractere exclu
Serial.print(« Arduino va executer : « );
Serial.print(chaineTest); // affiche
param=stringToLong(chaineReception.substring(posRef,posRef+3)); // extraction valeur 3 chiffres à partir caractères
Serial.print(param); // affiche
if (chaineReception.substring(posRef+3,posRef+4)==« ) ») { // si fermeture parenthèse = instruction valide
Serial.println(« ) »); // affiche
Serial.println(« Instruction valide ! »); // affiche
return(true); // renvoie true si instruction valide
} // fin si fermeture parenthèse
else {
Serial.println(« Instruction invalide ! »); // affiche
return(false); // renvoie false si instruction invalide
} // fin else
} // fin si reçoit l’instruction chaineTest(000)
} // fin fonction testInstruction
//——————- fin test instruction ————
//———— analyseChaine —————
void analyseChaine(String chaineRecue) { // fonction d’analyse de la chaine recue
// —- analyse de la chaine recue sur le port Série —-
chaineReception=chaineReception.trim(); // enlève les espaces
//xxxxxxxxxxxxxxxxxxx instructions sans paramètres xxxxxxxxxxxx
if (chaineReception==« arret() ») { // si instruction reçue
arret(); // exécute instruction si valide
joueSon(« r2d2_1.mp3 »,true); // joue son et attend fin son
parleSon(« Arret des moteurs », true); //synthèse vocale de la chaine et attend fin son
}
//xxxxxxxxxxxxxxxxxxxx instructions avec paramètres xxxxxxxxxxxxxxx
//————– test instruction enAvant ———–
if (testInstruction(« enAvant(« )==true) { // si instruction reçue valide
joueSon(« r2d2_3.mp3 »,true); // joue son et attend fin son
parleSon(« J’avance – vitesse à « + String(int(100*param/255))+ » pour cent », true); //synthèse vocale de la chaine et attend fin son
enAvant(param); // exécute instruction
} // fin test enAvant(xxx)
//————– test instruction enArriere ———–
if (testInstruction(« enArriere(« )==true) { // si instruction reçue valide
joueSon(« r2d2_3.mp3 »,true); // joue son et attend fin son
parleSon(« Je recule – vitesse à « +String(int(100*param/255))+ » pour cent », true); //synthèse vocale de la chaine et attend fin son
enArriere(param); // exécute instruction
} // fin test enArriere(xxx)
//————– test instruction tourne Droite ———–
if (testInstruction(« tourneDroite(« )==true) { // si instruction reçue valide
joueSon(« r2d2_4.mp3 »,true); // joue son et attend fin son
parleSon(« Je tourne à droite – vitesse à « +String(int(100*param/255))+ » pour cent », true); //synthèse vocale de la chaine et attend fin son
tourneDroite(param); // exécute instruction
} // fin test tourneDroite(xxx)
//————– test instruction tourne Gauche ———–
if (testInstruction(« tourneGauche(« )==true) { // si instruction reçue valide
joueSon(« r2d2_4.mp3 »,true); // joue son et attend fin son
parleSon(« Je tourne à gauche – vitesse à « +String(int(100*param/255))+ » pour cent », true); //synthèse vocale de la chaine et attend fin son
tourneGauche(param); // exécute instruction
} // fin test tourneDroite(xxx)
} // —————- fin fonction analyse chaine ———————-
// ———- 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 ————
//———— fonction déclenche lecture fichier coté PC ——–
void joueSon(String fichierSon, boolean retour) { // fonction joue son à partir nom fichier – si retour=true, attend caractère H fin son
Serial.println(fichierSon); //—– Message série pour message sonore dans Processing
if (retour==true) { // si doit attendre fin son
while (Serial.available()==0); // attend arrivée d’une réponse
while(Serial.read()!=‘H’); // attend un H renvoyé par Processing à la fin son
} // fin if retour==true
} // —————- fin joueSon ————–
//————- fonction parleSon() pour synthèse vocale ——-
void parleSon(String texte, boolean retour) { // envoie chaine pour synthese vocale sur le port Série – si retour=true, attend caractère H fin son
String envoi=« espeak= »+texte+« = »; // chaine comprise entre 2 =
Serial.println(envoi);
if (retour==true) { // si doit attendre fin son
while (Serial.available()==0); // attend arrivée d’une réponse
while(Serial.read()!=‘H’); // attend un H renvoyé par Processing à la fin son
} // fin if retour==true
} // fin parle son
//————- fonctions gestion moteurs robot —————
//— fonction controle moteur Droit
void moteurDroit(int sens, int vitesse) { // sens = 0 en arriere, sens = 1 en avant,
analogWrite(vitesseMoteurDroit,vitesse); // génère une impulsion PWM sur la broche de vitesse du moteur
digitalWrite(sensMoteurDroit,sens); // Marche arriere
}
//— fonction controle moteur Gauche
void moteurGauche(int sens, int vitesse) { // sens = 0 en arriere, sens = 1 en avant,
analogWrite(vitesseMoteurGauche,vitesse); // génère une impulsion PWM sur la broche de vitesse du moteur
digitalWrite(sensMoteurGauche,sens); // Marche arriere
}
//— fonction stop = arret complet
void arret() {
analogWrite(vitesseMoteurGauche,STOP); // génère une impulsion PWM sur la broche de vitesse du moteur
analogWrite(vitesseMoteurDroit,STOP); // génère une impulsion PWM sur la broche de vitesse du moteur
}
//—- fonction tourne à Droite
void tourneDroite (int vitesse) {
moteurGauche(AVANT, vitesse);
moteurDroit(ARRIERE, vitesse);
}
//—- fonction tourne à Gauche
void tourneGauche (int vitesse) {
moteurGauche(ARRIERE, vitesse);
moteurDroit(AVANT, vitesse);
}
//—- fonction en arriere
void enArriere (int vitesse) {
moteurGauche(ARRIERE, vitesse);
moteurDroit(ARRIERE, vitesse);
}
//—- fonction en avant
void enAvant (int vitesse) {
moteurGauche(AVANT, vitesse);
moteurDroit(AVANT, vitesse);
}
//—- vitesse
void vitesse (int vitesse) { // modifie la vitesse sans modifier le sens
analogWrite(vitesseMoteurGauche,vitesse); // génère une impulsion PWM sur la broche de vitesse du moteur
analogWrite(vitesseMoteurDroit,vitesse); // génère une impulsion PWM sur la broche de vitesse du moteur
}
// ////////////////////////// Fin du programme ////////////////////
- Bien, jusque là, rien de très compliqué… On continue..
Etape 2 : le programme Processing « serveur » (sur le PC distant)
Ce que fait ce programme
- l’interface Processing « serveur » va :
- envoyer la chaine reçue vers la carte Arduino « serveur » via le port série côté « serveur »
- interpréter les chaines reçues sur le port série pour déclencher la synthèse vocale ou la lecture des fichiers sons voulus.
Code du serveur Processing
- Ce programme correspond au programme de cette page (EeePC-Bot : Contrôle des moteurs depuis une interface Processing avec annonce sonore par synthèse vocale et bruitages sonores) complétée de la gestion du réseau (voir : Principe de déploiement d’une connexion entre 2 cartes Arduino via 2 PC en réseau wifi)
// généré avec le générateur de code Processing
// www.mon-club-elec.fr
// par X. HINAULT – Avril 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 Serveur réseau
// 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
// Utilise la ligne de commande programmée
// Utilise mplayer pour jouer des sons (Ubuntu)
// Utilise espeaker pour la synthèse vocale des sons (Ubuntu)
/*
> Reçoit chaine de caractère sur le réseau
> Envoie la chaine de caractère vers Arduino
> Reçoit la chaine renvoyée par Arduino sur le port série
et l’affiche dans la console.
La chaine de texte reçue est synthétisée si le format est valide.
Le fichier son voulu est joué en fonction de la chaine de caractères reçue
à l’aide d’une ligne de commande programmée qui lance le logiciel système Mplayer (Ubuntu)
Permet également l’envoi vers Arduino pour tests d’une chaîne saisie dans un champ texte.
*/
// XXXXXXXXXXXXXXXXXXXXXX ENTETE DECLARATIVE XXXXXXXXXXXXXXXXXXXXXX
// inclusion des librairies utilisées
import processing.serial.*; // importe la librairie série processing
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
//— pour le réseau —
String str1 = « machaine »; // déclare un objet String (chaine de caractère)
String chaineEnvoiSerie = « »; // déclare un objet String (chaine de caractère)
String chaineEnvoiNetwork = « »; // déclare un objet String (chaine de caractère)
String chaineEnvoi = « »; // déclare un objet String (chaine de caractère)
String[] command ; // pour envoi ligne de commande espeak
String nomFichier=« »; // variable pour nom du fichier son à jouer
//String cheminFichier= »/home/hinault/Bureau/mes_sons/ »; // chemin complet avec / de fin
String cheminFichier=« /home/xavier/Bureau/mes_sons/ »; // chemin complet avec / de fin
//— chemin où se trouvent les fichiers sons – à adapter selon les cas —
// — port Série —
Serial serialServerBoard; // Création objet désignant le port série de la carte Arduino « serveur »
String inStringFromServerBoard; // pour réception chaine en provenance carte Arduino « serveur »
// — objet Client Réseau —
Client clientNetwork; // déclaration d’un objet client réseau (pour réception données depuis client réseau)
// — objet Serveur Réseau —
Server serverNetwork; // déclaration d’un objet Serveur réseau = cet ordinateur
String inStringFromClientNetwork; // pour réception chaine en provenance Client réseau
// — interface GUI —
ControlP5 controlP5; // déclare un objet principal de la librairie GUI controlP5
Button envoiButton; // déclare objet Button
Textfield chaineText; // 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);
//—- variables utiles réseau —-
boolean clientConnected=false; // variable témoin connexion client active
//String ipClient= »192.168.0.3″; // ip du client (pas du serveur!) sur réseau wifi local
String ipClient=« 127.0.0.1 »; // ip du client sur boucle locale
//int portNetwork=5905; // pour reseau wifi
int portNetwork=12345; // port sur boucle locale
// 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(30);// Images par seconde
// — initialisation fenêtre de base —
size(400, 130); // 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]
//serialServerBoard = new Serial(this, Serial.list()[1], 115200); // Initialise une nouvelle instance du port Série – utilisé par la carte Arduino « serveur »
serialServerBoard = new Serial(this, « /dev/ttyUSB1 », 115200); // Initialise une nouvelle instance du port Série – utilisé par la carte Arduino « serveur »
serialServerBoard.bufferUntil(‘\n‘); // attendre arrivée d’un saut de ligne pour générer évènement série
//======== Initialisation Objets GUI ControlP5 =========
controlP5 = new ControlP5(this); // initialise l’objet principal de la librairie GUI controlP5
// typeObjet nomObjet=controlP5.addObjet(paramètres); // pour info : déclaration / initialisation possible en 1 ligne
// Textfield field = controlP5.addTextfield(« myWindowTextfield »,70,130,100,20); // exemple
//======== Initialisation Objets Button =========
//—- le bouton envoi chaine
envoiButton=controlP5.addButton(« envoiButton »,0,width–60,height–40,50,24); // initialise et ajoute un Button au ControlP5
envoiButton.setLabelVisible(true); // affichage des labels
envoiButton.setLabel(« ENVOI »); // fixe label du bouton
envoiButton.setColorActive(color(255,0,0)); // fixe la couleur active
envoiButton.setColorForeground(color(0,255,255)); // fixe couleur avant
//======== Initialisation Objets Textfield =========
//—- champ texte saisie chaine
chaineText=controlP5.addTextfield(« cheminText »,10,height–40,300,20); // initialise et ajoute un Textfield au ControlP5
chaineText.setAutoClear(false); // autoeffacement après return
chaineText.setValue(chaineEnvoi); // initialise Texte du champ
chaineText.setLabelVisible(true); // affichage des labels
chaineText.setLabel(« CHEMIN »); // fixe label
chaineText.setColorActive(color(255,0,0)); // fixe la couleur active
chaineText.setColorForeground(color(0,255,255)); // fixe couleur avant
//————- initialisation objet Serveur réseau —-
serverNetwork = new Server(this, portNetwork); // Ouvre un simple Serveur sur port
//serverNetwork = new Server(this, 5905); // Ouvre un simple Serveur 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
// info : l’adresse du serveur devra être utilisé par le client
println(« Serveur : Serveur réseau actif ! »);
} // fin fonction Setup
// XXXXXXXXXXXXXXXXXXXXXX Fonction Draw XXXXXXXXXXXXXXXXXXXX
void draw() { // fonction exécutée en boucle
//————- Code pour Serveur Réseau : Réception et renvoi série —-
clientNetwork = serverNetwork.available(); // l’objet client est un client connecté au serveur si il existe – renvoie null sinon
// available() différent de null seulement si client existe ET caractères disponibles
if (clientNetwork != null) { // si myClient existe
//————- réception de la chaine émise par le client réseau ———–
inStringFromClientNetwork = clientNetwork.readString(); // lit la chaine envoyée par le Client
print (« 4. Réception serveur Processing <== client Processing : « +inStringFromClientNetwork); // affiche la chaine reçue
//inStringClient = inStringClient.substring(0, inStringClient.indexOf(« \n »)); // Garde uniquement ce qui est avant le saut de ligne
//——— renvoi de la chaine sur le port Série de la carte Arduino serveur ——–
serialServerBoard.write(inStringFromClientNetwork); // envoie la chaine suivi saut ligne sur le port Série
print (« 5. Envoi Serveur Processing ==> serveur Arduino : « +inStringFromClientNetwork); // affiche la chaine envoyée
} // fin si client existe
} // fin de la fonction draw()
// XXXXXXXXXXXXXXXXXXXXXX Autres Fonctions XXXXXXXXXXXXXXXXXXXXXX
//————— Fonction de gestion Evènement Serveur = survient lorsque client se connecte ————
// Doc : The code inside serverEvent() is run when a new client connects to a server that has been created within the program.
void serverEvent(Server someServer, Client clientEntrant) { // la fonction reçoit l’objet serveur et un objet client de réception
if (clientEntrant != null) { // toujours le cas ici normalement car l’évènement survient quand un client se connecte
println(« Serveur : Un client s’est connecté avec l’adresse : « + clientEntrant.ip());
}
if (match(clientEntrant.ip(),ipClient)!=null) { // si l’adresse ip du client est celle attendue
println(« Serveur : Le client connecté est le client attendu (ip= « + clientEntrant.ip()+« ) ! »);
clientConnected=true; // mémorise connexion active
}
else {
println(« Serveur : Le client connecté n’est pas le client attendu ! »);
}
} //— fin gestion évènement serveur —-
//———— fonction de gestion de l’évènement Client = lorsque des caractères sont disponibles
// Doc : This function is called when a server sends a byte to an existing Client object.
void clientEvent(Client someClient) { // ne fonctionne que coté client ?
} // — fin de fonction de gestion de l’évènement client
//————- Fonction de gestion des évènements série —-
void serialEvent (Serial serialServerBoard) { // 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 inStringFromServerBoard = serialServerBoard.readStringUntil(‘\n‘); // chaine stockant la chaîne reçue sur le port Série
// saut de ligne en marque de fin
if (inStringFromServerBoard != null) { // si la chaine recue n’est pas vide
//———– messages de réception carte Arduino serveur —-
//inStringFromServerBoard = trim(inStringFromServerBoard); // enlève espace blancs de la chaine recue
//— si on a une réponse c’est que le serveur Arduino a bien reçu puis émis la chaine
println(« 6. Réception serveur Arduino <== Serveur Processing : « + inStringFromServerBoard); // affiche la chaine dans la console
println(« 7. Envoi serveur Arduino ==> Serveur Processing : « + inStringFromServerBoard); // affiche la chaine dans la console
// — réception réelle —
println(« 8. Réception serveur Processing <== serveur Arduino : « + inStringFromServerBoard); // affiche la chaine dans la console
print (inStringFromServerBoard); // affichage brut de la chaine recue
//xxxxxxxxxxxxxxxxxxxxxxxxxx Gestion du nom de fichier son xxxxxxxxxxxxxxxxxxxxxxxxxx
//———— analyse de la chaine reçue et sélection son ——–
//String nomFichier= » »; // String pour nom fichier
//—– tous les noms de fichiers suivants seront reconnus et lancés en lecture
//—— les fichiers doivent dans le répertoire de la variable cheminFichier (voir début programme)
if (match(inStringFromServerBoard,« r2d2_1.mp3 »)!=null) nomFichier=« r2d2_1.mp3 »; // test la chaine reçue et définit nom fichier son associé
if (match(inStringFromServerBoard,« r2d2_2.mp3 »)!=null) nomFichier=« r2d2_2.mp3 »; // test la chaine reçue et définit nom fichier son associé
if (match(inStringFromServerBoard,« r2d2_3.mp3 »)!=null) nomFichier=« r2d2_3.mp3 »; // test la chaine reçue et définit nom fichier son associé
if (match(inStringFromServerBoard,« r2d2_4.mp3 »)!=null) nomFichier=« r2d2_4.mp3 »; // test la chaine reçue et définit nom fichier son associé
if (match(inStringFromServerBoard,« r2d2_5.mp3 »)!=null) nomFichier=« r2d2_5.mp3 »; // test la chaine reçue et définit nom fichier son associé
if (match(inStringFromServerBoard,« lightsaber_turn_on.wav »)!=null) nomFichier=« lightsaber_turn_on.wav »; // test la chaine reçue et définit nom fichier son associé
//—- jeu de sons espeaker enregistrés —
if (match(inStringFromServerBoard,« moteur_gauche_en_marche_arriere.wav »)!=null) nomFichier=« moteur_gauche_en_marche_arriere.wav »; // test la chaine reçue et définit nom fichier son associé
if (match(inStringFromServerBoard,« test_des_moteurs.wav »)!=null) nomFichier=« test_des_moteurs.wav »; // test la chaine reçue et définit nom fichier son associé
if (match(inStringFromServerBoard,« stop_moteur.wav »)!=null) nomFichier=« stop_moteur.wav »; // test la chaine reçue et définit nom fichier son associé
if (match(inStringFromServerBoard,« moteur_gauche_en_marche_avant.wav »)!=null) nomFichier=« moteur_gauche_en_marche_avant.wav »; // test la chaine reçue et définit nom fichier son associé
if (match(inStringFromServerBoard,« moteur_droit_en_marche_avant.wav »)!=null) nomFichier=« moteur_droit_en_marche_avant.wav »; // test la chaine reçue et définit nom fichier son associé
if (match(inStringFromServerBoard,« moteur_droit_en_marche_arriere.wav »)!=null) nomFichier=« moteur_droit_en_marche_arriere.wav »; // test la chaine reçue et définit nom fichier son associé
if (match(inStringFromServerBoard,« je_tourne_a_droite.wav »)!=null) nomFichier=« je_tourne_a_droite.wav »; // test la chaine reçue et définit nom fichier son associé
if (match(inStringFromServerBoard,« je_tourne_a_gauche.wav »)!=null) nomFichier=« je_tourne_a_gauche.wav »; // test la chaine reçue et définit nom fichier son associé
if (match(inStringFromServerBoard,« je_recule.wav »)!=null) nomFichier=« je_recule.wav »; // test la chaine reçue et définit nom fichier son associé
if (match(inStringFromServerBoard,« j_avance.wav »)!=null) nomFichier=« j_avance.wav »; // test la chaine reçue et définit nom fichier son associé
if (nomFichier!=« ») { // si une chaine valide a été reçue
joueSonMplayer(cheminFichier, nomFichier); // appelle la fonction lecture son avec mplayer – sous Ubuntu
//— signale à Arduino fin son
serialServerBoard.write(‘H’); // envoie le caractère H sur le port Série pour signaler fin son
nomFichier=« »; // RAZ nom fichier
} // fin si chaine valide pour lecture fichier son
//xxxxxxxxxxxxxxxxxxxxxxxx Gestion chaine texte pour espeak xxxxxxxxxxxxxxxx
if (match(inStringFromServerBoard,« espeak= »)!=null) { // si chaine contenant espeak= reçue
println(« Chaine espeak valide reçue ! « ); // debug
String[] chaines = split(inStringFromServerBoard, ‘=’); // sépare chaine par le signe =
println (chaines[0]); // chaine espeak
println (chaines[1]); // chaine à parler
if (chaines[1]!=« ») { // si une chaine valide a été reçue
direTexte (chaines[1]); // espeak la chaine extraite
//— signale à Arduino fin son
serialServerBoard.write(‘H’); // envoie le caractère sur le port Série
} // fin si list[1] pas vide
} // fin si chaine espeak
} // 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
}
//—- evenement bouton envoi chaine
void envoiButton(int theValue) { // fonction évènement Button de meme nom – reçoit la valeur
println(« Evènement envoiButton »);
serialServerBoard.write(chaineText.getText()+« \n« ); // envoie la chaine suivi saut ligne sur le port Série
print(« 5. Envoi Serveur Processing ==> serveur Arduino : « );
// print(« Envoi de la chaine : »);
print(chaineText.getText()+« \n« );
chaineText.setValue(« »); // vide le champ texte
} // fin evènement bouton envoi
// —— gestion évènement Textfield ——
//—- evenement champ texte chemin fichier
public void chaineText(String theText) { // fonction évènement Textfield de meme nom – déclenché par return – reçoit la chaine
//println(« Evènement CheminText avec valeur = « +theText);
chaineEnvoi=theText; // mémorise le contenu du champ
//println(« Le chemin est : »+chaineEnvoi);
} // fin evènement champ texte chemin fichier
//——————— fonction lecture son avec Mplayer —————
void joueSonMplayer(String cheminSon, String fichierSon) {
//—— code type pour jouer son avec mplayer par ligne commande (Ubuntu) —-
command = new String[3]; // tableau String pour la ligne de commande
// mplayer /home/hinault/Bureau/mes_sons/r2d2_2.mp3 -quiet
command[0] = « mplayer »;
command[1] = cheminSon+fichierSon;
command[2]=« -quiet »;
//— exécution de la ligne de commande (code Java)
try {
Process p = exec(command); // exécute la commande
//— récupère la sortie de la commande dans la console de Processing
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = null;
while ((line = in.readLine()) != null) {
System.out.println(line);
}//fin while
} // fin try
catch (IOException e) { // gestion exception
e.printStackTrace();
} // fin catch
} //——————— fin joueSonMplayer
//————- fonction d’appel à espeak par ligne de commande —–
void direTexte(String texte) {
// le paquet espeak doit etre installé sous Ubuntu (depuis la logithèque)
command = new String[8];
// espeak -v fr -s 140 « lecture texte espeak »
// espeak -v fr -s 80 -p 30 \ »moteur droit en marche avant\ »
command[0] = « espeak »;
command[1] = « -v »;
command[2]=« fr+m4 »;
// les voix sont dans /usr/share/espeak-data/voices/!v
// les variantes dispo sont : croak f1 f2 f3 f4 fast klatt klatt2 klatt3 m1 m2 m3 m4 m5 m6 m7 whisper
// pour utiliser une variante faire : espeak -ven+m3
command[3]=« -s »; // la vitesse
command[4]=« 120 »; // entre 30 et 200
command[5]=« -p »; // la tonalité
command[6]=« 40 »; // entre 0 et 99
command[7]=« \ »« +texte+« \ »« ; // le texte entre guillemets
// param bien : voix m4/vitesse 120/ tonalité =40
// param bien : voix m2 / vitesse 100 / Tonalité = 20
//— exécution de la ligne de commande
try {
Process p = exec(command); // exécute la commande
//— récupère la sortie de la commande dans la console de Processing
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = null;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
}
catch (IOException e) {
e.printStackTrace();
}
}
//XXXXXXXXXXXXXXXXXX Fin du programme XXXXXXXXXXXXXXXXX
Etape 3 : le programme Processing « client » (sur le PC local)
- Cette étape est « l’étape de vérité » qui va permettre de vérifier que la communication wifi fonctionne bien entre l’interface Processing serveur et l’interface Processing client.
Ce que fait ce programme
- Ce programme Processing fournit la communication entre le réseau wifi et la carte Arduino Client.
- Un champs texte permet d’envoyer une chaine de caractère de test vers le serveur Processing via le réseau.
Code processing « client »
- Ce code est à copier/coller dans une interface Processing sur le PC client. Il ne reste plus alors qu’à lancer le programme.
// généré avec le générateur de code Processing
// www.mon-club-elec.fr
// par X. HINAULT – Avril 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
/*
Envoie vers Arduino une chaîne saisie dans un champ texte.
Reçoit la chaine renvoyée par Arduino et l’affiche dans la console.
*/
// XXXXXXXXXXXXXXXXXXXXXX ENTETE DECLARATIVE XXXXXXXXXXXXXXXXXXXXXX
// inclusion des librairies utilisées
import processing.serial.*; // importe la librairie série processing
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 str1 = « machaine »; // déclare un objet String (chaine de caractère)
String chaineEnvoiSerie = « »; // déclare un objet String (chaine de caractère)
String chaineEnvoiNetwork = « »; // déclare un objet String (chaine de caractère)
// — port Série —
Serial serialClientBoard; // Création objet désignant le port série de la carte Arduino Client
// — 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
// — 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 serialButton; // déclare objet Button
Button networkButton; // déclare objet Button
Textfield serialText; // déclare des objets Textfield
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.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
// 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(30);// Images par seconde
// — 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 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]
serialClientBoard = new Serial(this, Serial.list()[0], 115200); // Initialise une nouvelle instance du port Série carte Arduino Client
//serialClientBoard = new Serial(this, « /dev/ttyUSB1 », 115200); // Initialise une nouvelle instance du port Série carte Arduino Client
serialClientBoard.bufferUntil(‘\n‘); // attendre arrivée d’un saut de ligne pour générer évènement série
//======== Initialisation Objets GUI ControlP5 =========
controlP5 = new ControlP5(this); // initialise l’objet principal de la librairie GUI controlP5
// typeObjet nomObjet=controlP5.addObjet(paramètres); // pour info : déclaration / initialisation possible en 1 ligne
// Textfield field = controlP5.addTextfield(« myWindowTextfield »,70,130,100,20); // exemple
//======== Initialisation Objets Button =========
//—- le bouton envoi chaine vers serveur Arduino port série
serialButton=controlP5.addButton(« serialButton »,0,110,35+60,200,24); // initialise et ajoute un Button au ControlP5
serialButton.setLabelVisible(true); // affichage des labels
serialButton.setLabel(« ==> ENVOI serie vers client Arduino »); // fixe label du bouton
serialButton.setColorActive(color(255,0,0)); // fixe la couleur active
serialButton.setColorForeground(color(0,255,255)); // fixe couleur avant
//—- 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 Processing »); // 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
serialText=controlP5.addTextfield(« serialText »,10,10+60,300,20); // initialise et ajoute un Textfield au ControlP5
serialText.setAutoClear(false); // autoeffacement après return
serialText.setValue(chaineEnvoiSerie); // initialise Texte du champ
serialText.setLabelVisible(true); // affichage des labels
serialText.setLabel(« Saisir chaine »); // fixe label
serialText.setColorLabel(bleu); // fixe la couleur label
serialText.setColorActive(color(255,0,0)); // fixe la couleur active
serialText.setColorForeground(color(0,255,255)); // fixe couleur avant
//—- 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
inStringFromServerNetwork= clientNetwork.readString();
println(« 10.Réception client Processing <== serveur Processing: « + inStringFromServerNetwork);
}
} // fin de la fonction draw()
// XXXXXXXXXXXXXXXXXXXXXX Autres Fonctions XXXXXXXXXXXXXXXXXXXXXX
//————- Fonction de gestion des évènements série —-
void serialEvent (Serial serialClientBoard) { // fonction appelée lors de la survenue d’un évènement série
// ******** Gestion de la valeur reçue sur le port série depuis la carte Arduino Client **********
String inStringFromClientBoard = serialClientBoard.readStringUntil(‘\n‘); // chaine stockant la chaîne reçue sur le port Série depuis la carte Arduino Client
// saut de ligne en marque de fin
if (inStringFromClientBoard != null) { // si la chaine recue n’est pas vide
// print (inString); // affichage brut de la chaine recue
inStringFromClientBoard = trim(inStringFromClientBoard); // enlève espace blancs de la chaine recue
//int inByte_brut=int(inStringClientBoard); // conversion valeur reçue en valeur numérique entiere
//float inByte = float(inStringClientBoard); // conversion valeur reçue en valeur numérique décimale
//— si une chaine est reçue, alors l’étape 1 a obligatoirement eu lieu…
println(« 1. Envoi Client Arduino ==> client Processing : « + inStringFromClientBoard); // affiche la chaine dans la console
// réception effective de la chaine
println(« 2. Réception Client Processing <== client Arduino : « + inStringFromClientBoard); // affiche la chaine dans la console
//—– renvoie la chaine reçue vers le Serveur Réseau —-
clientNetwork.write(inStringFromClientBoard+« \n« ); //— envoie une chaine vers le Serveur suivie d’un saut de ligne
println(« 3. Envoi Client Processing ==> Serveur Processing : « + inStringFromClientBoard); // affiche la chaine dans la console
delay(1000); // entre deux envois
} // 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
}
//—- evenement bouton envoi chaine
void networkButton(int theValue) { // fonction évènement Button de meme nom – reçoit la valeur
println(« Client : Evènement envoiButton »);
//—– 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 Processing : « );
print(networkText.getText()+« \n« );
delay(100); // entre deux envois
networkText.setValue(« »); // vide le champ texte
} // fin evènement bouton envoi
//—- evenement bouton envoi chaine serie
void serialButton(int theValue) { // fonction évènement Button de meme nom – reçoit la valeur
println(« Client : Evènement serialButton »);
serialClientBoard.write(serialText.getText()+« \n« ); // envoie la chaine suivi saut ligne sur le port Série
print(« 5. Envoi Client Processing ==> client Arduino : « );
print(serialText.getText()+« \n« );
serialText.setValue(« »); // vide le champ texte
} // 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
//—- evenement champ texte serie
public void serialText(String theText) { // fonction évènement Textfield de meme nom – déclenché par return – reçoit la chaine
//println(« Evènement CheminText avec valeur = « +theText);
chaineEnvoiSerie=theText; // mémorise le contenu du champ
//println(« Le chemin est : »+chaineEnvoi);
} // fin evènement champ texte chemin fichier
//XXXXXXXXXXXXXXXXXX Fin du programme XXXXXXXXXXXXXXXXX
Test du programme
- Une fois que le programme est lancé (sur le poste client), on doit voir :

- De son côté, le serveur indique qu’il a détecté une connexion d’un client et précise si l’adresse ip du client est la bonne :

- Si vous obtenez bien ces messages, c’est que votre connexion wifi fonctionne bien entre les 2 PC !! Le simple fait que les 2 interfaces fonctionnent sans message d’erreur au lancement confirme que la connexion wifi est opérationnelle.
- Moi, je ne m’en lasse pas de cet accès distant au bureau du PC serveur depuis le PC client : trop top ! La procédure à suivre est ici : Configurer un accès bureau distant entre 2 PC sous Ubuntu
- Maintenant, on va pouvoir tester l’envoi d’une chaîne via le réseau wifi : saisir la chaine « arret() » ce qui doit déclencher un bruitage et un message de synthèse vocale côté robot.
Etape 4 (enfin !) : le programme Arduino « client » (sur la carte Arduino locale)
Ce que fait ce programme
- la carte Arduino « client » va émettre en fonction de la position du Joystick une chaine de caractères vers le « client » Processing via le port Série côté client.
Code du programme Arduino « client »
- Ce programme est à programmer dans la carte Arduino « client » :
// 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 : 1/4/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 envoie une chaine de caractère sur le port série
en fonction de la position d’un joystick
*/
// — Fonctionnalités utilisées —
// Utilise la connexion série matérielle vers le PC
// Utilise la carte d’extension Arduino (shield) Joystick + BP x 2
// ——– Circuit à réaliser ———
// La connexion série matérielle vers le PC utilise les broches 0 et 1 (via le câble USB)
// Enficher la carte d’extension Arduino (shield) Joystick + BP x 2 sur la carte Arduino
// les connexions sont réalisées broche à broche entre le module et la carte Arduino
// /////////////////////////////// 1. Entête déclarative ///////////////////////
// A ce niveau sont déclarées les librairies incluses, les constantes, les variables, les objets utiles…
// — Déclaration des constantes —
// — Inclusion des librairies —
// — Déclaration des constantes utiles —
const int APPUI=LOW; // constante pour tester état BP
// — Déclaration des constantes des broches E/S numériques —
const int bpRouge=3; // Constante pour la broche 3
const int bpBleu=4; // Constante pour la broche 4
const int bpJoystick=5; // Constante pour la broche 5
// — Déclaration des constantes des broches analogiques —
const int axe1Joystick=0; // Constante pour la broche analogique 0
const int axe2Joystick=1; // Constante pour la broche analogique 1
// — Déclaration des variables globales —
int positionAxe1=0; // Variable pour acquisition résultat brut de conversion analogique numérique axe 1 Joystick
int positionAxe2=0; // Variable pour acquisition résultat brut de conversion analogique numérique axe 2 Joystick
// — Déclaration des objets utiles pour les fonctionnalités utilisées —
// ////////////////////////// 2. FONCTION SETUP = Code d’initialisation //////////////////////////
// La fonction setup() est exécutée en premier et 1 seule fois, au démarrage du programme
void setup() { // debut de la fonction setup()
// — ici instructions à exécuter 1 seule fois au démarrage du programme —
// ——- Initialisation fonctionnalités utilisées ——-
Serial.begin(115200); // initialise connexion série matérielle à 115200 bauds
// IMPORTANT : régler le terminal côté PC avec la même valeur de transmission
// ——- Broches en sorties numériques ——-
// ——- Broches en entrées numériques ——-
pinMode (bpRouge,INPUT); // Broche bpRouge configurée en entrée
pinMode (bpBleu,INPUT); // Broche bpBleu configurée en entrée
pinMode (bpJoystick,INPUT); // Broche bpJoystick configurée en entrée
// ——- Activation si besoin du rappel au + (pullup) des broches en entrées numériques ——-
// Les BP du shield Joystick + BPx2 dispose d’un rappel au plus sur le shield
// ——- Initialisation des variables utilisées ——-
// ——- Codes d’initialisation utile ——-
} // fin de la fonction setup()
// ********************************************************************************
////////////////////////////////// 3. FONCTION LOOP = Boucle sans fin = coeur du programme //////////////////
// la fonction loop() s’exécute sans fin en boucle aussi longtemps que l’Arduino est sous tension
void loop(){ // debut de la fonction loop()
// — ici instructions à exécuter par le programme principal —
// ———– code type Shield Arduino Joystick + BPx2 ——
//—– lecture position Joytstick
positionAxe1=analogRead(axe1Joystick); // acquisition conversion analogique numérique sur broche analogique axe 1
positionAxe2=analogRead(axe2Joystick); // acquisition conversion analogique numérique sur broche analogique axe 2
//———— analyse axe 1 —————-
if (positionAxe1>900) { // si vers le haut
Serial.println(« enAvant(150) »); //
delay(500); //anti-rebond
}
if (positionAxe1<150) { // si vers le bas
Serial.println(« enArriere(150) »); //
delay(500); //anti-rebond
}
//———— analyse axe 2 —————-
if (positionAxe2>900) { // si vers le haut
Serial.println(« tourneDroite(100) »); //
delay(500); //anti-rebond
}
if (positionAxe2<150) { // si vers le bas
Serial.println(« tourneGauche(100) »); //
delay(500); //anti-rebond
}
//—- lecture état des BP du shield Joystick
if (digitalRead(bpRouge)==APPUI) { // si appui BP rouge
Serial.println(« arret() »); //
delay(1000); //anti-rebond
}
if (digitalRead(bpBleu)==APPUI) { // si appui BP
Serial.println(« appui BP Bleu »); //
delay(1000); //anti-rebond
}
if (digitalRead(bpJoystick)==APPUI) { // si appui BP joystick
Serial.println(« arret() »); //
delay(1000); //anti-rebond
}
//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 ////////////////////
// ////////////////////////// Fin du programme ////////////////////
Test du programme
- Ce programme est très facile à tester : il suffit d’ouvrir une fenêtre Terminal Arduino sur le PC client
Et aussi
- Vous lancer la webcam sur le eeePC du robot : comme çà, vous voyez ce qu’il voit quand il se ballade. Voir ici : Configurer un accès bureau distant entre 2 PC sous Ubuntu
Articles similaires:
- … d’une carte Arduino vers une autre carte Arduino via deux interfaces Processing Client/Serveur sur 2 PC connectés en réseau wifi.
- http://web.archive.org/web/20210804223007/http://www.mon-club-elec.fr/pmwiki_mon_club_elec/pmwiki.php?n=MAIN.ArduinoExpertWifi
- « Symbiose numérique » Arduino / PC
- Allumer une LED à partir d’une chaine avec paramètre reçue sur le port Série
- Saisir une chaîne dans un champ texte et l’envoyer vers le port Série
Articles Liés
- Javascript : Graphique Dygraphs simple
Le Javascript est un langage de programmation très populaire et puissant qui permet aux développeurs…
- Javascript : Afficher 6 widgets graphiques fournis par une librairie graphique externe.
Le Javascript est un langage de programmation très populaire qui permet aux développeurs de créer…
- Javascript : Graphique Dygraphs : afficher date à partir unixtime
Le langage de programmation Javascript est très populaire et est utilisé pour créer des applications…