![]() |
AW: COM Port Daten auslesen und auf bestimmtes Char reagieren
Readfile liefert in deiner Konstellation falsche Ergebnisse da es
entweder a) mit Overlapped wieder asynchron ist (Rücksprung bevor fertig gelesen) oder b) mit nil beim Overlapped einfach falsche Ergebnisse liefern kann. Du musst das Rückgabeergebnis von Readfile prüfen und wieder auf das Event warten:
Delphi-Quellcode:
Ich muss nochmals auf die Quelle schlechthin, MSDN, hinweisen. Steht alles da.
if not ReadFile(MyHandle, ReceiveBuffer, 1024, nil, @rOverlapped) then
if GetLastError()<>ERROR_IO_PENDING raise Exception.Create('COM Fehler'); case WaitForSingleObject(rOverlapped.hEvent,ATimeOutInMS) of ... ![]() "If hFile is opened with FILE_FLAG_OVERLAPPED, the lpOverlapped parameter must point to a valid and unique OVERLAPPED structure, otherwise the function can incorrectly report that the read operation is complete." "lpNumberOfBytesRead [out, optional] A pointer to the variable that receives the number of bytes read when using a synchronous hFile parameter. ReadFile sets this value to zero before doing any work or error checking. Use NULL for this parameter if this is an asynchronous operation to avoid potentially erroneous results." Unter Remarks: "Synchronization and File Position If hFile is opened with FILE_FLAG_OVERLAPPED, it is an asynchronous file handle; otherwise it is synchronous. The rules for using the OVERLAPPED structure are slightly different for each, as previously noted. Note If a file or device is opened for asynchronous I/O, subsequent calls to functions such as ReadFile using that handle generally return immediately, but can also behave synchronously with respect to blocked execution. For more information see ![]() Considerations for working with asynchronous file handles: ReadFile may return before the read operation is complete. In this scenario, ReadFile returns FALSE and the GetLastError function returns ERROR_IO_PENDING, which allows the calling process to continue while the system completes the read operation. The lpOverlapped parameter must not be NULL and should be used with the following facts in mind: Although the event specified in the OVERLAPPED structure is set and reset automatically by the system, the offset that is specified in the OVERLAPPED structure is not automatically updated. ReadFile resets the event to a nonsignaled state when it begins the I/O operation. The event specified in the OVERLAPPED structure is set to a signaled state when the read operation is complete; until that time, the read operation is considered pending. Because the read operation starts at the offset that is specified in the OVERLAPPED structure, and ReadFile may return before the system-level read operation is complete (read pending), neither the offset nor any other part of the structure should be modified, freed, or reused by the application until the event is signaled (that is, the read completes). If end-of-file (EOF) is detected during asynchronous operations, the call to GetOverlappedResult for that operation returns FALSE and GetLastError returns ERROR_HANDLE_EOF. " |
AW: COM Port Daten auslesen und auf bestimmtes Char reagieren
Ganz im Ernst, egal, ob du einen Zeitstempel brauchst. ReadFile liest das aus, was schon im Cache des Port ist.
Ob du nun mühevoll NUR eine Zeilen ausliest, oder einfach alles und dass dann trennst, ist egal ... DA ist DA. 1 alles in einen Puffer kopieren (Neues hinten anhängen) 2 Zeilenumruch suchen 2.1 bis dahin die erste Zeile ausschneiden 2.2 verarbeiten 2.3 gehe zu 2 3 gehe zu 1 Im eigenen Puffer kann man schneller voraussuchen. Für den internen Puffer gibt es keine Preview. Dauert das Verarbeiten länger, dann die extrahierten Zeilen mit Zeitstempel an einen anderen Thread übergeben. Da es hier um TEXT geht, vielleicht besser ein AnsiChar-Array, einen AnsiString oder einen TStringStream vervenden. PS: AssignFile+ReadLn geht auch bei COM, genauso wie der TStringStream+THandleStream/TFileStream. |
AW: COM Port Daten auslesen und auf bestimmtes Char reagieren
Nil und @rOverlapped ist sicherlich ein Tippfehler oder?
Delphi-Quellcode:
if not ReadFile(MyHandle, ReceiveBuffer, 1024, nil, @rOverlapped) then
Also sollte ich es so machen?
Delphi-Quellcode:
Muss ich mal probieren aber steht dann in den ReceivedBytes nicht wieder 1024 drinne?
while not Terminated do
begin HandleBuffer[0] := rOverlapped.hEvent; HandleBuffer[1] := wOverlapped.hEvent; Return := MsgWaitForMultipleObjects (Handles, HandleBuffer, False, 2000, QS_ALLINPUT); if Terminated then exit; Case Return of WAIT_OBJECT_0 : begin if ReadFile (MyHandle, ReceiveBuffer, 1024, ReceivedBytes, @rOverlapped) then begin ResetEvent(rOverlapped.hEvent); rOverlapped.Offset := 0; rOverlapped.OffsetHigh := 0; if ReceivedBytes > 0 then begin end; end; ... |
AW: COM Port Daten auslesen und auf bestimmtes Char reagieren
@Himitsu:
Zitat:
Aller 9ms steht sozusagen ein neuer Wert am COM an. Den brauche ich mir dem genauen Zeitstempel wann er kam. Der nächste Wert ist dann eben 9ms später. Das ist aber abhängig davon, wie schnell das Gerät sendet. Kann auch mal 12ms oder ähnliches sein... |
AW: COM Port Daten auslesen und auf bestimmtes Char reagieren
Und den bekommst du Niemals raus.
Windows, der Treiber und vorallem dein Programm sind kein Echtzeitsystem. Du kannst den Puffer nur schnell leeren und verarbeiten, womit du Zeitlich am Nächsten an die Empfangszeit ran kommst. Alles unter 20 (sicherheitshalber unter 50) Millisekunden kannst du praktisch vergessen. |
AW: COM Port Daten auslesen und auf bestimmtes Char reagieren
Zitat:
"lpNumberOfBytesRead [out, optional] A pointer to the variable that receives the number of bytes read when using a synchronous hFile parameter. ReadFile sets this value to zero before doing any work or error checking. Use NULL for this parameter if this is an asynchronous operation to avoid potentially erroneous results." Wenn du mit Overlapped arbeitest, steht nichts sinnvolles in diesem Parameter. |
AW: COM Port Daten auslesen und auf bestimmtes Char reagieren
Das lässt sich aber nicht compilieren:
Delphi-Quellcode:
Kannst du mir mal bitte in meinem Beispiel Source von oben zeigen, wie du das genau meinst?
if ReadFile (MyHandle, ReceiveBuffer, 1024, Nil, @rOverlapped) then
@himitsu Das Windows kein Echtzeitsystem ist weiß ich aber wenn ich mal eine Zeitmessung in einem while not Terminated Thread mache, dann komme ich laut Messung auf 10ms |
AW: COM Port Daten auslesen und auf bestimmtes Char reagieren
Bei Asynchronem Zugriff liefert dir die Funktion
![]() den gesuchten Wert. Von der Reihenfolge dann: WaitCommEvent WaitForSingleObject ReadFile WaitForSingleObject GetOverlappedResult Ich habe den Zugriff auf die seriell Schnittstelle bisher nur synchron erledigt. Das mit dem Overlapped macht es sehr viel komplizierter wie man sieht. |
AW: COM Port Daten auslesen und auf bestimmtes Char reagieren
Zitat:
|
AW: COM Port Daten auslesen und auf bestimmtes Char reagieren
Zitat:
Ein anderer Thread arbeit nun den Queue ab. Untersucht den Record. Ist #10 drin den Part bis #10 samt dem ebenfalls im Record befindlichen Zeitstempel wegschreiben. Den Rest auch noch untersuchen. Immer noch ne #10 drin, das ganze wieder. Wenn nicht den Rest merken. Nächsten Record (wenn denn schon einer im Queue ist) vornehmen. An den gemerkten Rest anhängen. Wieder nach #10 suchen. Falls gefunden mit dem neuen Zeitstempel aus dem neuen Record wegschreiben. usw.usw. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:30 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