ComPort auslesen, ist mein Weg wirklich optimal?



  • Hallo.

    Ich habe einen CBuilder2009 und die Komponente TComPort, worüber ich gern den ComPort auslesen möchte. Das funktioniert soweit auch gut, allerdings bin ich ein absoluter Frischling was den ComPort anbelangt und ich glaube ich mache es nicht wirklich richtig, da es zu vermurxt aussieht. Da dies eine allgemein technische Frage ist, gehört es wohl eher nicht ins CBuilder Forum, sondern hier ins WinAPI Forum rein.

    Ich bin der Client und empfange über RS422 vom Server ständig Daten, mit folgendem Aufbau:

    $PLDM,-1,0,2,11223,2011-08-03 12:00:00*CRC<CR><LF>

    Mit Hilfe des TComPort Events OnRxChar, lese ich den Text ein:

    void __fastcall TForm1::ComPortRxChar(TObject *Sender, int Count)
    {
    UnicodeString TextBuf;
    ComPort->ReadStr(TextBuf, Count); // Header-Definition: int __fastcall ReadStr(System::UnicodeString &Str, int Count);
    

    Auf diese Art und Weise erhalte ich immer beliebige Teilstrings, welche ich selbst zusammensetzen muss und erkennen wann etwas anfängt und wo endet, damit ich die Daten korrekt auswerten kann. Beispielsweise erhalte ich folgende fiktive Sendung: "xxx $PLDM,-99999,0,11111,11111,11111,2003-12-31 23:59:24*AA#13#10 xxx" in 10 "Sendungen".

    xxx $PLD
    M,-9999
    9,0,1111
    1,11111,
    11111,2
    003-12-3
    1 23:59:
    24*AA

    xxx

    Um jetzt wieder die Eingabezeile zu erhalten, habe ich folgendes geschrieben:

    void __fastcall TForm1::ComPortRxChar(TObject *Sender, int Count)
    {
    	try
    	{
    		UnicodeString TextBuf;
    		ComPort->ReadStr(TextBuf, Count);
    
    		for (int i=0;i<Count;i++)
    		{
    			// Start
    			if ((ReceivedState==0) && (TextBuf[i+1]==0x24)) // STX::Start of Text '$'
    			{
    				ReceivedState = 1; // Zeichenaufnahme starten, bis ETX::End of Text
    				ReceivedText = "";
    				continue;
    			}
    			// Ende mit (0x0D 0x0A) CR + LF
    			if ((ReceivedText.Length()>0) &&
                	(ReceivedText[ReceivedText.Length()]==0x0D) && (TextBuf[i+1]==0x0A))
    			{
    				Memo->Lines->Add(ReceivedText);
    
    				ReceivedState = 0; // Zeichenaufnahme unterbrechen, bis STX
    				continue;
    			}
    
    			// Nur wenn STX existierte, darf ein Text aufgenommen werden
    			if (ReceivedState==1)
    			{
    				ReceivedText = ReceivedText + TextBuf[i+1];
    			}
    		}
    	}
    	catch(...)
    	{
    		Memo->Lines->Add("\r\nError: " + DateTimeToStr(Now()) + "\r\n");
    	}
    }
    

    Als Ausgabe erhalte ich immer Zeilenweise

    PLDM,-99999,0,11111,11111,11111,2003-12-31 23:59:24*AA

    so wie von mir gewünscht. Aber muss man das tatsächlich so komplex machen oder gibt es da etwas einfacheres? Mich würde jetzt interessieren, ob dies wirklich der korrekte Weg ist oder doch völliges Gaga. Kann dazu jemand etwas sagen? Würde mich sehr darüber freuen. o/



  • Kann keiner etwas dazu sagen? 🙂



  • Der auswert-Teil ist eine Statemaschine (Anfang vorhanden, Ende vorhanden, ...). Das könnte man anders programmieren, aber im wesentlichen bleibt die Statemaschine.


Log in to reply