![]() |
Zugriff auf RS232 über TApdComPort und Thread
Hallo zusammen,
ich handle die komplette RS232-Kommunikation in einem Thread. Ziel ist:
Momentan habe ich aber das Problem, dass hin und wieder Antworten verloren gehen. Deshalb die Frage ob an meinem Konstrukt prinzipiell was falsch ist. Dieses sieht stark vereinfacht so aus:
Delphi-Quellcode:
und im Main Thread
unit Unit1;
interface uses Classes, AdPort; type TThreadString = procedure(Value: String) of object; TMyComThread = class(TThread) private FCommand: String; FCommandList: TStringList; FComPort: TApdComPort; FBuf: String; FBusy: Boolean; FResponse: String; FSyncResponse: TThreadString; procedure Execute; procedure SyncResponseEvent; procedure SetResponse(const Value: String); protected procedure ComPortTriggerAvail(CP: TObject; Count: Word); public property Response: String write SetResponse; property SyncResponse: TThreadString read FSyncResponse write FSyncResponse; constructor Create(sEinst: String); destructor Destroy; override; procedure SendCommand(sValue: String); end; implementation procedure TMyComThread.ComPortTriggerAvail(CP: TObject; Count: Word); var i: Integer; cBuf: Char; begin for i := 1 to Count do begin cBuf := Char(FComPort.GetChar); if cBuf = #13 then begin Response := FBuf; FBuf := ''; FBusy := False; end else FBuf := FBuf + cBuf; end; end; constructor TMyComThread.Create(sEinst: String); begin FComPort := TApdComPort.Create(nil); FComPort.OnTriggerAvail := ComPortTriggerAvail; end; destructor TMyComThread.Destroy; begin FComPort.Open := False; FComPort.Free; FCommandList.Free; inherited; end; procedure TMyComThread.Execute; begin FComPort.Open := True; FBusy := False; while not Terminated do begin if not FBusy and (FCommandList.Count > 0) then begin FCommand := FCommandList[0]; FCommandList.Delete(0); FComPort.PutString(AnsiString(FCommand + #13 + #10)); FBusy := True; end; TThread.Sleep(50); end; end; procedure TMyComThread.SendCommand(sValue: String); begin FCommandList.Add(sValue); end; procedure TMyComThread.SetResponse(const Value: String); begin FResponse := Value; Synchronize(SyncResponseEvent); end; procedure TMyComThread.SyncResponseEvent; begin if Assigned(FSyncResponse) then FSyncResponse(FResponse); end; end.
Delphi-Quellcode:
Ich habe aus dem Code alles wie Timeout-Überwachung, unterbrochene Verbindung, wiederholtes senden, falsches Kommando, Kommando ohne Rückgabewert, korrektes beenden, .... raus gelassen
Com := TMyComThread.Create (sEinst);
Com.SyncResponse:= SyncResponse; procedure TForm1.SyncResponse(sMsg: String); begin Edit1.Text:= sMsg; end; procedure TForm1.Button1ClickSender: TObject); begin Com.SendCommand(Edit2.Text); end; Es geht mir hauptsächlich darum
Vor allem bei 2. bin ich mir unsicher. Um Verzögerungen aus dem Main-Thread zu verhindern, schreibe ich die Responses in TForm ebenfalls in eine Liste und arbeite die dann ab. Grüße Gerd |
AW: Zugriff auf RS232 über TApdComPort und Thread
Vielleicht hilft Dir dies weiter ?
![]() ![]() ![]() ![]() ![]() ![]() ![]() Ich nutze für Ähnliches einen auf einem TMemoryStream basierenden, Ringbuffer, könnte aber auch TBytes sein, der von RS232 beschrieben wird. Dieser läuft in einem Thread und behandelt alle Write/Read Prozesse. |
AW: Zugriff auf RS232 über TApdComPort und Thread
Das ist nicht im Thread.
Delphi-Quellcode:
Aber
constructor TMyComThread.Create(sEinst: String);
begin FComPort := TApdComPort.Create(nil); FComPort.OnTriggerAvail := ComPortTriggerAvail; end; destructor TMyComThread.Destroy; begin FComPort.Open := False; FComPort.Free; FCommandList.Free; inherited; end;
Delphi-Quellcode:
und .PutString nicht.
FComPort.Open := False;
-> NICHT thread-save Der Zugriff auf FCommandList ist auch NICHT thread-save. Und wo ist im Contructor das Inherited, bzw.
Delphi-Quellcode:
?
inherited Create(False); // oder True
Vielen solcher Komponenten arbeien selbst mit einem Thread und synchronisieren dann die Events meistens in den Hauptthread. (aber nicht immer) Prüfen wo ComPortTriggerAvail ausgeführt wird. |
AW: Zugriff auf RS232 über TApdComPort und Thread
Ich habe da eine eigene Lösung, basierend auf einem aufgebohrtem TMemoryStream, den Orginalink dazu finde ich gerade nicht mehr,
war was älteres Asiatisches. Der war auch nicht Thread-Save, musste was drumrum gebaut werden. Bei den ganzen Links könnte aber was Passendes für de Fragesteller dabei sein, wenn er sich auf RingBuffer einlassen möchte. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:44 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