Découpage message sur arduino

[Fermé]
Signaler
Messages postés
6
Date d'inscription
mardi 12 novembre 2019
Statut
Membre
Dernière intervention
14 novembre 2019
-
Messages postés
5637
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
22 octobre 2021
-
Bonjour

j'espère que vous allez bien
je voulais savoir si vous pouvez m'aidé
je reçoit se message "X00/00/00 04:45:03 1234 000 B J 019074 A N 00 G 00.00" par rs 232 sur arduino et je voulais découpé à chaque espace " " pour récupéré quelque partie après l'espace pour les imprimés sur un écran lcd16/2

Merci à vous

2 réponses

Messages postés
5637
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
22 octobre 2021
952
Salut kamal3018,

Vois la fonction standard du C
strtok()
:

http://www.cplusplus.com/reference/cstring/strtok/


Dal
Messages postés
6
Date d'inscription
mardi 12 novembre 2019
Statut
Membre
Dernière intervention
14 novembre 2019

re
moi j'ai ce code



#include <LiquidCrystal.h>
// chaine de caractères pour contenir les données brutes
String inputString = "";
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
// pour savoir si la chaine est complète
boolean stringComplete = false;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
int cnt = 0; // nombre de données découpées
String data[10]; // stockage des données découpées

void setup() {
lcd.begin(16, 2);
Serial.begin(9600);
lcd.setCursor(0,0);
lcd.print(" Scanner un ANT");
lcd.setCursor(0,1);
lcd.print(" Scan een ANT");
}

void loop() {
// si le message est complet
if (stringComplete) {
// on le découpe à chaque espace ' '
// et on stocke les bouts dans un tableau
splitString(inputString, ' ');

// appel des fonctions selon le premier sélecteur
if (data[0] == "X00/00/00") {
light(data[1].toInt(), data[2].toInt());
}


// vide la chaine
inputString = "";
stringComplete = false;
}
}

// serialEvent()
void serialEvent() {
while (Serial.available()) {

// récupérer le prochain octet (byte ou char) et l'enlever
char inChar = (char)Serial.read();
// concaténation des octets reçus
inputString += inChar;


// caractère de fin pour notre chaine
if (inChar == '\n') {
stringComplete = true;
}
}
}

// méthode pour découper le message avec un séparateur (ou "parser")
void splitString(String message, char separator) {
int index = 0;
cnt = 0;
do {
index = message.indexOf(separator);
// s'il y a bien un caractère séparateur
if(index != 0) {
// on découpe la chaine et on stocke le bout dans le tableau
data[cnt] = message.substring(0,index);
cnt++;
// on enlève du message le bout stocké
message = message.substring(index+1, message.length());
} else {
// après le dernier espace
// on s'assure que la chaine n'est pas vide
if(message.length() > 0) {
data[cnt] = message.substring(0,index); // dernier bout
cnt++;
}
}
} while(index >=0); // tant qu'il y a bien un séparateur dans la chaine
}

// fonction personnalisable
void light(int pin, int brightness) {


Serial.print("Tram ");
Serial.print(pin);
Serial.print(" POST ");
Serial.println(brightness);

//analogWrite(pin,brightness);
}


en fait je reçois ce message à chaque passage d'un tram "X00/00/00 04:45:03 1234 000 B J 019074 A N 00 G 00.00" et je doit afficher ses information sur un écran lcd 16/2

je recouper 1234,B,A,N,G

et je les imprime par exemple : Tram 1234 Post B
Ant A MdF N ED G

Merci à vous
Messages postés
6
Date d'inscription
mardi 12 novembre 2019
Statut
Membre
Dernière intervention
14 novembre 2019

Ce que tu m'as envoyé
Messages postés
5637
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
22 octobre 2021
952
Je t'ai envoyé un exemple en langage C standard illustrant l'usage de la fonction
strtok()
avec une chaîne C codée en dur, et utilisant
printf()
pour afficher le résultat sur la sortie standard, le tout dans une fonction main au standard du C, mais pas de l'Arduino.

Ce n'était donc pas un code à copier coller et injecter à ton Arduino, mais un code dont tu pouvais t'inspirer pour l'intégrer au tiens sous réserve que tu envisages bien de traiter des chaînes C.
Messages postés
5637
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
22 octobre 2021
952
Ta fonction
splitstring()
peut, par exemple, probablement être remplacée par une autre comme suit pour utiliser
strtok()
, qui est une fonction standard du C traitant des chaînes C et non des objets
String
. Il faut d'abord disposer d'une chaîne C obtenue à partir de ton message, dont je fixe la longueur maximale à 55 caractères. Tu peux ensuite remplir ton tableau d'objets
String
en affectant les sous-chaînes C trouvées par
strtok()
reconverties en
String
.

// fonction pour découper le String message selon un séparateur espace 
// avec strtok() et placer le résultat dans un tableau String data[10];
#include <string.h>
#define MAX_LEN_MESSAGE 55
void splitstringwithspaces(String message) {
    if (message.length() > MAX_LEN_MESSAGE) {
        // TODO: erreur message trop long
        return;
    } else {
        char str[MAX_LEN_MESSAGE + 1];
        char * pch;
        int cnt = 0;

        strcpy(str, message.c_str());
        pch = strtok(str," ");
        while (pch != NULL) {
            if (cnt > 10) {
                // TODO: erreur il y a plus de caractères séparateurs que prévu
                return;
            }
            data[cnt] = String(pch);
            cnt++;
            pch = strtok(NULL, " ");
        }
    }
}


Pour tester cette fonction, tu dois l'intégrer dans le code que tu as posté et changer dans la fonction
loop()
l'appel à
splitString(inputString, ' '); 
par un appel à
splitstringwithspaces(inputString);
...

Je n'ai pas pu tester ceci, ne disposant pas d'un Arduino. Le langage Arduino n'étant pas du C ou du C++ standard, il m'est difficile de t'assurer que le code de cette fonction marchera. En particulier pour la ligne 21 qui convertit la chaîne C en objet
String
pouvant être affecté au tableau, je me suis basé sur des messages du forum Arduino (comme celui-ci), mais je n'ai trouvé aucune doc officielle précise Arduino sur le sujet dans ma recherche rapide.

Note aussi qu'en raison des ressources limitées d'un Arduino, il me semble que tu aurais intérêt à n'utiliser que des chaînes C et non pas des objets
String
dans ton code... mais c'est toi qui vois :-)

Je ne peux pas non plus vérifier si ton code d'origine dans
splitstring()
fonctionne ou s'il est incorrect, car je ne peux pas le tester. Les objets
String
sont particuliers à Arduino et disposent de méthodes n'existant pas en C++ dans l'objet
string
standard de ce langage.

Une autre possibilité est, puisque tu récupères la chaîne sur le port série caractère par caractère, de récupérer directement les caractères qui t'intéressent dans la fonction
serialEvent()
en vérifiant à mesure que tu les reçois si c'est un caractère séparateur.

Si tu postes du code sur le forum, veille, s'il te plaît, à utiliser les balises de code pour que ton code s'affiche sur le forum de façon plus lisible.

https://codes-sources.commentcamarche.net/faq/11288-les-balises-de-code
Messages postés
6
Date d'inscription
mardi 12 novembre 2019
Statut
Membre
Dernière intervention
14 novembre 2019

j'ai un petit souci ce que je ne reçois pas la lettre B je reçois un 0 a ça place

Merci a toi
Messages postés
5637
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
22 octobre 2021
952
il va falloir déboguer ton code alors :-)

tu peux déjà commencer par le fait qu'il y a un nombre d'espaces dans le message faisant que tu découpes plus de 10 sous-chaînes (12 si je compte bien) ... ce que tu aurais vu si tu avais implémenté les parties sur la gestion d'erreur en "TODO" ... l'as tu fait ?

ensuite, pour vérifier le résultat du découpage, tu peux afficher successivement le contenu du tableau data[] en affichant ce qui se trouve aux indices de 0 à 11 (en se basant sur un message découpé en 12 sous-chaînes).