---

Seriell mit Lazarus und Synaser                 

            

Elektronik-Labor  Projekte  Mikrocontroller  Raspberry     




Download: SerialSynaser.zip

Bei der Suche nach einem Plattform-übergreifenden Zugang auf die serielle Schnittstelle bin ich auf Synaser gestoßen. Die ersten Versuche habe ich unter Windows getestet. Unter https://github.com/marado/synapsel findet Synapse von Marado, eine große Sammlung diverser Schnittstellen-Units, die nicht installiert werden müssen. Vielmehr kopiert man einfach die benötigten Dateien aus dem Verzeichnis synapse-master in sein eigenes Projektverzeichnis. Entscheidend ist die Datei synaser.pas. Diese greift aber ihrerseits auf weitere Units zurück, die ebenfalls eingefügt werden müssen. 



In meinem ersten Versuch habe ich ein neues Projekt mit dem Namen SerialSynaser gebildet. Die markierten .pas- und .ppu-Dateien musste ich einfügen, die .o-Dateien sind beim Kompilieren entstanden. Dass das kompilierte Programm am Ende SeriealSyaser.exe (ohne n) heißt, beruht auf einem Tippfehler, der sich im ganzen Test gehalten hat.

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, ExtCtrls,
  synaser;

type
  { TForm1 }
  TForm1 = class(TForm)
    ButtonSend: TButton;
    EditText: TEdit;
    MemoLog: TMemo;
    TimerRx: TTimer;
    procedure ButtonSendClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure MemoLogAltChange(Sender: TObject);
    procedure TimerRxTimer(Sender: TObject);
  private
    Ser: TBlockSerial;
    procedure OpenPort;
  public
  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  Ser := TBlockSerial.Create;
  //Ser.RaiseExcept := True;   // Fehler als Exception ausgeben
  TimerRx.Interval := 100;   // alle 100 ms prüfen
  TimerRx.Enabled := True;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  TimerRx.Enabled := False;
  Ser.Free;
end;

procedure TForm1.TimerRxTimer(Sender: TObject);
var
  S: string;
begin
  if not Ser.InstanceActive then
    Exit;

  if Ser.CanReadEx(0) then
  begin
    S := Ser.RecvString(10);  //RecvPacket(0);   // alle gerade verfügbaren Bytes lesen
    //if (Ser.LastError = 0) and (S <> '') then
     MemoLog.Lines.Add('RX: ' + S);
  end;
end;

procedure TForm1.OpenPort;
begin
  if not Ser.InstanceActive then
  begin
    Ser.Connect('COM4');                  // unter Linux z.B. '/dev/ttyUSB0'
    Ser.Config(1000000, 8, 'N', 0, False, False);
  end;
end;

procedure TForm1.ButtonSendClick(Sender: TObject);
var
  S: string;
begin
  try
    OpenPort;
    Ser.DTR := True;
    S := EditText.Text + #13#10;          // CR/LF anhängen
    Ser.SendString(S);
    MemoLog.Lines.Add('Gesendet: ' + EditText.Text);
  except
    on E: Exception do
      ShowMessage('Fehler: ' + E.Message);
  end;
end;

end.    
                        
Es funktioniert einwandfrei mit COM 4 und 1 MBaud. Zum Test habe ich einen FT232 angeschlossen und die Anschlüsse TXD und RXD direkt verbunden. Wenn ich einen Text absende, wird er einen Moment später wieder empfangen und angezeigt.





Übertragung auf den RPi 4



Download: SerialSyaser.zip (kompiliert für RPi)

Das gesamte unter Windows erzeugte Verzeichnis konnte auf den RPi 4 übertragen werden. Die einzige Änderung betraf den Namen der Schnittstelle. Sie heißt hier '/dev/ttyUSB0'. Ich musste aber erst verstehen, dass dies die erste USB/Serielle Schnittstelle ist, die man an einer der vier möglichen USB-Buchsen angeschlossen hat. Wenn ich dagegen nacheinander mehrere Anschlüsse teste, bilde ich jedes Mal eine neue Schnittstelle. Also musste ich alles noch einmal neu starten und dann den gewählten Anschluss beibehalten.



Das Programm sollte auf unterschiedlichen RPis und mit unterschiedlichen USB/Seriell-Wandlern funktionieren, ich konnte aber nur mit meinen Geräten testen. Über Rückmeldungen würde ich mich freuen, wo funktioniert es und wo nicht.




Elektronik-Labor  Projekte  Mikrocontroller  Raspberry