Aller au contenu


Photo
- - - - -

Arduino : Reception chaine de caractère entière


  • Veuillez vous connecter pour répondre
17 réponses à ce sujet

#1 bypbop

bypbop

    Habitué

  • Membres
  • PipPip
  • 259 messages
  • Gender:Male
  • Location:Lille

Posté 18 septembre 2012 - 11:12

Bonjour à tous,

J'avance doucement sur mon projet de robot je m'attaque au code des moteurs AVANCE RECULE STOP ...
J'essaye de recevoir une chaine de caractère que j'envoie via le terminal arduino mais je n'arrive qu'a recevoir un caractere ...

// Moteur A
int dir1PinA = 13;
int dir2PinA = 12;
int speedPinA = 10;

// Moteur B
int dir1PinB = 11;
int dir2PinB = 8;
int speedPinB = 9;

// Vitesse Moteur
int speed;

void setup() {
  Serial.begin(57600);

  pinMode(dir1PinA, OUTPUT);
  pinMode(dir2PinA, OUTPUT);
  pinMode(speedPinA, OUTPUT);
  pinMode(dir1PinB, OUTPUT);
  pinMode(dir2PinB, OUTPUT);
  pinMode(speedPinB, OUTPUT);

  speed = 80;
}

void loop() 
{
  while (Serial.available())   
  {
    byte commande = Serial.read();
    switch (commande)
    {
    case 'L':
      analogWrite(speedPinA, speed);
      analogWrite(speedPinB, speed);
      digitalWrite(dir1PinA, LOW);
      digitalWrite(dir2PinA, HIGH);
      digitalWrite(dir1PinB, HIGH);
      digitalWrite(dir2PinB, LOW);
      break;
    case 'STOP':
      digitalWrite(dir1PinA, LOW);
      digitalWrite(dir2PinA, LOW);
      digitalWrite(dir1PinB, LOW);
      digitalWrite(dir2PinB, LOW);
      break;
    default:
      Serial.print("commande : ");
      Serial.print(commande);
      Serial.println(" non reconnue.");
      break;
    }
  }

}


Ma commande L fonctionne mais pas la STOP ...


Pourquoi cela ?

Cordialement,
bypbop

#2 seb03000

seb03000

    Pilier du forum

  • Membres
  • PipPipPipPipPip
  • 1 192 messages
  • Gender:Male
  • Location:Loins dérrière toi.
  • Interests:La Robotique , plus l'informatique

Posté 18 septembre 2012 - 11:46

Le critère ( STOP ) est trop long pour ta console terminal aisé ( S ) a la place de ( STOP ).

@Cordialement.

#3 bypbop

bypbop

    Habitué

  • Membres
  • PipPip
  • 259 messages
  • Gender:Male
  • Location:Lille

Posté 18 septembre 2012 - 11:52

Le critère ( STOP ) est trop long pour ta console terminal aisé ( S ) a la place de ( STOP ).

@Cordialement.


c'est juste à cause de la console alors ?

Cordialement,
bypbop

#4 seb03000

seb03000

    Pilier du forum

  • Membres
  • PipPipPipPipPip
  • 1 192 messages
  • Gender:Male
  • Location:Loins dérrière toi.
  • Interests:La Robotique , plus l'informatique

Posté 18 septembre 2012 - 11:57

Personnellement j'ai fait pas mal d'aisé avec des critères comme ( STOP ) , ( AVANCE ) , est d'autre , cela na pas fonctionné , donc je pence pour ma par que

cela fonctionne que pas une lettre , de plus sur le forum il y a ( il me semble ) un sujet sur se poins la.

#5 R1D1

R1D1

    Modérateur et Membre passionné

  • Modérateur
  • PipPipPipPipPip
  • 1 147 messages
  • Gender:Male
  • Location:Autriche

Posté 19 septembre 2012 - 12:57

Regarde bien le type de données que renvoie Serial.read, regarde les types byte et char. Tu devrais comprendre le problème. L'exemple de read est une base pas mal pour faire ce que tu veux, avec quelques adaptations. Je viens de faire un petit code qui récupérait l'envoie d'une chaîne et déclenchait des fonctions selon certains caractères spéciaux, ça marche à peu près nickel (il y a juste la remise à zéro de la chaîne qui est un peu ... sale ... faudra vérifier comment les destructeurs de classe sont gérés).
R1D1 - Calculo Sed Ergo Sum -- en ce moment, M.A.R.C.E.L.
Avatar tiré du site bottlebot

#6 bypbop

bypbop

    Habitué

  • Membres
  • PipPip
  • 259 messages
  • Gender:Male
  • Location:Lille

Posté 19 septembre 2012 - 01:33

Bonjour ca passe deja mieux avec un char ;-)

Par contre à mon avis une boucle s'impose sur la reception des caractères.
Tu peux mettre ton exemple de code sur ce post ?

Cordialement,
bypbop

#7 bypbop

bypbop

    Habitué

  • Membres
  • PipPip
  • 259 messages
  • Gender:Male
  • Location:Lille

Posté 19 septembre 2012 - 02:13

Re alors je viens de faire ce bout de code ca a l air de tourner ...
J'affiche la chaine de caractère commande sur le retour chariot
while (Serial.available())   
  {
    octetR = Serial.read();
    i++;
     
    
    if (octetR ==10){
    Serial.println(commande);
    i=0;
    commande="";
    delay(50);
    break;
    } 
    else {
    
    commande=commande+char(octetR);
    }
    }

Qu'en penses tu ?

Cordialement,
bypbop

#8 Black Templar

Black Templar

    Membre

  • Membres
  • PipPipPipPipPip
  • 1 430 messages
  • Gender:Male
  • Location:Lille

Posté 19 septembre 2012 - 06:41

Mieux :)

commande=commande+char(octetR);

Euuu ça marche ça ? non, je ne pense pas.
commande[i-1]=(char)octetR;

Mon site internet : http://ferdinandpiette.com/


#9 Astondb8

Astondb8

    Pilier du forum

  • Membres
  • PipPipPipPipPip
  • 1 111 messages
  • Gender:Male
  • Location:Paris

Posté 19 septembre 2012 - 07:59

Il est normal que tu n'ai qu'un seul carractere.
Le sérail ne peut envoyer qu'un seul carractere à la fois.
Tu dois donc créer une boucle pour afficher la suite de ta chaîne.

for (int i = 0; i < 6; i++){
Serial.println(myStrings[i]);
delay(500);
}
}

Ensuite pour les caractères spéciaux vas voir ça
http://arduino.cc/fr/Main/ChainesCaracteres

Cdlt
Yves

 


#10 R1D1

R1D1

    Modérateur et Membre passionné

  • Modérateur
  • PipPipPipPipPip
  • 1 147 messages
  • Gender:Male
  • Location:Autriche

Posté 19 septembre 2012 - 08:39

Tu es sur la bonne voie :)

Voici mon extrait de code :
//int incomingByte = 0;   // for incoming serial data
char incomingByte;   // for incoming serial data --> correction du Space Marine
String message;

void setup()
{
  Serial.begin(9600);     // opens serial port, sets data rate to 9600 bps
}

void loop()
{

  // send data only when you receive data:
  if (Serial.available() > 0)
  {
   // Serial.print("Old Message : ");
   // Serial.println(message);
    // read the incoming byte:
    incomingByte = Serial.read();

    // say what you got:
    Serial.print("I received: ");
    Serial.println(incomingByte, DEC);

    switch(incomingByte)
    {
    case'>' :
      Serial.println(message);
      break;
    case '<' :
      for(int i = 0 ; i < message.length() ; i++)
      {
        Serial.print(i);
        Serial.print("-");
        //message.setCharAt(32, i);
        message = String(); // /!\ ATTENTION : ça, ce n'est pas propre du tout, voire même très sale : il y a sûrement un moyen de vider la chaîne proprement, mais à 2h du mat', j'ai pas trouvé. Là, je ne me préoccupe à aucun moment de la manière dont la mémoire est libérée, donc il est probable que je finisse par tout allouer et ne plus rien avoir (je ne connais pas assez les mécanismes d'arduino pour savoir comment la désallocation est faite)
      }
      break;
     default :
      message += incomingByte;
    }

    // pas encore testé, mais ça devrait passer (EDIT : c'est bon, ça marche)
    if(message.equals("Avance")){ Serial.println("En avant toute, cap'tain ! "); }
    if(message.equalsIgnoreCase("DrOiTe")){ Serial.println("C'est toi la droite, cap'tain !"); }

  }
}


R1D1 - Calculo Sed Ergo Sum -- en ce moment, M.A.R.C.E.L.
Avatar tiré du site bottlebot

#11 Black Templar

Black Templar

    Membre

  • Membres
  • PipPipPipPipPip
  • 1 430 messages
  • Gender:Male
  • Location:Lille

Posté 19 septembre 2012 - 08:47

Salut R1D1 !

Pourquoi ne pas déclarer incomingByte en char directement ??

Mon site internet : http://ferdinandpiette.com/


#12 R1D1

R1D1

    Modérateur et Membre passionné

  • Modérateur
  • PipPipPipPipPip
  • 1 147 messages
  • Gender:Male
  • Location:Autriche

Posté 19 septembre 2012 - 09:27

Salut R1D1 !

Pourquoi ne pas déclarer incomingByte en char directement ??


Salut Black Templar ! (quelle énergie au réveil !)

Parce que quand j'ai écrit ce code, il était très tard, et que je suis parti de la version du site d'Arduino qui faisait comme ça. Ensuite, la saturation relative à certains neurones dans le cerveau a provoqué un grand sentiment de "Oh c'est beau, c'est bien, c'est Bosch, ça marche" ce qui a empêché le reste de signaler cette petite optimisation. Bref, tout ça pour dire que, oui, autant le déclarer tout de suite en char (pas Leclerc, le byte).

EDIt : corrigé dans le code.
R1D1 - Calculo Sed Ergo Sum -- en ce moment, M.A.R.C.E.L.
Avatar tiré du site bottlebot

#13 bypbop

bypbop

    Habitué

  • Membres
  • PipPip
  • 259 messages
  • Gender:Male
  • Location:Lille

Posté 19 septembre 2012 - 08:28

Bonsoir à tous,

Pour l'instant le code que j'ai fait foncionne bien mais comme ma variable commande est en String le switch case ne fonctionne plus ...
Que puis je faire ?

// Moteur A
int dir1PinA = 13;
int dir2PinA = 12;
int speedPinA = 10;

// Moteur B
int dir1PinB = 11;
int dir2PinB = 8;
int speedPinB = 9;

// Vitesse Moteur
int speed = 0;

String commande;
int i = 0;
int octetR = 0;


void setup() {
  Serial.begin(57600);

  pinMode(dir1PinA, OUTPUT);
  pinMode(dir2PinA, OUTPUT);
  pinMode(speedPinA, OUTPUT);
  pinMode(dir1PinB, OUTPUT);
  pinMode(dir2PinB, OUTPUT);
  pinMode(speedPinB, OUTPUT);

  speed = 80;
}

void loop() 
{
  while (Serial.available())   
  {
    octetR = Serial.read();
    i++;
     
    
    if (octetR ==10){
    Serial.println(commande);
    i=0;
    commande="";
    delay(50);
    break;
    } 
    else {
    
    commande=commande+char(octetR);
    }
    }
    
    /*
    switch (commande)
    {
    case 'L':
      analogWrite(speedPinA, speed);
      analogWrite(speedPinB, speed);
      digitalWrite(dir1PinA, LOW);
      digitalWrite(dir2PinA, HIGH);
      digitalWrite(dir1PinB, HIGH);
      digitalWrite(dir2PinB, LOW);
      break;
    case 'STOP':
      digitalWrite(dir1PinA, LOW);
      digitalWrite(dir2PinA, LOW);
      digitalWrite(dir1PinB, LOW);
      digitalWrite(dir2PinB, LOW);
      break;
    default:
      Serial.print("commande : ");
      Serial.print(commande);
      Serial.println(" non reconnue.");
      break;
    }
    */

}

Cordialement,
bypbop

#14 pierre92037

pierre92037

    Nouveau membre

  • Membres
  • 1 messages

Posté 19 septembre 2012 - 09:20

L'instruction switch ne fonctionne qu'avec des entiers, donc tu ne peux pas utiliser de switch pour tester la valeur d'un string

tu peux par contre utiliser la fonction:

if (strcmp(command, "STOP")  == 0) {
    // whatever
}


Au sujet du protocole (commandes), si tu a peu de commandes, c'est plus simple de ne lire qu'un seul caractere pour identifier la commande: tu peux alors eviter de faire une boucle pour lire jusqu'au \n et tu pourais utiliser ton switch statement

Si vraiment tu tiens a utiliser une string, tu peux jeter un oeil sur la methode readBytesUntil de Serial qui te permet de lire jusqu'a ce qu'un caractere particulier soit lu.

Par exemple, tu pourrais ecrire qqchose comme:

char buffer[132];

    int len = Serial.readBytesUntil('$', buffer, sizeof(buffer));
Tu peux voir un exemple dans cette librairie:
https://github.com/p.../arduino-serial

Bon courage

Pierre

Bonsoir à tous,

Pour l'instant le code que j'ai fait foncionne bien mais comme ma variable commande est en String le switch case ne fonctionne plus ...
Que puis je faire ?

// Moteur A
int dir1PinA = 13;
int dir2PinA = 12;
int speedPinA = 10;

// Moteur B
int dir1PinB = 11;
int dir2PinB = 8;
int speedPinB = 9;

// Vitesse Moteur
int speed = 0;

String commande;
int i = 0;
int octetR = 0;


void setup() {
  Serial.begin(57600);

  pinMode(dir1PinA, OUTPUT);
  pinMode(dir2PinA, OUTPUT);
  pinMode(speedPinA, OUTPUT);
  pinMode(dir1PinB, OUTPUT);
  pinMode(dir2PinB, OUTPUT);
  pinMode(speedPinB, OUTPUT);

  speed = 80;
}

void loop() 
{
  while (Serial.available())   
  {
    octetR = Serial.read();
    i++;
     
    
    if (octetR ==10){
    Serial.println(commande);
    i=0;
    commande="";
    delay(50);
    break;
    } 
    else {
    
    commande=commande+char(octetR);
    }
    }
    
    /*
    switch (commande)
    {
    case 'L':
      analogWrite(speedPinA, speed);
      analogWrite(speedPinB, speed);
      digitalWrite(dir1PinA, LOW);
      digitalWrite(dir2PinA, HIGH);
      digitalWrite(dir1PinB, HIGH);
      digitalWrite(dir2PinB, LOW);
      break;
    case 'STOP':
      digitalWrite(dir1PinA, LOW);
      digitalWrite(dir2PinA, LOW);
      digitalWrite(dir1PinB, LOW);
      digitalWrite(dir2PinB, LOW);
      break;
    default:
      Serial.print("commande : ");
      Serial.print(commande);
      Serial.println(" non reconnue.");
      break;
    }
    */

}

Cordialement,
bypbop



#15 bypbop

bypbop

    Habitué

  • Membres
  • PipPip
  • 259 messages
  • Gender:Male
  • Location:Lille

Posté 19 septembre 2012 - 09:34

Merci je regarde tt ca et je vous tiens au courant.

Encore Merci,
bypbop

#16 seb03000

seb03000

    Pilier du forum

  • Membres
  • PipPipPipPipPip
  • 1 192 messages
  • Gender:Male
  • Location:Loins dérrière toi.
  • Interests:La Robotique , plus l'informatique

Posté 24 septembre 2012 - 01:04

Alors bypbop est-ce que cela a fonctionné

#17 Telson

Telson

    Membre chevronné

  • Membres
  • PipPipPipPip
  • 975 messages
  • Gender:Male
  • Location:Punaauai - Tahiti

Posté 24 septembre 2012 - 04:03

il existe plusieurs exemples sur le site suivant :

http://www.mon-club-elec.fr/pmwiki_mon_club_elec/pmwiki.php?n=MAIN.ArduinoExpertSerieDepuisPCReceptionString

A+

#18 bypbop

bypbop

    Habitué

  • Membres
  • PipPip
  • 259 messages
  • Gender:Male
  • Location:Lille

Posté 24 septembre 2012 - 07:04

Bonjour à tous,

Oui pour l'instant j'ai suivi vos conseils à savoir que j'utilise juste une lettre.

J'ai mis une petite video sur le forum le sujet se trouve ici

Cordialement,
bypbop




0 utilisateur(s) li(sen)t ce sujet

0 members, 0 guests, 0 anonymous users