![]() |
COM Port Daten auslesen und auf bestimmtes Char reagieren
Hallo zusammen,
ich habe ein Gerät, welches mir ca. aller 10ms ein Wert über die serielle Schnittstelle liefert. Dieser String hat immer den gleichen Aufbau und endet mit #13#10. Das Gerät kann aber auch andere Daten schicken aber es wird immer mit #13#10 abgeschlossen. In meiner Software habe ich eingestellt, dass ich auf das #10 reagieren möchte und damit das Ende eines Strings erkenne. Leider wird mir immer der komplette Buffer gefüllt den ich bei ReadFile angegeben habe und nicht nur bis zu dem gesetztem RXFlagChar (#10). Zum seriellen Gerät: Baudrate: 19200 Parität: Keine StopBits: 1 Hier ein Ausschnitt, wie ich die serielle Schnittstelle initialisiere:
Delphi-Quellcode:
Die Software läuft soweit und die Kommunikation zum seriellen Gerät ist auch vorhanden nur habe ich wie gesagt das Problem, dass immer der komplette Buffer gefüllt wird, bevor ich ein Event bekomme. Ich hätte gerne ein Event nach jedem #10.
MyHandle := CreateFileA (tmpStr, Generic_Read or Generic_Write, 0, Nil,
Open_Existing, FILE_FLAG_OVERLAPPED, 0); if MyHandle <> INVALID_HANDLE_VALUE then begin if SetupComm (MyHandle, 1024, 1024) then //eigentlich interessiert mich der Buffer nicht da ich immer nur bis #10 erkennen möchte begin FillChar (DCB, SizeOf(TDCB), 0); DCB.DCBlength := SizeOf (TDCB); DCB.BaudRate := 19200; DCB.Flags := $0001; DCB.Parity := 0; DCB.ByteSize := ByteSize; DCB.StopBits := 0; DCB.EvtChar := #10; if SetCommState (MyHandle, DCB) then begin With CommTimeOuts do begin ReadIntervalTimeout := 10; ReadTotalTimeoutMultiplier := 0; ReadTotalTimeoutConstant := 0; WriteTotalTimeoutMultiplier := 0; WriteTotalTimeoutConstant := 0; end; if SetCommTimeouts(SerHandle, CommTimeOuts) then begin if SetCommMask(SerHandle, EV_RXFLAG) then .... Hier der Ausschnitt vom ReadFile:
Delphi-Quellcode:
Kann mir da jemand ein Tip geben wo ich weiter suchen könnte?
rOverlapped.Offset := 0;
rOverlapped.OffsetHigh := 0; ReadFile (MyHandle, ReceiveBuffer, 1024, ReceivedBytes, @rOverlapped); Viele Grüße |
AW: COM Port Daten auslesen und auf bestimmtes Char reagieren
Lies mal, was SetCommState zum EvtChar sagt.
![]() Das steuert nicht was du aussliest. Mit ReadFile liest man immer so viel aus, wie man angibt. Willst du das nicht, mußt du Char-Weise auslesen, oder einen Puffer/Zwischenspeicher verwenden. ![]() |
AW: COM Port Daten auslesen und auf bestimmtes Char reagieren
Wie wäre es mit dem lesen von jeweils einem Char? (wie himitsu´s Vorschlag)
Delphi-Quellcode:
Beispiel:
DCB.EvtChar := #0;
Delphi-Quellcode:
function ReadChar(var MyChar : Char) : boolean; var Buffer : array[0..1] of char; nReadChars : dword; begin if not ReadFile ( MyHandle, Buffer, 1, nReadChars, nil) then begin result := false; exit; end; if nReadChars = 0 then result := false else begin result := true; MyByte := Buffer[0]; end; end; function GetAnswer(const ATimeOutInMS : Cardinal) : String; var i : Integer; TimeStamp : Cardinal; AnswerChars : Array of Char; CurrentChar : Char; begin TimeStamp := GetTickCount; Result := ''; while True do begin if ReadChar(CurrentChar) then begin // #13#10 beendet gültige Antwort: if CurrentChar=#13 then break; SetLength(AnswerChars,Length(AnswerChars)+1); AnswerChars[High(AnswerChars)] := CurrentChar; end; if GetTickCount>TimeStamp+ATimeOutInMS then begin //Result := 'Timeout beim Lesen'; exit; end; end; SetLength(Result,Length(AnswerChars)); for i:= 1 to Length(AnswerChars) do Result[i] := AnswerChars[i]; end Verknüpft mit einem "ATimeOutInMS" von 9 (ms) sollte das deinen Zwecken genügen. Evtl. ist noch was falsch im Code. Nur im Browser getippt; er ist nicht getestet. |
AW: COM Port Daten auslesen und auf bestimmtes Char reagieren
Ok, Zeichenweise auslesen wäre auch noch möglich aber ich dachte das "EvtChar" ist genau dafür da.
Da steht ja: The value of the character used to signal an event. Ich bin davon ausgegangen, dass ich ein Event bekomme wenn das entsprechende Char gefunden wurde im Buffer... Das andere muss ich mir mal genauer angucken von "Photoner" |
AW: COM Port Daten auslesen und auf bestimmtes Char reagieren
Habe anstatt dem ReadFile folgenden Aufruf gemacht:
Delphi-Quellcode:
Darauf wird auf alle Fälle reagiert aber wie komme ich jetzt an die Daten? Nach dem ReadFile stehen die Daten ja in dem übergebenen ReceiveBuffer.
TmpMask := EV_RXFLAG;
WaitCommEvent(MyHandle, TmpMask, @rOverlapped); |
AW: COM Port Daten auslesen und auf bestimmtes Char reagieren
Warum die Comport-Geschichte selber bauen wenn es sie schon fertig gibt?
Komponente TComport Dejan Crnila, kann man mit allen Delphi-Versionen einsetzen und läuft bei mir einwandfrei. |
AW: COM Port Daten auslesen und auf bestimmtes Char reagieren
Zitat:
(Zitat MSDN : "EV_RXFLAG 0x0002 The event character was received and placed in the input buffer. The event character is specified in the device's DCB structure, which is applied to a serial port by using the SetCommState function." ) |
AW: COM Port Daten auslesen und auf bestimmtes Char reagieren
Folgendes habe ich vergessen zu sagen:
Ich brauche zu jedem Wert den ich übermittelt bekommen habe sozusagen ein Zeitstempel wann der Wert eingetroffen ist. Wenn ich jetzt den Buffer sehr groß stelle, dann werden intern "ganz viele" Werte aufgesammelt. Anschließend soll ich die ja einzeln abgrasen und auf das bestimmte Ev_Char prüfen. Ich will ja keine Verzögerung zwischen dem Eingang des Strings und der Weitergabe habe (also kein Buffer von x Strings). Und die Länge vor dem #10 ist auch unterschiedlich. Ein String vor dem #10 kann mal 16 Bytes lang sein, mal aber auch nur 4 Byte oder 18 Bytes... |
AW: COM Port Daten auslesen und auf bestimmtes Char reagieren
Bin beim lesen darauf gestoßen:
Zitat MSDN: ------------------------------------------------------------------------------------------------------------------------------ ReadIntervalTimeout The maximum time allowed to elapse before the arrival of the next byte on the communications line, in milliseconds. If the interval between the arrival of any two bytes exceeds this amount, the ReadFile operation is completed and any buffered data is returned. A value of zero indicates that interval time-outs are not used. A value of MAXDWORD, combined with zero values for both the ReadTotalTimeoutConstant and ReadTotalTimeoutMultiplier members, specifies that the read operation is to return immediately with the bytes that have already been received, even if no bytes have been received. ------------------------------------------------------------------------------------------------------------------------------ Setz das und lese als Reaktion auf dein Event. Dein Event "#10 Empfangen" wird gefeuert --> du hast einen kompletten String im Buffer und einen ziemlich exakten Zeitstempel. Readfile blockiert mit der oben erwähnten Einstellung nicht (Zeitstempel hier ist also auch ok) und kommt sofort zurück (Wenn du 1024 bytes anforderst bekommst du trotzdem nur das was im Buffer -Stichwort ReceivedBytes- ist) Zufrieden :)? |
AW: COM Port Daten auslesen und auf bestimmtes Char reagieren
Also ich würde so etwas immer aufteilen.
Eine Klasse holt Bytefolgen vom ComPort ab und gibt diese mit dem Zeitstempel weiter. Eine Klasse nimmt die Bytefolge/Zeitstempel Nachricht und baut bei jedem Vorkommen von #13#10 eine Nachricht mit Bytefolge/Zeitstempel und gibt diese weiter. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:48 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