Reading Raspberry Pi GPIO Pins using Lazarus / Free Pascal

Way back when, I did a simple example of using Free Pascal to turn an LED on and off:

Accessing Raspberry Pi GPIO using Lazarus/Free Pascal

To date, that has been the most I’ve needed to do to the real world with a Raspberry Pi. Mainly I use Arduinos and have them talk to a Raspberry Pi.

A project I’m working on at the moment requires that I sense a push button being pressed on a Raspberry Pi, so I can silence an alarm.

I found that both pull up and pull down resistors are available, so I figured I would write a quick test program and verify I can make everything work under Free Pascal.

As you probably know, you need to make sure you use the 3.3V power pins when feeding them back into GPIO ports; otherwise, you will fry your RPI.

I find the GPIO pin numbers vs. the physical pin numbers to be a bit confusing. The GPIO pin numbers are printed on the RPI and Pi Cobbler but (at least) Free Pascal want physical pin numbers.

To map between the two I use this diagram:

I am using the wiringpi library and free pascal wrapper found at

When you attempt to run a program compiled with this library, it must have root permission, so if you name your program xyz, use ‘sudo xyz’ to run it!

Using a Physical Pull Down Resistor

First I use a pull down resistor, mainly to make sure everything works before I mess with the internal pull down resistor.

I wired the switch as follows:

gpio-in-fig1

When the switch is open, the GPIO pin is LOW, pulled down to ground. When the switch is closed, it goes HIGH to 3.3V.

I then used the following code to test this configuration:

program readgpio;

{$mode objfpc}{$H+}

uses
    {$IFDEF UNIX}{$IFDEF UseCThreads}
    cthreads,
    {$ENDIF}{$ENDIF}
    Classes,
    hwiringpi;

{$R *.res}

var
    lastState                   : integer;

begin

If wiringPiSetup = -1 then begin // Setup Hardware (Gordons magic)
    writeln('wirintPiSetup failed');
    halt;
    end;

pinMode(p15, INPUT);

lastState := LOW;

while true do begin

    if digitalRead(p15) <> lastState then begin     // print state when it changes
        delay(50);                                  // debounce
        lastState := abs(lastState - 1);            // tricky way to toggle state between low/high 0/1
        if lastState = LOW then
            writeln('LOW')
        else
            writeln('HIGH');
        end;

    delay(10);

    end; // while

end.

This worked perfect. Pressing the button displays ‘HIGH’ and releasing it displays ‘LOW’.

Now to try an internal pull down resistor. The switch is now wired like this:

gpio-in-fig2

To enable the internal pull down resistor, I use the pullUpDnControl call:

program readgpio;

{$mode objfpc}{$H+}

uses
    {$IFDEF UNIX}{$IFDEF UseCThreads}
    cthreads,
    {$ENDIF}{$ENDIF}
    Classes,
    hwiringpi;

{$R *.res}

var
    lastState                   : integer;

begin

If wiringPiSetup = -1 then begin // Setup Hardware (Gordons magic)
    writeln('wirintPiSetup failed');
    halt;
    end;

pinMode(p15, INPUT);
pullUpDnControl(p15, PUD_DOWN);                 // enable pull down resistor

lastState := LOW;

while true do begin

    if digitalRead(p15) <> lastState then begin // print state when it changes
        delay(50);                              // debounce
        lastState := abs(lastState - 1);        // tricky way to toggle state between low/high 0/1
        if lastState = LOW then
            writeln('LOW')
        else
            writeln('HIGH');
        end;

    delay(10);

    end; // while

end.

This worked exactly like having the physical pull down resistor in place.

Instead of using the internal pull down transistor you can use the internal pull up transistor. In the pullUpDnControl call, just use PUD_UP instead.

When using the pull up resistor, it uses the same reverse logic one must handle when using pull up resistors on the arduino.

When doing this, you must connect the switch to ground. So when the switch is pressed, you get a LOW instead of a HIGH.

I tend to NOT think like this and must immediately NOT the digitalRead into positive logic so I don’t get confused. It is really nice not to have to do that on the RPI.

Advertisements
This entry was posted in c-lazarus, c-rpi and tagged . Bookmark the permalink.

3 Responses to Reading Raspberry Pi GPIO Pins using Lazarus / Free Pascal

  1. Pingback: Accessing Raspberry Pi GPIO using Lazarus/Free Pascal | Big Dan the Blogging Man

  2. Danny says:

    One thing thats causing issues for me is when I add {$R *.res}
    it errors and says can’t open resource file “/home/pi/Scanner.unit1.res…

  3. Dan TheMan says:

    Hmmm, I’ve never seen that type of problem and I’ve written a fair amount of Laz code. It sounds like something very basic is wrong if it can’t find a resource file.

    If it were me, I’d comment out everything to the point of having just a ‘hello world’ program and once I knew that worked, I’d start adding stuff back until I saw what caused the resource file error.

    I’ve been forced to do that very thing with the Arduino IDE repeatedly as it has had some very odd behaviors in the past.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s