Découper une trame

strtok est ton ami... :)

Un truc du genre :

String trame = "<1111,22.22,3333,4444,5555,666.66,777.7,888.8,999.9,101.1,121.2,314.1,59,26,12345678>";
char trame2[];
float val[];

void setup()
{
  Serial.begin(9600);
  trame2 = trame.c_str();  // <-- pas sûr, à vérifier
// Si ça compile pas,essayer :
// strcpy (trame2, trame.c_str());
}

void loop()
{
  char * pch;
  int i = 0;
  pch = strtok (trame2,"<,>");
  while (pch != NULL)
  {
    pch = strtok (NULL, "<,>");
    if (i>0 && pch!='>') val[i] = atof(pch);
    Serial.print(i); Serial.print(" : "); Serial.println(val[i]);
    ++i;
  }
}

A tester...

NON :

  for (int i = 0; i < 19; i++) {
    tableau [i] = Serial.readStringUntil(",");
  }
  Serial.println(tableau[i]);

OUI:

  for (int i = 0; i < 19; i++) {
    tableau [i] = Serial.readStringUntil(",");
    Serial.println(tableau[i]); // A L'INTERIEUR DE LA BOUCLE
  }
String trame = "<1111,22.22,3333,4444,5555,666.66,777.7,888.8,999.9,101.1,121.2,314.1,59,26,12345678>";

Il manque un truc important, si la trame arrive par la voie série, il faut déjà la lire caractère par caractère pour arriver jusqu'au > final, c'est à dire faire une analyse avant de l'avoir. Le problème est différent si la trame est sans une string.

Moi j'utilise Json et il fait le boulot à ta place ;)

Autant lire la trame en une seule fois, la stocker dans un tableau de char et la traiter ensuite (après détection du '>'), plutôt que tout faire d'un coup.

lesept: Autant lire la trame en une seule fois, la stocker dans un tableau de char et la traiter ensuite (après détection du '>'), plutôt que tout faire d'un coup.

tout dépend de la longueur de la trame et s'il faut faire des traitements pendant la réception. Dans l'absolu, oui, si la trame n'est pas trop longue, c'est plus simple de traiter une trame entière d'un coup car on peut vérifier sa validité totale.

éventuellement vous pouvez jeter un oeil à mon petit tuto sur le sujet

Merci à tous pour vos réponses !!
Effectivement lesept j’ai utilisé la fonction strtok. Je ne savais pas qu’elle existait mais elle simplifie beaucoup de choses.
Je suis actuellement en train d’essayer de récupérer la trame, puis de la stocker dans un tableau pour ensuite la découper.
Je regrouperais les 2 fonctions ensemble par la suite.

char string[200];
  int availableBytes = Serial.available();
  for (int i = 0; i < availableBytes; i++)
  {
    string[i] = Serial.read();
  }
Serial.print (string);

J’ai un petit soucis avec mon bout de code j’obtiens quelque chose comme : <<<<<<<<<<<<<<<AAAA,BB.BB,etc…
Comme si la boucle prenais le premier caractère plusieurs fois. Je ne comprends pas très bien …

Your string isn’t terminated by the code snippet you posted, so you can’t print it and expect consistent results.

Cherche le tuto de J-M-L qui explique comment lire le port série.

Pense à mettre un 0 à la fin de la chaine, donc après le } de la boucle for :

string[availableBytes] = '\0';

Damned, grilled by Prince !!!

mon petit tuto sur le sujet du port série ;)

J-M-L tu es mon sauveur ! :grinning: J'ai suivi ton tuto pour comprendre comment fonctionne le port série (on dirait pas mais c'est pas si simple) Finalement, j'ai adapté ton code pour qu'il réagisse à ma trame et tout fonctionne !

En bonus j'ai réussi rassembler les 2 codes en 1. Le port série en lecture c'est beaucoup plus complexe que ça y parait, je ne pensais pas que sans "délimitation" tout partirait en sucette comme avec mon code précédent...

bravo ! :)

Une dernière question J-M-L. Comme expliqué, j'arrive bien à récupérer et séparer ma trame pour obtenir : tableau[0] = AAAA tableau[1] = BB.BB ...

Le problème que je rencontre c'est quand j'appel un élément du tableau, exemple tableau[1], il me retourne que la première valeur à savoir B et non pas BB.BB... J'ai loupé quelque chose ou il y a un problème dans mon tableau ?

Ce serait plus facile si tu postais ton code

Le tableau est défini sous forme de char ou de char* ?

Oui postez le code sinon on joue aux devinettes

Effectivement ...

char tableau[19];
char * pch;

char decoupe_message(char trame[100])
{
  pch = strtok (trame, "<>,");
  while (pch != NULL)
  {
    for (int i = 0; i < 19; i++)
    { 
      tableau[i] = pch;
      Serial.print ("tableau[");
      Serial.print  (i);
      Serial.print  ("] : ");
      Serial.println  (pch);
      fonction (i, pch);
      pch = strtok (NULL, "<>,");
      
    }
  }
}

Pour l'explication, ma trame est réceptionnée précédemment dans un tableau. Ma fonction "decoupe_message" retires tous les caractères "inutiles" et sépare les valeurs dans un tableau (tableau[ ]). A la fin j'obtiens : tableau[0] = AAAA tableau[1] = BB.BB ....

Dans une autre fonction, j'appelle i et pch. En fonction de i, il me retourne la valeur qui lui ai associée. C'est la que ça coince ...

Déjà, je ne suis pas sûr que ceci soit bon, car il n’y aura pas de caractère 0 à la fin

tableau[i] = pch;

Ensuite, il faudrait aussi le code de la fonction…

Voilà le code de la fonction "fonction"

void fonction (int i, char val)
{
  switch (i) {
    case 0: 
     Serial.println(val);
      break;
    case 1: 
     Serial.println(val);
      break;
    case 2: 
     Serial.println(val);
      break;
}
}

Pour l'instant il n'y a pas vraiment de code. Déjà vérifier que la valeur est bien prise en compte. A l'avenir "val" sera un nombre entier ou flottant.

void fonction (int i, char val)
{
  if (i >= 0 && i <= 2) {
     Serial.println(val);
  }
}

Ce n'est pas le but de ma fonction TheMember. "val" est différent si i vaut 0, 1 ou 2. Sinon oui l'utilisation d'un if était une bonne idée.