Interpréter une chaîne de caractère vis Serial

Bonjour,

J'aimerais savoir comment il serait possible de transformer une chaîne de caractère envoyer sur le port séries dans des variables int dédier a set effet :slight_smile:

Exemple :

RUN a10 b12 x90 y90 z0 s0

après décodage :
RUN (fait une fonction déterminée )

int a=10;
int b=12;
int x=90;
int y=90;
int z=0;
int s=0;

J'aimerais au final que deux arduinos communique entre eux via le serial et interagisse entre eux en fonction de leurs commande.

Merci :slight_smile:

Bonjour,

Par exemple comme ceci:

 Serial.print("RUN a");
 Serial.print(a);
 Serial.print(" b");
 Serial.print(b);
 Serial.print(" b");
 Serial.print(b);
 Serial.print(" x");
 Serial.print(y);
 Serial.print(" z");
 Serial.print(z);
 Serial.print(" s");
 Serial.println(s);

Tu peux essayer :

kamill:
Bonjour,

Par exemple comme ceci:

 Serial.print("RUN a");

Serial.print(a);
Serial.print(" b");
Serial.print(b);
Serial.print(" b");
Serial.print(b);
Serial.print(" x");
Serial.print(y);
Serial.print(" z");
Serial.print(z);
Serial.print(" s");
Serial.println(s);

Merci mais c’est totalement l’inverse que j’aimerais faire :wink:

Tahitibob35 : ça m’as l’air intéressant mais je dois pouvoir communiqué de la sorte depuis une mega sur tout ses ports séries et faire de même sur plusieurs carte du coup… :slight_smile:

En réalisant un parseur de tes données, qui les interprète caractère à caractère. J’étais précisément en train de modifier un programme dans lequel j’ai été amené à implémenter une liaison série sans passer par la classe Serial.

Voilà la partie qui devrait t’intéresser:

char line_buffer[taille_du_buffer_de_caractères];
int line_counter = 0;

int inValue = 0;

while(condition_au_choix){
    char c = linebuffer[line_counter]
    if (c >= '0' && c <= '9'){
        inValue *= 10;
        inValue += (c - 48);
        line_counter++;
    }
}

Le code complet est là: projecteur laser.

Gruniek:
Merci mais c'est totalement l'inverse que j'aimerais faire :wink:

Oups, j'étais complètement à coté de la plaque :-[

Tu peux faire comme ceci

 char msg[30];
 // ... ici reception du message
 if (strcmp(strtok(msg," "),"RUN")==0)
 {
   // trouvé le message
   char *p;
   while ((p=strtok(NULL," "))!=NULL)
   {
     int val=atoi(p+1);
     switch(*p)
     {
       case 'a': a=val; break;
       case 'b': b=val; break;
       case 'x': x=val; break;
       case 'y': y=val; break;
       case 'z': z=val; break;
       case 's': s=val; break;
     }
   }
 }

Troisiemetype : Pas mal mais je foire sur une ou deux fonction, faut que j’etudie cela :slight_smile:

Kamil :

SI je comprend bien ton code, ceci peu être fonctionnel ?

//

...


void loop() {

char msg[30];

 char = "RUN a10 b12 x90 y90 z0 s0";

 if (strcmp(strtok(msg," "),"RUN")==0)
 {
   // trouvé le message
   char *p;
   while ((p=strtok(NULL," "))!=NULL)
   {
     int val=atoi(p+1);
     switch(*p)
     {
       case 'a': a=val; break;
       case 'b': b=val; break;
       case 'x': x=val; break;
       case 'y': y=val; break;
       case 'z': z=val; break;
       case 's': s=val; break;
     }
   }
 }

 Serial.print("RUN a");
 Serial.print(a);
 Serial.print(" b");
 Serial.print(b);
 Serial.print(" b");
 Serial.print(b);
 Serial.print(" x");
 Serial.print(y);
 Serial.print(" z");
 Serial.print(z);
 Serial.print(" s");
 Serial.println(s);


while(1) { }

}

( donc il me retourne sur le port serie, l’identique message de base mais décomposée dans la puce du duino ? )

oui, c'est fonctionnel sauf

char = "RUN a10 b12 x90 y90 z0 s0";

qui est erroné et doit être remplacé par exemple par

strcpy(msg,"RUN a10 b12 x90 y90 z0 s0");

et si je fait :

char dataIn;

if (Serial.available() > 0) 
{
    dataIn = Serial.read();
   char msg[30];


 if (strcmp(strtok(msg, dataIn),"RUN")==0)
 {
   // trouvé le message
   char *p;
   while ((p=strtok(NULL," "))!=NULL)
   {
     int val=atoi(p+1);
     switch(*p)
     {
       case 'a': a=val; break;
       case 'b': b=val; break;
       case 'x': x=val; break;
       case 'y': y=val; break;
       case 'z': z=val; break;
       case 's': s=val; break;
     }
   }
 }

 Serial.print("RUN a");
 Serial.print(a);
 Serial.print(" b");
 Serial.print(b);
 Serial.print(" b");
 Serial.print(b);
 Serial.print(" x");
 Serial.print(y);
 Serial.print(" z");
 Serial.print(z);
 Serial.print(" s");
 Serial.println(s);

}

? :smiley:

Avec cette méthode il faut recevoir le message en entier avant de le traiter. Il est de bonne pratique de terminer le message par un caractère connu par exemple le caractère de fin de ligne (line feed)
Ce qui donne (par exemple):

  char msg[30];
  if (Serial.available() > 0)
  {
    Serial.readBytesUntil('\n', msg, sizeof msg);

    if (strcmp(strtok(msg, " "), "RUN") == 0)
    {
      // trouvé le message
      char *p;
      while ((p = strtok(NULL, " ")) != NULL)
      {
        int val = atoi(p + 1);
        switch (*p)
        {
          case 'a': a = val; break;
          case 'b': b = val; break;
          case 'x': x = val; break;
          case 'y': y = val; break;
          case 'z': z = val; break;
          case 's': s = val; break;
        }
      }
    }

    Serial.print("RUN a");
    Serial.print(a);
    Serial.print(" b");
    Serial.print(b);
    Serial.print(" x");
    Serial.print(x);
    Serial.print(" y");
    Serial.print(y);
    Serial.print(" z");
    Serial.print(z);
    Serial.print(" s");
    Serial.println(s);
  }

Ok!

Je teste ca se soir des que je touche a un arduino :slight_smile:

Note : Maintenant si je veux donner d'autre commende que RUN, je suppose que c'est ici que sa ce passe ?

....


    if (strcmp(strtok(msg, " "), "RUN") == 0)
    {
      .....
    }

    if (strcmp(strtok(msg, " "), "SET") == 0)
    {
      .....
    }

    if (strcmp(strtok(msg, " "), "PUT") == 0)
    {
      .....
    }

Merci !

comme strtok(msg, " ") modifie la chaine msg, il ne faut l'appeler qu'une seule fois

  char *cmd=strtok(msg, " "); // lit la commande

  if (strcmp(cmd, "RUN") == 0)
  {
    //  .....
  }

  if (strcmp(cmd, "SET") == 0)
  {
    //  .....
  }

  // .....

Ok je comprend tous le code la :smiley:
Je regarde à ça ce soir en vrai :wink: merci !

ça fonctionne parfaitement Merci =D

Par contre, il donne un temps de latence au programme, comme s'il avait un ping time out qui bloque tous le process, peu t'on by-passé ce time out ?
Car il me faut aucun temps de bloquage :slight_smile:

C'est sans doute que tu n'as pas de caractère de fin de chaine (line feed dans mon exemple). S'il ne trouve pas le caractère de fin de chaine attendu, il y a un time-out (je pense que c'est 1S par défaut)

je l'ai remis dans mon code final et sa fonctionne sans time out, bizard mais tant mieux :slight_smile:
Je peu rajouter comment ce caractère fin de chaîne ? un mot clef genre un ACK ?

Tu peux utiliser n'importe quel caractère qui ne peux pas se trouver dans la chaine. On utilise souvent line feed ('\n') car il peut être envoyé par les terminaux quand on appuie sur entrée (par exemple avec le terminal de l'ide arduino en sélectionnant 'nouvelle ligne' en bas).

Tu envoies ta commande comment?

ACK a une autre fonction, bien que ce soit possible, évites de l'utiliser comme fin de message

Ok compris :wink:

Merci pour tous !