On remarque que le format de chaque ligne est <etiquette>(<valeur>[*<unite>])\r\n
La seule subtilité est la présence ou non de l'étoile qui introduit une unité, les autres éléments en bleus sont obligatoires dans cet ordre pour une ligne bien formée
Comme le format est répétitif, il suffit de faire une boucle sur chaque ligne, on va chercher les pointeurs sur les différents éléments et on vérifie un minimum de cohérence, par exemple que les parenthèses sont là, que si on trouve une étoile, pour qu'elle soit valable il faut qu'elle soit avant la parenthèse fermante de cette ligne etc...
Enfin on remarque que la fin d'une trame est notée par "!\r\ne" donc on commencera par tester si on en est là, si oui on a fini l'analyse, sinon on a une ligne à analyser.
Lors de l'analyse, on fait quelques tests pour s'assurer que l'on ne sature pas nos buffers de lecture des différents éléments d'une ligne.
par exemple ce bout de code
char message[] = "F.F(00)\r\n0.0( 2359)\r\nC.1.0(38451126)\r\nC.1.1( )\r\n1.8.1(000011.096*kWh)\r\n1.8.2(000019.999*kWh)\r\n2.8.1(000000.000*kWh)\r\n2.8.2(000000.000*kWh)\r\n5.8.1(000000.000*kvarh)\r\n5.8.2(000000.000*kvarh)\r\n6.8.1(000000.000*kvarh)\r\n6.8.2(000000.000*kvarh)\r\n7.8.1(000000.000*kvarh)\r\n7.8.2(000000.000*kvarh)\r\n8.8.1(000007.226*kvarh)\r\n8.8.2(000005.419*kvarh)\r\n1.8.0(000031.096*kWh)\r\n2.8.0(000000.000*kWh)\r\n5.8.0(000000.000*kvarh)\r\n6.8.0(000000.000*kvarh)\r\n7.8.0(000000.000*kvarh)\r\n8.8.0(000012.645*kvarh)\r\nC.7.0(0006)\r\n32.7(236*V)\r\n52.7(235*V)\r\n72.7(237*V)\r\n31.7(00.139*A)\r\n51.7(001.60*A)\r\n71.7(00.457*A)\r\n33.7(0.16)\r\n53.7(0.90)\r\n73.7(0.65)\r\n13.7(0.83)\r\n82.8.1(0001)\r\n82.8.2(0000)\r\n0.2.0(M29)\r\nC.5.0(0401)\r\n!\r\ne";
// On remarque que le format est <etiquette>(<valeur>[*<unite>])\r\n
const byte maxData = 20;
char etiquette[maxData + 1];
char valeur[maxData + 1];
char unite[maxData + 1];
enum : byte {ANALYSE_OK, ERREUR_FORMAT, ERREUR_DONNEE_TROP_LONGUE} erreur;
void setup() {
char * debutPtr = message;
erreur = ANALYSE_OK;
size_t nbCaracteres;
Serial.begin(115200);
Serial.println(F("\n------------------------------------"));
Serial.println(F(" ANALYSE DU FLUX"));
Serial.println(F("------------------------------------"));
Serial.println(message);
Serial.println(F("------------------------------------\n"));
while (*debutPtr) {
if (strcmp(debutPtr, "!\r\ne") == 0) break; // FIN DU MESSAGE
// -------------------------------------------------------
// ON TROUVE LES SEPARATEURS ET ON FAIT QUELQUES VERIFS
// -------------------------------------------------------
char * parentheseOuvrante = strchr (debutPtr, '(');
char * parentheseFermante = strchr (debutPtr, ')');
char * etoile = strchr (debutPtr, '*');
char * finDeLigne = strchr (debutPtr, '\n');
if ((parentheseOuvrante == NULL) || (parentheseFermante == NULL) || (finDeLigne == NULL) || (parentheseOuvrante > parentheseFermante)) {
erreur = ERREUR_FORMAT;
break;
}
nbCaracteres = parentheseOuvrante - debutPtr;
if (nbCaracteres > maxData) {
erreur = ERREUR_DONNEE_TROP_LONGUE;
break;
}
strncpy(etiquette, debutPtr, nbCaracteres);
etiquette[nbCaracteres] = '\0';
// -------------------------------------------------------
// ON SAUTE LA PARENTHESE OUVRANTE, ON LIT LES DONNEES
// -------------------------------------------------------
debutPtr = parentheseOuvrante + 1;
// LES DONNES SE TERMINENT SOIT PAR UNE PARENTHESE FERMANTE, SOIT PAR UNE *
if ((etoile == NULL) || (etoile > finDeLigne)) {
// On est dans le cas où il n'y as pas d'unités
nbCaracteres = parentheseFermante - debutPtr;
if (nbCaracteres > maxData) {
erreur = ERREUR_DONNEE_TROP_LONGUE;
break;
}
strncpy(valeur, debutPtr, nbCaracteres);
valeur[nbCaracteres] = '\0';
unite[0] = '\0'; // pas d'unités
} else {
// il y a des unités
nbCaracteres = etoile - debutPtr;
if (nbCaracteres > maxData) {
erreur = ERREUR_DONNEE_TROP_LONGUE;
break;
}
strncpy(valeur, debutPtr, nbCaracteres);
valeur[nbCaracteres] = '\0';
// on saute l'étoile
debutPtr = etoile + 1;
nbCaracteres = parentheseFermante - debutPtr;
if (nbCaracteres > maxData) {
erreur = ERREUR_DONNEE_TROP_LONGUE;
break;
}
strncpy(unite, debutPtr, nbCaracteres);
unite[nbCaracteres] = '\0';
}
// On passe au champs suivant
debutPtr = finDeLigne + 1;
Serial.print(F("ETIQUETTE = \"")); Serial.print(etiquette);
Serial.print(F("\", VALEUR = \"")); Serial.print(valeur);
if (unite[0] != '\0') { // si on avait des unités
Serial.print(F("\", UNITE = \"")); Serial.print(unite);
}
Serial.println(F("\""));
} // FIN DU WHILE
if (erreur != ANALYSE_OK) {
Serial.print(F("CODE ERREUR D'ANALYSE = "));
Serial.println(erreur);
} else {
Serial.print(F("FIN CORRECTE D'ANALYSE"));
}
}
void loop() {}
(suite au message suivant)