Go Down

Topic: Chaine de caractère liaison série (Read 5030 times) previous topic - next topic

maxouche

Bonjour à tous,

Je voudrais dans effectuer détecter une chaîne de caractère spécifique dans une chaîne reçue par liaison série mais j'ai un petit soucis... Marche pas !

En fait je souhaite détecter la réception des caractères suviants :      \S

Voici  mon code :

void loop()
{
 char Buffer[8];
 String CR_char;

 memset(Buffer, '\0', 9);
 int x=0;
 
 while (Serial.available()>0)
 {
   Buffer
  • =Serial.read();
       CR_char = Buffer[x-1] + Buffer
  • ;
       if (CR_char == "\S")
       {
           Serial.println("fin de transmission");
       }
       delay(10);
       x++;      
     }
     
     if (Buffer[0] > 1)
       {
         Serial.print("recu    :");
         Serial.println((char*)Buffer);
             
       }
    }    


    Merci pour votre aide.

    Max

skywodd

#1
Jul 12, 2011, 05:19 pm Last Edit: Jul 12, 2011, 09:53 pm by skywodd Reason: 1
Bonjour,

Un truc comme ça sa irait ?

Code: [Select]

char buffer[2] = {
  '\0', '\0'}; // buffer pour stocker le char avant/aprés
char data[8]; // buffer pour stocker les donnée recu
byte index = 0; // index pour le buffer circulaire

void setup(){
  Serial.begin(9600);
  for(int i = 0; i < 8; i++) data[i] = '\0'; // pas de memset sur un microcontroleur par pitié !
}

void loop()
{
  while(Serial.available() > 0) // tant que des byte sont dispo sur l'uart
  {
    buffer[1] = Serial.read(); // lecture d'un octet depuis le port série
    if ((buffer[0] == '\\') && (buffer[1] == 'S')){ // si les deux char précendant correspondent on quite
      Serial.println("fin de transmission");
      if(data[0]){
        index--;
        data[index--] = '\0'; // on cloture data avec un char null
        Serial.print("recu : ");
        index = 0; // on reset l'index
        Serial.print(data[index]); // on print le 1er char
        while((data[index++] != '\0') && (index < 8)) // tant que la fin de data n'est pas atteinte ou d'overflow
          Serial.print(data[index]); // on print le char
        Serial.println(); // on envoie une nouvelle ligne
        index = 0; // on reset l'index
        break;
      }
    }
    if(index < 8){ // on évite les buffer overflow
      data[index] = buffer[1]; // on stock le char
      index++; // et on passe au suivant
    }
    buffer[0] = buffer[1]; // on swap les char avant/aprés
  } // et on repart pour un tour
}
Des news, des tutos et plein de bonnes choses sur http://skyduino.wordpress.com !

zoroastre

#2
Jul 12, 2011, 07:39 pm Last Edit: Jul 12, 2011, 07:55 pm by zoroastre Reason: 1
Yep!

Je suis sur un truc similaire et je trouve la classe String interessante et peu utilisée me semble-t'il !

Pour ma part, je détecte un séparateur sur une chaine de caractère. Cà peu peut être aider ;)

Code: [Select]
#define SEPARATOR ';' // separator
String comString[16]; // string array of 16 lines
char buffer; // buffer for incoming

...

void readMessageFromServer(char buffer, int bufsize) {
 int i= 0;
 String line = "";
   while (Serial.available()){
     buffer = Serial.read();
     for (i = 0; i < bufsize; i++) {
           // SEPARATOR
       if (buffer == SEPARATOR) {buffer = '\0'; comString[i] = line; line = ""; i++; }
           // END OF BUFFER
       if (buffer == DATA_END) {buffer = '\0'; comString[i] = line; line = ""; lenCom = i; }
       else {line.concat(buffer); }
     }
   }
   Serial.println();
}


Chaque caractère du buffer constitue une ligne tant que le séparateur ou la fin de transmission n'est détectés.

Dans ton cas, je pense qu'il faut tout d'abord détecter le premier caractère '\' et contrôler le suivant. L'idée de Skywodd semble interessante, mais je doute qu'elle fonctionne !!!

Code: [Select]
buffer[1] = Serial.read(); ???

A la rigueur :

Code: [Select]
buffer[0] = Serial.read();
buffer[1] = Serial.read();


@+

Zoroastre.
Gné! ;)

skywodd


Je suis sur un truc similaire et je trouve la classe String interessante et peu utilisée me semble-t'il !

La class string n'est rien d'autre qu'une surchouche du type char* qui consomme beaucoup de ram, les avantages tel que les opérateur == =! & co ainsi que le concaten auto avec des chiffres, char ou char* sont trés pratique mais il faut avoir la ram pour ça. ;)


Dans ton cas, je pense qu'il faut tout d'abord détecter le premier caractère '\' et contrôler le suivant. L'idée de Skywodd semble intéressante, mais je doute qu'elle fonctionne !!!

Si tu rempli buffer[0] puis buffer[1] c'est que tu n'as pas compris comment mon code marche ;)
Dans le principe c'est pourtant trés simple, un buffer "flip flop" et un buffer circulaire,
Le buffer circulaire est rempli avec les donnée résultante du "flip flop",
buffer[1] contient le serial.read le plus récent et buffer[0] celui qui précédé, quand buffer == "\\S" on stop et ce retrouve dans data les donné recu du port série.
Des news, des tutos et plein de bonnes choses sur http://skyduino.wordpress.com !

zoroastre

Yep!

Ce que je ne comprends pas :

Code: [Select]
buffer[1] = Serial.read();

Là je me demande si le code va remplir la colonne 2 du tableau buffer ou créer un tableau de 1 caractère...buffer[0] étant l'index du premier char ???

Code: [Select]
buffer[0] == '\\'

Comment ici le buffer peut-il contenir 2 caractères ??? Pas vu dans le code ???

Code: [Select]
data[index] = buffer[1]; Même problème que le précedent, j'ai jamais réussi à créer un tableau avec un char perso !!!

http://www.arduino.cc/en/Reference/String

@+

Zoroastre.


Gné! ;)

skywodd


Code: [Select]
buffer[1] = Serial.read();
Là je me demande si le code va remplir la colonne 2 du tableau buffer ou créer un tableau de 1 caractère...buffer[0] étant l'index du premier char ???

:smiley-eek: c'est une assignation, le char résultant du Serial.read() va étre placé dans le char accessible par le pointeur buffer[1].


Code: [Select]
buffer[0] == '\\'

Comment ici le buffer peut-il contenir 2 caractères ??? Pas vu dans le code ???

:smiley-eek: :smiley-eek: /facepalm et les caractère d'échappement y compte pour du beurre ;) (http://www.gillius.org/ctut/app_a.htm)


Code: [Select]
data[index] = buffer[1]; Même problème que le précedent, j'ai jamais réussi à créer un tableau avec un char perso !!!

:smiley-eek: :smiley-eek: :smiley-eek: Un char* correspond à un tableau contenant des char accessible par des pointeurs.
data[n] ou buffer[n] correspond à un char n mappé en mémoire et accessible uniquement par le pointeur qui va bien.


http://www.arduino.cc/en/Reference/String

La solution de facilité qui bouffe 50% de la ram et qui fait rien de plus ...
Raaa toute une éducation à refaire ]:D
Des news, des tutos et plein de bonnes choses sur http://skyduino.wordpress.com !

zoroastre

Yep!

Merci pour ces explications !

Effectivement, les pointeurs c'est pas ma tasse de thé ;)

Tu as testé ?


Quote
fin de transmission
recu : salut\
fin de transmission
recu : Scava\
fin de transmission
recu : S23commesalut\Scava\S23comment vas tu ? \S yep!
fin de transmission
recu : S yep!arsalut\Scava\S23comment vas tu ? \S yep!arduino \S rocks!


@+

Zoroastre.
Gné! ;)

skywodd


effectivement, les pointeurs c'est pas ma tasse de thé ;)

C'est quelque chose de primordial tu devrais essayer tu verra c'est trés pratique ;)


Tu as testé ?

Je suis sur mon notebook donc non pas encore ;)

Quote
fin de transmission
recu : salut\
fin de transmission
recu : Scava\
fin de transmission
recu : S23commesalut\Scava\S23comment vas tu ? \S yep!
fin de transmission
recu : S yep!arsalut\Scava\S23comment vas tu ? \S yep!arduino \S rocks!

DOH ><en voulant faire cheap pour l'affichage j'ai copier collé une erreur du code de base !
Honte à moi pour ce copier coller !

Ps: t'est sur de ton coup pour les 2 dernière mon buffer fait 8 char et ta phrase reçu 49 :smiley-eek-blue:
Des news, des tutos et plein de bonnes choses sur http://skyduino.wordpress.com !

zoroastre

Yep!

En une phrase : "salut \S skywodd \S ce test \S dit tout \S"

Quote
fin de transmission
recu : salut \
fin de transmission
recu : S skywodsalut \S skywodd \S ce test \S dit tout \S
fin de transmission
recu : S ce tessalut \S skywodd \S ce test \S dit tout \S
fin de transmission
recu : S dit tosalut \S skywodd \S ce test \S dit tout \S


@+

Zoroastre.
Gné! ;)

skywodd

bon pour le bug du \ en premier ligne normal j'avais oublier un index--
pour la suite c'est bizarre ...

code testé et fonctionnel
Code: [Select]
char buffer[2] = {
  '\0', '\0'}; // buffer pour stocker le char avant/aprés
char data[8]; // buffer pour stocker les donnée recu
byte index = 0; // index pour le buffer circulaire

void setup(){
  Serial.begin(9600);
  for(int i = 0; i < 8; i++) data[i] = '\0'; // pas de memset sur un microcontroleur par pitié !
}

void loop()
{
  while(Serial.available() > 0) // tant que des byte sont dispo sur l'uart
  {
    buffer[1] = Serial.read(); // lecture d'un octet depuis le port série
    if ((buffer[0] == '\\') && (buffer[1] == 'S')){ // si les deux char précendant correspondent on quite
      Serial.println("fin de transmission");
      if(data[0]){
        index--; // enlève le \ de data
        data[index--] = '\0'; // on cloture data avec un char null
        Serial.print("recu : ");
        index = 0; // on reset l'index
        Serial.print(data[index]); // on print le 1er char
        while((data[index++] != '\0') && (index < 8)) // tant que la fin de data n'est pas atteinte ou d'overflow
          Serial.print(data[index]); // on print le char
        Serial.println(); // on envoie une nouvelle ligne
        index = 0; // on reset l'index
        break; // empêche le S en début de ligne
      }
    }
    if(index < 8){ // on évite les buffer overflow
      data[index] = buffer[1]; // on stock le char
      index++; // et on passe au suivant
    }
    buffer[0] = buffer[1]; // on swap les char avant/aprés
  } // et on repart pour un tour
}

Des news, des tutos et plein de bonnes choses sur http://skyduino.wordpress.com !

zoroastre

Yep!

Bon j'envoie une première fois : "012345\S012345\S012345\S"

Quote
fin de transmission
recu : 012345
fin de transmission
recu : 012345
fin de transmission
recu : 012345


Ensuite pour confirmation : "0123456\S01234567\S012345678\S"

Quote
fin de transmission
recu : 0123456
fin de transmission
recu : 0123456
fin de transmission
recu : 0123456


@+

Zoroastre.

Gné! ;)

skywodd


Ensuite pour confirmation : "0123456\S01234567\S012345678\S"

Quote
fin de transmission
recu : 0123456
fin de transmission
recu : 0123456
fin de transmission
recu : 0123456


Bon bin c'est ok ! buffer de 8 char : 0123456 => 7 char + \0 => 8 char le compte est bon !
Des news, des tutos et plein de bonnes choses sur http://skyduino.wordpress.com !

Go Up