AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Problem mit Kommunikation mit Comport über WinApi
Thema durchsuchen
Ansicht
Themen-Optionen

Problem mit Kommunikation mit Comport über WinApi

Ein Thema von hlware · begonnen am 22. Jul 2010 · letzter Beitrag vom 5. Okt 2011
Antwort Antwort
Seite 2 von 2     12   
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.048 Beiträge
 
Delphi 12 Athens
 
#11

AW: Problem mit Kommunikation mit Comport über WinApi

  Alt 5. Okt 2011, 11:53
Was bedeutet die Ausgabe?? 4294967295, -1, -1 das bekomme ich zurück : bei dem Code
Das hatte ich extra nochmal geschrieben.
4294967295 = $FFFFFFFF = -1 (als Integer) = INVALID_HANDLE_VALUE

Der Port konnte also nicht geöffnet werden.
(wie gesagt, das >0 ist vollkommen falsch)

Delphi-Quellcode:
H := CreateFile(...);
if H <> INVALID_HANDLE_VALUE then begin
  ...
end else
  RaiseLastOSError; // oder ShowMessage(SysErrorMessage(GetLastError);
Und schon bekommt man auch die zugehörige Fehlermeldung geliefert.

ich brauche also nur Create, Read und Write für meine Aufgabe?
Wenn das Geräte an dem COM-Port die selben Einstellungen nutzt, wie als Standardwerte im Windows angegeben wurden, dann ja.
Ansonsten mußt du den Port entsprechend konfigurieren. (was dir eben die entsprechenden Komponenten erleichtern)


PS: Mit dem Befehl (als Char) bekommst du ab Delphi 2009 arge Probleme mit dem Unicode.

Tipp: verwende besser den [delphi]-Tag für Quellcodes (der Button mit dem roten Helm).
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.

Geändert von himitsu ( 5. Okt 2011 um 11:57 Uhr)
  Mit Zitat antworten Zitat
hlware

Registriert seit: 2. Jul 2010
Ort: Würzburg
5 Beiträge
 
Turbo Delphi für Win32
 
#12

AW: Problem mit Kommunikation mit Comport über WinApi

  Alt 5. Okt 2011, 12:15
Hallo,

Meine endgültige Lösung sah damals so aus: (Heute würde ich das Grundlegend anders aufbauen, aber es funktionierte)

Delphi-Quellcode:
unit cComDigital;

interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls, ComCtrls;

type
  cCom = class
     public
        
        availablePorts : TStringList;
        
        procedure cComInitialize;

        function GethCom(): Thandle;
        procedure SethCom(hCom2 : THandle);

        procedure ReadAvailableComPorts();

        function ConnectToComPort(Connect : Boolean; Port: String):Boolean;
        function DisconnectComPort(Port: String) : Boolean;

        function WriteDataToCOMPort(cByte: Integer):Boolean;
       

     private
        hCom: THandle;
        DCB: TDCB;
        TimeOut: TCommTimeouts;
        ChosenPort : String;
        
        function SetDCBproperties() : Boolean;
        function SetcComTimeOut() : Boolean;

  end;

implementation

// Klassenimplementierung cCom
procedure cCom.cComInitialize;
begin
    SethCom(0);
end;

procedure cCom.ReadAvailableComPorts;
var
  TestHandle : THandle;
  i : integer;
begin
  availablePorts := TStringList.Create;
  for i := 1 to 10 do
  begin
    TestHandle := CreateFile(PChar({'\\.\COM'}'COM'+IntToStr(i)),GENERIC_READ or GENERIC_WRITE,0,nil,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,LongInt(0));
    if (TestHandle > 0) then
    begin
      availablePorts.Add('COM'+ IntToStr(i));
      CloseHandle(TestHandle);
    end;
  end;
end;

function cCom.SetDCBproperties;
begin
    if hCom > 0 then
    begin
      GetCommState(GethCom(),DCB);
      DCB.DCBlength := SizeOf(DCB);
      DCB.ByteSize := 8;
      DCB.Parity := NoParity;
      DCB.StopBits := TWOSTOPBITS;
      DCB.BaudRate := 2400;
      DCB.Flags := 5123; { Wenn 2 Pins belegt sind } //4113
      DCB.EofChar := #0;
      DCB.ErrorChar := #0;
      DCB.EvtChar := #0;
      DCB.XoffChar := #0;
      DCB.XoffLim := 0;
      DCB.XonChar := #0;
      DCB.XonLim := 0;
      SetCommState(GethCom(),DCB);
    end;
end;

function cCom.SetcComTimeOut;
begin
    if hCom > 0 then
    begin
      GetCommTimeOuts(GethCom(), TimeOut);

      TimeOut.ReadIntervalTimeOut := 100;
      TimeOut.ReadTotalTimeoutMultiplier := 0;
      TimeOut.ReadTotalTimeoutConstant := 250;

      TimeOut.WriteTotalTimeoutMultiplier := 0;
      TimeOut.WriteTotalTimeoutConstant := 200;
      SetCommTimeouts(hCom, TimeOut);
    end;
end;

function cCom.GethCom;
begin
  GethCom := hCom;
end;

function cCom.ConnectToComPort(Connect: Boolean; Port : String) : Boolean;
Var i : Integer;
begin
   // Mit ComPort (hCom) verbinden

    if Connect = True then
    begin
      i := 0;
      while (GethCom <= 0) and (i < 10) do begin
          SethCom((CreateFile(pChar(Port), GENERIC_READ or GENERIC_WRITE,
                              0, nil, OPEN_EXISTING, 0, 0)));
          inc(i);
      end;
      if GethCom() = INVALID_HANDLE_VALUE then begin
          ShowMessage('Fehler '+IntToStr(GetLastError())+': Schnittstelle konnte nicht geöffnet werden!' + #13#10 + 'Bite die richtige Schnittstelle einstellen!');
          ConnectToComPort := false;
      end
      else begin
      // Set DCB, Timeouts etc.
          if SetDCBproperties() then
              begin
                  if SetcComTimeOut() then
                    ConnectToComPort := true
                  else begin
                      ShowMessage('Fehler '+IntToStr(GetLastError())+': Timeouts konnten nicht gesetzt werden!');
                      ConnectToComPort := false;
                  end;
              end
          else begin
              ShowMessage('Fehler '+IntToStr(GetLastError())+': Schnittstellen-Eigenschaften konnten nicht gesetzt werden!');
              ConnectToComPort := false;
          end;
      end;
    end
    else
    begin
          FileClose(GethCom());
          SethCom(0);
    end;

end;

function cCom.DisconnectComPort(Port: String):Boolean;
begin
    ConnectToComPort(false,Port);
end;

function cCom.WriteDataToCOMPort(cByte: Integer) : Boolean;
var i : integer;
    j : char;
begin
// Byte an Com Port schicken
    if GethCom > 0 then
    begin
      j := chr(cByte);
      i := FileWrite(GethCom(), j, 1);
      if i > 0 then WriteDataToCOMPort := True
      else WriteDataToCOMPort := False;
    end;
end;

procedure cCom.SethCom(hCom2: THandle);
begin
  hCom := hCom2;
end;

end.
Verwendet habe ich die Klasse dann so:

Delphi-Quellcode:

procedure TForm1.FormCreate(Sender: TObject);
begin
cCom1 := cDigital.Create();
  cCom1.cComInitialize;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  if cCom1.GethCom > 0 then begin
    FileClose(cCom1.GethCom);
    cCom1.SethCom(0);
  end;
end;
  Mit Zitat antworten Zitat
sneumann
(Gast)

n/a Beiträge
 
#13

AW: Problem mit Kommunikation mit Comport über WinApi

  Alt 5. Okt 2011, 12:31
Was bedeutet die Ausgabe?? 4294967295, -1, -1 das bekomme ich zurück : bei dem Code
Das hatte ich extra nochmal geschrieben.
4294967295 = $FFFFFFFF = -1 (als Integer) = INVALID_HANDLE_VALUE

Der Port konnte also nicht geöffnet werden.
(wie gesagt, das >0 ist vollkommen falsch)

Delphi-Quellcode:
H := CreateFile(...);
if H <> INVALID_HANDLE_VALUE then begin
  ...
end else
  RaiseLastOSError; // oder ShowMessage(SysErrorMessage(GetLastError);
Und schon bekommt man auch die zugehörige Fehlermeldung geliefert.

ich brauche also nur Create, Read und Write für meine Aufgabe?
Wenn das Geräte an dem COM-Port die selben Einstellungen nutzt, wie als Standardwerte im Windows angegeben wurden, dann ja.
Ansonsten mußt du den Port entsprechend konfigurieren. (was dir eben die entsprechenden Komponenten erleichtern)


PS: Mit dem Befehl (als Char) bekommst du ab Delphi 2009 arge Probleme mit dem Unicode.

Tipp: verwende besser den [delphi]-Tag für Quellcodes (der Button mit dem roten Helm).
Woran kann es liegen dass der Port nicht geöffnet werden konnte wahrs alles mögliche sein..

Habe Delphi 7 daher egal..
Ok das heisst ich benutze zum Beispiel von den Comport die komponente zum einstellen der werte und dann benutze ich create , read, write, close, zum öffnen schließen lesen und schreiben

habe jetzt folgende Hinweise und warnungen kompilierne tut er keine fehler nur hinweise warnungen
Delphi-Quellcode:
[Warnung] main.pas(38): Unsicherer Typ 'PChar'
[Hinweis] main.pas(72): Auf 'ComHandle' zugewiesener Wert wird niemals benutzt
[Warnung] main.pas(36): Variable 'ComHandle' ist möglicherweise nicht initialisiert worden
  Mit Zitat antworten Zitat
hlware

Registriert seit: 2. Jul 2010
Ort: Würzburg
5 Beiträge
 
Turbo Delphi für Win32
 
#14

AW: Problem mit Kommunikation mit Comport über WinApi

  Alt 5. Okt 2011, 12:42
Hallo,

Habe einen wichtigen Teil vergessen.

Delphi-Quellcode:
procedure TForm1.ActionConnectToComExecute(Sender: TObject);
Var Portname : String;
begin
   // ConnectToComPort;
  PortName := 'Com'+IntToStr(ComPortNr);
  if ActionConnectToCom.Checked then Begin // Checkbox im Menü
      if cCom1.ConnectToComPort(true, PortName) then
      StatusBar1.Panels[1].Text := PortName + ' Handle: ' + IntToStr(cCom1.GethCom) // Statusmeldung
      else ActionConnectToCom.Checked := false;
  end
  else begin
      cCom1.DisconnectComPort('Com2');
      StatusBar1.Panels[1].Text := 'Disconnnect' + 'Handle: ' + IntToStr(cCom1.GethCom);
  end;

end;
Das mein Code Probleme mit Unicode machen könnte kann durchaus sein, er ist damals auf Turbo Delphi 2006 entstanden.

Tut mir leid, dass er nicht so gut kommentiert ist, dass hielt ich früher noch nicht für nötig.

Ich hoffe es hilft etwas weiter
  Mit Zitat antworten Zitat
Robotiker
(Gast)

n/a Beiträge
 
#15

AW: Problem mit Kommunikation mit Comport über WinApi

  Alt 5. Okt 2011, 12:57
Wenn das Geräte an dem COM-Port die selben Einstellungen nutzt, wie als Standardwerte im Windows angegeben wurden, dann ja.
Windows nutzt die Standardeinstellungen einer seriellen Schnittstelle anscheinend nur zur Initialisierung beim Start.

Das funktioniert soweit einwandfrei, aber nur, wenn ich zuvor einmal eine Verbindung mit einem alten C++ Programm hergestellt und wieder geschlossen habe. Bis zu einem Windows-Neustart gibt es dann keine Probleme mehr.
Das ist der Grund für solche Effekte, die Schnittstelle bleibt, wenn der Rechner läuft, immer auf dem Stand, den das letzte Programm verwendet hat. Das war schon unter Windows NT so und hat sich, meines Wissens nach, seitdem nicht geändert.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 2     12   


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:43 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz