Recent

Author Topic: TLazSerial : serial port component for Lazarus (windows and linux).  (Read 407389 times)

dbannon

  • Hero Member
  • *****
  • Posts: 3687
    • tomboy-ng, a rewrite of the classic Tomboy
Re: TLazSerial : serial port component for Lazarus (windows and linux).
« Reply #510 on: December 15, 2025, 12:41:12 pm »
Hmm, thought I'd have a look. I have an old app using JP's very early version of this so downloaded the "version0.7".

But it fails to compile during package install, Linux. Cannot find NaturalSortCompare.

In SerialSelector we have -
Code: Pascal  [Select][+][-]
  1. {$IF FPC_FULLVERSION >= 30002}
  2. function NaturalSortCompare(List: TStringList; Index1, Index2: Integer): Integer;
  3. begin
  4.   Result := NaturalCompareText(List[Index1], List[Index2]);
  5. end;
  6. {$endif}


but up in the uses clause we have -
Code: Pascal  [Select][+][-]
  1. uses
  2. ....
  3.  {$ifNdef linux}, process, StrUtils{$endif};


If I put strutils back into uses, it all builds and installs nicely. And my very old app even works, remarkable given the development that has happened to LazSerial since 2021.

Davo
Lazarus 3, Linux (and reluctantly Win10/11, OSX Monterey)
My Project - https://github.com/tomboy-notes/tomboy-ng and my github - https://github.com/davidbannon

CM630

  • Hero Member
  • *****
  • Posts: 1626
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: TLazSerial : serial port component for Lazarus (windows and linux).
« Reply #511 on: December 15, 2025, 09:56:09 pm »
Hmm, thought I'd have a look. I have an old app using JP's very early version of this so downloaded the "version0.7".
...
But it fails to compile during package install, Linux. Cannot find NaturalSortCompare.
...
And my very old app even works, remarkable given the development that has happened to LazSerial since 2021.
...

I do not understand what have happened and what you have done.
I just installed from TLazSerial 2025.12.13.7z, it built and installed in Linux Mint Mate. Earlier today I have installed it in Windows 11.
The latest release of TLazSerial that I have found is from 3 years ago, not very new.
Also, I think that I have done almost no changes for Linux, since it worked fine... almost.
For some reason GetSerialPortNames for Unix removes the busy devices from the list, which does not seem okay to me - devices open by other apps are not displayed, but actually they are here.
I will try to make this filter switchable.


...
I see you silently changed your reply...  8)

StrictDelimiter = False by default, and I do not see that it is set to True in my example.
In your example StrictDelimiter = False as this is the default value. So your example works standalone, but when I tried to benefit from this trick it did not works in my code. So when I found the reason, I decided it to add this info, just in case someone else gets there.
« Last Edit: December 15, 2025, 10:02:11 pm by CM630 »
Лазар 4,4 32 bit (sometimes 64 bit); FPC3,2,2

dbannon

  • Hero Member
  • *****
  • Posts: 3687
    • tomboy-ng, a rewrite of the classic Tomboy
Re: TLazSerial : serial port component for Lazarus (windows and linux).
« Reply #512 on: December 16, 2025, 10:26:17 am »

I do not understand what have happened and what you have done.
I just installed from TLazSerial 2025.12.13.7z, it built and installed in Linux Mint Mate. Earlier today I have installed it in Windows 11.

SerialSelector is a new file, it does not appear in JP's repository.  So, have you added it ?

I downloaded your "7z ball"  and tried to install it in current Lazarus IDE. The compiler could not find NaturalCompareText() and that, obviously was because in SerialSelector.pas we have -

Code: Pascal  [Select][+][-]
  1. uses ...
  2. {$ifNdef linux}, process, StrUtils{$endif};

That means StrUtils is not used if Linux is defined. 

Now, is that because -
  • NaturalCompareText() should NOT be used under Linux ?, or
  • Linux gets its NaturalCompareText() from somewhere else ?, or 
  • SerialSelector should not be included in a Linux build ?, or
  • StrUtils should not be excluded from a Linux compile ?


Last one seems most likely but its your code !


I think its great you are improving LazSerial but I'm not so happy its stopped installing under Linux. I am sure you agree.

Davo
Lazarus 3, Linux (and reluctantly Win10/11, OSX Monterey)
My Project - https://github.com/tomboy-notes/tomboy-ng and my github - https://github.com/davidbannon

tetrastes

  • Hero Member
  • *****
  • Posts: 739
Re: TLazSerial : serial port component for Lazarus (windows and linux).
« Reply #513 on: December 16, 2025, 11:36:09 am »
In your example StrictDelimiter = False as this is the default value. So your example works standalone, but when I tried to benefit from this trick it did not works in my code. So when I found the reason, I decided it to add this info, just in case someone else gets there.

This is because GetSerialPortNames for unix uses spaces as delimiter, not commas. It is very easy to correct.

CM630

  • Hero Member
  • *****
  • Posts: 1626
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: TLazSerial : serial port component for Lazarus (windows and linux).
« Reply #514 on: December 16, 2025, 12:24:27 pm »
Code: [Select]
{$ifNdef linux}, process, StrUtils{$endif};...
Definitely, my code is wrong. I cannot understand how come that it compiled  :o
Maybe something cashed was not cleared?

...
I'm not so happy its stopped installing under Linux. I am sure you agree.
...
I am even unhappier than you ;), work is in progress, thanks for the feedback!



...
This is because GetSerialPortNames for unix uses spaces as delimiter, not commas. It is very easy to correct.
Yes, I was wondering how it could have been made this way, but .CommaText almost explains it.


EDIT: Added TLazSerial 2025.12.27.7z (implementation of WMI retrieving for Windows started, not yet complete).
« Last Edit: December 28, 2025, 12:19:19 am by CM630 »
Лазар 4,4 32 bit (sometimes 64 bit); FPC3,2,2

steve612

  • Newbie
  • Posts: 2
Re: TLazSerial : serial port component for Lazarus (windows and linux).
« Reply #515 on: January 04, 2026, 12:24:44 pm »
Hello, can you please share an example project with the new components for beginners? thank you in advance :)

CM630

  • Hero Member
  • *****
  • Posts: 1626
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: TLazSerial : serial port component for Lazarus (windows and linux).
« Reply #516 on: January 05, 2026, 03:09:32 pm »
Inside the .7z there are 2 samples- one in folder Test and another in folder Test1.
Test1 seems simpler to me. It does not work today, I will try to fix in a couple of days.
Maybe it will be useful if I add a simple snippet for Arduino to connect to the PC. What do you think?
« Last Edit: January 05, 2026, 04:35:14 pm by CM630 »
Лазар 4,4 32 bit (sometimes 64 bit); FPC3,2,2

steve612

  • Newbie
  • Posts: 2
Re: TLazSerial : serial port component for Lazarus (windows and linux).
« Reply #517 on: January 05, 2026, 06:28:54 pm »
Sure would be great regarding Arduino. I mainly interested for making project with an industrial device that sends data through rs232 and expects acknowledge signal, and also should be reliable for 24/7 operation.

CM630

  • Hero Member
  • *****
  • Posts: 1626
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: TLazSerial : serial port component for Lazarus (windows and linux).
« Reply #518 on: January 06, 2026, 10:37:35 am »
Reliability and USB do not go hand in hand, so if you use an inbuilt COM port for your task, maybe there will be no benefit from the updated TLazSerial, version 0.6. should be just fine.
Also still there is some issue that with 0.7 Lazarus dies sometimes without a sign when connecting/disconnecting COM ports, if I cannot fix it all the work will go into the drain.
0.7 (tries to) improve listing of the serial ports, adds an event for a disconnected /lost serial port while a connectiоn is runing.
And adds a more user-friendly selector for the serial ports. It seems like that none of these is needed for your task.

Anyway, if you intend to use USB serial device in Windows, I would recommend you not to use Prolifix devices.

The sample in Test1 works now.
I have attached a snippet for Arduino, s.o. have posted it in this forum, unfortunately it has no credits, maybe (s)he will see this post. The snippet is for controlling the inbuilt LED from the serial port.

Edit: Another but to fix: .Refresh causes ItemIndex := 0;.
Edit 2: Fixed.
« Last Edit: January 23, 2026, 04:28:47 pm by CM630 »
Лазар 4,4 32 bit (sometimes 64 bit); FPC3,2,2

CM630

  • Hero Member
  • *****
  • Posts: 1626
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: TLazSerial : serial port component for Lazarus (windows and linux).
« Reply #519 on: January 23, 2026, 04:27:04 pm »
There is an issue with GetSerialPortNames from LazSynaSer in  Linux.
The function that gets the list is below.
The problem is that if a serial port is open (by some other app), it is not listed. FD returns -1, etc.
       FD := fpopen(thedevice,O_RdWr or O_NonBlock or O_NoCtty);

On the other hand, the list of the serial ports can be retrieved with readlink -f /dev/serial/by-id/*.
Could there be a reason for not using the simple method, instead of the complex one, which is currently implemented?

Edit: It occurs that readlink -f /dev/serial/by-id/* does not show the embedded serial port (/dev/ttyS0).


Code: Pascal  [Select][+][-]
  1. {$IFNDEF MSWINDOWS}
  2. // Modif J.P   03/2013 - O1/2017 - 11/2022
  3. // Modif СМ630 2025
  4. //Gets the list of the serial devices in Unix. OnlyAccessible removes the unaccesible devices from the list, incl. those, which are already open.
  5. function GetSerialPortNames: string;
  6. var
  7.   Index: Integer;
  8.   Data: string;
  9.   TmpPorts: String;
  10.   flags : Longint;
  11.   sr : TSearchRec;
  12.   PortIndex : integer = 0;
  13.   debstr : string = '';
  14. // J.P  01/2017  new boolean parameter : special
  15.  
  16.   procedure ScanForPorts(const ThisRootStr : string; special :  boolean); // added by PDF
  17.   var theDevice : String;
  18.   var FD : Cint;
  19. {$IFnDEF DARWIN}        // RPH - Added 14May2016
  20.    var Ser : TSerialStruct;
  21. {$ENDIF}
  22.   begin
  23.     if FindFirst(ThisRootStr, flags, sr) = 0 then
  24.     begin  //A file is found
  25.       repeat
  26.         if (sr.Attr and flags) = Sr.Attr then
  27.         begin
  28.           data := sr.Name;
  29.           index := length(data);
  30.           theDevice := '/dev/' + data;
  31. // try to open the device
  32.        FD := fpopen(thedevice,O_RdWr or O_NonBlock or O_NoCtty);
  33.        if FD > 0 then
  34.           begin
  35. // try to get serial info from the device
  36.           {$IFDEF DARWIN}       // RPH - Added 14May2016 for OS-X
  37.            if fpioctl( FD,TIOCEXCL, nil) <> -1  then
  38.              begin
  39.               TmpPorts := TmpPorts + '  ' + theDevice;
  40.               fpclose(FD);
  41.              end;
  42.           {$ELSE}
  43.            if fpioctl( FD,TIOCGSERIAL, @Ser) <> -1 then
  44.              begin
  45. // device is serial if type is not unknown (if not special device)
  46.               // new parameter special
  47.               if ((Ser.typ <> 0) OR (special) ) then
  48.                TmpPorts := TmpPorts + '  ' + theDevice;
  49.               fpclose(FD);
  50.              end;
  51.           {$ENDIF}
  52.           end;
  53.         end;
  54.       until FindNext(sr) <> 0;
  55.     FindClose(sr);
  56.     end;
  57.   end;
  58.  
  59. begin
  60.   try
  61.     TmpPorts := '';
  62.     flags := faAnyFile AND (NOT faDirectory);
  63.     {$if defined (linux)}
  64.     //Cannot use a loop, some are True, others- false
  65.     ScanForPorts('/dev/rfcomm*',true);
  66.     ScanForPorts('/dev/ttyUSB*',true);
  67.     ScanForPorts('/dev/ttyS*',false);
  68.     ScanForPorts('/dev/ttyACM*',true);
  69.     {$elseif defined (DARWIN)}
  70.     for PortIndex :=0 to high(OSPrefixes) do
  71.     begin
  72.       ScanForPorts(OSPrefixes[PortIndex],false);
  73.     end;
  74.     {$ELSE} //Todo: This is executed in Linux, is there sth. wrong with the ELSE?
  75.      ScanForPorts('/dev/ttyAM*',false); // for ARM board
  76.    {$ENDIF}
  77.   finally
  78.     Result:=TmpPorts;
  79.   end;
  80. end;
  81. {$ENDIF}
« Last Edit: January 23, 2026, 08:20:06 pm by CM630 »
Лазар 4,4 32 bit (sometimes 64 bit); FPC3,2,2

ccrause

  • Hero Member
  • *****
  • Posts: 1093
Re: TLazSerial : serial port component for Lazarus (windows and linux).
« Reply #520 on: January 24, 2026, 07:25:31 am »
The problem is that if a serial port is open (by some other app), it is not listed. FD returns -1, etc.
       FD := fpopen(thedevice,O_RdWr or O_NonBlock or O_NoCtty);
What options do one have if a serial port exists but is not accessible?
  • List the port, but then an error will be generated when it is opened
  • Do not list the port since it cannot be opened

One could argue that a port may be opened for read only or write only exclusive access, so checking whether it is accessible for both may be overly restrictive.  Making the access check user specified (read or write or read + write) would complicate the code further (maybe not a lot, but still more complicated).

CM630

  • Hero Member
  • *****
  • Posts: 1626
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: TLazSerial : serial port component for Lazarus (windows and linux).
« Reply #521 on: January 26, 2026, 01:32:39 pm »
...
What options do one have if a serial port exists but is not accessible?
  • List the port, but then an error will be generated when it is opened
  • Do not list the port since it cannot be opened
...
Currently, it is the first option. I prefer the second one - if the user cannot open the port, then (s)he will know that it exists and that it shall be freed.

One could argue that a port may be opened for read only or write only exclusive access, so checking whether it is accessible for both may be overly restrictive.  Making the access check user specified (read or write or read + write) would complicate the code further (maybe not a lot, but still more complicated).
Even if TLazSerial behaves this way, the other serial apps might not. I will try some other things, as a last resort I will leave the non ttyUSB* ports listed the current way, and the ttyUSB* ones listed by readlink -f /dev/serial/by-id/*.
It occurs that there are PCIE to Serial adapters, I wonder what names will they be given by linux.

EDIT: As far as I understood and tried:
In every folder /sys/class/tty/ttyS*/ there is a file named type. If it contains a 4, then there is a serial port.
« Last Edit: January 27, 2026, 11:22:26 pm by CM630 »
Лазар 4,4 32 bit (sometimes 64 bit); FPC3,2,2

CM630

  • Hero Member
  • *****
  • Posts: 1626
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: TLazSerial : serial port component for Lazarus (windows and linux).
« Reply #522 on: February 06, 2026, 11:02:03 pm »
What has changed from ver. 06:

1. New control “TSerialSelector” - a combo box listing the serial ports.
2. New control “TSerialWatcher” - notifies when the presence of serial ports changes (plugged in/out, lost...)
3. New method (WMI) of listing the serial devices in Windows (the old one is also available). Is seems to return more reliable info for the devices.
4. New method of listing the serial devices in Linux (the old one is also available). Unlike the old one, it does not filter the busy devices.
5. Maybe it works better on Mac, no one seems to care.
6. TLazSerial: Custom baudrates are now available.
7. TLazSerial: Added event OnRemoved.
7. There is a new example in folder “Test1”.

Known issues:
1. “TSerialSelector” causes the Lazarus IDE to disappear sometimes when a serial device is plugged in/out. This behaviour was not observed in a standalone app. Something seems to go wrong when reading the windows registry... or I do not know, Lazarus likes to disappear quite often recently.
Possibly this is a Lazarus issue.
2. When Windows assigns the same COM number to more than one device, the friendly data is not retrieved properly. This should never happen, but Windows does it. Currently no intention to fix this issue.

Test scope:
1. Tested in Windows with all serial devices that I had around:
CH340G, PL2303 (Prolific), CP2102 (Silicon Labs), STM (Bluepill), FT232, GwInstek, Arduino Leonardo
2. Tested in Linux with CH340G and PL2303 (Prolific) on real HW and on more devices in a virtual machine.

Affected files from version 0.6:
1. lazsynaser.pas
2. lazserial.pas
3. The other changes are in newly added files.


Has anybody seen @Jurassic Pork recently?
« Last Edit: February 09, 2026, 09:23:16 am by CM630 »
Лазар 4,4 32 bit (sometimes 64 bit); FPC3,2,2

tetrastes

  • Hero Member
  • *****
  • Posts: 739
Re: TLazSerial : serial port component for Lazarus (windows and linux).
« Reply #523 on: February 10, 2026, 01:50:51 pm »
As you began to improve lazsynaser.pas...

There are 3 errors/typos in synaser.pas from the very beginning, and they were inherited in lazsynaser.pas. It seems that nobody notice them...

Code: Diff  [Select][+][-]
  1. --- lazsynaser.pas
  2. +++ lazsynaser-new.pas
  3. @@ -897,7 +897,7 @@
  4.    if pos('COM', uppercase(Value)) = 1 then
  5.      FComNr := StrToIntdef(copy(Value, 4, Length(Value) - 3), PortIsClosed + 1) - 1;
  6.    if pos('/DEV/TTYS', uppercase(Value)) = 1 then
  7. -    FComNr := StrToIntdef(copy(Value, 10, Length(Value) - 9), PortIsClosed - 1);
  8. +    FComNr := StrToIntdef(copy(Value, 10, Length(Value) - 9), PortIsClosed);
  9.  end;
  10.  
  11.  procedure TBlockSerial.SetBandwidth(Value: Integer);
  12. @@ -1032,7 +1032,7 @@
  13.      Exit;
  14.    SetCommMask(FHandle, 0);
  15.    SetupComm(Fhandle, FRecvBuffer, 0);
  16. -  CommTimeOuts.ReadIntervalTimeout := MAXWORD;
  17. +  CommTimeOuts.ReadIntervalTimeout := MAXDWORD;
  18.    CommTimeOuts.ReadTotalTimeoutMultiplier := 0;
  19.    CommTimeOuts.ReadTotalTimeoutConstant := 0;
  20.    CommTimeOuts.WriteTotalTimeoutMultiplier := 0;
  21. @@ -2320,13 +2320,16 @@
  22.    //FPC forgot to add getsid.. :-(
  23.    {$IFNDEF FPC}
  24.    if Libc.getsid(ReadLockfile) = -1 then
  25. +  {$ELSE}
  26. +  // FPC has fpgetsid for many years... ;-)
  27. +  if fpgetsid(ReadLockfile) = -1 then
  28. +  {$ENDIF}
  29.    begin //  Lockfile was left from former desaster
  30.      DeleteFile(Filename); // error recovery
  31.      CreateLockfile(MyPid);
  32.      result := true;
  33.      exit;
  34.    end;
  35. -  {$ENDIF}
  36.    result := false // Sorry, port is owned by living PID and locked
  37.  end;
  38.  

CM630

  • Hero Member
  • *****
  • Posts: 1626
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: TLazSerial : serial port component for Lazarus (windows and linux).
« Reply #524 on: February 10, 2026, 02:54:48 pm »
Do you want to apply the changes in the latest .7z and upload a new one?
Or I can do it, but the chance of making an error increases.

There are also some pull requests, I wonder if I shall apply them:
https://github.com/JurassicPork/TLazSerial/pulls

If I remeber (some of) these from lazsynaser.pas also have different names:

Code: Pascal  [Select][+][-]
  1.   dcb_Binary = $00000001;
  2.   dcb_ParityCheck = $00000002;
  3.   dcb_OutxCtsFlow = $00000004;
  4.   dcb_OutxDsrFlow = $00000008;
  5.   dcb_DtrControlMask = $00000030;
  6.   dcb_DtrControlDisable = $00000000;
  7.   dcb_DtrControlEnable = $00000010;
  8.   dcb_DtrControlHandshake = $00000020;
  9.   dcb_DsrSensivity = $00000040;
  10.   dcb_TXContinueOnXoff = $00000080;
  11.   dcb_OutX = $00000100;
  12.   dcb_InX = $00000200;
  13.   dcb_ErrorChar = $00000400;
  14.   dcb_NullStrip = $00000800;
  15.   dcb_RtsControlMask = $00003000;
  16.   dcb_RtsControlDisable = $00000000;
  17.   dcb_RtsControlEnable = $00001000;
  18.   dcb_RtsControlHandshake = $00002000;
  19.   dcb_RtsControlToggle = $00003000;
  20.   dcb_AbortOnError = $00004000;
  21.   dcb_Reserveds = $FFFF8000;    

Maybe some of these:
https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntddser/ns-ntddser-_serial_handflow

It would be better if these constants were named both ways.
 
« Last Edit: February 10, 2026, 03:03:29 pm by CM630 »
Лазар 4,4 32 bit (sometimes 64 bit); FPC3,2,2

 

TinyPortal © 2005-2018