Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Comport-Exception abfangen und verbindung schließen (https://www.delphipraxis.net/128723-comport-exception-abfangen-und-verbindung-schliessen.html)

delphifant 4. Feb 2009 20:23


Comport-Exception abfangen und verbindung schließen
 
Hallo zusammen,
seit geraumer Zeit erfreue iich mich über die Komponete TComPort. Sie funktioniert eigentlich richtig gut nur bei einer Exception
geht sich richtig ab.Ich bin jetzt schon länger auf der suche nach einer Möglichkeit eine TComport-Excetion sauber abzufangen und meine Verbindung sauber zu schließen. Es handelt sich um Exception die ausgelöst wird im Falle bei dem Abbruch der Kommunikation (z.B. Kabel ziehen).

Vielleicht hatte bei euch auch jemand das Problem und könnte mir einen Tip geben.

Im voraus Danke :oops:

nuclearping 4. Feb 2009 20:43

Re: Comport-Exception abfangen und verbindung schließen
 
Was hast du bisher versucht? try-except-end-Blöcke? Was für eine Exception kommt genau?

divBy0 4. Feb 2009 21:12

Re: Comport-Exception abfangen und verbindung schließen
 
try-except funktioniert doch bestens dabei.

Welche Exception bekommst du denn? Bei mir kam noch nie ein Fehler beim Kabelziehen.

Chemiker 4. Feb 2009 22:51

Re: Comport-Exception abfangen und verbindung schließen
 
Hallo delphifant,

Zitat:

Zitat von divBy0
Bei mir kam noch nie ein Fehler beim Kabelziehen.

Das kann ich bestätigen, in meinem Programm lassen ich einen Trigger mitlaufen, damit das Programm mitbekommt, wenn keine Daten übertragen werden.

Bis bald Chemiker

divBy0 4. Feb 2009 23:47

Re: Comport-Exception abfangen und verbindung schließen
 
Zeig mal deinen Code, wo die Exception auftritt bitte.

delphifant 5. Feb 2009 10:30

Re: Comport-Exception abfangen und verbindung schließen
 
Hallo erstmal danke für eure schnelle Reaktion...

Es Handelt sich hier um das ständige abfragen von Messwerten einer Elektronik...
Delphi-Quellcode:
//++++++++++++++++++++++++++++++++++
//Sender der Message an über Comport
//++++++++++++++++++++++++++++++++++
function TForm1.SendMessagetoCOM(const FTCMessage: String; const interval: word ; var ErrorMsg: String; bSetRich: Boolean): boolean;
var
 iDelay  : word;
 i       : integer;
 MyChar  : Char;
 wfmo,
 LoopMax : word;
begin
 result:= false;
 if ComPort.Connected then
 begin
   
   //MPCComData ist eine globaler Variable (Record)
   MPCComData.text    := '';
   iDelay             := COM_DELAY;  //Const
   wfmo               := 0;
   LoopMax            := COM_LOOP_RECIEVED;

   MPCComData.bRecieved:=   True;
 
 
   // Sender der Chars (mit einer Delay) wegen hoher Bautrate 921600
   for I := 1 to length(FTCMessage) do
   begin
       MyChar:= FTCMessage[i];
       ComPort.WriteStr(MyChar);
       delay( iDelay);
   end;

  i       := 0;
  ErrorMsg := '';

  // Schleife wird durchlaufen und bei Event oder nach Durchlauf von Loop beendet...
  // Rückantwort verarbeiten...
  repeat
    wfmo := WaitForMultipleObjects(length(EventRecieveds), @EventRecieveds, False, interval );

    Application.ProcessMessages;                        //Nur bei Hautthread benötigt...
    inc(i);
    if Application.Terminated then i:=LoopMax;         // oder Thread.terminated
  until (wfmo <> WAIT_TIMEOUT) or ( i = LoopMax);

   MPCComData.bRecieved:=   false;

   if wfmo=0 then
   begin
     if bSetRich then
      RiCOMText.Lines.Add(MPCComData.text);
     result:= true;
   end;

    case wfmo of
      WAIT_OBJECT_0 + 0: ErrorMsg := rsEventRecieved;
      WAIT_OBJECT_0 + 1: ErrorMsg := rsEventCustomer;
      WAIT_OBJECT_0 + 2: ErrorMsg := Format(rsEventSignaled, [WAIT_OBJECT_0 + 3]);
      WAIT_TIMEOUT:  ErrorMsg:= rsTimeOut;
    else
     ErrorMsg:= 'Error';
    end;

    if i= LoopMax then
     ErrorMsg:= 'Loop to end';
 end;
end;

//++++++++++++++++++++++++++++++++++
// Empfangen der Daten
//++++++++++++++++++++++++++++++++++
procedure TForm1.ComPortRxChar(Sender: TObject; Count: Integer);
var
  Str: String;
  i : integer;
   rxBuffer: String ;
begin
  ComPort.ReadStr(Str, Count);

  if MPCComData.bRecieved then
  begin
    for i := 1 to length(str) do
    begin
      if (str[i] = #10) or (str[i] = #13) then
      begin
        MPCComData.text            := rxbuffer;
        MPCComData.bRecieved       := false;
        SetEvent(EventRecieveds[0]);
        break;
      end
      else
        rxbuffer:=rxbuffer+str[i];
    end;
  end;
end;
Wegen der hohen Bautrate ist kein Software-Handshake möglich... also muß ich immer auf eine Antwort warten, damit ich auch eine Steuerung über meine Software ermöglich kann...

Gruß

Delpifant

delphifant 5. Feb 2009 11:51

Re: Comport-Exception abfangen und verbindung schließen
 
Ich habe noch eines vergessen...

Die Exception werden zu einen eigenen Exception-Handler weitergleitet...wo sie auch ankommen.
Delphi-Quellcode:
procedure TForm1.HandleOnException(Sender: TObject; E: Exception);
begin
 
  if (E is EComPort) then
  begin
    //-> Hier wird die Exception hingeleitet
    // Jedoch fand ich noch keinen Weg meine Exception
    // sauber zu verarbeiten
   
     MessageDlg(E.Message, mtError, [mbOk], 0);
  end
  else begin
    screen.Cursor:=crDefault;
    MessageDlg(E.Message, mtError, [mbOk], 0);
  end;
end;
Ok, das noch (es ist eine EComPort-Exception)

P.S. die Sache mit dem Trigger hört sich interessant an
Zitat:

in meinem Programm lassen ich einen Trigger mitlaufen
Vielleicht könnte das schon helfen...könnte hier ein kleine Hilfe gebrauchen

Chemiker 5. Feb 2009 19:08

Re: Comport-Exception abfangen und verbindung schließen
 
Hallo delphifant,

da war ich auf den falschen Dampfer. Ich benutze eine andere Komponente ist auch kostenlos, vielleicht lohnt es sich diese mal anzusehen.

TurboPower Async Prof.

Bis bald Chemiker

delphifant 5. Feb 2009 21:53

Re: Comport-Exception abfangen und verbindung schließen
 
Die TComport-Komponente hat viele gute Seiten...wenn ich jedoch nicht eine Möglichkeit finde das Problem zu lösen werde ich mich wohl nach Alternativen umschauen müssen. Ich habe auch die Komponente
Zitat:

Turbo Power Asynnc Prof
angeschaut...aber die TComport hat es mir angetan. Jedoch finde ich die Idee mit dem Triggern immer noch nicht die schlechteste

messie 6. Feb 2009 07:35

Re: Comport-Exception abfangen und verbindung schließen
 
Du hast meiner Meinung nach noch keine Antwort auf die Verwendung von try...except-Blöcken gegeben. Ich verarbeite meine Exceptions von TComport damit und das funktioniert gut.

Deine Art, Daten zu empfangen, passt nicht gut zur hohen Baudrate. Ich habe das in einer Anwendung mit hoher Datenrate über einen Timer gelöst, der dann den Buffer einsammelt und sortiert.

Grüße, Messie

delphifant 6. Feb 2009 08:54

Re: Comport-Exception abfangen und verbindung schließen
 
Hallo messie,
ich werde nun als nächster Schritt try...except direkt beim senden und empfangen einsetzen. Bis jetzt hoffte ich, ich könne die Exceptions direkt an einen Punkt im Programm abfangen.

Das Senden läuft momentan auch schon über einen Timer... wenn du willst kann ich auch noch gerne Auszüge davon posten. Jedoch findet in der Timer-Routine nur die Verarbeitung der Antworten statt.

Fand es eine nette Lösung in der Sende-Prozedur eine gewisse Zeit auf die Antwort zu warten oder die Prozedur abzubrechen.

Aber ich lasse mich gerne eines besseren belehren und bin um jede Hilfe froh.

messie 6. Feb 2009 09:03

Re: Comport-Exception abfangen und verbindung schließen
 
Erkläre mal Deine Datenübertragung: machst Du Polling-Betrieb, bei dem vom externen Gerät nur auf einen Befehl hin gesendet wird oder schreibt das Gerät die Daten selbständig?

Grüße, Messie

delphifant 6. Feb 2009 09:30

Re: Comport-Exception abfangen und verbindung schließen
 
Hallo messie,
ich arbeite im Pooling-Betrieb. Ich sende meinen Gerät Befehle im IEEE-Standart (*RST) und mein Gerät meldet sich dann mit einer definierten Antwort z.B "OK<CR><LF>". Hier noch ein Außzug aus der

Dokumentation vom Elektroniker
Zitat:

Schnittstelle: virtueller COM-Port an USB
Baudrate: 921600
Datenbits: 8
Parität: keine
Stoppbits: 1
Handshake: OFF

Synchronisation: Es darf immer nur ein Befehl abgesetzt werden.
Jeder Befehl gibt eine Antwort, auf die der PC
warten muss. Erst dann ist das Gerät bereit für den
nächsten Befehl.
(Das erspart BUSY / READY Flags)
Ach, ich habe nun versucht direkt um meine Befehle zur Schnittstelle mit try..exception-Blöcke das Ergebnis ist jedoch das gleiche
Zitat:

... Klasse EComPort mit der Meldung WriteFile function failed (win error code: 5)' ...

messie 6. Feb 2009 09:59

Re: Comport-Exception abfangen und verbindung schließen
 
Also beim Abziehen des seriellen Kabels sollte es mit try..except klappen. Beim Abziehen des USB-Kabels trennt man die Verbindung zweischen Treiber und Hardware. Das habe ich auch noch nicht abfangen können.

Grüße, Messie

delphifant 6. Feb 2009 12:17

Re: Comport-Exception abfangen und verbindung schließen
 
Hallo messie,
genau da befindet sich mein Problem. Ich arbeite über USB.
Wenn der Konflikt zwischen Hardware und Treiber auftritt, aber ich kann mich auch täuschen, sollte ich nun die USB-Events abfragen und hoffen rechtzeitig darauf reagieren zu können.

Ich habe nun mal die USB-Events abgefangen...jedoch muss ich nun noch versuchen das Event herauszufinden welches mich betrifft.-> Also das Handle meinen Treiber zuzuordnen. Vielleicht gelingt es mir so.

Danke für die Hilfe

Koonunga Hill 22. Apr 2009 17:32

Re: Comport-Exception abfangen und verbindung schließen
 
Hallo Leute,

ich schlage mich mit genau dem gleichen Problem herum und bekomme nach dem Ziehen des USB-Kabels von der TComPort Komponente immer die Meldung PurgeComm Function failed on COM4.
Das Problem ist, daß ich den Port gar nicht mehr dis-connecten kann oder an einem anderen gültigen COM-Port anmelden kann. Auch das Abfragen der USB-Messages von WIndows hilft nicht weiter, da der Port ja schon 'weg' ist, wenn das Event auftritt.

Irgendeine Idee, wie ich den ComPort zur Laufzeit wieder DisConnected bekomme??

Gruß, Michael

messie 22. Apr 2009 21:26

Re: Comport-Exception abfangen und verbindung schließen
 
Schwierig.
Eigentlich geht es nur dann, wenn Du auch die Hardware der Gegestelle programmierst. Dann kannst Du eine Art Watchdogfunktion implementieren. Solange der Treiber keine eindeutige Antwort "Hardwareverbindung getrennt" liefert, bist Du weitgehend hilflos.
Das Problem ist, dass der Treiber bei abgezogener Hardware bisher in der Abfrage steckenbleibt. Dann kannst Du ihn auch nicht durch einen anderen Thread deaktivieren.
Wenn man es schaffen könnte, einen Windows-Treiber zur Laufzeit hart zu deaktivieren und neu initialisieren zu können, könnte das klappen, wenn der Treiber beim Fehler (Kabel abgezogen) eine Meldung macht.

Grüße, Messie


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:33 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