Sign in Join
Wiki copytemporary

Serial unit: what changed

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

Title: Serial unit

OldNewLine
1+Unit **Serial** in FPC supports work with serial port. It provides many Ser* functions.
2+
3+## Example of usage
4+
5+Note that this uses Windows-style device names, unix systems (Linux, SunOS etc.) have their own conventions.
6+
7+``` pascal
8+{
9+ Usage:
10+ TestSerialPortCom
11+ Uses default port COM1.
12+ TestSerialPortCom 8 'Hello'
13+ Uses COM8 and outputs 'Hello' before waiting for an answer.
14+
15+ The program will open a serial port and output 'Hello', after that the code will wait until
16+ a CR (#13) is received, or a key is pressed.
17+}
18+program TestSerialPortCom;
19+uses
20+ serial, crt;
21+
22+var
23+ serialhandle : LongInt;
24+ ComPortName : String;
25+ s,tmpstr,txt : String;
26+ ComIn : String;
27+ ComPortNr : Integer;
28+ writecount : Integer;
29+ status : LongInt;
30+ Flags : TSerialFlags; { set of (RtsCtsFlowControl); }
31+ ErrorCode : Integer;
32+
33+begin
34+ ComPortNr:= 1;
35+ tmpstr:= '';
36+ txt:= '';
37+
38+ writeln('Parameters: ', ParamCount);
39+ if (ParamCount>0) then
40+ begin
41+ tmpstr:= ParamStr(1);
42+ val(tmpstr, ComPortNr, ErrorCode);
43+
44+ if (ParamCount>1) then
45+ txt:= ParamStr(2);
46+ end;
47+
48+ str(ComPortNr, tmpstr);
49+
50+ ComPortName:= 'COM'+tmpstr+':';
51+ writeln('Using: '+ComPortname);
52+
53+ serialhandle := SerOpen(ComPortName);
54+ Flags:= []; // none
55+ SerSetParams(serialhandle, 9600, 8, NoneParity, 1, Flags);
56+
57+ s:= txt; // use the input text
58+ writeln('Output: '+s);
59+ s:= s+#13+#10; // CR + LF
60+ writecount:= length(s);
61+
62+ status:= SerWrite(serialhandle, s[1], writecount);
63+
64+ // for debugging only
65+ writeln('Status: ', status, ', WriteCount: ', writecount);
66+
67+ if status > 0 then
68+ begin
69+ writeln('Waiting for answer');
70+ s:= '';
71+ ComIn:= '';
72+ while (Length(ComIn)<10) and (status>=0) and not KeyPressed do
73+ begin
74+ status:= SerRead(serialhandle, s[1], 10);
75+ if (s[1]=#13) then
76+ status:= -1; // CR => end serial read
77+
78+ if (status>0) then
79+ begin
80+ ComIn:= ComIn+s[1];
81+ writeln('Status: ', status, ', Len: ', length(ComIn), ', ASCII: ', ord(s[1]), ', Input: ', ComIn);
82+ end;
83+ end;
84+ end
85+ else
86+ writeln('Error: unable to send');
87+
88+ SerSync(serialhandle); // flush out any remaining before closure
89+
90+ SerFlushOutput(serialhandle); // discard any remaining output
91+
92+ SerClose(serialhandle);
93+end.
94+```
95+
96+## Timeout values
97+
98+Q: I'm trying to figure out when the timeout timer in SerRead/SerReadTimeout starts.
99+
100+A (by FPC developer Christo Crause): FPC uses the OS provided functionality to interact with the serial port. On Windows the timeout seems to start when the read request is made - \[<https://learn.microsoft.com/en-us/previous-versions/ff547486(v=vs.85>) Link\]. On POSIX (at least Linux) it depends on the specific set of flags specified , scroll down to the discussion on canonical/noncanonical mode for the details - [Link](https://linux.die.net/man/3/termios).
101+
102+A bit more information after peeking into the source code: on Win32 the timeout information can be read or set using Get/SetCommTimeouts. The [COMMTIMEOUTS structure](https://learn.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-commtimeouts) contains a read interval timeout and total timeouts for read & write operations. SerReadTimeout sets the ReadTotalTimeoutConstant value, so basically the total timeout duration.
103+
104+On Linux SerReadTimeout uses a fpSelect on the handle with the specified timeout, so in principle it is the same behaviour as on Windows, i.e. a total timeout.
105+
106+While both OSs provide some functionality to specify inter character timeouts, FPC does not directly expose this functionality in the Serial unit.
107+
108+Note from last maintainer: SerReadTimeout() explicitly says "<https://github.com/MarkMLl/serialcomms>" i.e. the intention is that timing starts when the function is called. Different lineages of unix handle fpSelect() differently, while not tested it's reasonable to assume that the Mac's OS-X behaves like SunOS/Solaris. See <https://github.com/MarkMLl/serialcomms> for examples, comments on known issues etc.
109+
110+---
111+*From the Free Pascal wiki, page "Serial unit", as it stood on 2023-04-25 after a change by MarkMLl, 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