Chaine de caractère liaison série

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[x]=Serial.read();
CR_char = Buffer[x-1] + Buffer[x];
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

Bonjour,

Un truc comme ça sa irait ?

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
}

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 :wink:

#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 !!!

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

A la rigueur :

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

@+

Zoroastre.

zoroastre:
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. :wink:

zoroastre:
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 :wink:
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.

Yep!

Ce que je ne comprends pas :

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 ???

buffer[0] == '\\'

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

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.

zoroastre:

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 ???

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

zoroastre:

buffer[0] == '\\'

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

:astonished: :astonished: /facepalm et les caractère d'échappement y compte pour du beurre :wink: (Appendix A -- Escape Characters)

zoroastre:
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 !!!

:astonished: :astonished: :astonished: 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.

zoroastre:
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 ]:smiley:

Yep!

Merci pour ces explications !

Effectivement, les pointeurs c'est pas ma tasse de thé :wink:

Tu as testé ?

fin de transmission
recu : salut
fin de transmission
recu : Scava
fin de transmission
recu : S23commeasalut\Scava\S23comment vas tu ? \S yep!
fin de transmission
recu : S yep!arasalut\Scava\S23comment vas tu ? \S yep!arduino \S rocks!

@+

Zoroastre.

zoroastre:
effectivement, les pointeurs c'est pas ma tasse de thé :wink:

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

zoroastre:
Tu as testé ?

Je suis sur mon notebook donc non pas encore :wink:

fin de transmission
recu : salut
fin de transmission
recu : Scava
fin de transmission
recu : S23commeasalut\Scava\S23comment vas tu ? \S yep!
fin de transmission
recu : S yep!arasalut\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 :fearful:

Yep!

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

fin de transmission
recu : salut
fin de transmission
recu : S skywodasalut \S skywodd \S ce test \S dit tout \S
fin de transmission
recu : S ce tesasalut \S skywodd \S ce test \S dit tout \S
fin de transmission
recu : S dit toasalut \S skywodd \S ce test \S dit tout \S

@+

Zoroastre.

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

code testé et fonctionnel

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
}

Yep!

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

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

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

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

@+

Zoroastre.

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

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 !