![]() |
TComPort 4.0, OnRXChar, Zeile erkennen
Hi,
ich stehe vor einem blöden Problem. Ich benutze die TComPort Komponente um mit der RS232 Daten zu empfangen. Diese Daten werden im Ereigniss OnRxChar in einem Richedit als Text hinzugefügt. Je nachdem, wie lange der PC/delphi braucht kommt über OnRxChar das nächste Teilstück von Daten daher. Auch kommen in den Daten die Zeilenumbrüche mit. Nun kann es aber sein, dass beim ersten OnRxChar noch kein Zeilenumbruch dabei war und dieser erst beim zweiten OnRxChar ankommt. Also ca. so: 1. 28wa98ap#$D#$As28ra0 2. 0a00np#$D#$As28wa88 3. ap#$D#$A.... Komplett zusammengefügt schaut es natürlich OK aus:
Code:
Nun möchte ich jede Zeile "Übersetzen". z.B. s28r wird zu Device 0x28, Read usw.
28wa98ap
s28ra00a00np s28wa88ap s28ra00a00np s20wap s21wap s3Cwap s50wap Dieses Übersetzen macht natürlich nur Sinn, wenn die Zeile komplett ist. Nun Frage ich mich wie ich das machen kann, damit ich "live" die Daten übersetzen kann. Aber natürlich nur wenn die Line volständig ist. Gibt es sowas wie ein Event "On new line" in einem Memo/Richedit/... Oder wie könnte man das lösen? Danke! |
AW: TComPort 4.0, OnRXChar, Zeile erkennen
Hoi,
so weit ich mich erinnern kann ist "#0" das Zeilenende / Datenende bei RS232. Lies doch solange ein bis das Zeichen angekommen ist, dann ist deine zeile komplett. cya |
AW: TComPort 4.0, OnRXChar, Zeile erkennen
Schreibe im OnRXChar erstmal alles in einen Puffer-String (immer schön alles hinten anhängen),
dann schaust du am Ende von OnRXChar, ob ein Zeilenumbruch vorhanden ist, nimmst alles vor diesem Zeilenumbruch raus (und inkl. Zeilenumbruch aus dem Puffer löschen), interpretierst/übersetzt es und zeigst es an. Das wiederholen, bis kein Zeilenumbruch mehr erkannt wird. Der Rest verbleibt im Puffer-String, bis weitere Daten eintreffen oder bis die Verbindung getrennt wird. Tja, nun wartest du halt bis zu den nächsten Daten oder auf das Ende und beginnst von vorne. |
AW: TComPort 4.0, OnRXChar, Zeile erkennen
Ein #0 habe ich leider nicht dabei.
Ok, dann werde ich mir mal einen Buffer bauen. Hatte gehofft, dass es dazu schon etwas einfacheres gäbe... ;) |
AW: TComPort 4.0, OnRXChar, Zeile erkennen
Schau Dir mal die Paket-Erkennung in TComPort von Dejan Crnilla an.
Da ist alles drin was Du brauchst. Das OnPaket Event wird erst ausgelöst, wenn die gewünschte Zeichenkombination gefunden wurde, in Deinem Fall also #$0d#$0a. Gruß Erich |
AW: TComPort 4.0, OnRXChar, Zeile erkennen
Werde ich mir noch ansehen!
Zur Zeit habe ich es so gelöst:
Delphi-Quellcode:
function TForm1.SplitBuffer(Value: String; var Data : TStringList): String;
var i : Integer; begin Result := Value; while Pos(#$D#$A, Result) <> 0 do begin i := Pos(#$D#$A, Result); Data.Add(LeftStr(Result, i - 1)); Result := RightStr(Result, Length(Result) - i - 5); end; end;
Delphi-Quellcode:
procedure TForm1.OnRxChar(Sender: TObject; Count: Integer);
var ReceivedData : AnsiString; i, count : Integer; begin ComPort_Connection.ReadStr(ReceivedData, count); TextBuffer := TextBuffer + ReceivedData; NewLines.Clear; TextBuffer := SplitBuffer(TextBuffer, NewLines); // Analyse NewLines here... end; |
AW: TComPort 4.0, OnRXChar, Zeile erkennen
Bei dem "Count" scheint was nicht zu stimmen, denn dieses hast du grade doppelt ... als Parameter und als lokale Variable (aber hier sollte Delphi ja mecker)
ansonsten ... wozu doppelt suchen:
Delphi-Quellcode:
und notfalls kann man es auch direkt in der Schleife verarbeiten und sich so die StringList sparen:
procedure TForm1.SplitBuffer(var Value: String; Data: TStringList);
var i : Integer; begin while true do begin i := Pos(#$D#$A, Value); if i = 0 then exit; Data.Add(LeftStr(Value, i - 1)); // Data.Add(Copy(Value, 1, i - 1)); Delete(Value, i + 1); end; end; procedure TForm1.OnRxChar(Sender: TObject; Count: Integer); var ReceivedData : AnsiString; i: Integer; begin ComPort_Connection.ReadStr(ReceivedData, Count); TextBuffer := TextBuffer + ReceivedData; NewLines.Clear; SplitBuffer(TextBuffer, NewLines); // Analyse NewLines here... end;
Delphi-Quellcode:
und beim Trennen der Verbindung, dann noch den Rest verarbeiten
procedure TForm1.OnRxChar(Sender: TObject; Count: Integer);
var ReceivedData : AnsiString; i: Integer; begin ComPort_Connection.ReadStr(ReceivedData, Count); TextBuffer := TextBuffer + ReceivedData; while true do begin i := Pos(#$D#$A, TextBuffer); if i = 0 then break; Value := LeftStr(TextBuffer, i - 1); // Value := Copy(TextBuffer, 1, i - 1); // Analyse Value here... end; end;
Delphi-Quellcode:
if TextBuffer <> '' then
begin // Analyse TextBuffer here... end; |
AW: TComPort 4.0, OnRXChar, Zeile erkennen
Danke für die Verbesserungen!
Werde ich dann mal testen. Jetzt habe ich noch aber eine andere Frage zu diesem Thema! Über die OnRxChar kommen laufen neue Daten rein. Und das nicht wenig (Baud=230400). Jetzt habe ich das Problem, wenn ich die Stringbearbeitung in der OnRxChar drinnen habe das mir anscheinend der COM-Port/Buffer geblockt wird und mir Daten verloren gehen. Das RS232 Device ist nur über die TX Leitung verbunden. Also nichts mit Handshake usw. Die String-Bearbeitung ist dann auch noch um einiges größer. Wenn ich nur die Daten auslese per ComPort_Connection.ReadStr(ReceivedData, Count) und dann einfach in ein Memo einfüge geht es ohne Probleme. Gibt es da eine leichte Möglichkeit die Daten wohin zu schaufeln, damit der COM-Port nicht gebremst wird? Meine Idee wäre ein Thread, denn ich dauernd die ReceivedData zugebe. Die String Verarbeitung erfolgt dann erst im Thread und dieser Synchronisiert sich dann mit einen Memo für die Ausgabe. Damit sollte der Hauptthread dann nicht blockiert werden. Kann der Hauptthread den Thread per Property eigentlich laufend Daten übergeben oder muss dazu der Thread pausiert werden? Rückwerts Thread->Hauptthread geht ja über Synchronize. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:19 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz