From Free Pascal wiki

Deutsch (de) English (en) español (es)

Arduino Logo.svg

This article applies to Arduino boards only.

See also: Multiplatform Programming Guide

Many Arduino projects have the need to send data to a PC running a program for data aquisition and visualisation. Lazarus is highly suitable for developing such programs, i.e. to build the PC-sided counterpart of an Arduino project.

For Lazarus developers Arduino opens a whole new world of smart physical sensors and actuators for monitoring, control and data acquisition.

The fpc compiler is even capable to compile programs for Arduino boards itself.

Arduino Uno R3.png

FPC on Arduino

Currently (2017) most Arduino boards carry microcontrollers of the AVR family (Atmega). An other popular arduino board carries a STM32 (ARM Cortex). For both microcontroller families there are fpc compilers available. Programming Arduino with FPC of course doesn't mean to use the arduino ecosystem with just a different language. Nevertheless arduino libs (C++) can be used in fpc programms, but mixing languages obviously is an advanced topic. While compilation the fpc creates a .hex-file (binary), this can be loaded to the microcontroller, arduino board respectively, using a programming software by choice. AVRDude e.g. also supports program upload using the Arduino bootloader.

There are further wiki pages for programing AVR microcontrollers: AVR, AVR Programming

There is also a tutorial on how to use Lazarus on a AtMega328p (Arduino Uno/Nano) in German language: AVR Embedded Tutorial/de

Communication between a Lazarus application and Arduino

The following section describes how your Lazarus/FPC application can communicate with Arduino boards, no matter whether fpc or arduino is running on the arduino board.

One-way serial communication example using Synaser

Here we show how to communicate with your board through serial communication channel.

Lazarus side serial application

There are many ways for serial communication in Lazarus and FPC.

Minimal Lazarus Synaser serial example

We will use Synaser from Synapse library in this example. Create Lazarus application with one form and two buttons. Include Synaser unit and add Synapse package as a new requirement to your project (you do this in Project Inspector). In OnClick event of both buttons put something like this:

procedure TForm1.Button1Click(Sender: TObject);
  ser: TBlockSerial;
  ser := TBlockSerial.Create;
    ser.Connect('COM1'); // write here Arduino COM port number (on linux it's something like '/dev/ttyUSB0')
    ser.config(9600, 8, 'N', SB1, False, False);
    ser.SendString('on'); // button 2 should have 'off' here

Arduino side serial application

You can program your Arduino in several languages.

Minimal Arduino C sketch serial example

You can follow this nice step by step tutorial. In short, you need to add a led with proper resistor to your input pin 13, compile this sketch in your Arduino IDE, and download it to your board:

int led = 13; // Pin 13

void setup()
    pinMode(led, OUTPUT); // Set pin 13 as digital out

    // Start up serial connection
    Serial.begin(9600); // baud rate

void loop()
    String input = "";

    // Read any serial input
    while (Serial.available() > 0)
        input += (char); // Read in one char at a time
        delay(5); // Delay for 5 ms so the next char has time to be received

        if (input == "on")
            digitalWrite(led, HIGH); // on
        else if (input == "off")
            digitalWrite(led, LOW); // off

Minimal Arduino mikroPascal serial example

mikroPascal for AVR can be used to develop Arduino programs. TBD.

Minimal Arduino E-Lab AvrCo serial example

E-Lab AvrCo Multitasking Pascal can be used to develop Arduino programs. TBD.

Minimal Arduino FPC serial example

Yes, your Arduino 8-bit AVR board can be programmed with FPC too. TBD.

Bidirectional serial communication example using SDPO

The single directional example is based on synaser, which is not a visual component. SDPO provides a visual wrapper around Synaser, and some people may find this method easier. The following example requires the SDPO package (currently 0.4.0) to be installed in Lazarus. There are other tutorials to show you how to install package. If you cannot find the SDPO component on your component palette, this example will not work.

Lazarus Side of Bidirectional SDPO serial example

Open a new project, and add the following to a form: (Names are the default names)

  1. the SDPO port (under the SDPO tab after you have installed it).
  2. four buttons. Caption as follows: Button1 SEND; Button2 CLEAR; Button3 UP; Button4 DOWN;
  3. a memo. Used to display what is sent and received.
  4. a panel. Used to display which number is being sent.

Configure the Sdposerial1 properties to match the Arduino with the object inspector.

  • Baudrate = br__9600;
  • Device = YourSerialPort ( mine is /dev/ttyUSB0 ). This is probably the same port you use to program your Arduino.
  • FlowControl = fcNone;
  • Parity = pNone;
  • StopBits = sbOne;
  • SynSer = (TBlockSerial); (notice this from the previous example?)
  • Tag = 0;

Using the code window, find the spot under var where it defines Form1: Tform; , and add the next three variables:

  Form1: TForm1;
  incomingstring: String;
  completestring: String;
  messagenum: integer;

Add the following events (code is shown below)

  • OnCreate for Form1
  • OnDestroy for Form1
  • OnRxData for Sdposerial1
  • OnClick for each button (4 events)

In the empty code blocks for each event, add the following code.

procedure TForm1.SdpoSerial1RxData(Sender: TObject);
  // add whatever is in the serial buffer to the incoming string
  incomingstring := incomingstring + SdpoSerial1.ReadData;
  // arduino terminates a serial.println transmission with a CR (#13) and a LF (#10).
  // check to see if our incming string is terminated by a linefeed
  if (incomingstring[Length(incomingstring)] = #10 ) then
      // the string ends a linefeed, so the whole string from the arduino is here.
      // remove the extra two characters before adding the incoming string to the memo (adds extra lines if you dont)
      completestring := LeftStr(incomingstring,Length(incomingstring)-2);  // trim two places
      Memo1.Lines.add(completestring);  // echo the new string to the memo
      incomingstring := '';             // clear the incoming string so we can start again

procedure TForm1.FormCreate(Sender: TObject);
  incomingstring := '';;
  SdpoSerial1.Active := true;

procedure TForm1.Button3Click(Sender: TObject);
// request to go higher
  // check to see if we have reached the upper limit
  if (messagenum < 32) then
      messagenum := messagenum + 1; // increase the number
      panel1.caption := inttostr(messagenum); // display the new number
  // if we have reached the limit, this won't do anything

procedure TForm1.Button2Click(Sender: TObject);
  memo1.lines.clear;  // clear the memo

procedure TForm1.Button1Click(Sender: TObject);
// send a request to the arduino
  memo1.lines.add(panel1.caption);  // echo the request to the memo
  SdpoSerial1.WriteData(panel1.caption + #13#10);

procedure TForm1.Button4Click(Sender: TObject);
// request to go lower
  // check to see if we have reached the lower limit
  if (messagenum > 0) then
      messagenum := messagenum - 1; // decrease the number
      panel1.caption := inttostr(messagenum); // display the new number
  // if we have reached the limit, this won't do anything

procedure TForm1.FormDestroy(Sender: TObject);
  SdpoSerial1.Active := false;

Test the program, and verify that it compiles.

Arduino side of Bidirectional serial example application

The following code has been tested on a Arduino Mega 2560 clone board. Feel free to alter it as you see fit. It is provided as one block to avoid adding your own strings.

//** This program is to demo simple bidirectional serial communication
//** between an Arduino a computer running Lazarus.  This is one side 
//** of the tutorial.  See for more
//** details.  Tested on Linux Mint with off-brand Arduino mega 2560.  
//** Program draws heavily on the work of others.  Use program freely, 
//** but at your own risk.  so-called insults adapted from

char incoming;
String textnum;
int number;
String insult[34];

void setup()
    // Start up serial connection
    Serial.begin(9600); // baud rate
    delay(1000);  // give the port time to work
    insult[0] = "If I wanted to kill myself I'd climb your ego and jump to your IQ.";
    insult[1] = "Two wrongs can't make a right - take your parents as an example.";
    insult[2] = "Support bacteria - they're the only culture you have.";
    insult[3] = "I don't engage in mental combat with the unarmed.";
    insult[4] = "I was going to give you a nasty look, but you already had one.";
    insult[5] = "I'm not insulting you. I'm describing you.";
    insult[6] = "Stupidity is not a crime so you are free to go.";
    insult[7] = "Don't you love nature, despite what it did to you?";
    insult[8] = "I'm jealous of all the people that haven't met you!";
    insult[9] = "You're so fake, Barbie is jealous.";
    insult[10] = "You are proof that evolution CAN go in reverse.";
    insult[11] = "There's only one problem with your face - I can see it.";
    insult[12] = "Brains aren't everything. In your case they're nothing.";
    insult[13] = "The last thing I want to do is hurt you - but it's on the list.";
    insult[14] = "If I had a face like yours, I'd sue my parents.";
    insult[15] = "We all sprang from apes, but you didn't spring far enough.";
    insult[16] = "If I wanted to hear from an asshole, I'd fart.";
    insult[17] = "As an outsider, what do you think of the human race?";
    insult[18] = "Hell is wallpapered with all your deleted selfies.";
    insult[19] = "Ordinarily people live and learn. You just live.";
    insult[20] = "You're so ugly, you scared the crap out of the toilet.";
    insult[21] = "Your gene pool could use a little chlorine.";
    insult[22] = "You look like a before picture.";
    insult[23] = "You're proof that god has a sense of humor.";
    insult[24] = "I may love to shop but I'm not buying your bullshit.";
    insult[25] = "You're about as useless as an asshole with tastebuds.";
    insult[26] = "You're so fat, you could sell shade.";
    insult[27] = "If shit was music, you'd be an orchestra.";
    insult[28] = "Shock me, say something intelligent.";
    insult[29] = "Whatever kind of look you were going for, you missed.";
    insult[30] = "He's as sharp as a bowling ball.";
    insult[31] = "Are your parents siblings?";
    insult[32] = "You're a few clowns short of a circus.";    
    insult[33] = "ERROR - SOMETHING WENT WRONG";    

void loop()
    textnum = "";  // clear the number
    number = 33;   // set the number to give the error message

    // Read any serial input
    while (Serial.available() > 0)
      incoming = (char); // Read in one char
      if (isdigit(incoming)) textnum += incoming; 
        delay(50); // Delay for 50 ms so the next char has time to be received

    if (textnum != "")
        number = String(textnum).toInt();  // convert the incoming string to a number
        Serial.println(insult[number]);    // send the appropriate string back


Compile and upload this code to your board. You should be able to test the program by opening the Serial Monitor in Arduino, and sending a number from 0 to 32 to the Arduino. It should respond by "insulting" you with the appropriate numbered insult. No error checking is provided, so keep your requests in range.

Connecting the Two Sides

Serial Ports cannot be opened by more than one program at a time - particularly when a program grabs the port and hogs it like this simple example does. Make sure you close the Arduino Serial Monitor before attempting to run the Lazarus program. Your Arduino should be plugged in and powered up. If you are working under Linux, you may need to run the program as a superuser, or you may need to add your user to the dialout group. In any case, once the Arduino is up and running, you can run the program. It must be able to connect with the Arduino when it creates the main window, and it will hog the port until you properly close the application. Depending on your computer, sleeping or hibernating may mess up your communications.

Ethernet communication

Here we show how to communicate with your board through ethernet communication channel.

Lazarus side ethernet application


Arduino side ethernet application


Wiki Resources

External Resources