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:

Arduino/Raspberry Pi via I2C

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:

http://wiki.freepascal.org/Lazarus_on_Raspberry_Pi

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+}

uses
    baseUnix,
    classes,
    {$IFDEF UNIX}{$IFDEF UseCThreads}
    cthreads,
    {$ENDIF}{$ENDIF}
    sysutils;

const
    I2C_SLAVE            = 1795;

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

begin

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

while true do begin

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

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

    buf[0] := #99;
    sleep(10);

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

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

fpclose(handle);

end.

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

i2c1

and here is the Arduino echoing the 2 back:

i2c2

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:

    Hi,
    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 comment

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