Sign in Join
Wiki copytemporary

Arduino: what changed

Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.

Title: Arduino

OldNewLine
1+*(Arduino only)*
2+
3+Many [Arduino](https://en.wikipedia.org/wiki/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.
4+
5+For Lazarus developers Arduino opens a whole new world of smart physical sensors and actuators for monitoring, control and data acquisition.
6+
7+The fpc compiler is even capable to compile programs for Arduino boards itself.
8+
9+<figure>
10+<img src="Arduino_Uno_R3.png" title="Arduino_Uno_R3.png" />
11+<figcaption>Arduino_Uno_R3.png</figcaption>
12+</figure>
13+
14+# FPC on Arduino
15+
16+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.
17+
18+There are further wiki pages for programing AVR microcontrollers: [[AVR]], [[AVR Programming]]
19+
20+There is also a tutorial on how to use Lazarus on a AtMega328p (Arduino Uno/Nano) in German language: [[AVR Embedded Tutorial/de]]
21+
22+# Communication between a Lazarus application and Arduino
23+
24+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.
25+
26+## One-way serial communication example using Synaser
27+
28+Here we show how to communicate with your board through serial communication channel.
29+
30+### Lazarus side serial application
31+
32+There are many ways for [[Hardware Access|serial]] communication in Lazarus and FPC.
33+
34+#### Minimal Lazarus Synaser serial example
35+
36+We will use [Synaser](http://synapse.ararat.cz/doc/help/synaser.html) from [Synapse library](http://www.ararat.cz/synapse/doku.php) in this example. Create Lazarus application with one form and two buttons. Include Synaser unit and add [[Synapse|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:
37+
38+``` pascal
39+procedure TForm1.Button1Click(Sender: TObject);
40+var
41+ ser: TBlockSerial;
42+begin
43+ ser := TBlockSerial.Create;
44+ try
45+ ser.Connect('COM1'); // write here Arduino COM port number (on linux it's something like '/dev/ttyUSB0')
46+ Sleep(250);
47+ ser.config(9600, 8, 'N', SB1, False, False);
48+ ser.SendString('on'); // button 2 should have 'off' here
49+ finally
50+ ser.free;
51+ end;
52+end;
53+```
54+
55+### Arduino side serial application
56+
57+You can program your Arduino in several languages.
58+
59+#### Minimal Arduino C sketch serial example
60+
61+You can follow [this](http://www.chrisbrand.co.za/2013/06/30/arduino-serial-port/) 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](https://www.arduino.cc/en/Main/Software), and download it to your board:
62+
63+``` cpp
64+int led = 13; // Pin 13
65+
66+void setup()
67+{
68+ pinMode(led, OUTPUT); // Set pin 13 as digital out
69+
70+ // Start up serial connection
71+ Serial.begin(9600); // baud rate
72+ Serial.flush();
73+}
74+
75+void loop()
76+{
77+ String input = "";
78+
79+ // Read any serial input
80+ while (Serial.available() > 0)
81+ {
82+ input += (char) Serial.read(); // Read in one char at a time
83+ delay(5); // Delay for 5 ms so the next char has time to be received
84+
85+ if (input == "on")
86+ {
87+ digitalWrite(led, HIGH); // on
88+ }
89+ else if (input == "off")
90+ {
91+ digitalWrite(led, LOW); // off
92+ }
93+ }
94+}
95+```
96+
97+#### Minimal Arduino mikroPascal serial example
98+
99+[mikroPascal for AVR](https://www.mikroe.com/mikropascal/) can be used to develop Arduino programs. TBD.
100+
101+#### Minimal Arduino E-Lab AvrCo serial example
102+
103+[E-Lab AvrCo Multitasking Pascal](http://e-lab.de/AVRco/index_en.html) can be used to develop Arduino programs. TBD.
104+
105+#### Minimal Arduino FPC serial example
106+
107+Yes, your Arduino 8-bit AVR board [[AVR Programming|can be programmed with FPC]] too. TBD.
108+
109+## Bidirectional serial communication example using SDPO
110+
111+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.
112+
113+#### Lazarus Side of Bidirectional SDPO serial example
114+
115+Open a new project, and add the following to a form: (Names are the default names)
116+
117+1. the SDPO port (under the SDPO tab after you have installed it).
118+2. four buttons. Caption as follows: Button1 SEND; Button2 CLEAR; Button3 UP; Button4 DOWN;
119+3. a memo. Used to display what is sent and received.
120+4. a panel. Used to display which number is being sent.
121+
122+Configure the Sdposerial1 properties to match the Arduino with the object inspector.
123+
124+- Baudrate = br__9600;
125+- Device = YourSerialPort ( mine is /dev/ttyUSB0 ). This is probably the same port you use to program your Arduino.
126+- FlowControl = fcNone;
127+- Parity = pNone;
128+- StopBits = sbOne;
129+- SynSer = (TBlockSerial); (notice this from the previous example?)
130+- Tag = 0;
131+
132+Using the code window, find the spot under var where it defines **Form1: Tform;** , and add the next three variables:
133+
134+``` pascal
135+var
136+ Form1: TForm1;
137+ incomingstring: String;
138+ completestring: String;
139+ messagenum: integer;
140+```
141+
142+Add the following events (code is shown below)
143+
144+- OnCreate for Form1
145+- OnDestroy for Form1
146+- OnRxData for Sdposerial1
147+- OnClick for each button (4 events)
148+
149+In the empty code blocks for each event, add the following code.
150+
151+``` pascal
152+procedure TForm1.SdpoSerial1RxData(Sender: TObject);
153+begin
154+ // add whatever is in the serial buffer to the incoming string
155+ incomingstring := incomingstring + SdpoSerial1.ReadData;
156+ // arduino terminates a serial.println transmission with a CR (#13) and a LF (#10).
157+ // check to see if our incming string is terminated by a linefeed
158+ if (incomingstring[Length(incomingstring)] = #10 ) then
159+ begin
160+ // the string ends a linefeed, so the whole string from the arduino is here.
161+ // remove the extra two characters before adding the incoming string to the memo (adds extra lines if you dont)
162+ completestring := LeftStr(incomingstring,Length(incomingstring)-2); // trim two places
163+ Memo1.Lines.add(completestring); // echo the new string to the memo
164+ incomingstring := ''; // clear the incoming string so we can start again
165+ end;
166+end;
167+
168+procedure TForm1.FormCreate(Sender: TObject);
169+begin
170+ incomingstring := '';
171+ SdpoSerial1.open;
172+ SdpoSerial1.Active := true;
173+end;
174+
175+procedure TForm1.Button3Click(Sender: TObject);
176+// request to go higher
177+begin
178+ // check to see if we have reached the upper limit
179+ if (messagenum < 12) then
180+ begin
181+ messagenum := messagenum + 1; // increase the number
182+ panel1.caption := inttostr(messagenum); // display the new number
183+ end;
184+ // if we have reached the limit, this won't do anything
185+end;
186+
187+procedure TForm1.Button2Click(Sender: TObject);
188+begin
189+ memo1.lines.clear; // clear the memo
190+end;
191+
192+procedure TForm1.Button1Click(Sender: TObject);
193+// send a request to the arduino
194+begin
195+ memo1.lines.add(panel1.caption); // echo the request to the memo
196+ SdpoSerial1.WriteData(panel1.caption + #13#10);
197+end;
198+
199+procedure TForm1.Button4Click(Sender: TObject);
200+// request to go lower
201+begin
202+ // check to see if we have reached the lower limit
203+ if (messagenum > 0) then
204+ begin
205+ messagenum := messagenum - 1; // decrease the number
206+ panel1.caption := inttostr(messagenum); // display the new number
207+ end;
208+ // if we have reached the limit, this won't do anything
209+end;
210+
211+procedure TForm1.FormDestroy(Sender: TObject);
212+begin
213+ SdpoSerial1.Active := false;
214+ SdpoSerial1.close;
215+end;
216+
217+```
218+
219+Test the program, and verify that it compiles.
220+
221+### Arduino side of Bidirectional serial example application
222+
223+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.
224+
225+``` cpp
226+//** This program is to demo simple bidirectional serial communication
227+//** between an Arduino a computer running Lazarus. This is one side
228+//** of the tutorial. See https://wiki.freepascal.org/Arduino for more
229+//** details. Tested on Linux Mint with off-brand Arduino mega 2560.
230+//** Program draws heavily on the work of others. Use program freely,
231+//** but at your own risk.
232+
233+char incoming;
234+String textnum;
235+int number;
236+String txt[12];
237+
238+void setup()
239+{
240+ // Start up serial connection
241+ Serial.begin(9600); // baud rate
242+ Serial.flush();
243+ delay(1000); // give the port time to work
244+ txt[ 0] = "You asked for message 0.";
245+ txt[ 1] = "You asked for message 1.";
246+ txt[ 2] = "You asked for message 2.";
247+ txt[ 3] = "You asked for message 3.";
248+ txt[ 4] = "You asked for message 4.";
249+ txt[ 5] = "You asked for message 5.";
250+ txt[ 6] = "You asked for message 6.";
251+ txt[ 7] = "You asked for message 7.";
252+ txt[ 8] = "You asked for message 8.";
253+ txt[ 9] = "You asked for message 9.";
254+ txt[10] = "You asked for message 10.";
255+ txt[11] = "You asked for message 11.";
256+ txt[12] = "ERROR - SOMETHING WENT WRONG";
257+}
258+
259+void loop()
260+{
261+ textnum = ""; // clear the number
262+ number = 12; // set the number to give the error message
263+
264+ // Read any serial input
265+ while (Serial.available() > 0)
266+ {
267+ incoming = (char) Serial.read(); // Read in one char
268+ if (isdigit(incoming)) textnum += incoming;
269+ delay(50); // Delay for 50 ms so the next char has time to be received
270+ }
271+
272+ if (textnum != "")
273+ {
274+ number = String(textnum).toInt(); // convert the incoming string to a number
275+ Serial.println(txt[number]); // send the appropriate string back
276+ }
277+
278+
279+}
280+```
281+
282+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.
283+
284+### Connecting the Two Sides
285+
286+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.
287+
288+## Ethernet communication
289+
290+Here we show how to communicate with your board through ethernet communication channel.
291+
292+### Lazarus side ethernet application
293+
294+TBD
295+
296+### Arduino side ethernet application
297+
298+TBD
299+
300+## Wiki Resources
301+
302+- [[Portal:Embedded|Embedded Portal]]
303+- [[AVR]]
304+- [[AVR Programming]]
305+
306+## External Resources
307+
308+- [Forum topic that started this article](http://forum.lazarus.freepascal.org/index.php?topic=36885)
309+- [Raspberry Pi Lazarus application talking to Arduino over serial](https://bigdanzblog.wordpress.com/2014/11/07/serial-communications-usb-between-a-raspberry-pi-and-an-arduino-using-lazarus-free-pascal/)
310+- [FPC application talking to ESP8266 over TCP](https://bigdanzblog.wordpress.com/2016/02/14/using-lazarus-free-pascal-to-communicate-with-esp8266/)
311+- [FPC application talking to Arduino Nano over TCP](https://bigdanzblog.wordpress.com/2014/11/19/tcp-communications-between-a-pc-and-an-arduino-nano-using-lazarus-free-pascal/)
312+- [Arduino projects](https://www.allaboutcircuits.com/projects/category/arduino/)
313+
314+---
315+*From the Free Pascal wiki, page "Arduino", as it stood on 2023-08-22 after a change by AllPascal, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history