Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   serielle schnittstelle Ich versteh nur bahnhof (https://www.delphipraxis.net/98112-serielle-schnittstelle-ich-versteh-nur-bahnhof.html)

snow 21. Aug 2007 16:23


serielle schnittstelle Ich versteh nur bahnhof
 
Hallo

ich würde gerne die serielle schnittstelle ansteuern. (2400bit ,2Stopbits,8datenbits, keine parität,)

dabei möchte ich blos ein byte senden.

es handelt sich um COM1

ich habe übrigens die suche benutz aber ich versteh nur bahnhof. Unter delphi muss man irgend was installieren???? aber manches kostet geld manches nicht???? Es kann doch nicht so schwer sein die schnittstelle anzusprechen , schließlich schafft BASIC das mit 3 zeilen quelltext.

kann mir jemand mal erklären wie ich blos ein byte versenden kann???

MfG snow

Ach ja ich nutze lazarus macht das probleme?

oki 21. Aug 2007 16:40

Re: serielle schnittstelle Ich versteh nur bahnhof
 
Hallo,

such mal hier im Forum nach Comport oder Com und Komponente. Für das Ansprechen der Com-Schnittstelle gibt es einige freie Komponenten im Netz. Damit müßtest du dann weiter kommen.

Gruß oki

snow 21. Aug 2007 17:04

Re: serielle schnittstelle Ich versteh nur bahnhof
 
naja wirklich helfen tut das nicht. ich hab mir synapse geladen aber 1. wie soll man diese komponente installieren??(lazarus)
2. das sind ganz schön viele units nur um was zu senden. wiso brauch ich das so viele.

ich check einfach nicht wie die pakete installieren soll und wie ich dann so was wie baudrate einstellen kann und wie ich dann etwas senden kann.

gibt es nicht auch eine lösung einfach nur ein qbasic program versteckt aufrufen zu lassen und dem dann befehler auf irgendeinem port zuzustecken???

mfG snow

dominikkv 21. Aug 2007 17:54

Re: serielle schnittstelle Ich versteh nur bahnhof
 
Schau dir mal CPort an
Delphi-Quellcode:
uses CPort, CPortCtl

// ...

var
  ComPort: TComPort;

// ...

  ComPort := TComPort.Create(self);
  ComPort.OnRxChar := ComPortRxChar; // Ereignis wenn Bytes empfangen werden

  ComPort.ShowSetupDialog;

  ComPort.Open;

  ComPort.WriteStr('A'); // 'A' Senden

  if ComPort.Connected then
    ComPort.Close

// ...

procedure TForm1.ComPortRxChar(Sender: TObject; Count: Integer);
var
  S: String;
begin
  ComPort.ReadStr(S, Count);
  showmessage('Das hier hab ich empfangen: ' + S);
end;

snow 21. Aug 2007 18:12

Re: serielle schnittstelle Ich versteh nur bahnhof
 
Hallo ich habs mal runtergeladen un entpakt.

so dann hab ich eine neue unit gebastelt und die beiden teile von dir im uses teil dazugepakt.

dann noch deinen quelltext dazu und mal F9 gedrükt.

jetzt bekomm ich einen ressourcen-ladefehler
Zitat:

Die alte ressourcendatei konnte nicht geladen werden.
Die ressourcendatei ist die erste include-datei im initialisierungsabschnitt.

z.B Unit1.lrs
wenn ich dan auf datei überspringen klicke dann kommt

Zitat:

---------------------------------------------
unit1.pas(22,11) Error: : erwartet aber := gefunden
Unit1.pas(1,1) Fatal: Can't find unit CPort
wo liegt mein fehler?

MfG snow

oki 21. Aug 2007 18:17

Re: serielle schnittstelle Ich versteh nur bahnhof
 
Hi Snow,

Sorry, hab das mit lazarus glatt übersehen.

Das Problem ist, dass du an die COM-Schnittstelle nicht so einfach wie früher rankommst (Interrupt, Register). Basic stellt dir da auch nur eine Klasse zur Verfügung. Ist halt nur dabei (glaub ich). Bei Delphi (ich denke auch bei Lazarus) ist eine Klasse (oder Komponente) für den Zugriff auf die serielle Schnittstelle leider nicht von Hause aus enthalten. Aus diesem Grund mußt du eine entsprechende Klasse (Komponente) zusätzlich installieren. Zum Glück gibt es da ne Menge gute freie Sachen (ohne Geld). Wie so eine Installation unter Lazarus abläuft, weiß ich leider nicht. :( Wenn du hier im Forum nichts dazu findest, schau mal im Forum für Lazarus nach.

Ist bei deinem Download kein readme dabei?

Der Link von dominikkv ist zwar gut, aber so wie es aussieht nur für Delphi und nicht für Lazarus. Ob unter Lazarus auch funzt kann ich nicht sagen. Glaub aber nicht.

Schau mal, ob dir dieser Link für das Installationsproblem oder das Finden geeigneter Kompos weiterhilft Lazarus_Documentation

Tut mir leid, dass ich doch nicht viel helfen konnte,

Gruß oki

Reinhard Kern 21. Aug 2007 18:31

Re: serielle schnittstelle Ich versteh nur bahnhof
 
Zitat:

Zitat von oki
Hi Snow,

Sorry, hab das mit lazarus glatt übersehen.

Das Problem ist, dass du an die COM-Schnittstelle nicht so einfach wie früher rankommst (Interrupt, Register).
...
Gruß oki

Hallo oki,

das ist überhaupt nicht der Punkt - es wäre ja hirnrissig, die serielle Schnittstelle als Hardware anzusprechen, und natürlich geht das unter keinem modernen Betriebssystem, darf auch nicht.

Ebenso selbstverständlich kann man ein COM-Port unter Windows ansprechen, und zwar als Datei mit CreateFile, WriteFile und CloseHandle wie bei einer anderen Datei auch.

Wie gesagt - mit Hardwarezugriffen und Protected Mode hat das nicht das geringste zu tun.

Gruss Reinhard

snow 21. Aug 2007 18:46

Re: serielle schnittstelle Ich versteh nur bahnhof
 
Zitat:

Hallo oki,

das ist überhaupt nicht der Punkt - es wäre ja hirnrissig, die serielle Schnittstelle als Hardware anzusprechen, und natürlich geht das unter keinem modernen Betriebssystem, darf auch nicht.

Ebenso selbstverständlich kann man ein COM-Port unter Windows ansprechen, und zwar als Datei mit CreateFile, WriteFile und CloseHandle wie bei einer anderen Datei auch.

Wie gesagt - mit Hardwarezugriffen und Protected Mode hat das nicht das geringste zu tun.
ja und wie geht das??

mir ist es eigendlich egal wie die bytes gesendet werden ob direkt oder durch das betriebssytem.

das einzige was später machbar sein muss ist das ich die CTS leitung abfragen kann.

du schreibst das hier so locker hin aber ich hab KEINE ahnung. wi heist den der Dateiname und wiso create? ich kann die doch nicht herstellen sondern nur öffnen.

könntest du mir ein paar code-schnipsel reinposten?? nur wie ich senden kann.

MfG snow

oki 21. Aug 2007 19:13

Re: serielle schnittstelle Ich versteh nur bahnhof
 
Mist, hab mir grad meinen Beitrag zerschossen.

Halt noch mal von vorn.

@Reinhardt: Da hab ich mich wohl sehr missverständlich ausgedrückt. Ich wollte vermeiden, dass snow bei seiner Suche auf ältere Codeschnipsel mit Registern und Interrupts stösst. Eine Analogie zu VB oder ähnlichem solle das nicht sein.

Imho glaube ich nicht, dass snow mit CreateFile klar kommt (kann mich auch irren).

@snow: Schau dir doch mal den Link zur Lazarus-Dokumentation an. Dort gibt es weitere Links zu:
Hardware Access
und dort auf entsprechende Tutoriels:
Zitat:

Serielle Kommunikation

Der Externe Links Abschnitt enthält UNIX und Windows Tutorials über den seriellen Anschluß.
Dort müsstest du eigentlich mit deinem Problem weiter kommen.

Also bitte mal lesen.

Gruß oki

EDatabaseError 21. Aug 2007 19:17

Re: serielle schnittstelle Ich versteh nur bahnhof
 
Ich schätze das du die CTS Leitung nur abfragen willst/musst um zu wissen wann du wieder was senden darfst. Clear to send imho.
Wenns das ist mach dir da keine Sorgen das macht Windows/Linux theoretisch schon allein. :|


ADD: schau mal bei den schweizern swissdelphicenter.ch da gibts genau die Codeschnippsel die du brauchst

snow 21. Aug 2007 19:27

Re: serielle schnittstelle Ich versteh nur bahnhof
 
Zitat:

Ich schätze das du die CTS Leitung nur abfragen willst/musst um zu wissen wann du wieder was senden darfst. Clear to send imho.
Wenns das ist mach dir da keine Sorgen das macht Windows/Linux theoretisch schon allein. Neutral


ADD: schau mal bei den schweizern swissdelphicenter.ch da gibts genau die Codeschnippsel die du brauch
nein leider muss ich die cts leitung öfters mal abfragen, da das daran angeschlossene Interface bei einem kurzschluss auf der Modellbahn die CTS leitung aktiviert um nicht von daten überschwemmt zu werden und damit der pc weis wann ein not-halt ausgelöst wurde.

MfG snow

snow 21. Aug 2007 19:43

Re: serielle schnittstelle Ich versteh nur bahnhof
 
Sorry das ich hier jetzt ein bissel was reintexte aber anders gehts net

Delphi-Quellcode:
function OpenCOMPort: Boolean;
var
  DeviceName: array[0..80] of Char;
  ComFile: THandle;
begin
   { First step is to open the communications device for read/write.
     This is achieved using the Win32 'CreateFile' function.
     If it fails, the function returns false.

     Wir versuchen, COM1 zu öffnen.
     Sollte dies fehlschlagen, gibt die Funktion false zurück.
   }
  StrPCopy(DeviceName, 'COM1:');

  ComFile := CreateFile(DeviceName,
    GENERIC_READ or GENERIC_WRITE,
    0,
    nil,
    OPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL,
    0);

  if ComFile = INVALID_HANDLE_VALUE then
    Result := False
  else
    Result := True;
end;


function SetupCOMPort: Boolean;
const
  RxBufferSize = 256;
  TxBufferSize = 256;
var
  DCB: TDCB;
  Config: string;
  CommTimeouts: TCommTimeouts;
begin
   { We assume that the setup to configure the setup works fine.
     Otherwise the function returns false.

     wir gehen davon aus das das Einstellen des COM Ports funktioniert.
     sollte dies fehlschlagen wird der Rückgabewert auf "FALSE" gesetzt.
   }

  Result := True;

  if not SetupComm(ComFile, RxBufferSize, TxBufferSize) then
    Result := False;

  if not GetCommState(ComFile, DCB) then
    Result := False;

  // define the baudrate, parity,...
  // hier die Baudrate, Parität usw. konfigurieren
   
  Config := 'baud=9600 parity=n data=8 stop=1';

  if not BuildCommDCB(@Config[1], DCB) then
    Result := False;

  if not SetCommState(ComFile, DCB) then
    Result := False;

  with CommTimeouts do
  begin
    ReadIntervalTimeout        := 0;
    ReadTotalTimeoutMultiplier := 0;
    ReadTotalTimeoutConstant   := 1000;
    WriteTotalTimeoutMultiplier := 0;
    WriteTotalTimeoutConstant  := 1000;
  end;

  if not SetCommTimeouts(ComFile, CommTimeouts) then
    Result := False;
end;


{
  The following is an example of using the 'WriteFile' function
  to write data to the serial port.

  Folgendes Beispiel verwendet die 'WriteFile' Funktion, um Daten
  auf den seriellen Port zu schreiben.
}


procedure SendText(s: string);
var
  BytesWritten: DWORD;
begin
   {
     Add a word-wrap (#13 + #10) to the string

     An den übergebenen String einen Zeilenumbruch (#13 + #10) hängen
   }
  s := s + #13 + #10;
  WriteFile(ComFile, s[1], Length(s), BytesWritten, nil);
end;


{
  The following is an example of using the 'ReadFile' function to read
  data from the serial port.
 
  Folgendes Beispiel verwendet die 'ReadFile' Funktion, um Daten
  vom seriellen Port zu lesen.
}


procedure ReadText: string;
var
  d: array[1..80] of Char;
  s: string;
  BytesRead, i: Integer;
begin
  Result := '';
  if not ReadFile(ComFile, d, SizeOf(d), BytesRead, nil) then
  begin
    { Raise an exception }
  end;
  s := '';
  for i := 1 to BytesRead do s := s + d[I];
  Result := s;
end;


procedure CloseCOMPort;
begin
  // finally close the COM Port!
  // nicht vergessen den COM Port wieder zu schliessen!
  CloseHandle(ComFile);
end;

Das hab ich gefunden. Damit sollte es doch auch ohne eine komponeten gehen oder?

Doch irgenwas fehlt da noch. do der ganze anfang xD


ich schau mal was ich so hinkriege

Reinhard Kern 22. Aug 2007 01:36

Re: serielle schnittstelle Ich versteh nur bahnhof
 
Zitat:

Zitat von snow
Sorry das ich hier jetzt ein bissel was reintexte aber anders gehts net

....
ich schau mal was ich so hinkriege

Hallo snow,

das sieht schon ganz vernünftig aus. Um CTS zu überprüfen, kannst du GetCommModemStatus verwenden, ist auch ganz einfach.

Um die Theoretiker zufriedenzustellen, kann man die Einzel-Routinen auch in eine Comport-Klasse packen, das ist eben das, was die meisten freien und bezahlten COMx-Komponenten tun, mehr oder weniger universell und damit auch mehr oder weniger komplex.

Kompliziert wird es erst, wenn du aus Performancegründen asynchron und/oder mit Threads arbeiten must - die von dir angeführten Routinen blockieren den Programm-Ablauf, bis Senden/Empfang abgeschlossen sind. Bei kurzen Datensätzen und funktionierender Verbindung merkst du das wahrscheinlich garnicht.

Ich schreibe kommerzielle Software und verwende zugekaufte Komponenten daher nur im äussersten Notfall. Bisher habe ich mir für serielle Verbindungen immer eigene Klassen oder Komponenten erstellt; da oft nur ein Bruchteil der Funktionen gebraucht wird, sind die oft recht einfach. Technisch sind sie natürlich so gut wie jede gekaufte Software auch.

Gruss Reinhard

christian_u 22. Aug 2007 12:33

Re: serielle schnittstelle Ich versteh nur bahnhof
 
Wiso nimmst du eigentlich nicht einfach wie ich es vorgeschlagen hatte (Im Lazarusforum) Synapse dort hast du das mit ein paar zeilen Code erledigt und es ist auch noch Plattformunabhängig. Statt dessen schlägst du dich mit der WinAPI rum ? In wie vielen Foren hast du die Frage denn noch gestellt ?

snow 22. Aug 2007 15:20

Re: serielle schnittstelle Ich versteh nur bahnhof
 
Hallo Ich hab mir synapse runtergeladen und entzipt. Doch jetzt hab ich 39 dateien auf dem rechner. doch was nun???

Wie kreig ich die dinger zum funktionieren????. Was muss ich wie wo einbinden. (mal ne ganz dumme frage muss ich synapse im quelltext in den uses teil reinschreiben oder muss ich bei lazarus irgendwas dazuinstallieren????)

Brauch ich alle 39 Dateien??? oder reicht ein teil.

MfG snow

christian_u 22. Aug 2007 16:11

Re: serielle schnittstelle Ich versteh nur bahnhof
 
Drauf hab ich dir im lazarusforum schon geantwortet gehabt und du hast danach auch schon geantwortet deshalb bin ich wohl davon ausgegangen das du meine antworten liest, wie dumm von mir.

Kopier die Synaser.pas in dein projektverzeichnis, schreib SynaSer in deine Uses Klausel und verwende den beispielcode den ich dir im lazarusforum gepostet habe und schon machst du eine ausgabe mit der Seriellen Schnittstelle. Ich weiss nicht mehr genau wie die Konstante für 2 Stopbits war, SB2 glaub ich das müsstest du in der Dokumentation die auch im lazarusforum schon verlinkt ist nachschlagen.

snow 22. Aug 2007 16:17

Re: serielle schnittstelle Ich versteh nur bahnhof
 
Hab ich doch gelesen doch ich wusste net was das projektverzeichniss ist.

Aber theo hat mir ja jetzt geholfen

snow

snow 22. Aug 2007 16:27

Re: serielle schnittstelle Ich versteh nur bahnhof
 
So hab jetzt alles so gemacht wie es sein sollte doch........


Delphi-Quellcode:
unit test;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, SynaSer,
  Buttons;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  Form1: TForm1;

implementation

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
begin
ser:=TBlockserial.Create;
  try
    ser.Connect('COM1');
    ser.Config(2400,8,'N',0,false,false);
    ser.SendString(IntToStr(14)+';'+IntToStr(06)+';')
  finally
    ser.Free;
  end;

end;

initialization
  {$I test.lrs}

end.

Zitat:

test.pas(35,1) Error: Identifier not found "ser"
test.pas(37,5) Error: Identifier not found "ser"
test.pas(37,16) Error: Illegal expression
test.pas(37,16) Fatal: Syntax error, "EXCEPT" expected but "(" found
schon wieder ein fehler. wie soll ich den diesmal beheben?

christian_u 22. Aug 2007 16:30

Re: serielle schnittstelle Ich versteh nur bahnhof
 
Ja, ser ist ja auch nicht deklariert. Aber auch das kann Lazarus für dich machen setz einfach den Cursor vor oder in das erste vorkommen von ser und drück Strg+Umschalt+C.

Mit "Projekt verzeichnis" meinte ich das "Verzeichnis" deines "Projektes"...

Dann brauchst du nämlich den Pfad nicht in den Compilereinstellungen hinzufügen.

snow 22. Aug 2007 17:15

Re: serielle schnittstelle Ich versteh nur bahnhof
 
So es lässt sich jetzt starten.....

hab auch herausgefunden wie man 2 stopbits einschaltet

aber:

es wird einfach nix gesendet :wall: :wall: :wall:

Woran kann das den liegen?? eine andere software schafft die komunikation zum interface.... also hardwaremäßig alles ok.


Delphi-Quellcode:
ser.Connect('COM1');
    ser.Config(2400,8,'N',2,false,false);
    ser.SendString(IntToStr(12)+';'+IntToStr(18)+';')
so wie ich das hier verstehe wird als string gesendet. aber das interface soll Dezimal verstehen(eigendlich auch string und binär aber ich hab sonst keine idee woran das liegen kann.

snow

shmia 22. Aug 2007 17:53

Re: serielle schnittstelle Ich versteh nur bahnhof
 
Delphi-Quellcode:
ser.Connect('COM1');
ser.Config(2400,8,'N',2,false,false);
ser.SendString(Chr(12)+';'+Chr(18)+';'); // Variante 1
ser.SendString(#12';'#18';'); // Variante 2

christian_u 22. Aug 2007 17:56

Re: serielle schnittstelle Ich versteh nur bahnhof
 
Die 2 die du dort hingeschrieben hast, entspricht nicht 2 Stopbits dafür gibts in synapse Konstanten ich hab das nicht aus dudeldei erzählt ;)
Das mit der 2 funktioniert garantiert nicht.

snow 22. Aug 2007 18:35

Re: serielle schnittstelle Ich versteh nur bahnhof
 
Ich hab mal getestet. Das Interface läuft auch mit nur einem Stopbit.(nur unter BASIC)

mit diesem basic-code läuft es problemlos


Zitat:

100 OPEN "COM1:2400,N,8,1," FOR RANDOM AS #1
200 INPUT " Byte1 (Geschw. 0-15) "; GE
210 INPUT " Byte2 (Loknr. 1-80) "; LN
300 PRINT #1, CHR$(GE); CHR$(LN);
close #1
auch shmia's methoden funzen net. :wall:

snow

christian_u 22. Aug 2007 19:27

Re: serielle schnittstelle Ich versteh nur bahnhof
 
var
ser : TBlockSerial;
Loknr : byte;
Geschw : byte;
begin
ser := TBlockSerial.Create;
ser.Connect('COM1');
ser.Config(2400,8,'N',SB1,false,false);
ser.SendString(Chr(Loknr)+Chr(Geschw));
ser.Free;
end;

snow 22. Aug 2007 20:48

Re: serielle schnittstelle Ich versteh nur bahnhof
 
Vielen Vielen Dank.

es hat geklappt. :bounce1: :bounce1: :bounce1: :bounce1: :bounce1: :bounce1: :bounce1: :bounce1: :bounce1: :bounce1:



Lok 18 fährt jetzt mit geschwindigkeit 12 im kreis.

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

 var
ser : TBlockSerial;
Loknr : byte;
Geschw : byte;
begin
Loknr := 18;
geschw := 12;
ser := TBlockSerial.Create;
ser.Connect('COM1');
ser.Config(2400,8,'N',SB2,false,false);
ser.SendString(Chr(Geschw)+Chr(Loknr));
ser.Free;
end;
so dann schnell mal abspeichern und sicherheitskopie anfertigen

und dann sofort weiterprogrammiern


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