Pages: [1]   Go Down
Author Topic: [Resolu] Communication arduino <-> processing via port USB  (Read 643 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 21
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Bien le bonjours à tous les Arduinautes !

Voila je rencontre quelques difficultés depuis avant hier avec la fonction Serial pour faire communiquer Arduino avec un programme processing sur le port USB.
Je vous explique mon "projet". J'ai voulu découvrir le language processing et de tests en expérimentation j'en suis arrivé à coder un jeu du Pong (dont je suis plutôt content soit dit en passant  smiley-cool ).
Après ça j'ai eu la bonne idée de faire discuter le jeux du pong avec mon arduino d'une façon très simple via une LED RGB : si je joueur gagne la LED est allumé en vert, si l'ordinateur gagne la LED est éclairé en rouge et si le score est ex aequo, celle-ci est illuminé en bleu (On est d'accord ça sert à rien, d’autant plus que je jeux du Pong affiche déjà le score, mais cela me semblais être un bon entraînement  smiley-lol ).

Le problème que j'ai se situe sur l'utilisation de la bibliothèque  Serial, je me suis appuyé sur cet exemple pour m'aider : http://www.mon-club-elec.fr/pmwiki_mon_club_elec/pmwiki.php?n=MAIN.ArduinoExpertSerieDepuisPCSliderPWMVarieLED

Malheureusement comme vous devez vous en douter, cela ne se passe pas comme prévu  smiley-fat

Bon je vais commencer par vous partager mon code arduino et la partie de mon code processing qui gère la communication série et je vous explique juste ensuite ce qu'il se passe.

Voici pour la partie Arduino :
Code:
const int rouge = 2;
const int vert = 3;
const int bleu = 4;
int led = 3;

int octetReception = 0;
long nombreReception = 0;
long nombreReception0 = 0;
String chaineReception = "";

void setup()
{
  pinMode(rouge,OUTPUT);
  pinMode(vert,OUTPUT);
  pinMode(bleu,OUTPUT);
  
  digitalWrite(rouge, LOW);
  digitalWrite(vert, LOW);
  digitalWrite(bleu, LOW);
  
  Serial.begin(115200);
  Serial.print(octetReception);
}

void loop()
{
  if(Serial.available()==true)
  {
    led = etat();
    if (led == 1)
    {
      digitalWrite(rouge, HIGH);
      digitalWrite(vert, LOW);
      digitalWrite(bleu, LOW);
    }
    else if (led == 2)
    {
      digitalWrite(vert, HIGH);
      digitalWrite(rouge, LOW);
      digitalWrite(bleu, LOW);
    }
    else if (led == 3)
    {
      digitalWrite(bleu, HIGH);
      digitalWrite(rouge, LOW);
      digitalWrite(vert, LOW);
    }
    else
    {
      //rien
    }
  }
  else
  {
  }
}

int etat()
{
int octetRecu = 0;
int etat = 3; //par defaut le score est de 0/0 donc LED en bleu
  
  while (Serial.available()>0)  //Tant que le port série reçoit des données
  {
    octetRecu = Serial.read();  //stock l'octet reçu dans la variable
    Serial.print(octetRecu);
    if (octetRecu == 10)    //si octetRecu corespond au saut de ligne en ASCII, on sort de la boucle while
    {
      break;
    }
    else
    {
      if(octetRecu = 97)  //97 = a en ASCII
      {
        etat = 1;
      }
      else if (octetRecu = 98)  //98 = b en ASCII
      {
        etat = 2;
      }
      else if (octetRecu = 99)  //99 = c en ASCII
      {
        etat = 3;
      }
      else
      {
        //Eh bah rien ne se passe !
      }
    }
  }
  return(etat);
}

Et le petit bout de processing qui gère la liaison série :
Code:
 import processing.serial.*;
  Serial portCom;

void setup()
{
  println(Serial.list());
  portCom = new Serial(this,Serial.list()[1],115200);
  portCom.bufferUntil('\n');
}

void led()
{
  if(changementScore == 1)
  {
    if(scoreIA > scoreJoueur)
    {
      portCom.write(str(char('a'))+"\n");
      changementScore = 0;
      println("envoie a");
    }
    else if(scoreIA < scoreJoueur)
    {
      portCom.write(str(char('b'))+"\n");
      changementScore = 0;
      println("envoie b");
    }
    else if(scoreIA == scoreJoueur)
    {
      portCom.write(str(char('c'))+"\n");
      changementScore = 0;
      println("envoie c");
    }
    else
    {
      portCom.write(str(char('c'))+"\n");
      changementScore = 0;
      println("envoie truc bizard");
    }
  }
  else
  {
    //rien
  }
}

Voila alors le code arduino s'initialise bien (la LED s'allume par défaut en bleu comme prévu) par contre rien ne se passe lorsque le score change. Suite a pas mal de test, la liaison série semble bien se faire (j'avais fait un if(Serial.available()==true) ==> faire changer la LED de couleur, et la LED change bien de couleur lorsque je lance le code processing du Pong) de plus le "Serial.print(octetRecu);" que j'ai placé dans le code arduino pour qu'il me montre un peut ce qu'il reçoit renvoi presque toujours des "ÿ" alors que je m'attendrais à voir apparaitre la lettre a, b ou c, ou peut être la valeur décimale de la table ASCII d'une de ces trois lettres ...  

Je vous avoue que je me sent totalement frustré de ne pas trouvé la solution surtout vu le nombre important d'exemple de communication sur le port USB que l'on trouve sur internet.  smiley-sweat

Si quelqu'un avait une idée de ce qui pose problème, je lui en serait très reconnaissant !

PS : Je ne vous ai pas partagé le code complet de mon jeu Pong pour des histoires de visibilité du problème, mais si jamais il vous intéresse, dites le moi  smiley-surprise

Cordialement

Maskim
« Last Edit: December 17, 2012, 01:07:46 pm by Maskim » Logged

France
Offline Offline
Faraday Member
**
Karma: 38
Posts: 3531
There is an Arduino for that
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
ce qu'il reçoit renvoi presque toujours des "ÿ" alors que je m'attendrais à voir apparaitre la lettre a, b ou c,
Problème de vitesse? en même temps personnellement, j'éviterais le 115200 bauds avec un arduino. Tu devrais commencer avec une vitesse plus faible.

Code arduino
Code:
if(Serial.available()==true)
à remplacer par ça
Code:
if(Serial.available()>0)

« Last Edit: December 17, 2012, 11:17:49 am by fdufnews » Logged

Ales
Offline Offline
Faraday Member
**
Karma: 39
Posts: 3641
Do or DIY
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Alors déjà " if(Serial.available()==true) " ça s'utilise pas vraiment parce que ça peut porter à confusion. Ecrit soit "if(Serial.available())" soit "if(Serial.available()>=1)".

Ensuite toujours mettre un petit delay à la réception, le temps que le buffer se remplisse. La comme y'a qu'un char je pense pas que ça changera quelque chose mais c'est une bonne habitude à prendre que de mettre un petit "delay(5);".

Ensuite c'est un peu l'usine à gaz ton code, tu utilises des fonctions qui sont pas forcement pertinente. Moi j'aurais fait :

Code:
const int rouge = 2;
const int vert = 3;
const int bleu = 4;

void setup()
{
  pinMode(rouge,OUTPUT);
  pinMode(vert,OUTPUT);
  pinMode(bleu,OUTPUT);
  
  digitalWrite(rouge, LOW);
  digitalWrite(vert, LOW);
  digitalWrite(bleu, LOW);
  
  Serial.begin(115200);
}

void loop()
{
  if(Serial.available())
  {
    char Buffer = Serial.read()
    if (Buffer == 'a')
    {
      digitalWrite(rouge, HIGH);
      digitalWrite(vert, LOW);
      digitalWrite(bleu, LOW);
    }
    if (Buffer == 'b')
    {
      digitalWrite(vert, HIGH);
      digitalWrite(rouge, LOW);
      digitalWrite(bleu, LOW);
    }
    if (Buffer == 'c')
{
       digitalWrite(bleu, HIGH);
      digitalWrite(rouge, LOW);
      digitalWrite(vert, LOW);
    }  
    }
}
  

Logged


Offline Offline
Newbie
*
Karma: 0
Posts: 21
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Effectivement B@tto, avec ton code, tout fonctionne parfaitement  smiley-slim
J'était persuadé que l'arduino ne pouvait pas tester directement un caractère reçu sur le Serial mais que l'on était obligé de passé par la valeur ASCII du caractère.
C'est clair que à côté mon code faisait vraiment usine à gaz  smiley-mad
Bon au moins je me doutait bien que le problème se situait côté Arduino et pas Processing.

En tout cas merci, tu m'auras appris une méthode bien plus simple  smiley-yell

Cordialement

Maskim
 
Logged

Ile-de-France (92 sud), France
Offline Offline
Edison Member
*
Karma: 24
Posts: 2055
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Alors déjà " if(Serial.available()==true) " ça s'utilise pas vraiment parce que ça peut porter à confusion. Ecrit soit "if(Serial.available())" soit "if(Serial.available()>=1)".

Effectivement, ca ne peut pas marcher parce que retourne Serial.available() est le nombre de caractère dispo et non pas un booléen.

Par ailleurs dans le cas général, on évite généralement toute comparaison a TRUE.
Si le résultat d'une fonction est un boolean, on utilise la valeur de la fonction directement :
Code:
if ( toto.test() ) // retourne FALSE ou non-FALSE (~= TRUE)
Soit on compare à FALSE par égalité ou non égalite
Code:
if ( toto.test() != false )

Pourquoi ? parce que le C ne définit pas de manière unique la valeur TRUE : Toute valeur différent de FALSE (0) est TRUE !
Logged

Barbuduino: Arduino sur Breadboard & VinciDuino: Clone Leonardo // WR703: Mini-routeur hacké // LauchPad MSP430 et Stellaris // Panda II Arduino-like .NetMF sous VisualC#
RTFC: Read That F.....g Code / RTFD: Read That F.....g Doc / RTFDS: Read That F.....g DataSheet / RTFS: Read That F.....g Schematic / Wot da ya wanna D.I.Y. today ?

Pages: [1]   Go Up
Jump to: