Go Down

Topic: Fonction strtok (Read 1 time) previous topic - next topic

maccoa

Bonjour , encore moi avec ma chaudière !

j'ai débusquer un petit sketch qui permet de faire un log des data reçue sur un port com , ça tombe bien c'est pile poil se que je cherché ! mais je me suis vite rendue compte que la taille devenait assez énorme en 1h donc pour faire des log sur 24h ou plus ...

je me suis donc demander de quoi j'avais besoin au minimum?
pour info je reçois environ 30 valeur de la chaudière (30 index) sous cette forme

Quote
Kesseltemp.;0126;2;2;°C;


en fouinant sur le fofo j'ai lue un post sur la fonction strtok et je me suis dit "ça c'est se qu'il te faut!"
resultat  j'arrive à juste avoir.

Quote
2;63


soit l'index et la vrai valeur cela fait déja une économie de place sur la uSD

voici le code que j'ai trouvé et un peut adapter .
Quote

/*

   In your program, you would read stuff into a char array.
   For purposes of testing strtok, I'll just set it up
   a "string" in an initialized array.

 */

char arr[30] = {
    "Kesseltemp.;0126;2;2;°C;"
};
    
    
void setup()
{
    Serial.begin(9600);
    Serial.println("Index;Valeur");
}

void loop()
{
    char str[30];
    int val, ind, div;
    int errors = 0;
    
    strcpy(str, arr);

    // First is throwaway unless you want to do strcmp with "!ANG" or some such thing
    char *chpt = strtok(str, ";");
    if (chpt == NULL) {
        Serial.println("First strok returns NULL");
        ++errors;
    }

    if (errors == 0) {
        chpt = strtok(NULL, ";");
        if (chpt == NULL) {
            Serial.println("Second strok returns NULL");
            ++errors;
        }
        else {
            val = atof(chpt);
        }
    }

    if (errors == 0) {
        chpt = strtok(NULL, ";");
        if (chpt == NULL) {
            Serial.println("Third  strok returns NULL");
            ++errors;
        }
        else {
            ind = atof(chpt);
        }
    }

    if (errors == 0) {
        chpt = strtok(NULL, ",\r\n");
        if (chpt == NULL) {
            Serial.println("Fourth strok returns NULL");
            ++errors;
            // This is an input error: do something to handle it.
        }
        div = atof(chpt);
    }
    if (errors == 0) {
      
        Serial.print(ind);
        Serial.print(";");
        Serial.print((val)/(div));
        Serial.println();
    }

    delay(1000);




bon comme on peut le voir c'est facile dans se cas puisque au début c'est moi qui donne "Kesseltemp.;0126;2;2;°C;".
bon je débute alors je commence simple en essayant de comprendre (avec la grippe spo toujours facile :smiley-mr-green:)

le début d'une transmission commence par $ (24) chaque donnée est séparer par un retour chario (0D) et la fin se termine par 1A .
donc si j'ai bien compris àprés il faut etre sur d'avoir tous ce qu'il y'a entre $ et 1A on le met dans le buffer. ça sert à rien s'il manque des infos -> donc on jéte.

se que je comprend pas c'est comment faire quand on ne connait pas la taille du buffer ! en effet dans mon cas cela peut étre variable , la chaudière peut envoyer les données pour les 30 index comme une autre fois elle peut envoyer les données pour 15 index.

pour le moment la plus grande trame que j'ai capturer c'est:

Quote
$ Prêt;0019;1;1;zst;..Kesseltemp.;0126;2;2;°C;..Abgastemp.;0060;3;1;°C;..Abgastemp S;0070;11;1;°C;..Kesselstrg ;0091;4;1;%;..Primärluft ;0000;5;1;%;..Rest O2 ist;0000;6;10;%;..O2 Regler  ;0100;7;1;%;..Sekundärluft;0000;8;1;%;..Saugzug Soll;0000;9;1;%;..SaugzugIst;0000;10;1;U;..Einschub Ist;0000;12;1;%;..O2 Regler Pell ;0031;13;1;%;..Füllstand: ;20700;14;207;%;..Ansauggeschw.;0454;15;100;m/s;..Strom Austrags;0595;16;1000;A;..Fühler 1;0149;17;2;°C;..Kesselsoll ;0080;18;2;°C;..Pufferoben ;0000;20;2;°C;..Pufferunten ;0000;21;2;°C;..Pufferpumpe ;8192;22;1;%;..Boiler 1;0124;23;2;°C;..Vorlauf 1;0036;24;2;°C;..Vorlauf 2;0038;25;2;°C;..HK Pumpe 1;0000;26;1; ;..HK Pumpe 2;0000;27;1; ;..Aussentemp;0030;28;2;°C;..Kollektortemp;0000;29;2;°C;..Betriebsstunden;1221;30;1;h;..Fehler;Kein Fehler ;99;1; ;...


aurriez vous des idées ou une piste à suivre?

merci au fofo .

moribond

Salut,

Je ne me nomme pas fofo mais j'ai pêtre un début de réponse:
http://www.ortholud.com/

chabot380

Salut !



SORS DU CORPS DE MORIBOND   :D

ORDINAUSORE 2Ghz AMD64 QUI S'ALLUME EN 48 SECONDES AVEC UBUNTU 12.04
ARDUINO UNO / Shield Ethernet / RTC DS1307
Programmation Python et j'apprends le C
Technicien Télé Vidéo à la retraite.

barbudor

Si tu connais bien la syntaxe des trames, peut importe qu'elles soient à longueur variable si tu implémente un automate.

Lit le flux caractère par caractère et en fonction du caractère reçu, déplace toi dans un arbre de décision.
Ecrit d'abord l'arbre à la main sur un papier avant de le coder.
N'oublie pas de traiter aussi les cas où le caractère reçu ne correspond pas à un caractère attendu (soit à cause d'une erreur de transmission, soit à cause d'une erreur dans ton arbre) sinon ton automate peut se retrouver bloqué.
Barbuduino: Arduino sur Breadboard & VinciDuino: Clone Leonardo // WR703: Mini-routeur hacké // LauchPad MSP430 et Stellaris // Panda II Arduino-like .NetMF sous VisualC#
RTFC: Read That F.....g Code / RTFD: Read That F.....g Doc / RTFDS: Read That F.....g DataSheet / RTFS: Read That F.....g Schematic / Wot da ya wanna D.I.Y. today ?

maccoa

bon , ça à avancée un petit peut  :)

quand au début du sketch on déclare :
Code: [Select]
char arr[30] = {
    "Kesseltemp.;0126;2;2;°C;"
};


le résulta attendue est : 2;63 et c'est bien se qui s'affiche. donc ok

il faut donc remplacer   char arr[30] par les data qui arrivent via un port com (mega 2560)

me voila donc reparti à la pêche aux infos (je me suis commandé 2/3 livres d'occase sur l'arduino ).

avec se sketch on lit sur le serial puis on "parse" (désoler j'ai pas encore tous les termes en tête)

Quote
char inData[30];
byte index = 0;

void setup()
{
    Serial.begin(57600);
}

void loop()
{
   while(Serial.available() > 0)
   {
   char aChar = Serial.read();
   if(aChar == '\r'|| index==30)
   {
      // End of record detected. Time to parse
Serial.print(inData)
      index = 0;
      inData[index] = NULL;
   }
   else
   {
      inData[index] = aChar;
      index++;
      inData[index] = '\0'; // Keep the string NULL terminated
   }


   }
   
}


donc si mes lectures et TRADUCTIONS (merci google) sont bonne:

dans le sketch qui teste la fonction strtok() nous avons
Code: [Select]
strcpy(str,inData);
ici on copie inData dans str , d'après ce que j'ai lue on pourrait utilisé strlcpy(str,inData,30) qui est moins "gourmand" mais bon déjà la .... on fait simple

à ce moment si je fait un Serial.print(str); c'est toujours ok le terminale affiche les données que j'ai envoyées.
mais après plus rien ne va plus , on passe à:
Code: [Select]
char *chpt = strtok(str, ";");
    if (chpt == NULL) {
        Serial.println("First strok returns NULL");
        ++errors;

et la j'ai un beau : First strok returns NULL

auriez vous une idée info ?
merci

Go Up