[gelöst] Serielle Schnittstelle RS232 & synaser

Antworten
Theozh
Beiträge: 99
Registriert: So 1. Jul 2012, 10:56

[gelöst] Serielle Schnittstelle RS232 & synaser

Beitrag von Theozh »

Hallo zusammen,

seit einiger Zeit versuche ich, ein Messgerät über die serielle Schnittstelle anzusprechen.
Das Prinzip ist ja immer das gleiche: Schnittstelle konfigurieren, String senden, String empfangen. So weit, so einfach. Für diese Aufgabe wird im Netz 'synaser' empfohlen.
Leider habe ich kein Minimalbeispiel eines funktionierenden Programms gefunden.
Wenn ich das Gerät z.B. mit PuTTy anspreche, meldet sich das Gerät zurück. Natürlich laufen die Programme bei Tests nicht gleichzeitig. Am Zugriff oder einem Konflikt sollte es also nicht liegen. Selbst mit dem Lazarus Programm schaltet das Messgerät auf den Remote-Modus um. Also irgendwas scheint anzukommen.
Aber warum bekomme ich nichts zurück? Woran liegt's? Kurze Antwort: An mir natürlich ;-)...
Nach dem TimeOut wird in Memo1 angezeigt:
COM1,COM3,COM12 HalloEnde
d.h. 'Carriage Return' chr(13) wird in Memo1 nicht angezeigt, liegt's vielleicht auch beim SendString() am chr(13) oder ist das ein anderes Thema?
Danke für Hinweise.
Theo.


Der Code:

Code: Alles auswählen

 
unit tbeserial;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  SynaSer;
 
type
 
  { TForm1 }
 
  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    StaticText1: TStaticText;
    procedure Button1Click(Sender: TObject);
    procedure RS232_connect(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end; 
 
var
  Form1: TForm1; 
 
implementation
 
{$R *.lfm}
 
{ TForm1 }
 
procedure TForm1.Button1Click(Sender: TObject);
begin
  RS232_connect(Sender);
end;
 
procedure TForm1.RS232_connect(Sender: TObject);
var
  ser: TBlockSerial;
  Response, Command: string;
begin
  ser:=TBlockSerial.Create;
  ser.Connect('COM1');
  ser.config(19200, 8, 'N', SB1, False, False);
  Command := '*IDN?' + chr(13);
  ser.SendString(Command);
  sleep(1000);
  Response := ser.RecvString(3000);
  Memo1.Append(GetSerialPortNames() + chr(9) + 'Hallo' + chr(13) + Response + chr(13) + 'Ende');
end;
 
end.
 
Zuletzt geändert von Theozh am Sa 20. Apr 2013, 09:03, insgesamt 1-mal geändert.

Benutzeravatar
theo
Beiträge: 10920
Registriert: Mo 11. Sep 2006, 19:01

Re: Serielle Schnittstelle RS232 & synaser

Beitrag von theo »

Reicht Chr(13) als Terminator beim Senden? Nicht eher #13#10 ?

Theozh
Beiträge: 99
Registriert: So 1. Jul 2012, 10:56

Re: Serielle Schnittstelle RS232 & synaser

Beitrag von Theozh »

Am Messgerät kann man alles einstellen: CR, LF, CR/LF und LF/CR...
an dem sollte es nicht liegen...

Theozh
Beiträge: 99
Registriert: So 1. Jul 2012, 10:56

Re: Serielle Schnittstelle RS232 & synaser

Beitrag von Theozh »

Danke Theo für den Hinweis, ...probieren konnte ja nicht schaden...
PuTTy kommt mit nur 'CR' zurecht.
synapse braucht wohl 'CR/LF'...
so funktioniert's... ... komisch... muss man nicht verstehen, oder?

Benutzeravatar
theo
Beiträge: 10920
Registriert: Mo 11. Sep 2006, 19:01

Re: Serielle Schnittstelle RS232 & synaser

Beitrag von theo »

Theozh hat geschrieben: so funktioniert's... ... komisch... muss man nicht verstehen, oder?
Verstehen vllt. nicht, aber Doku lesen kommt immer gut:
http://synapse.ararat.cz/doc/help/synas ... SendString
:wink:

Theozh
Beiträge: 99
Registriert: So 1. Jul 2012, 10:56

Re: Serielle Schnittstelle RS232 & synaser

Beitrag von Theozh »

ja ja, das habe ich schon gelesen...
wenn aber am Gerät CR oder/und LF als Terminator einstellbar ist... warum muss (laut synapse-Doku) offenbar "zwingend" ein CR/LF geschickt werden?
Desweiteren bringt das Display am Gerät noch eine Fehlermeldung: "Init ignored". Offenbar wird bei jeder Anfrage unnötigerweise zuviel initialisiert, was aber eine korrekte Rückmeldung nicht zu beeinflussen scheint...

Benutzeravatar
theo
Beiträge: 10920
Registriert: Mo 11. Sep 2006, 19:01

Re: Serielle Schnittstelle RS232 & synaser

Beitrag von theo »

Wenn du es wirklich wissen möchtest, frag auf der Synapse Mailing List:

http://sourceforge.net/mailarchive/foru ... ist-public
http://synapse.ararat.cz/doku.php/support

Benutzeravatar
corpsman
Lazarusforum e. V.
Beiträge: 1629
Registriert: Sa 28. Feb 2009, 08:54
OS, Lazarus, FPC: Linux Mint Mate, Lazarus GIT Head, FPC 3.0
CPU-Target: 64Bit
Wohnort: Stuttgart
Kontaktdaten:

Re: Serielle Schnittstelle RS232 & synaser

Beitrag von corpsman »

Um die string problematik zu umgehen, kannst du auch einfach

Code: Alles auswählen

 
    fserial.SendByte(..); 
 
nehmen, so mache ich das zumindest. Der Vorteil du kannst auch 0 Werte schicken. Zum Lesen kommt dann etwas in dieser Form :

Code: Alles auswählen

 
Function TUart.Read: String;
Var
  b: Boolean;
  c: Char;
Begin
  result := '';
  If Not assigned(fserial) Then exit;
  b := true;
  While b Do Begin
    c := chr(fserial.RecvByte(10));
    If fserial.LastError = 0 Then Begin
      result := result + c;
    End
    Else Begin
      b := false;
    End;
  End;
End;
 
Alles zusammen findest du hier
--
Just try it

Benutzeravatar
theo
Beiträge: 10920
Registriert: Mo 11. Sep 2006, 19:01

Re: Serielle Schnittstelle RS232 & synaser

Beitrag von theo »

corpsman hat geschrieben: Der Vorteil du kannst auch 0 Werte schicken.
Das kann man mit Sendstring auch: "you can use this function for sending binary data too"

Theozh
Beiträge: 99
Registriert: So 1. Jul 2012, 10:56

Re: Serielle Schnittstelle RS232 & synaser

Beitrag von Theozh »

Hallo nochmals,

das Problem ist nun endlich gelöst. Vergesst die oberen Beispiele.
Das "Geheimnis" liegt in der Benutzung der richtigen Funktion:

ser.RecvTerminated(1000, chr(10));

oder einem entsprechend anderen 'Termination-Character' z.B. chr(13) oder chr(13)+chr(10)...

Vielleicht sucht ja jemand anderes auch noch nach der Lösung.
Deshalb poste ich mal hier ein (bei mir) einwandfrei funktionierendes Minimalbeispiel.

Code: Alles auswählen

 
unit RS232Test;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  ExtCtrls, Synaser;
 
type
 
  { TForm1 }
 
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    LabeledEdit1: TLabeledEdit;
    LabeledEdit2: TLabeledEdit;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;
 
var
  Form1: TForm1;
  ser: TBlockSerial;
 
implementation
 
{$R *.lfm}
 
{ TForm1 }
 
procedure TForm1.FormCreate(Sender: TObject);
begin
  ser:=TBlockSerial.Create;
  ser.Connect('COM1');
  ser.config(19200, 8, 'N', SB1, False, False);
end;
 
procedure TForm1.Button1Click(Sender: TObject);
var
  Command: string;
begin
  Command := LabeledEdit1.Text + chr(13) + chr(10);
  ser.SendString(Command);
  LabeledEdit2.Text := ser.RecvTerminated(1000, chr(10));
end;
 
procedure TForm1.Button2Click(Sender: TObject);
begin
  ser.free;
end;
 
end.
 

Antworten