Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   TSerial - RS232 ansprechen (https://www.delphipraxis.net/115140-tserial-rs232-ansprechen.html)

Netblaster 6. Jun 2008 15:55


TSerial - RS232 ansprechen
 
Hallo Allerseits,

ich möchte für ein Mikrocontrollerprojekt eine Anwendung in Delphi (7) schreiben, welches Datenpakete seriell senden und empfangen kann.
Ich habe mir die TComPort-Komponente installiert und versuche das damit.Leider ist mein Fachenglisch nicht das beste :gruebel:

Aus Gründen des besseren Verstehens, erhoffe ich mir von der (deutschen) TSerial Komponente von R.Reusch mehr Erfolge als ich bisher habe.

Weiß jemand woher ich noch die TSerial - Komponente bekommen kann, ohne gleich ein Zeitschriftenabbo auslösen zu müssen ???

Danke - Andrej!

arnold mueller 6. Jun 2008 16:03

Re: TSerial - RS232 ansprechen
 
Hallo,

die TSerial Komponente ist lizenzpflichtig. Mit dem Erwerb der entsprechenden Toolbox Zeitschrift erhält man auch eine Lizenz.

Ich habe selbst mal eine Komponente geschrieben, die Du gerne verwenden darfst.

-
arno

Delphi-Quellcode:
unit Com;

interface

uses
  WinTypes, WinProcs, Classes, SysUtils;

type
  TRTSMode = (RTS_DISABLED, RTS_ENABLED, RTS_HANDSHAKE, RTS_TOGGLE);
  TDTRMode = (DTR_DISABLED, DTR_ENABLED, DTR_HANDSHAKE);
  TParity = (NOPARITY, ODDPARITY, EVENPARITY, MARKPARITY, SPACEPARITY);
  TStopbits = (ONESTOPBIT, ONE5STOPBITS, TWOSTOPBITS);
  TCOM = class(TComponent)
  private
    FDCB: TDCB;
    FHandle: Cardinal;
    FTimeouts: TCommTimeouts;
    FError: Cardinal;
    FComNo: byte;
    FBaud: word;
    FParity: TParity;
    FDatabits: byte;
    FStopbits: TStopbits;

    function GetRTS: boolean;
    procedure SetRTS(const Value: boolean);
    function GetDTR: boolean;
    procedure SetDTR(const Value: boolean);
    function GetDCD: boolean;
    function GetDSR: boolean;
    function GetRI: boolean;
    function GetCTS: boolean;
    function GetIsOpen: boolean;
    function GetInBufUsed: cardinal;
    function GetOutBufUsed: cardinal;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;

    function TestComPortAvailable(ComNo: integer): boolean;
    function Open(ComNo: integer; RTSMode: TRTSMode; DTRMode: TDTRMode): boolean;
    function RxFlush: boolean;
    function TxFlush: boolean;
    function Send(Data: Char): boolean; overload;
    function Send(Data: PChar; Len: cardinal): boolean; overload;
    function GetChar(var data: Char): boolean;

    procedure Close;
    procedure Reset;
  published
    property ComNo: byte read FComNo;
    property Baud: word read FBaud write FBaud;
    property Databits: byte read FDatabits write FDatabits;
    property Stopbits: TStopbits read FStopbits write FStopbits;
    property Parity: TParity read FParity write FParity;
    property IsOpen: boolean read GetIsOpen;
    property InBufUsed: cardinal read GetInBufUsed;
    property OutBufUsed: cardinal read GetOutBufUsed;
    property Error: cardinal read FError;
    property RTS: boolean read GetRTS write SetRTS;
    property CTS: boolean read GetCTS;
    property DTR: boolean read GetDTR write SetDTR;
    property DSR: boolean read GetDSR;
    property RI: boolean read GetRI;
    property DCD: boolean read GetDCD;
  end;

var FCOM: TCOM;

implementation


{----------------------------------------------------------------------------------------------}

constructor TCOM.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FHandle := INVALID_HANDLE_VALUE;

  Baud := CBR_9600;
  Databits := 8;
  Parity := NOPARITY;
  StopBits := ONESTOPBIT;
end;

{----------------------------------------------------------------------------------------------}

destructor TCOM.Destroy;
begin
  if IsOpen then Close; { Port schließen falls geöffnet         }
  inherited destroy;
end;

{----------------------------------------------------------------------------------------------}

function TCOM.TestComPortAvailable(ComNo: integer): boolean;
begin
  Result := Open(ComNo, RTS_DISABLED, DTR_DISABLED);
end;

{----------------------------------------------------------------------------------------------}

function TCOM.Open(ComNo: integer; RTSMode: TRTSMode; DTRMode: TDTRMode): boolean;
var init: string;
begin
  if FHandle = INVALID_HANDLE_VALUE then
  begin
    init := '\\.\COM' + IntToStr(ComNo);
    FHandle := CreateFile(@init[1],
      GENERIC_READ or GENERIC_WRITE,
      0, nil,
      OPEN_EXISTING,
      FILE_ATTRIBUTE_NORMAL,
      0);
    if FHandle <> INVALID_HANDLE_VALUE then
    begin
      FComNo := ComNo;
      // aktuelle Einstellungen ermitteln
      if GetCommState(FHandle, FDCB) then
      begin
        // rudimentäre Parameter setzen
        FDCB.Baudrate := FBaud;
        FDCB.Bytesize := Databits;
        FDCB.Parity := Ord(FParity);
        FDCB.Stopbits := Ord(FStopbits);

        // RTS Modus setzen
        FDCB.flags := FDCB.flags and $CFFB; {RTS aus}
        case RTSMode of
          RTS_ENABLED: FDCB.flags := FDCB.flags or $1000; {RTS ein}
          RTS_HANDSHAKE: FDCB.flags := FDCB.flags or $2004; {RTS Handshake ein (gekoppelt an RX Buffer 0= Empfangspuffer zu 3/4 voll)}
          RTS_TOGGLE: FDCB.flags := FDCB.flags or $3000; {RTS gekoppelt an Tx Buffer (1=Daten im Sendepuffer)}
        end;
        // DTR Modus setzen
        FDCB.flags := FDCB.flags and $FFC7; {DTR aus (und bleibt aus)}
        case DTRMode of
          DTR_ENABLED: FDCB.flags := FDCB.flags or $0010; {DTR ein (und bleibt ein)}
          DTR_HANDSHAKE: FDCB.flags := FDCB.flags or $0028; {DTR Handshake ein}
        end;

        if SetCommState(FHandle, FDCB) then
        begin
          if SetupComm(FHandle, 1024, 1024) then {Rx-/Tx-Buffer-Einstellungen}
          begin
            FTimeouts.ReadIntervalTimeout := 0; {Timeoutzeiten setzen}
            FTimeouts.ReadTotalTimeoutMultiplier := 0;
            FTimeouts.ReadTotalTimeoutConstant := 1;
            FTimeouts.WriteTotalTimeoutMultiplier := 0;
            FTimeouts.WriteTotalTimeoutConstant := 0;
            SetCommTimeouts(FHandle, FTimeouts);
          end;
        end;
      end;
    end;
  end;

  FError := GetLastError;

  if Error <> 0 then
  begin
    Close;
  end;

  Result := Error = 0; { Ergebnis zurückgeben                  }
end;

{-----------------------------------------------------------------------------------------------}

function TCOM.GetCTS: boolean;
var nStatus: cardinal;
begin
  Result := false;
  if FHandle <> INVALID_HANDLE_VALUE then
  begin
    if GetCommModemStatus(FHandle, nStatus) then
      Result := (nStatus and MS_CTS_ON) > 0;
  end;
end;

{-----------------------------------------------------------------------------------------------}

function TCOM.GetDSR: boolean;
var nStatus: cardinal;
begin
  Result := false;
  if FHandle <> INVALID_HANDLE_VALUE then
  begin
    if GetCommModemStatus(FHandle, nStatus) then
      Result := (nStatus and MS_DSR_ON) > 0;
  end;
end;

{-----------------------------------------------------------------------------------------------}

function TCOM.GetIsOpen: boolean;
begin
  Result := FHandle <> INVALID_HANDLE_VALUE;
end;

{-----------------------------------------------------------------------------------------------}

function TCOM.GetInBufUsed: cardinal;
var
  Comstat: _Comstat;
  Errors: DWord;
begin
  if ClearCommError(FHandle, Errors, @Comstat) then
    Result := Comstat.cbInQue else Result := 0;
end;
{-----------------------------------------------------------------------------------------------}

function TCOM.GetOutBufUsed: cardinal;
var
  Comstat: _Comstat;
  Errors: DWord;
begin
  if ClearCommError(FHandle, Errors, @Comstat) then
    Result := Comstat.cbOutQue else Result := 0;
end;

{-----------------------------------------------------------------------------------------------}

function TCOM.GetRI: boolean;
var nStatus: cardinal;
begin
  Result := false;
  if FHandle <> INVALID_HANDLE_VALUE then
  begin
    if GetCommModemStatus(FHandle, nStatus) then
      Result := (nStatus and MS_RING_ON) > 0;
  end;
end;

{-----------------------------------------------------------------------------------------------}

function TCOM.GetRTS: boolean;
begin
  Result := false;
  if GetCommState(FHandle, FDCB) then
  begin
    Result := (FDCB.Flags and $3000) > 0;
  end;
end;

{-----------------------------------------------------------------------------------------------}

procedure TCOM.SetRTS(const Value: boolean);
begin
  if (Value = True) then
    EscapeCommFunction(FHandle, WinTypes.SETRTS)
  else
    EscapeCommFunction(FHandle, WinTypes.CLRRTS);
end;

{-----------------------------------------------------------------------------------------------}

function TCOM.GetDTR: boolean;
begin
  Result := false;
  if GetCommState(FHandle, FDCB) then
  begin
    Result := (FDCB.Flags and $0010) > 0;
  end;
end;
{-----------------------------------------------------------------------------------------------}

procedure TCOM.SetDTR(const Value: boolean);
begin
  if (Value = True) then
    EscapeCommFunction(FHandle, WinTypes.SETDTR)
  else
    EscapeCommFunction(FHandle, WinTypes.CLRDTR);
end;
{-----------------------------------------------------------------------------------------------}

function TCOM.GetDCD: boolean;
var nStatus: cardinal;
begin
  Result := false;
  if FHandle <> INVALID_HANDLE_VALUE then
  begin
    if GetCommModemStatus(FHandle, nStatus) then
      Result := (nStatus and MS_RLSD_ON) > 0;
  end;
end;


{-----------------------------------------------------------------------------------------------}

procedure TCOM.Close;
begin
  if CloseHandle(FHandle) then { Schnittstelle schließen               }
    FHandle := INVALID_HANDLE_VALUE;

  FError := GetLastError;
end;

{-----------------------------------------------------------------------------------------------}

procedure TCOM.Reset;
begin
  if not EscapeCommFunction(FHandle, WinTypes.RESETDEV) then
    FError := GetLastError;
end;

{-----------------------------------------------------------------------------------------------}

function TCOM.RxFlush: boolean;
begin
  if FHandle <> INVALID_HANDLE_VALUE then
  begin
    PurgeComm(FHandle, PURGE_RXCLEAR);
    FError := GetLastError;
  end;

  Result := FError = 0;
end;

{-----------------------------------------------------------------------------------------------}

function TCOM.TxFlush: boolean;
begin
  if FHandle <> INVALID_HANDLE_VALUE then
  begin
    PurgeComm(FHandle, PURGE_TXCLEAR);
    FError := GetLastError;
  end;

  Result := FError = 0;
end;

{-----------------------------------------------------------------------------------------------}

function TCOM.Send(Data: Char): boolean;
var nWritten, nCount: Cardinal;
begin
  Result := false;

  if FHandle <> INVALID_HANDLE_VALUE then
  begin
    nCount := SizeOf(Data);
    if WriteFile(FHandle, Data, nCount, nWritten, nil) then
    begin
      Result := nCount = nWritten;
    end;
    FError := GetLastError;
  end;
end;

{-----------------------------------------------------------------------------------------------}

function TCOM.Send(Data: PChar; Len: cardinal): boolean;
var nWritten, nCount: Cardinal;
begin
  Result := false;

  if FHandle <> INVALID_HANDLE_VALUE then
  begin
    nCount := Len;
    if WriteFile(FHandle, Data^, nCount, nWritten, nil) then
    begin
      Result := nCount = nWritten;
    end;
    FError := GetLastError;
  end;
end;

{-----------------------------------------------------------------------------------------------}

function TCOM.GetChar(var data: Char): boolean;
var nCount, nRead: cardinal;
begin
  Result := false;

  if FHandle <> INVALID_HANDLE_VALUE then
  begin
    nCount := SizeOf(data);

    if InBufUsed >= nCount then
    begin
      if ReadFile(FHandle, data, nCount, nRead, nil) then
      begin
        Result := nCount = nRead;
      end;
    end;

    FError := GetLastError;
  end;
end;


end.

Netblaster 6. Jun 2008 16:07

Re: TSerial - RS232 ansprechen
 
Hi Arno,

danke für deine Antwort - ich werde umgehend mal deine Komponente ausprobieren. :thumb:
Wenn ich Fragen habe darf ich mich doch melden :coder:

Grüße - Andrej!

LDericher 22. Aug 2008 23:21

Re: TSerial - RS232 ansprechen
 
Sehr übersichtlich, sehr benutzerfreundlich, einfach TOP!

:hello: :spin: :thumb: :bounce1: :bouncing4: :bounce2: :dancer2: :dancer:

wirklich tolle Unit! einfach einbinden, geht, hab ich vorher noch NIE gehabt!
Perfekt, ich freue mich!

LG Superwinger

Edit:
Zitat:

Zitat von Dr. Fluke Hawkins (in MDK2, Level 9 Intro)
Es ist brillant! Es ist einfach! Es iiist - Wissenschaft!


LuJ 10. Sep 2008 12:11

Re: TSerial - RS232 ansprechen
 
Guten Tag,
ich (Neuling/ahnungslos)bin im Zuge eines Schulprojekts auf dieses Forum und diesen Thread gestoßen.
Auch bei uns ein Mikrocontrollerprojekt.
Unser Problem ist im Wesentlichen, den Quelltext von arnold mueller zu verstehen (einsetzen ist kein Problem- aber man muss ja auch verstehen was passiert).
Unser Kernproblem hierbei ist die TCOM.Send Funktion.
Wenns nicht zuviel verlangt wäre, würde es uns sehr weiterhelfen, wenn jemand versuchen würde, den Quelltext etwas zu erläutern und zu kommentieren, damit wir effektiv mit der Komponente arbeiten können.

Und wenns geht, dabei berücksichtigen, das wir auf dem Stand Stufe 13.1 sind- wenig Fachchinesisch und viel "Zeile xy hängt zusammen mit Zeile z und löst dieses und jenes aus"

Vielen Dank im Voraus, falls sich jemand die Mühe macht- ein paar armen, verzweifelten Schülern könnte damit sehr geholfen werden!

-LuJ-
:glaskugel:

Nersgatt 12. Sep 2008 14:07

Re: TSerial - RS232 ansprechen
 
Moin!

Zitat:

Zitat von LuJ
Wenns nicht zuviel verlangt wäre, würde es uns sehr weiterhelfen, wenn jemand versuchen würde, den Quelltext etwas zu erläutern und zu kommentieren, damit wir effektiv mit der Komponente arbeiten können.

Wo genau hakt es denn im Verständnis? Prinzipiell wird ein COM-Port ähnlich wie eine Datei behandelt. Bei der Send-Funktion werden die zu sendenden Daten einfach nur in diese "Datei" geschrieben.

Gruß,
Jens

angos 12. Sep 2008 14:49

Re: TSerial - RS232 ansprechen
 
Zitat:

Zitat von LuJ
[...]Unser Kernproblem hierbei ist die TCOM.Send Funktion.[...]

Delphi-Quellcode:

function TCOM.Send(Data: Char): boolean;
var
  nWritten, nCount: Cardinal;
begin
  Result := false; // Initialisierung

  if FHandle <> INVALID_HANDLE_VALUE then // Wenn der Comport aktiviert ist und daher benutzt werden kann
  begin
    nCount := SizeOf(Data); // Zählvariable auf die Größe der zu übertragenden Daten setzen

    // FHandle = Handle des Comports, Data = zu sendende Daten, nCount = Größe von Data
    // nWritten = gesendete Anzahl an Daten. Diese Variable wird von WriteFile gefüllt
    if WriteFile(FHandle, Data, nCount, nWritten, nil) then // und Daten abschicken.
    begin
      Result := nCount = nWritten; // Wenn alle Daten übertragen wurden ist die Funktion erfolgreich
    end;
    FError := GetLastError;
  end;
end;
HTH

LuJ 15. Sep 2008 06:29

Re: TSerial - RS232 ansprechen
 
Zitat:

Zitat von Nersgatt
Moin!

Zitat:

Zitat von LuJ
Wenns nicht zuviel verlangt wäre, würde es uns sehr weiterhelfen, wenn jemand versuchen würde, den Quelltext etwas zu erläutern und zu kommentieren, damit wir effektiv mit der Komponente arbeiten können.

Wo genau hakt es denn im Verständnis? Prinzipiell wird ein COM-Port ähnlich wie eine Datei behandelt. Bei der Send-Funktion werden die zu sendenden Daten einfach nur in diese "Datei" geschrieben.

Gruß,
Jens

Sorry für die lange Abwesenheit.

Beim Verständnis an und für sich hakts nicht, mit dem Prinzip kommt man noch klar. Bei der Aufschlüsselung des Quelltextes hakts dann aber- deshalb auch vielen Dank an angos für die Mühe!

Ich denke das bringt uns ein Stückchen weiter :)


Edit: Wenn man voraussetzt, dass an der seriellen Schnittstelle nichts dranhängt (Nullmodemkabel zB), würde das Programm dann immer bei " FHandle = INVALID_HANDLE_VALUE " den Geist aufgeben?

Oder anders formuliert, wenn an der seriellen Schnittstelle keine "Verbindung" hängt, welche Reaktion des Programms würdet ihr erwarten?

christian_u 16. Sep 2008 10:41

Re: TSerial - RS232 ansprechen
 
Es gibt keine Möglichkeit herauszufinden ob etwas an der Schnittstelle hängt, die daten werden dann also einfach ins nirvana gesendet.

arnold mueller 16. Sep 2008 11:07

Re: TSerial - RS232 ansprechen
 
Zitat:

Zitat von christian_u
Es gibt keine Möglichkeit herauszufinden ob etwas an der Schnittstelle hängt, die daten werden dann also einfach ins nirvana gesendet.

Die Handshake Leitungen DTR/DSR nutzt man normalerweise, um herauszufinden, ob die Gegenstelle angeschlossen ist.

Grundlagen gibt es hier:
http://www.sprut.de/electronic/inter...s232/rs232.htm

-
arno

LuJ 16. Sep 2008 14:10

Re: TSerial - RS232 ansprechen
 
Zitat:

Zitat von christian_u
Es gibt keine Möglichkeit herauszufinden ob etwas an der Schnittstelle hängt, die daten werden dann also einfach ins nirvana gesendet.

Also keine Fehlermeldung, kein Aufhängen oder derartiges?
Mist... dann machen wirs wohl nach wie vor falsch.

An diesem Punkt: "FHandle = INVALID_HANDLE_VALUE" hängt sich unser Programm jedes Mal auf.

Hätte jemand vielleicht ein kleines Anwendungsbeispiel für das Ausführen von arnold muellers Quelltext? Also was ganz simples, bspw. die Ausgabe eines Buchstaben über die serielle Schnittstelle- einfach ins Nirvana hinein, ohne jeden Sinn, einfach als Beispiel.

arnold mueller 16. Sep 2008 14:52

Re: TSerial - RS232 ansprechen
 
Das Beispiel sendet ein Hallo Welt über COM1 und wartet 1 Sekunde auf Antwort.

Delphi-Quellcode:

procedure TForm1.ButtonClick(Sender: TObject);
var c: Char;
    tx_buffer, rx_buffer: string;
    tick: cardinal;
begin
  tx_buffer := 'Hallo Welt!';

  with TCom.Create(nil) do
  try
    // com 1 öffnen
    if Open(1,RTS_DISABLED,DTR_DISABLED) then
    begin
      // senden
      if Send(PChar(tx_buffer),Length(tx_buffer))then
      begin
        tick := GetTickCount;

        // 1 Sekunde auf Daten warten
        repeat

           // Daten aus der Schnittstelle lesen, sofern vorhanden
           if GetChar(c) then
           begin
             rx_buffer := rx_buffer + c;
           end;

        until (GetTickCount-Tick) > 1000;
      end;
    end;
  finally
    // com 1 schließen
    Close;
    Free;
  end;
end;
-
arno

LuJ 17. Sep 2008 12:13

Re: TSerial - RS232 ansprechen
 
Danke, wunderbar!
Das Beispiel hilft uns schonmal extrem viel weiter, wir habens jetzt soweit, das unsere Kommunikation einseitig funktioniert- also setzen wir uns ans Nächste...

...d.h. ich melde mich sicher bald nochmal mit weiteren Fragen ;9
Danke schonmal für eure bisherige Geduld!

zebrafalke 7. Nov 2008 13:50

Re: TSerial - RS232 ansprechen
 
Hallo,
ich mache auch gerade was mit Microcontrollern und habe die unit oben auch mal ausprobiert. Sie funktioniert mit dem Beispielcode von arnold mueller auch sehr gut. Jetzt möchte ich aber nicht, wie im Beispiel, 1 Sekunde auf Daten warten, sondern dauerhaft auslesen um dann z.b. bei bestimmten gesendeten zeichen einzelne daten aus dem datenstrom entnehmen. Hat da jemd eine Idee, ob/wie sich das bewerkstelligen ließe?

Gruß
zebrafalke

Chemiker 7. Nov 2008 17:00

Re: TSerial - RS232 ansprechen
 
Hallo zebrafalke,

es gibt noch bei Sourceforge die Komponente Async Professional mit der man eigentlich sehr gut die Serielle Schnittstelle auslesen kann. Dort sind unter anderem auch Demos mit dabei.

Du hast jetzt nicht genau geschrieben welche Daten (in welcher Form) die Daten anfallen.
Aber ich postuliere mal, dass das mit dieser Komponente gehen müsste.

Async Professional

Bis bald Chemiker

Chriss112 11. Feb 2009 21:00

Re: TSerial - RS232 ansprechen
 
´Hallo!
hab mal ne frage und zwar is da ne funktion dabei, die mir sagt ob an irgeneinem pin ein signal anliegt?

Chemiker 11. Feb 2009 21:14

Re: TSerial - RS232 ansprechen
 
Hallo Chriss112,

in Post #15 steht der Link zum Downloaden der Komponente, dabei ist auch eine sehr ausführliche Hilfe.

Man kann bestimmte Zustände mit einem "TriggerStatus" anzeigen lassen.

Bis bald Chemiker

Chriss112 11. Feb 2009 21:58

Re: TSerial - RS232 ansprechen
 
Vielen Dank!

hadschi92 4. Jun 2009 16:03

Re: TSerial - RS232 ansprechen
 
Dann hätte ich doch auch mal eine Frage.

Ich möchte eine dauerhafte Spannung an einem Pin anliegen haben, mein Code sieht bis jetzt so aus:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var Zeichen : char;
begin
  if Button1.Caption = 'Start' then begin
    Button1.Caption := 'Stop';
    Zeichen := 'ÿ';
    with TCom.Create(nil) do
    try
      Label2.Caption := 'läuft';
      Label2.Font.Color := clLime;
      if Open(1,RTS_DISABLED,DTR_DISABLED) then
        while Button1.Caption = 'Stop' do begin
          Send(Zeichen);
          Application.ProcessMessages;
        end;
    finally
      Label2.Caption := 'gestoppt';
      Label2.Font.Color := clRed;
      Button1.Caption := 'Start';
      Close;
      Free;
    end;
  end
  else Button1.Caption := 'Start';
end;
Das Zeichen 'ÿ' habe ich genommen, weil es als Byte dargestellt "1111 1111" ist und daher dauernd Spannung anliegen müsste. Ich weiß zwar nicht ob mein Gedankengang bis jetzt richtig ist, doch ich weiß nicht an welchem Pin das Signal ausgegeben wird. Kann man das auch einstellen oder wird es auf allen Pins ausgegeben?

Hinzufügen möchte ich, dass ich ein altes Kabel einer Maus angeschlossen habe und dieses aufgeschnitten habe.Diese Kabel hat aber nur 5 Adern, kann ich damit überhaupt arbeiten?

Edit:
Zitat:

Objekte, die als Typ char deklariert sind, können jedes Zeichen aus dem nicht erweiterten ASCII-Zeichensatz aufnehmen.
Funktioniert das überhaupt mit meinem Zeichen, denn es kommt im ASCII-Zeichensatz gar nicht vor!?

Klaus01 4. Jun 2009 16:17

Re: TSerial - RS232 ansprechen
 
.. Du hast eine serielle Verbindung
also sollten die Daten auf dem TX Pin anliegen.
Sie liegen aber nicht daherhaft an, wenn ich micht recht
entsinne kommen nach 8 Datenbits Steuersignale (siehe dazu hier)

Grüße
Klaus

hadschi92 4. Jun 2009 17:12

Re: TSerial - RS232 ansprechen
 
Ok, es funktioniert jetzt einigermaßen. Schließe ich eine LED zwischen Pin 3 (Sendedaten) und Pin 5 (Ground) so leuchtet die LED wenn ich meine Funktion anschalte und wenn ich sie wieder deaktiviere, dann leuchtet die LED nicht mehr. Schließe ich die LED jedoch verkehrt herum an, dann leuchtet sie immer, auch wenn kein Signal gegeben werden sollte.

Ich werde noch irgendwann ausprobieren, ob man verschiedene Signale geben kann, denn bei einem 0-Bit wird anscheinend eine positive Spannung abgegeben und bei einem 1-Bit eine negative Spannung. Vielleicht wird das aber auch von Stopbits und anderen Bits die mitgesendet werden überdeckt.

Klaus01 4. Jun 2009 17:46

Re: TSerial - RS232 ansprechen
 
Zitat:

Zitat von hadschi92
Ok, es funktioniert jetzt einigermaßen. Schließe ich eine LED zwischen Pin 3 (Sendedaten) und Pin 5 (Ground) so leuchtet die LED wenn ich meine Funktion anschalte und wenn ich sie wieder deaktiviere, dann leuchtet die LED nicht mehr. Schließe ich die LED jedoch verkehrt herum an, dann leuchtet sie immer, auch wenn kein Signal gegeben werden sollte.

.. das mag daran liegen, dass die Logische Eins auf -12V liegt und die
logische Null auf +12V.

Du solltest aber vorsichtig damit sein, Verbraucher direkt an die Schnittstelle anszuschließen.
Du solltest zumindest eine galvanische Trennung haben - das ist in manchen Fälllen für den PC
überlebenswichtig.

Grüße
Klaus

hadschi92 4. Jun 2009 18:10

Re: TSerial - RS232 ansprechen
 
Wann kann dies gefährlich werden, wenn Kurzschlüsse entstehen, oder wenn zu viel Spannung auf den PC kommt? Würde ein MOSFET oder ein Transistor dazu ausreichen? Diese schalten ja nur wenn negative Spannung richtig anliegt, so sollte man dann auch richtig Ströme schalten können.

Was ich jedoch schade finde, ist dass man nur eine Leitung schalten kann. Ich werde mich mal auf Conrad umsehen, ob ich nicht irgendeine Platine mit USB Interface finde, die mehr kann. Vielleicht kennt jemand von euch auch eine gute.

Cyf 4. Jun 2009 19:09

Re: TSerial - RS232 ansprechen
 
Zitat:

Zitat von hadschi92
Wann kann dies gefährlich werden, wenn Kurzschlüsse entstehen, oder wenn zu viel Spannung auf den PC kommt? Würde ein MOSFET oder ein Transistor dazu ausreichen? Diese schalten ja nur wenn negative Spannung richtig anliegt, so sollte man dann auch richtig Ströme schalten können.

Was ich jedoch schade finde, ist dass man nur eine Leitung schalten kann. Ich werde mich mal auf Conrad umsehen, ob ich nicht irgendeine Platine mit USB Interface finde, die mehr kann. Vielleicht kennt jemand von euch auch eine gute.

Die Sache ist ja hier, dass du nur einen Pin "schalten" kannst, weil du mit der seriellen Schnittstelle arbeitest und der Rest nunmal Steuersignale sind, die durch das Protokoll vorgegeben sind. Wenn du die Steuerpins manuell schalten würdest, oder die parallele Schnittstelle (IEEE 1284) nutzen, könntest du mehr Pins als IO-Pins missbrauchen, allerdings geht das unter Windows NT nur noch im Kernelmode und bedarf entweder eines Treibers, der Anfragen durchreicht oder die entsprechenden DMA-Bereiche im für Usermode-Programme freigibt.
Probleme könnten hier eher entstehen, wenn zu große Ströme direkt an den Schnittstellen hängen. Eine galvanische Trennung wäre als spontane Idee wohl mit Optokopplern zu erreichen, aber bis jetzt hab ich eigentlich (am LPT) auch MOSFET benutzt.

Lee500 20. Okt 2009 15:28

Re: TSerial - RS232 ansprechen
 
Hallihallo,

Ich habe auch vor mit einem Mikrocontroller zu komunizieren. Im HyperTerminal funktioniert das bereits. Das läuft in etwa so:
Ich sende ein beliebiges Zeichen und der Controller antwortet mit 8 Bytes. Wie gesagt im HT läuft es wunderbar, aber mein Programm will noch nicht so richtig.

Folgenden Code nutze ich: (abgeändert vom Beispielcode weiter vorn)
Delphi-Quellcode:
procedure TForm1.readcomClick(Sender: TObject);
var c: Char;
    digits: array [0..7] of string;
    tick: cardinal;
    count: Integer;
begin
  c := 'x'; // zu sendendes Zeichen

  with TCom.Create(nil) do
  try
    // com öffnen
    if Open(COM,RTS_DISABLED,DTR_DISABLED) then
    begin
      // senden
      if Send(c) then //Zeichen senden
      begin
        tick := GetTickCount;
        count := 0;

        // 1 Sekunde bzw. auf 8 Bytes Daten warten
        repeat

          // Daten aus der Schnittstelle lesen, sofern vorhanden
          if GetChar(c) then
          begin
            digits[count] := c;
            count := count+1;
          end;

        until ((GetTickCount-Tick) > 1000) or (count >= 7);
        if count >= 7 then //Die erhaltenen Zeichen verarbeiten
        begin
          time1.Text := digits[0] + digits[1] + ',' + digits[2] + digits[3];
          time2.Text := digits[4] + digits[5] + ',' + digits[6] + digits[7];
        end;
      end;
    end;
  finally
    // com schließen
    Close;
    Free;
  end;
end;
Die Variable COM wird in den Einstellungen gesetzt.

Beim HT hab ich folgendes eingestellt: 9600Baud; keine Parität; 1Stopbit; Datenbits: 8; Keine Flussteuerung

Ich hoffe ihr findet meinen Denkfehler.

Klaus01 20. Okt 2009 15:32

Re: TSerial - RS232 ansprechen
 
Hallo,

was funktioniert denn nicht?
Bist Du schon einmal in der Routine einen Haltepunkt gesetzt
und bist mit F8 den Code schrittweise durchgegangen?

Grüße
Klaus

Lee500 20. Okt 2009 15:34

Re: TSerial - RS232 ansprechen
 
Es erzeugt ja keinen Fehler, deshalb bin ich ja auch total überfragt was grade los ist.

Klaus01 20. Okt 2009 15:38

Re: TSerial - RS232 ansprechen
 
Zitat:

Zitat von Lee500
Es erzeugt ja keinen Fehler, deshalb bin ich ja auch total überfragt was grade los ist.

Was soll den passieren, bzw. was passiert denn nicht?

Dann setze mal einen Haltepunkt und arbeite mit F8 den Code ab.
Dann wirst Du sehen, ob alles so läuft wie Du es Dir vorgestellt hast.

Grüße
Klaus

Lee500 20. Okt 2009 15:42

Re: TSerial - RS232 ansprechen
 
Wie gesagt, es sollte ein Zeichen gesendet werden. Dann soll die Antwort von 8 Zeichen empfangen werden. Ob das senden funktioniert kann ich nicht sagen weil ich nicht weiß wie ichs testen soll. Empfangen tut er jedenfalls nix.

Gruß Lee

OldGrumpy 20. Okt 2009 15:49

Re: TSerial - RS232 ansprechen
 
Zuerstmal musst Du eingrenzen wo das Problem überhaupt liegt. Welcher Microcontroller? Je nach Plattform gibts mehr oder weniger erschwingliche Hardwaredebugger dafür. Zweitens solltest Du beim Microcontroller erstmal ein paar simple Signalisierungsmöglichkeiten schaffen. Immer wieder gern genommen ist z.B. eine LED die angeht, wenn der Controller ein Zeichen empfangen hat. So kann man Schritt für Schritt einkreisen, was denn überhaupt das Problem ist. Hast Du z.B. daran gedacht RX und TX zu kreuzen? Senden auf der einen ist ja Empfangen auf der anderen Seite.

Lee500 20. Okt 2009 16:03

Re: TSerial - RS232 ansprechen
 
Also ich habe mir jetz ne LED an einen ausgang gebastelt. Wenn ich per Delphi sende passiert gar nix. Mach ichs per HyperTerminal geht sie an sobald ich was sende.

Zitat:

Hast Du z.B. daran gedacht RX und TX zu kreuzen? Senden auf der einen ist ja Empfangen auf der anderen Seite.
Wenn ich das nicht getan hätte würde die Verbindung wohl kaum mit dem HT gehen oder?

Gruß Lee

OldGrumpy 20. Okt 2009 16:17

Re: TSerial - RS232 ansprechen
 
Wenn Du nicht ganz grobe Verdrahtungsfehler drin hast (wovon ich nicht ausgehe) dann zeigt das ja zumindest schonmal, dass das Senden an den Controller geht, wenn auch nicht mit Delphi :mrgreen:. Geht denn auch die Antwort des Controllers? Die sollte durchaus auch per Hyperterminal zu sehen sein. Wenn das klappt, sind wir schonmal einen Schritt weiter mit der Fehlereingrenzung. Wenn der Part des Controllers dann komplett funktioniert, dann sehen wir uns die Delphi-Seite an. Immer einen Schritt nach dem anderen machen.

Lee500 20. Okt 2009 16:22

Re: TSerial - RS232 ansprechen
 
Ja der Hardware Teil funktioniert. Wenn ich per HyperTerminal ein 'x' sende, antwortet mir der Controller mit '12345678'.

Wenn ich per HT sende geht die LED auch an, da der Controller ein Zeichen empfangen hat. Bei Delphi ist dies nicht der fall. Also vermute ich mal, sendet Delphi gar nicht, oder so, dass der Controller es nicht lesen kann.

Gruß Lee

shmia 20. Okt 2009 16:23

Re: TSerial - RS232 ansprechen
 
Hast du schon mit Portmon nachgeschaut, was da rein und raus geht?

Lee500 20. Okt 2009 16:32

Re: TSerial - RS232 ansprechen
 
Per HT sagt mir Portmon folgendes:
Delphi-Quellcode:
0.12418143   hypertrm.exe   IRP_MJ_CREATE   Serial2   SUCCESS   Options: Open    
0.00000782   hypertrm.exe   IOCTL_SERIAL_SET_QUEUE_SIZE   Serial2   SUCCESS   InSize: 8192 OutSize: 8192   
0.00000251   hypertrm.exe   IOCTL_SERIAL_CONFIG_SIZE   Serial2   SUCCESS   Size: 0   
0.00000196   hypertrm.exe   IOCTL_SERIAL_GET_BAUD_RATE   Serial2   SUCCESS      
0.00000196   hypertrm.exe   IOCTL_SERIAL_GET_LINE_CONTROL   Serial2   SUCCESS      
0.00000196   hypertrm.exe   IOCTL_SERIAL_GET_CHARS   Serial2   SUCCESS      
0.00000196   hypertrm.exe   IOCTL_SERIAL_GET_HANDFLOW   Serial2   SUCCESS      
0.00000196   hypertrm.exe   IOCTL_SERIAL_GET_BAUD_RATE   Serial2   SUCCESS      
0.00000196   hypertrm.exe   IOCTL_SERIAL_GET_LINE_CONTROL   Serial2   SUCCESS      
0.00000196   hypertrm.exe   IOCTL_SERIAL_GET_CHARS   Serial2   SUCCESS      
0.00000196   hypertrm.exe   IOCTL_SERIAL_GET_HANDFLOW   Serial2   SUCCESS      
0.00000223   hypertrm.exe   IOCTL_SERIAL_SET_BAUD_RATE   Serial2   SUCCESS   Rate: 9600   
0.00275426   hypertrm.exe   IOCTL_SERIAL_SET_RTS   Serial2   SUCCESS      
0.00297496   hypertrm.exe   IOCTL_SERIAL_SET_DTR   Serial2   SUCCESS      
0.00000279   hypertrm.exe   IOCTL_SERIAL_SET_LINE_CONTROL   Serial2   SUCCESS   StopBits: 1 Parity: NONE WordLength: 8   
0.00295652   hypertrm.exe   IOCTL_SERIAL_SET_CHAR   Serial2   SUCCESS   EOF:0 ERR:0 BRK:0 EVT:0 XON:11 XOFF:13   
0.01298852   hypertrm.exe   IOCTL_SERIAL_SET_HANDFLOW   Serial2   SUCCESS   Shake:80000001 Replace:80000040 XonLimit:80 XoffLimit:200   
0.00000391   hypertrm.exe   IOCTL_SERIAL_SET_TIMEOUTS   Serial2   SUCCESS   RI:10 RM:0 RC:0 WM:0 WC:5000   
0.00000363   hypertrm.exe   IOCTL_SERIAL_SET_WAIT_MASK   Serial2   SUCCESS   Mask: RLSD ERR    
0.00000000   hypertrm.exe   IOCTL_SERIAL_WAIT_ON_MASK   Serial2         
0.00000000   hypertrm.exe   IRP_MJ_READ   Serial2      Length 80   
0.00076993   hypertrm.exe   IRP_MJ_WRITE   Serial2   SUCCESS   Length 1: .   
0.00000670   hypertrm.exe   IOCTL_SERIAL_GET_COMMSTATUS   Serial2   SUCCESS      
0.00092945   hypertrm.exe   IRP_MJ_WRITE   Serial2   SUCCESS   Length 1: .   
21.23459630   hypertrm.exe   IRP_MJ_READ   Serial2   TIMEOUT   Length 8: 12305678
per Delphi macht es das:
Delphi-Quellcode:
0.12224207   Zeitmessung.exe   IRP_MJ_CREATE   Serial2   SUCCESS   Options: Open    
0.00000475   Zeitmessung.exe   IOCTL_SERIAL_GET_BAUD_RATE   Serial2   SUCCESS      
0.00000251   Zeitmessung.exe   IOCTL_SERIAL_GET_LINE_CONTROL   Serial2   SUCCESS      
0.00000223   Zeitmessung.exe   IOCTL_SERIAL_GET_CHARS   Serial2   SUCCESS      
0.00000223   Zeitmessung.exe   IOCTL_SERIAL_GET_HANDFLOW   Serial2   SUCCESS      
0.00000196   Zeitmessung.exe   IOCTL_SERIAL_GET_BAUD_RATE   Serial2   SUCCESS      
0.00000196   Zeitmessung.exe   IOCTL_SERIAL_GET_LINE_CONTROL   Serial2   SUCCESS      
0.00000196   Zeitmessung.exe   IOCTL_SERIAL_GET_CHARS   Serial2   SUCCESS      
0.00000196   Zeitmessung.exe   IOCTL_SERIAL_GET_HANDFLOW   Serial2   SUCCESS      
0.00000196   Zeitmessung.exe   IOCTL_SERIAL_SET_BAUD_RATE   Serial2   SUCCESS   Rate: 9600   
0.00277857   Zeitmessung.exe   IOCTL_SERIAL_CLR_RTS   Serial2   SUCCESS      
0.00299871   Zeitmessung.exe   IOCTL_SERIAL_CLR_DTR   Serial2   SUCCESS      
0.00000251   Zeitmessung.exe   IOCTL_SERIAL_SET_LINE_CONTROL   Serial2   SUCCESS   StopBits: 1 Parity: NONE WordLength: 8   
0.00295764   Zeitmessung.exe   IOCTL_SERIAL_SET_CHAR   Serial2   SUCCESS   EOF:0 ERR:0 BRK:0 EVT:0 XON:11 XOFF:13   
0.00000307   Zeitmessung.exe   IOCTL_SERIAL_SET_HANDFLOW   Serial2   SUCCESS   Shake:80000000 Replace:80000000 XonLimit:2048 XoffLimit:512   
0.00000223   Zeitmessung.exe   IOCTL_SERIAL_SET_QUEUE_SIZE   Serial2   SUCCESS   InSize: 1024 OutSize: 1024   
0.00000223   Zeitmessung.exe   IOCTL_SERIAL_SET_TIMEOUTS   Serial2   SUCCESS   RI:0 RM:0 RC:1 WM:0 WC:0   
0.00090235   Zeitmessung.exe   IRP_MJ_WRITE   Serial2   SUCCESS   Length 1: x   
0.00000279   Zeitmessung.exe   IOCTL_SERIAL_GET_COMMSTATUS   Serial2   SUCCESS      
0.00000223   Zeitmessung.exe   IOCTL_SERIAL_GET_COMMSTATUS   Serial2   SUCCESS      
0.00000223   Zeitmessung.exe   IOCTL_SERIAL_GET_COMMSTATUS   Serial2   SUCCESS      
0.00000251   Zeitmessung.exe   IOCTL_SERIAL_GET_COMMSTATUS   Serial2   SUCCESS      
0.00000223   Zeitmessung.exe   IOCTL_SERIAL_GET_COMMSTATUS   Serial2   SUCCESS      
0.00000251   Zeitmessung.exe   IOCTL_SERIAL_GET_COMMSTATUS   Serial2   SUCCESS      
0.00000223   Zeitmessung.exe   IOCTL_SERIAL_GET_COMMSTATUS   Serial2   SUCCESS      
... es folgt noch mehr davon
Gruß Lee

Klaus01 20. Okt 2009 17:28

Re: TSerial - RS232 ansprechen
 
.. in Deinem 2. Protokoll taucht doch ein x auf
Zitat:

.00090235 Zeitmessung.exe IRP_MJ_WRITE Serial2 SUCCESS Length 1: x
Wohingegen im 1. Protokoll zwei mal der Punkt '.' auftaucht.

Grüße
Klaus

Lee500 20. Okt 2009 17:30

Re: TSerial - RS232 ansprechen
 
Das hat ja nix zu sagen, weil es das Zeichen ist was gesendet wird. Der Controller sendet aber auch zurück wenn er ein x bekommt, da er sendet sobald ein Zeichen kommt, egal welches.

Gruß Lee

//EDIT: Habe jetzt herausgefunden warum es nicht ging. Mein Controller erwartete einen Zeilenumbruch bzw. ein Zeilenende oder sowas. Ohne dieses Ende antwortet er nicht, weil er glaubt nichts empfangen zu haben. Jetzt, mit Zeilenumbruch, funktioniert es wunderbar.

delphihasen 2. Apr 2012 11:45

AW: TSerial - RS232 ansprechen
 
Hallo erstmal,

vielen Dank für die Com Unit! Hab allerdings ein Problem:
Ich mochte den Port RTS auf High schalten.

So hab ich mir das vorgestellt


Delphi-Quellcode:
//////////////////////////////////////////////////////////////////////////////////////
procedure TForm1.Button1Click(Sender: TObject);
begin

  with TCom.Create(nil) do
  try
    // com öffnen
    if Open(COM,RTS_DISABLED,DTR_DISABLED) then
    begin
        Memo1.Lines.Add ('Com'+IntToStr(Com)+' ausgewählt!');
        SetRTS(akt);
    end;
  finally
    // com schließen
    Close;
    Free;
end;
///////////////////////////////////////////////////////////////////

Bei der Prozedur SetRTS gibt Delphi mir allerdings die Fehlermeldung "Missing Operator" aus. Die Variable akt(boolean) habe ich zuvor jedoch schon true zugewiesen...

Kann mir jemand helfen???


Vielen Dank für eure Mühen

DeddyH 2. Apr 2012 12:58

AW: TSerial - RS232 ansprechen
 
Schmeiß erst einmal das "with" raus. Und dann scheint da noch das "end" zum "finally" zu fehlen.

delphihasen 2. Apr 2012 13:03

AW: TSerial - RS232 ansprechen
 
Ohne with gehts gar nicht. Sorry end war noch drin-->habs lediglich nicht mitkopiert...

Denke das Problem liegt an der Prozedur:

Delphi-Quellcode:
procedure TCOM.SetRTS(const Value: boolean);
begin
  if (Value = True) then
    EscapeCommFunction(FHandle, WinTypes.SETRTS)
  else
    EscapeCommFunction(FHandle, WinTypes.CLRRTS);
end;
Um diese auszuführen bzw. RTS zu schalten sollte ich sie doch lediglich so:
Delphi-Quellcode:
SetRTS(true);
ausführen können oder nicht?


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:56 Uhr.
Seite 1 von 2  1 2      

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