Pages: [1] 2   Go Down
Author Topic: Serial libraries avec Processing >> Arduino  (Read 1988 times)
0 Members and 1 Guest are viewing this topic.
Geneva
Offline Offline
Faraday Member
**
Karma: 24
Posts: 3171
Yoplait... le pt'it suisse
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

J'essaie de faire une interface Processing pour configurer l'aéroquad.

Lorsque la carte reçoit un caractère, elle renvoie un string, Exemple :

Processing envoi "L", Arduino envoi 0.20,0.20,0.500

Si j'envoie un caractère en solo, pas de problème, par contre si j'envoie une série de caractère différents je devrais avoir ça :

Processing envoi "L", Arduino envoi 0.20,0.20,0.500
processing envoi "Q", Arduino envoi -1,-1,1,-525,-527,-757,0,0,0.00,0.00
Processing envoi "R", Arduino envoi -2,0,2,-426,-467,-679
et ainsi de suite....

Et ce n'est pas ce que j'obtiens... j'ai plutôt ça :

Code:
Q 0,0,0,-527,-529,-756,0,0,0.00,0
L .00

L 0.20,0.20,0.50,

Q -1,0,1,-523,-530,-756,0,0,0.00,0.00

L 0.20,0.20,0.50,

Q 0,-1,-1,-522,-531,-759,0,0,0.00,0.00

Q 0.20,0.20,0.50,

Q -1,0,-1,-526,-527,-758,0,0,0.00,0.00

Q 0.20,0.20,0.50,

L -1,-1,-1,-525,-530,-759,0,0,0.00,0.00

L 0.20,0.20,0.50,

L -1,-1,0,-522,-527,-755,0,0,0.00,0.00

L 0.20,0.20,0.50,

Q -1,-1,1,-525,-527,-757,0,0,0.00,0.00

Q 0.20,0.20

avec ce code test :

Code:
import processing.serial.*;
Serial myPort;
char send_char;
String portName;
void setup()
{
  size(490, 200);
  background(51);
  frame.setResizable(true);
  println(Serial.list());
  String portName = Serial.list()[3];
  myPort = new Serial(this, portName, 115200);
}

void draw()
{ myPort.clear();
  new Serial(this, portName, 115200);
  send_char='Q';
  myPort.write(send_char); // envoi un caractere a l'arduino
  while (myPort.available() > 0) {
    String inBuffer = myPort.readString();  
    if (inBuffer != null) {
      print (send_char+" ");
      println(inBuffer);
    }
    myPort.clear();
  }
new Serial(this, portName, 115200);
  send_char='L';
  myPort.write(send_char); // envoi un caractere a l'arduino
  while (myPort.available() > 0) {
    String inBuffer = myPort.readString();  
    if (inBuffer != null) {
      print (send_char+" ");
      println(inBuffer);
    }
    myPort.clear();
  }
}

(Serial libraries)

Comment est ce que je peux faire pour pouvoir changer de caractère et que ça match à chaque fois avec le string entrant ?
« Last Edit: April 27, 2010, 03:15:39 pm by jfs » Logged

MacBook intel core 2 duo  os X snow Leopard 10.6<br/> eMac PPc G4  os X Leopard 10.5<br/>powerbook G4 os X Leopard 10.5
imac PPC G3 os X Pa

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

Je connais pas très bien processing mais comme c'est à peu près la même histoire dans tous les languages : peut-être faut-il rajouter des delay le temps que l'arduino ait le temps de réagir ? Parce que la si je comprend bien ton code, tu envois le caractère et de suite après tu guettes le buffer d'entrée.
Logged


Geneva
Offline Offline
Faraday Member
**
Karma: 24
Posts: 3171
Yoplait... le pt'it suisse
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

J'ai essayé avec des delay et des boucles for et le problème persiste.
Le bout de code que j'ai mis est simplement un test, celui que j'ai pour le quadricoptère est un peu plus conséquent .

Lorsque je change de caractère avec des boutons-radios l'affichage de mes vumètres est figé pendant 10-15 secondes.
lorsque je change le caractère destiné à l'Arduino, il ne match pas immédiatement avec le string reçu.
Logged

MacBook intel core 2 duo  os X snow Leopard 10.6<br/> eMac PPc G4  os X Leopard 10.5<br/>powerbook G4 os X Leopard 10.5
imac PPC G3 os X Pa

Geneva
Offline Offline
Faraday Member
**
Karma: 24
Posts: 3171
Yoplait... le pt'it suisse
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

J'ai fait des test en utilisant myPort.stop() et apparemment on ne peut réouvrir un port depuis la boucle draw(), donc a la deuxième lecture du port ça plante.

d'après ce que je constate , ce serait les buffers qui ne se vident pas assez vite et qui serait relu une deuxième fois.

comment faire pour être sur que le buffer est bien vide, j'ai déjà tester avec myPort.clear() et il n'y a pas de changement.
« Last Edit: April 28, 2010, 08:29:30 am by jfs » Logged

MacBook intel core 2 duo  os X snow Leopard 10.6<br/> eMac PPc G4  os X Leopard 10.5<br/>powerbook G4 os X Leopard 10.5
imac PPC G3 os X Pa

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

Mais si je comprend tu ouvres et ferme ton port dans la boucle ?? Pourquoi ? Une fois que tu l'as ouvert dans ton setup tu n'as juste qu'à surveiller l'envoi et la réception dans le draw.
Logged


Geneva
Offline Offline
Faraday Member
**
Karma: 24
Posts: 3171
Yoplait... le pt'it suisse
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Normalement je ne fais pas d'ouverture fermeture dans la boucle... là il se trouve que dans le code publié, je vide le buffer (myport.clear()), mai je ne le ferme jamais.
Par contre si je ne refais pas "new Serial(this, portName, 115200);" à chaque fois ça ne fonctionne pas du tout (dans cet exemple).

le port est ouvert dans le setup et ne peut pas être réouvert depuis la boucle draw() (d'après mes essais).
Logged

MacBook intel core 2 duo  os X snow Leopard 10.6<br/> eMac PPc G4  os X Leopard 10.5<br/>powerbook G4 os X Leopard 10.5
imac PPC G3 os X Pa

Geneva
Offline Offline
Faraday Member
**
Karma: 24
Posts: 3171
Yoplait... le pt'it suisse
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Bon j'ai peut-être trouvé ce qui ne va pas.

Est ce possible de limiter la longueur d'un float en forçant à deux chiffres après la virgule, par exemple pour 0.234567, de le tronquer à 0.234 ?
« Last Edit: April 29, 2010, 12:10:03 am by jfs » Logged

MacBook intel core 2 duo  os X snow Leopard 10.6<br/> eMac PPc G4  os X Leopard 10.5<br/>powerbook G4 os X Leopard 10.5
imac PPC G3 os X Pa

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

L'idée saugrenue  qui me vient comme ça : tu multiplis par 1 000 000 tu passes en integer, tu divises par 1 000, tu repasses en float et tu redivises par 1000.

Mais j'imagine qu'il doit bien y avoir une autre soluce mais la journée est longue aujourd'hui ...  ;D
Logged


Geneva
Offline Offline
Faraday Member
**
Karma: 24
Posts: 3171
Yoplait... le pt'it suisse
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

J'ai fait comme ça :

Code:
String []send_value_filter=new String[7];
      send_value_filter[0]=str(send_char);
      send_value_filter[1]=nf(gyro_Filter,1,2);  //%2.f,nombre
      send_value_filter[2]=";";
      send_value_filter[3]=nf(accel_Filter,1,2);
      send_value_filter[4]=";";
      send_value_filter[5]=nf(time_Filter,1,2);
      send_value_filter[6]=";";
      String joinedsend_value_filter=join(send_value_filter,"");
      String[]list=split (joinedsend_value_filter,',');
      
      myPort.write(list[0]+"."+list[1]+"."+list[2]+"."+list[3]);

parce qu'avec la fonction nf() ça me met une "," dans mon nombre et ça ne passe qu'avec un ".".... :smiley et ce ne sont pas les floats avec plus de deux chiffres après la virgule qui me font foirer mon appli.... smiley-razz mais ce n'est pas le but de ce post.

J'aimerais tout de même trouver une solution pour que le buffer entrant match avec le caractère sortant.
« Last Edit: April 29, 2010, 11:21:32 am by jfs » Logged

MacBook intel core 2 duo  os X snow Leopard 10.6<br/> eMac PPc G4  os X Leopard 10.5<br/>powerbook G4 os X Leopard 10.5
imac PPC G3 os X Pa

Geneva
Offline Offline
Faraday Member
**
Karma: 24
Posts: 3171
Yoplait... le pt'it suisse
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Je fais au plus simple avec une incrémentation de A+1 pour comptabiliser le nombre de cycle, avec ce code :

Code:
void setup()
{
  size(490, 200);
  background(51);
  frame.setResizable(true);

  println(Serial.list());
  String portName = Serial.list()[3];
  myPort = new Serial(this, portName, 115200);
}

void draw()
{
  frame.setSize(800, 500);
  smooth();
  strokeWeight(2.0);
  stroke(0, 102, 153);
  background(150);
receive_value_filter();
println(A+"sortie "+gyro+" "+accel+" "+time);
send_value_filter();
A++;
}


void receive_value_filter()
{
 

    for(int a=0; a<=20;a=a+1){
      myPort.write(str('L')); // envoi un caractere a l'arduino
      while (myPort.available() > 0) {
        String inBuffer = myPort.readString();
        if (inBuffer != null) {
          String[] nums = split(inBuffer, ',');
          if((nums.length)==3){  // 6 pour'R"
            for (int i = 0; i <=2; i = i+1) {
              filtre_value[i] = nums[i];
            }
            myPort.clear();
            gyro_Filter=float(filtre_value[0]+"f");
              accel_Filter=float( filtre_value[1]+"f");
              time_Filter=float( filtre_value[2]+"f");
            gyro=float(filtre_value[0]);
            accel=float(filtre_value[1]);
            time=float(filtre_value[2]);
         }
        }
      }
  }
  
}


void send_value_filter()
{
      gyro_Send=0.2;
      accel_Send=0.3;
      time_Send=0.4;
  String send=('K'+str(gyro_Send)+';'+str(accel_Send)+';'+str(time_Send)+';'+';');
      for(int a=0; a<=40;a=a+1){
      myPort.write(send); // envoi un caractere a l'arduino
      }
      myPort.clear();
}

Le premier nombre affiché avant sortie est le nombre de cycle pour que l'arduino commence à afficher les valeurs que je lui envoi :

Code:
30.0sortie 0.2 0.2 0.5
31.0sortie 0.2 0.2 0.5
32.0sortie 0.2 0.2 0.5
33.0sortie 0.2 0.2 0.5
34.0sortie 0.2 0.3 0.4
35.0sortie 0.2 0.3 0.4
36.0sortie 0.2 0.3 0.4

Donc 34 boucles avec chaque fois 40 envois pour que mes valeurs passent  :o

J'ai du faire une erreurs  quelque part, alors si quelqu'un vois un truc qui cloche... ou bien aurait une piste à explorer  smiley-wink
« Last Edit: May 01, 2010, 08:04:54 am by jfs » Logged

MacBook intel core 2 duo  os X snow Leopard 10.6<br/> eMac PPc G4  os X Leopard 10.5<br/>powerbook G4 os X Leopard 10.5
imac PPC G3 os X Pa

Geneva
Offline Offline
Faraday Member
**
Karma: 24
Posts: 3171
Yoplait... le pt'it suisse
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Je fais des essais avec serialEvent()

On dirait que ça marche pas trop mal. Je vais creuser un peu  smiley-wink
« Last Edit: May 01, 2010, 03:57:58 pm by jfs » Logged

MacBook intel core 2 duo  os X snow Leopard 10.6<br/> eMac PPc G4  os X Leopard 10.5<br/>powerbook G4 os X Leopard 10.5
imac PPC G3 os X Pa

Geneva
Offline Offline
Faraday Member
**
Karma: 24
Posts: 3171
Yoplait... le pt'it suisse
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Avec une liaison série en continu, le chip Ftdi a tendance  à chauffer, je lui ai rajouté un radiateur.
Logged

MacBook intel core 2 duo  os X snow Leopard 10.6<br/> eMac PPc G4  os X Leopard 10.5<br/>powerbook G4 os X Leopard 10.5
imac PPC G3 os X Pa

Geneva
Offline Offline
Faraday Member
**
Karma: 24
Posts: 3171
Yoplait... le pt'it suisse
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Voici une petite vidéo de ce que donnent mes essais de liaisons série :




lors du lancement de l'application, les valeurs contenues dans la carte sont lues et les sliders sont alignés par rapports à ces dernières.
Ensuite, les valeurs sélectionnées par les sliders sont envoyées à l'arduino, tant que les valeurs de la carte ne sont pas égales aux sliders, le point reste rouge et les valeurs des sliders sont renvoyées à l'Arduino.

Lorsque les valeurs sont équivalentes entre la carte et les sliders, le point devient vert. Tant que l'équivalence est avérée seule une lecture de la carte 2-3 fois par seconde subsiste.

Voici mon code Processing :

Code:
import processing.serial.*;
import guicomponents.*;

GWSlider gyroSlider,accelSlider,timeSlider;
Serial myPort;
String portName;

PFont myFont;

float chrono=0;
float oldChrono=0;

float gyro=0;
float accel=0;
float time=0;

String []filtre_value = new String[4];
float gyro_Filter = 0;
float accel_Filter = 0;
float time_Filter = 0;

String inString;
float gyro_receive= 0;
float accel_receive = 0;
float time_receive = 0;

String send;
float gyro_Send= 0;
float accel_Send = 0;
float time_Send = 0;

float A=1;
float Z=1;

int B=1;
int M=0;
int lf = 10;

char send_char;

boolean OK=false;

void setup()
{
  size(490, 200);
  background(51);
  frame.setResizable(true);

  println(Serial.list());
  String portName = Serial.list()[3];
  myPort = new Serial(this, portName, 115200);

  gyro_Filter=float("1.5f");
  gyroSlider = new GWSlider(this,"blue18px",500,80,260);  //Gyro filter slider
 // gyroSlider.setInertia(2);
  gyroSlider.setValueType(GWSlider.DECIMAL);
  gyroSlider.setLimits(1.5f, 0f, 3.0f);
  gyroSlider.setRenderValueLabel(true);

  accel_Filter=float("1.5f");
  accelSlider = new GWSlider(this,"blue18px",500,200,260);
 // accelSlider.setInertia(2);
  accelSlider.setValueType(GWSlider.DECIMAL);
  accelSlider.setLimits(1.5f, 0f, 3.0f);
  accelSlider.setRenderValueLabel(true);

  time_Filter=float("1.5f");
  timeSlider = new GWSlider(this,"blue18px",500,320,260);
 // timeSlider.setInertia(2);
  timeSlider.setValueType(GWSlider.DECIMAL);
  timeSlider.setLimits(1.5f, 0f, 3.0f);
  timeSlider.setRenderValueLabel(true);
  
  myPort.bufferUntil(lf);
}

void draw()
{
  frame.setSize(800, 500);
  smooth();
  strokeWeight(2.0);
  background(150);
  
  if (A==0){
    receive_value_filter();
    A=20;
   }
  
     if(B<=10){
       while (B<=8) {
    receive_value_filter();
    if (inString != null) {
    String[] nums = split(inString, ',');
    if((nums.length)==3){  // 6 pour'R"
      gyro  = float(nums[0]);
      accel = float(nums[1]);
      time  = float(nums[2]);
    } B++;
  }set_slider_value();
  }
   B=20;}
  A--;
    if(OK==false){fill(240,30,0);
   ellipse(600, 40, 35, 35);}
   else{fill(0,240,100);
   ellipse(600, 40, 35, 35);}
   noFill();
   fill(80,80,80);
  text(Z+" valeurs reçues: " + inString, 200,50);
  text(str(OK), 200,80);
   text(Z+" valeurs envoyées: " + send, 200,110);

  if (inString != null) {
    String[] nums = split(inString, ',');
    if((nums.length)==3){  // 6 pour'R"
      gyro  = float(nums[0]);
      accel = float(nums[1]);
      time  = float(nums[2]);
    }
  }

  Z++;
   if((gyro!=gyro_Send)||(accel!=accel_Send)||(time!=time_Send)){
    OK=false;
    M++;
  }
  else{
     OK=true;
    M=0;
  }
  if(M>=10){
    OK=false;
    send_value_filter();
     M=0;
   }
  else{ return; }
}

void set_slider_value(){
  
  gyroSlider.setValue(gyro);
 
  accelSlider.setValue(accel);

  timeSlider.setValue(time);

  gyro_Filter =  gyro;
  accel_Filter = accel;
  time_Filter =  time;
}


void handleSliderEvents(GSlider slider) {

  if ((mouseY >65) && (mouseY< 95)){
    gyro_Filter = slider.getValuef();
  }  
  else if ((mouseY >185) && (mouseY< 215)){
    accel_Filter=slider.getValuef();
  }
  else if ((mouseY >305) && (mouseY< 335)){
    time_Filter=slider.getValuef();
  }  
  else{
    return;
  }
   slider.getValuef());
   gyro_Send=float(int(gyro_Filter*100))/100;
  accel_Send=float(int(accel_Filter*100))/100;
  time_Send=float(int(time_Filter*100))/100;
}


void receive_value_filter()
{
 char send_char='L';
  myPort.write('L');
  myPort.clear();
}


void send_value_filter()
{
  gyro_Send=float(int(gyro_Filter*100))/100;
  accel_Send=float(int(accel_Filter*100))/100;
  time_Send=float(int(time_Filter*100))/100;
  send=('K'+str(gyro_Send)+';'+str(accel_Send)+';'+str(time_Send)+';'+';');
  for(int a=0; a<=40;a=a+1){
    myPort.write(send);
  }
  myPort.clear();
}


void serialEvent(Serial p)
{
  inString = p.readString();
  myPort.clear();
}

En l'état, ça ne fonctionne pas de façon très "stable", les valeurs ne sont pas enregistrées immédiatement dans la carte donc le point reste au rouge pendant de long moment et parfois la liaison est rapide et le point devient vert en 1-2 seconde.

Si quelqu'un à des corrections à me suggérer, c'est vraiment bien venu  smiley-wink
« Last Edit: May 03, 2010, 03:29:13 pm by jfs » Logged

MacBook intel core 2 duo  os X snow Leopard 10.6<br/> eMac PPc G4  os X Leopard 10.5<br/>powerbook G4 os X Leopard 10.5
imac PPC G3 os X Pa

près de Toulouse
Offline Offline
Newbie
*
Karma: 0
Posts: 29
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

bien que n'y connaissant rien , j'ai remarqué en regardant la vidéo que le temps de réaction été plus long lorsque tu diminues une valeur peut être que je me trompe :-/
Logged

Geneva
Offline Offline
Faraday Member
**
Karma: 24
Posts: 3171
Yoplait... le pt'it suisse
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

C'est aléatoire.
Logged

MacBook intel core 2 duo  os X snow Leopard 10.6<br/> eMac PPc G4  os X Leopard 10.5<br/>powerbook G4 os X Leopard 10.5
imac PPC G3 os X Pa

Pages: [1] 2   Go Up
Jump to: