Skyduino:~#
Articles
arduino, programmation

[Arduino] Parser une chaine de caractéres

Bonjour tout le monde !

C’est ma semaine de partiels les articles se font donc rares.
Je vais tenter demain ou vendredi de finir mon article sur le DF3120 mais je ne garantie rien ;)

Histoire de vous donner votre dose d’arduino voici un petit morceau de code réalisé pour un membre du forum arduino.
Le but est simple, parser (= parcourir et interpréter) une chaine de caractères reçue sur le port série pour en extraire les données utiles quelle contient.

La chaine type utilisait dans le cadre de ce code a cette forme :
$ texte;valeur;index;diviseur;°c/f;

Le code est facilement modifiable pour coller à n’importe quelle format, il suffit de suivre le principe de base ;)

Sans plus attendre, le code :

// Buffer qui va contenir la trame série
#define TAILLE_MAX 32

// Buffer qui va contenir le texte (taille du buffer / 2, oui j'ai mis ça au pif)
char texte[TAILLE_MAX / 2], unite;
// Données utiles extraites
int valeur, index, diviseur;

// setup()
void setup() {
  // Initialisation du port série
  Serial.begin(9600);
}

// loop()
void loop() {
  // Récupération d'une trame + parsing
  if(recupInfo(texte, &valeur, &index, &diviseur, &unite)) {
    Serial.println("Erreur de trame !");
    return;
  }
  
  // Affichage
  Serial.print("Texte: ");
  Serial.println(texte);
  Serial.print("Valeur: ");
  Serial.println(valeur);
  Serial.print("Index: ");
  Serial.println(index);
  Serial.print("Diviseur: ");
  Serial.println(diviseur);
  Serial.print("Unité: ");
  Serial.println(unite);
}

/*
 * Parse une chaine au format $ texte;valeur;index;diviseur;°c/f;
 * Et retourne la valeur des différents champs.
 */
int recupInfo(char *texte, int *valeur, int *index, int *diviseur, char *unite) {
  char c, buf[TAILLE_MAX + 1];
  unsigned char i = 0;

  /* Attente du $ espace */
  do {
    /* Attente de 2 char sur le port série */
    while(Serial.available() < 2);

    /* Tant que chaine != $ espace -> boucle */
  } 
  while(Serial.read() != '$' && Serial.read() != ' ');

  /* Remplissage du buffer */
  do{
    /* Si la chaine a dépassé la taille max du buffer*/
    if(i == (TAILLE_MAX + 1)) 
      /* retourne 1 -> erreur */
      return 1;

    /* Attente d'un char sur le port série */
    while(Serial.available() < 1);

    /* Tant que char != 0x1A (fléche) -> boucle */
  } 
  while((buf[i++] = Serial.read()) != 0x1A);

  /* Cloture la chaine de char */
  buf[i] = '\0';

  /* Copie le texte au début de buf[] dans texte[] */
  i = 0;
  while((texte[i] = buf[i]) != ';') i++;
  texte[i] = '\0';

  /* Parse la chaine de caractères et extrait les champs */
  if(sscanf(buf + i, ";%d;%d;%d;%*c%c;", valeur, index, diviseur, unite) != 4)
    /* Si sscanf n'as pas pu extraire les 4 champs -> erreur*/
    return 1;

  /* retourne 0 -> pas d'erreur */
  return 0;
}

Voila voila Enjoy ! :)

Discussion

12 réflexions sur “[Arduino] Parser une chaine de caractéres

  1. Fonctionne parfaitement!!

    Publié par maccoa | 24 mars 2012, 14 h 09 min
  2. Salut,
    j’effectue un projet à peu près pareil, une communication via port série RS232 avec un module GPS, la carte arduino alors traite la trame GPS reçue & l’affiche sur écran, pourriez vous m’orienter vers une documentation qui peut m’aider à établir cette connection et dans un second lieu exploiter ce bout de code??

    Publié par Atef | 28 avril 2013, 21 h 14 min
  3. Bonjour,
    Lorsque je le lance le programme il me retourne systématiquement ‘Erreur de trame ».
    Est ce que l’erreur peut venir du sscanf? je ne connais pas cette fonction!!!
    Merci.

    Publié par Xavier | 6 juin 2013, 12 h 26 min
  4. Bonjour,
    Comment faire pour ne pas rendre l’application non bloquante, pour qu’elle puisse faire autre chose.
    si j’exécute se code, le programme est tjs en attente du serial et ne fait rien d’autre.
    pour afficher par exemple « je suis en attente »

    Publié par Thierry | 3 juillet 2014, 13 h 00 min
    • -> « Machine à états fini » + interruption sur le port série pour traiter les caractères un à un en parallèle du programme principal.

      Autant prévenir de suite c’est tout sauf simple et c’est ultra chiant à débugger.
      Cherche « FSM ragel » sur google pour avoir un outil bien pratique qui génère le code de l’automate en fonction d’une série d’expressions régulières.

      Publié par Skywodd | 4 juillet 2014, 21 h 04 min
  5. Bonjour

    je construit une télécommande ou je dois envoyer 3 paramètres.
    j’ai réussi à les concaténer avec sprintf(machaine, « %d-%d-%d »,angle,relaisemb,relais), mon séparateur étant -.
    Mais je n’arrive pas à le séparer à la réception (et à retrouver mes 3 valeurs: angle, relais emb, relais).

    le système envoie les caractères en ascii, mais je ne sais pas comment les séparer (sachant que la valeur angle peut prendre une valeur entre 1 et 180, y compris la valeur 49, valeur ascii du séparateur..

    Si quelqu’un pouvait m’aider, je lui en serait reconnaissant.

    Merci

    Publié par thomas lecomte | 12 juin 2015, 17 h 19 min
  6. Super ton bout de code je travaille sans succès sur du decodage de trame entre 2 arduinos en liaison série mais sans succès
    je test ton code dès ce soir cependant je ne comprends pas pourquoi « tant que char != 0x1A » pourquoi parle tu de flèche?

    Publié par alex | 16 juin 2015, 8 h 08 min
    • 0x1A est le code ascii pour SUB qui est souvent représenté par une flèche.
      C’est aussi le code généré par la séquence de touche CTRL+Z.

      Après je pourrai pas t’en dire plus. Je me rappelle plus du tout du pourquoi de ce code …

      Publié par Skywodd | 3 juillet 2015, 15 h 40 min

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s

Archives

Suivre

Recevez les nouvelles publications par mail.

Rejoignez 916 autres abonnés