eigenes Protokoll auswerten



  • Hallo liebes Forum,

    ich hab mal wieder ein Problem. Wir brauchen ein Programm um Daten die uns auf der Seriellen Schnittstelle (9600bit/s also laaaaangsam) gesendet werden zu verarbeiten.
    Die Daten sind in eine Art Protokoll verpackt. Ich benötige also ein Programm um diese Daten auszuwerden. Ich beschreibe hier mal kurz das Protokoll (Alles in Hex). Es wird jede Sekunde ein Frame gesendet. Innerhalb eines Frames gibt es sogenannte Batches (Unternachrichten) die die Nutzdaten enthalten

    FF FF 00 00- leitet ein Frame ein
    10 2A - Leitet Batch 2A ein
    10 2B - Leitet Batch 2B ein
    10 03 - beendet 2A o. 2B

    Ein Frame sieht also so aus.

    FF FF 00 00 10 2A {ca. 50 byte Nutzdaten} 10 03 10 2B {ca. 100 byte Nutzdaten}

    Das wars schon.

    Was ich von euch will:

    Ich möchte kein fertiges Programm (würde ich eh nicht bekommen) sondern Tips wie man sowas am besten online verabeitet. Alle meine Lösungen mündeten in einem durcheinander an if-else Anweisungen. 😞
    Wie würdet ihr diese Daten verarbeiten?

    Beste Grüße

    Christian



  • Ein Anfang wäre zB folgendes:

    - einen ganzen Frame einlesen (also von FFFF0000 bis vor FFFF0000)
    - dann zwei Byte lesen (die ja ein Batch einleiten).

    dann kannst du zB folgendes machen:

    std::map<string, void (*)(string)> Batchverarbeiter;
    
    void fktFuerBatchA(string inhalt) { }
    void fktFuerBatchB(string inhalt) { }
    // usw.
    
    Batchverarbeiter["102A"] = fktFuerBatchA;
    Batchverarbeiter["102B"] = fktFuerBatchB;
    

    Du erstellst also eine Map von string nach Funtionszeiger. abhängig vom start des batches kannst du so die Verarbeitung beser verteilen:

    // Pseudomäßig
    string frame = frameLesen();
    
    int i = 0;
    while(i < frame.size())
    {
      string batchIdentifier = frame.substr(i, 2);
      // irgendwie das Ende des Batches finden, bzw. bis zum nächsten batchanfang
      string inhalt = frame.substr(i+2, lengthOfBatch(batchIdentifier));
    
      Batchverarbeiter[batchIDentifier](inhalt);   // die jeweilige Funktion für den speziellen Batch aufrufen
    
      i += 2 + inhalt.size();
    }
    

    So kannst du den frame schonmal in die einzelnen Batches leichter zerlegen



  • Was Maxi da vorschlägt ist eine mögliche Form des State Pattern. So als Google Stichwort.



  • Hallo!
    Das würde ich ganz einfach angehen: switch case Anweisung.
    Eine Konvertierung in einen string Index ala Batch["NOT NECESSARY"] = ... halte ich für unnötig. Aber bei der langsamen Schnittstelle ist es wohl eh egal, rattert der Prozi halt ein paar Millionen mal öfter. 😃

    Es werden wohl kaum tausende von Funktionen sein, die es aufzurufen gilt, daher dürfte eine switch case Anweisung genügen. Ansonsten könntest du das Prinzip von Maxi verfolgen und anstelle eines string Index "10 2A" gleich einen Index auf ein Funktionszeigerarray senden, dann hast du direkten 1:1 Zugriff auf die Batchfunktionen, schneller gehts nimma:

    #define BATCHFUNC_QUANTITY 20
    typedef void (*pBatchFunc)(); 
    pBatchFunc pFuncArr[BATCHFUNC_QUANTITY];
    

Anmelden zum Antworten