Raspberry Pi/I2C with Lazarus/Free Pascal

(This post discusses communication between arduino and raspberry Pi using I2C. If you want to use the USB connection as a serial connection, see this post: Serial Communications (USB) between a Raspberry Pi and an Arduino Using Lazarus / Free Pascal).

Spent a couple of days researching how to use I2C on the Raspberry Pi with Lazarus/Free Pascal. My prior experiment was to use a python program verbatim:


I can kind of read python and that’s about all. It isn’t a language I have any plans to use. My preference is Pascal. So I wanted to see what is necessary to use I2C with Pascal. Ends up being pretty simple.

There are some links on the FP website regarding accessing RPI hardware with FP:


There is a library listed on that web page, RPI_HAL, that supports I2C. I downloaded the library and did the sample (which doesn’t do any I2C calls). I then attempted to write a program to do a simple I2C write. I got run time errors unrelated to I2C. I decided it would be easier to just directly access I2C rather than figure out why the library was acting up.

Turns out, it is VERY easy to access I2C with Free Pascal.  To do so you open I2C as a file:

iDevAddr               : Cint = $04;
devPath                : string = '/dev/i2c-1';

handle := fpopen(devPath,O_RDWR);
fpIOCtl(handle, I2C_SLAVE, pointer(iDevAddr));

To write a byte from buf:

fpwrite(handle, buf, 1);

To read a byte into buf:

fpread(handle, buf, 1);

Here is my program that is a replacement of the python program from my prior post:

program testrpi;

{$mode objfpc}{$H+}

    {$IFDEF UNIX}{$IFDEF UseCThreads}

    I2C_SLAVE            = 1795;

    buf                  : packed array [0..1] of char;
    c                    : char;
    devPath              : string = '/dev/i2c-1';
    handle               : Cint;
    iDevAddr             : Cint = $04;


    handle := fpopen(devPath,O_RDWR);
    fpIOCtl(handle, I2C_SLAVE, pointer(iDevAddr));
    writeln('Error initalizing i2c');

while true do begin

    write('Enter digit 1-9:');
    if (not(c in ['1'..'9'])) then begin
        writeln('oops - try again');
    buf[0] := chr(ord(c) - ord('0'));

        fpwrite(handle, buf, 1); 
        writeln('Error writing');
    end; //try

    buf[0] := #99;

        fpread(handle, buf, 1);
        writeln('Error reading');
    end; //try

    writeln('buf=', ord(buf[0]));
    end; //while



I got to use my new logic analyzer while learning I2C. Here is the trace of the RPI sending a ‘2’ to the Arduino:


and here is the Arduino echoing the 2 back:


Aug 2014 Update:

If you are using a user other than ‘pi’, MAKE SURE that user has been assigned to the I2C group in the /etc/group file.  Click here if you don’t know how to do this.

This entry was posted in Arduino/RPI I2C, c-lazarus, c-rpi. Bookmark the permalink.

7 Responses to Raspberry Pi/I2C with Lazarus/Free Pascal

  1. Pingback: Serial Communications (USB) between a Raspberry Pi and an Arduino Using Lazarus / Free Pascal | Big Dan the Blogging Man

  2. fnemeth says:

    thanks for this post. I would have a question. What is 1795? How did you get this number?

  3. Igor Zakharov says:

    This program working great!!! Thank you!
    But how to access ds1307 RTC from lazarus form application?

  4. Igor Zakharov says:

    Hi, thanks for this example. How to do the same in Form application?

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 )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.