Running lights and LED control with Lazarus

Breadboard, Lazarus und Freepascal

With running lights you create amazing effects in a simple way. That’s no problem with a Raspberry Pi and some Python code. Even with Lazarus and Free Pascal is easy and visualization is cool.

Lazarus is a Delphi-like programming language for many platforms based von Pascal. The basic version of Lazarus still has no functions or classes for programming the GPIO pins on the Raspberry. But there are some ways you can code with pins.

An overview is the Wiki at http://wiki.freepascal.org/Lazarus_on_Raspberry_Pi . I use the package PascalIO for this project . Download it and save it in your Larazus library.

Integrate PascalIO

For a first test start a new Lazarus Project. Add the package PascalIO. The easiest way by the package via the menu item package is loaded from your folder. By clicking on the Add to Project it is available for your project.

Lazarus add package PascalIO
Add PascalIO to your project

 

Toggle outputs

The use of PascalIO for GPIO programming is very simple. In the first step is to add the needed units. If only GPIO need to be connected, it is only the unit fpgpio.

Dialog an Breadboard
Example for the control of a single LED

In this example a LED is connected via a resistor of 330 Ω. The program toggles the GPIO18 from LOW to HIGH and back.

In the FormCreate procedure, similar to Python, the settings of Pins are made:

  • Declare the GPIO pin number: Led: = TGpioLinuxPin.Create(18);
  • Type of pin set – input or output:  Led.Direction: = gdOut;

To turn the pin on or off use the property value. It is boolean.

  • Output HIGH: Led.Value: = true;
  • Output to 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
 { private declarations }
   Led : TGpioLinuxPin;
 public
 { public declarations }
 end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  Led:=TGpioLinuxPin.Create(18); //use GPIO18
  Led.Direction:=gdOut; //declare as output
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Led.Value:=true; //set value to HIGH
  Shape1.Brush.Color:=clLime;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  Led.Value:=false; //set value to LOW
  Shape1.Brush.Color:=clWhite;
end;

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

end.

For a test, you must call the program generated with sudo. You can find the link for a download to it at the end of the article.

sudo ./test_led

 

A running light

For my mediaplayer I wanted to control 7 single LEDs and a multi-LED (3-color LED) with a changeable sequence.

My solution in Lazarus is based on my own class TLedSequence . In this all GPIO pins are packed inside a list.

TLedSequence = class
   private
     FLedCount : integer; //Number of pins
     FCount : integer; //Number of sequences
     FSequence : TStringList; //List of sequences
     FPins : TList; //List of 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;

With the method AddPin the GPIO contacts are adjusted in accordance with the description in the above example as an output and added to a TList.

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;

To setup the seven single LEDs only the following code is necessary:

SingleLeds:=TLedSequence.Create;
SingleLeds.AddPin(14);
SingleLeds.AddPin(15);
SingleLeds.AddPin(18);
SingleLeds.AddPin(23);
SingleLeds.AddPin(24);
SingleLeds.AddPin(25);
SingleLeds.AddPin(8);

The numbers represent the corresponding GPIO names: GPIO14, GPIO15, GPIO18 etc.

So the preparations are complete. Now the implementation of your custom sequence starts. We store the information about this in a TStringList . Each sequence – which corresponds to a line in the TStringList – is a sequence of 0 or 1 (on or off) for each of the 7 LED’s. In every other line, another sequence can follow.

Example:

  • 1000000: Only LED 1 is on, all others are from
  • 1010101: LED1, LED3, LED5 and LED7 are turned on

The code for this is in the method NextStep . It is called regularly by a timer.

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;

The best way to test this is with a sample project. Just connect the 7 LED’s with a resistor on a breadboard to one GPIO pin. I would like to have additional other colors, so a multi-LED is also connected through 3 GPIO pins.

The three LEDs of the multi-LED are controlled by another instance of TLedSequence.

Breadboard
The 7 single LEDs and the multi-LED on the breadboard

With the example program rlt (running light tester), various sequences can be easily tested. Type in your animation and press Start.

Lazarus form for testing
Test program for the development of a running light animation

The example program you need for a test with sudo access:

sudo ./rlt

You can find the link for a download at the end of the article.

If you don’t want to start every program with sudo, you have to allow the user pi to access the GPIO pins.

Create a file for example under /home/pi/scripts/gpio_init.sh

#!/bin/sh
sudo chmod -R 666 /sys/class/gpio/gpio0/value
sudo chmod -R 666 /sys/class/gpio/gpio0/direction
And make it executable:
chmod a+x gpio_init.sh

But this have to be done at every re-boot. So it’s better to add the script to the file /etc/rc.local.

Beispielanimation auf dem Breadboard
Example animation on the breadboard

In the example you see (hopefully) one of the advantages of Lazarus as IDE for the GPIO’s of the Raspberry Pi: The simple visualization !

With a few TShape elements you can built a meaningful visualization. And better than in Python: visually on a form, not only source code.

Dialogfenster von Lauflicht Tester
Easy visualization of the LED’s in the test program

And now a lot of fun testing and further development with Lazarus an the Raspberry Pi!

Download

symbol_download

  Lazarus project „Running light tester“ and LED example

Unpack the archives with:

tar xfv rtl.tar
tar xfv example.tar

 

Links


Klicken Sie hier, um diesen Artikel in Deutsch zu lesen.

Dieser Beitrag hat 4 Kommentare

Kommentar verfassen