Lauflichter und LED-Steuerung mit Lazarus

Breadboard, Lazarus und Freepascal

Mit einem Lauflichter lassen sich auf einfache Weise tolle Effekte erzeugen. Das geht mit dem Raspberry Pi nicht nur klassisch über die Programmiersprache Python. Auch mit Lazarus und Freepascal ist das einfach möglich.

In der Basisversion kennt Lazarus noch keine Funktionen oder Klassen für die GPIO-Pins des Raspberry. Es gibt aber einige Möglichkeiten, wie man die Pins ansprechen kann.

Eine Übersicht gibt das Wiki unter http://wiki.freepascal.org/Lazarus_on_Raspberry_Pi/de. Für dieses Projekt verwende ich das Paket PascalIO. Laden Sie es herunter und speichern es in Ihrer Larazus-Bibliothek.

PascalIO einbinden

Für einen ersten Test legen Sie sich ein neues Lazarus-Projekt an. Binden Sie das Paket PascalIO ein. Das geht am einfachsten, indem das Paket über den Menüpunkt Package aus Ihrem Ordner geladen wird. Mit dem Klick auf Zum Projekt hinzufügen ist es für Ihr Projekt verfügbar.

PascalIO zum Projekt
Einfügen von PascalIO in Ihrem Projekt

Ausgänge schalten

Die Verwendung von PascalIO für die GPIO-Programmierung ist sehr einfach. Im ersten Schritt müssen die entsprechenden Units aus dem Paket eingebunden werden. Sollen nur GPIO geschaltet werden, ist das die Unit fpgpio.

Schaltung mit 1 LED
Beispiel für die Ansteuerung einer einzelnen LED

In diesem Beispiel wird an den GPIO18 eine LED über einen Vorwiderstand 330 Ω angeschlossen und vom Programm ein- und ausgeschaltet.

In der FormCreate Methode erfolgen, ähnlich zu Python, die Einstellungen des Pins:

  • Festlegung der GPIO-Pin Nummer: Led:=TGpioLinuxPin(18);
  • Art des Pins festlegen – Eingang oder Ausgang: Led.Direction:=gdOut;

Um den Pin ein- oder auszuschalten, wird die Eigenschaft Value benutzt. Sie ist vom Typ Boolean.

  • Ausgang auf HIGH: Led.Value:=true;
  • Ausgang auf LOW: Led.Value:=false;
unit Unit1;
{$mode objfpc}{$H+}

interface

uses
 Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
 ExtCtrls, fpgpio;

type
TForm1 = class(TForm)
 Button1: TButton;
 Button2: TButton;
 Shape1: TShape;
 procedure Button1Click(Sender: TObject);
 procedure Button2Click(Sender: TObject);
 procedure FormCreate(Sender: TObject);
 procedure FormDestroy(Sender: TObject);
 private
   Led : TGpioLinuxPin;
 public
 end;

var
  Form1: TForm1;

implementation
{$R *.lfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  Led:=TGpioLinuxPin.Create(18); //GPIO18 verwenden
  Led.Direction:=gdOut; //als Ausgang verwenden
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Led.Value:=true; //Ausgang auf HIGH setzen
  Shape.Brush.Color:=clLime;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  Led.Value:=true; //Ausgang auf LOW setzen
  Shape.Brush.Color:=clWhite;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  Led.Free;
end;

end.

Für einen Test müssen Sie das erzeugte Programm mit sudo aufrufen. Den Link dazu finden Sie am Ende des Artikels.

sudo ./test_led

Ein Lauflicht

In meinem Fall sollen 7 einzelne LED’s und eine Multi LED (3-Farb-LED) möglichst variabel angesteuert werden.

Meine Umsetzung in Lazarus basiert auf einer eigenen Klasse TLedSequence. In dieser werden alle GPIO-Pins in einer Liste zusammengefasst.

 TLedSequence = class
   private
     FLedCount : integer; //Pins die angesteuert werden sollen
     FCount : integer; //Anzahl der Sequenzen
     FSequence : TStringList; //Reihenfolge der Ansteuerung
     FPins : TList; //Liste der GPIO-Pins
   public
     step : integer;
     stepstr : string;
     constructor Create;
     destructor Destroy;
     procedure AddPin(PinId: integer);
     procedure ReadSetup(Strings : TStrings);
     procedure NextStep;
     procedure AllOff;
   published
     property Count : integer read FCount write FCount;
     property LedCount : integer read FLedCount write FLedCount;
     property Sequence : TStringList read FSequence write FSequence;
     property Pins : TList read FPins write FPins;
end;

Mit der Methode AddPin werden die GPIO-Kontakte entsprechend der Beschreibung im obigen Beispiel als Ausgang eingestellt und einer TList hinzugefügt.

procedure TLedSequence.AddPin(PinId: integer);
{$IFDEF UNIX}
var Pin : TGpioLinuxPin;
 {$ENDIF}
begin
   {$IFDEF UNIX}
   Pin:=TGpioLinuxPin.Create(PinId);
   Pin.Direction:=gdOut;
   Pins.Add(Pin);
  FLedCount:=FLedCount+1;
   {$ENDIF}
end;

Um die 7 LED’s so einzustellen, ist nur noch folgender Code mit Angabe des GPIO-Pins notwendig:

//Pin-Definitionen für die 7 einzelnen LED's
SingleLeds:=TLedSequence.Create;
SingleLeds.AddPin(14);
SingleLeds.AddPin(15);
SingleLeds.AddPin(18);
SingleLeds.AddPin(23);
SingleLeds.AddPin(24);
SingleLeds.AddPin(25);
SingleLeds.AddPin(8);

Die Zahlen stehen für die entsprechenden GPIO-Bezeichnungen: GPIO14, GPIO15, GPIO18 usw.

Damit sind die Vorbereitungen auch schon abgeschlossen. Jetzt geht es um die Umsetzung einer variablen Reihenfolge-Programmierung der LED’s.  Die Speicherung passiert in einer TStringList. Jede Sequenz – das entspricht einer Zeile in der TStringList – ist eine Folge von 0 oder 1 (ein oder aus) für jede der 7 LED’s. In jeder weiteren Zeile, kann eine weitere Sequenz folgen.

Beispiel:

  • 1000000: Nur LED1 ist eingeschaltet, alle anderen sind aus
  • 1010101: LED1, LED3, LED5 und LED7 sind eingeschaltet

Der Code dafür steht in der Methode NextStep. Sie wird regelmäßig über einen Timer aufgerufen.

procedure TLedSequence.NextStep;
var
  i,j : integer;
  s : string;
{$IFDEF UNIX}
  var Pin : TGpioLinuxPin;
{$ENDIF}
begin
  step:=step+1;
  if step>FCount-1 then step:=0;
  stepstr:=FSequence[step];
  {$IFDEF UNIX}
  for i:=0 to FLedCount-1 do
    begin
     Pin:=TGpioLinuxPin(FPins[i]);
     try
       s:=copy(FSequence[step],i+1,1);
     except
       s:='0';
     end;
     if s='1' then Pin.Value:=true
     else Pin.Value:=false;
   end;
   {$ENDIF}
end;

Am besten lässt sich das über ein Beispielprojekt testen. Dafür verbinden Sie die 7 LED’s und einem Vorwiderstand auf einem Breadboard mit jeweils einem GPIO-Pin. Ich möchte zusätzlich noch andere Farben haben, deshalb wird auch noch eine Multi-LED über 3 GPIO-Pins genauso angeschlossen.

Um die 3 LED’s der Multi-LED kümmert sich eine weitere Instanz von TLedSequence.

Lauflichter für den Raspberry mit Lazarus
Aufbau der 7 einzelnen LED’s und der Multi-LED auf dem Breadboard

Mit dem Beispielprogramm Lauflicht Tester lassen sich verschiedene Sequenzen einfach testen. Tragen Sie Ihre Animation ein und drücken auf Start.

Lauflichter Tester unter Lazarus
Testprogramm für die Entwicklung einer Lauflicht-Animation

Auch das Beispiel-Programm müssen Sie für einen Test mit sudo aufrufen:

sudo ./test_ll

Den Link dazu finden Sie auch am Ende des Artikels.

Animation der Lauflichter mit Lazarus gesteuert vom Raspberry
Beispielanimation auf dem Breadboard

Im Beispiel zeigt sich auch einer der Vorteile von Lazarus als Progammierumgebung für die GPIO’s des Raspberry Pi: Die einfache Visualisierung!

Mit ein paar TShape-Elementen lässt sich eine aussagefähige Visualisierung aufbauen. Und anders als in Python nicht über nur Quelltext, sondern visuell per Maus direkt im Formular.

Dialogfenster von Lauflichter Tester
Visualisierung des Lauflichts im Test-Programm

Ich verwende das Lauflicht gleich in meinem nächsten Projekt. Der Testaufbau von oben kommt als optische Erweiterung in meinen Medienplayer. Wie dieser bisher – vor der Erweiterung – aussieht, können Sie unter TACTbox – Mein Mediaplayer nachlesen.

Jetzt aber viel Spaß beim Testen und Weiterentwickeln.

Downloads

symbol_download

  LED-Beispiel

symbol_download

  Lauflicht mit Einzel- und 3-fach-LED

Links


Click here to read this article in English.

Dieser Beitrag hat 4 Kommentare

  1. Thomas Angielsky

    Die Lösung jedes Programm mit sudo aufzurufen, ist auf Dauer nicht zufriedenstellend. Eine Möglichkeit ist, die entsprechenden Ordner für den Benutzer pi zu berechtigen.

    Erstellen Sie eine Datei mit diesem Inhalt unter z. B. /home/pi/skripte/gpio_init.sh

    #!/bin/sh
    sudo chmod -R 666 /sys/class/gpio/gpio0/value
    sudo chmod -R 666 /sys/class/gpio/gpio0/direction

    Dann machen Sie das Skript ausführbar mit:
    chmod a+x gpio_init.sh

    Das muss aber bei jedem Start neu getan werden. Um das noch zu automatisieren, fügen Sie den Aufruf in der Datei /etc/rc.local ein. Dann klappen die Programmierung und der Test unter Lazarus wesentlich einfacher.

Kommentar verfassen