Lazarus

Programming => General => Topic started by: Lauriet on May 22, 2025, 04:23:55 am

Title: Serial port
Post by: Lauriet on May 22, 2025, 04:23:55 am
Everything is a file.......right ?

I want to use the serial port to simply write and read strings thru it.

Can I just:


assign(f, 'ttyxxx');
rewrite(f);
write(f, 'whatever');


Of course I would have to of setup the baudrate etc.

Title: Re: Serial port
Post by: MarkMLl on May 22, 2025, 09:15:22 am
No, you can't. WriteLn() etc. take a parameter of type text, not of type file.

You can do it with a lot of futzing around by messing with the low-level implementation of the buffers etc. as shown in the telnet server project in my Git repo, but (a) that's at the whim of the developers who might decide to break it and (b) it is likely to depend on the OS (and you've not told us what you're using).

MarkMLl
Title: Re: Serial port
Post by: Lauriet on May 22, 2025, 09:56:24 am
Well, what if:

var
  f : text;

assign(f, '/dev/ttyUsb');  { for a usb to serial adaptor}
rewrite(f);
write(f, 'some stuff');

But doesn't /dev/ttyUsb exist as a file ???



Title: Re: Serial port
Post by: CM630 on May 22, 2025, 12:26:53 pm
I use https://github.com/JurassicPork/TLazSerial . I found no wiki for it, but it has some examples.
Title: Re: Serial port
Post by: Nimbus on May 22, 2025, 12:33:52 pm
Or use synapse
https://wiki.freepascal.org/Hardware_Access#Synaser
Title: Re: Serial port
Post by: Lauriet on May 23, 2025, 03:11:55 am
Hmmmmmm  :-\

Maybe I need to google unix/linux sites cause I seem to remember in the dark past being able to use the port as a file. The other options will be OK........but, you know, enquiring minds must have answer.


Here is what "deep thought" says:
In Linux, serial ports are treated as special files within the /dev directory. This allows you to interact with them using standard file I/O operations and utilities, making it easy to read, write, and redirect data to and from serial devices.
Title: Re: Serial port
Post by: cdbc on May 23, 2025, 08:19:40 am
Hi
Hmmm, if I were you, I would have a 'LookSee' at @MarkMLl's github thingy and see how he does it...  ;D
Regards Benny
Title: Re: Serial port
Post by: paule32 on May 23, 2025, 08:34:26 am
it give the libusb library.
Title: Re: Serial port
Post by: MarkMLl on May 23, 2025, 09:02:07 am
Hi
Hmmm, if I were you, I would have a 'LookSee' at @MarkMLl's github thingy and see how he does it...  ;D
Regards Benny

Basically, I'm pretty sure that people have looked at direct file access to (typically) /dev/ttyUSBn (on unix, YMMV) in the past and found it wanting. It might be worth trying again though, but there's lots of things like getting the control lines set that you have to use ioctl() for.

The serial.pp unit which is a standard part of the RTL is OK for Windows and Linux, although I've not done any maintentance on it recently. It's tested on SunOS/Solaris but not with anything else in the BSD family of OSes, i.e. including Macs. There's also another support file in one of my Github repos that does things like checking how much data is available: the comments go into some detail about a nasty kernel-level problem that affects Linux.

The telnet stuff includes setup of the low-level buffers that support WriteLn() etc. That probably isn't necessary /if/ going directly to the named port works... basically, I do a lot of instrumentation access and normally serial.pp plus possibly Str() etc. is entirely adequate.

MarkMLl
Title: Re: Serial port
Post by: ccrause on May 23, 2025, 01:35:10 pm
Basically, I'm pretty sure that people have looked at direct file access to (typically) /dev/ttyUSBn (on unix, YMMV) in the past and found it wanting. It might be worth trying again though, but there's lots of things like getting the control lines set that you have to use ioctl() for.

As said above, you can.  Below an example using virtual serial ports complements of socat (tested on Linux only):
Code: Bash  [Select][+][-]
  1. socat -d -d pty,rawer,echo=0 pty,rawer,echo=0
  2. 2025/05/23 12:38:35 socat[307365] N PTY is /dev/pts/11
  3. 2025/05/23 12:38:35 socat[307365] N PTY is /dev/pts/12
  4. 2025/05/23 12:38:35 socat[307365] N starting data transfer loop with FDs [5,5] and [7,7]

Use one endpoint as file in Pascal:
Code: Pascal  [Select][+][-]
  1. program Project1;
  2.  
  3. var
  4.   f: text;
  5.  
  6. begin
  7.   Assign(f, '/dev/pts/12');
  8.   rewrite(f);
  9.   write(f, 'Text from FPC');
  10.   CloseFile(f);
  11. end.

Open the other end point in a terminal like app, in this case minicom:
Code: Bash  [Select][+][-]
  1. Welcome to minicom 2.8
  2.  
  3. OPTIONS: I18n
  4. Port /dev/pts/11, 12:42:24
  5.  
  6. Press CTRL-A Z for help on special keys
  7.  
  8. Text from FPC

So it "works" (reading data quickly becomes challenging), but as MarkMLl said, you don't have access to settings such as baud rate, parity, stop bits, blocking / non blocking transmission etc.  There is a good reason for having several serial port libraries and components - quite a bit more than just file I/O is typically needed to interface with a serial port.
Title: Re: Serial port
Post by: Lauriet on May 24, 2025, 06:44:02 am
Socat looks interesting:

would I have to set baudrates and stuff beforehand ???
Title: Re: Serial port
Post by: Lauriet on May 24, 2025, 06:46:34 am
I've tried serial.pp but the SerOpen('/dev/ttyACM0') returns with -1.......so i guess it wasn't opened.

Did i give it the right param ???
Title: Re: Serial port
Post by: af0815 on May 24, 2025, 08:17:07 am
-1 can be returned if the device is used by another process or not correct freed from an older process. And only one process can work with this device and you must have the rights to use the device. By default a normal user have no rights for the devices.
Title: Re: Serial port
Post by: ccrause on May 24, 2025, 08:35:21 am
Socat looks interesting:

It is useful to perform testing without hardware. Since socat is software emulation it cannot as AFAIK emulate baud rate mismatches.

Quote

would I have to set baudrates and stuff beforehand ???
If you are referring to assigning a serial port as a file, then yes the baud rate etc should be configured separately from Pascal's file handling.
Title: Re: Serial port
Post by: ccrause on May 24, 2025, 08:41:47 am
-1 can be returned if the device is used by another process or not correct freed from an older process. And only one process can work with this device and you must have the rights to use the device. By default a normal user have no rights for the devices.
+1

Check permissions of /dev/ttyUSB0, does it include your username or a group which you belong to?
Title: Re: Serial port
Post by: Jurassic Pork on May 24, 2025, 08:54:17 am
Hello,
To access serial ports on Linux without needing root permissions, you can add your user to the dialout group. This group grants access to serial devices like /dev/ttyUSB0 and /dev/ttyS0
Friendly, J.P
Title: Re: Serial port
Post by: MarkMLl on May 24, 2025, 09:21:57 am
-1 can be returned if the device is used by another process or not correct freed from an older process. And only one process can work with this device and you must have the rights to use the device. By default a normal user have no rights for the devices.

The unix default is that serial devices can be shared, that's something I'd possibly change if I did any more work on serial.pp.

First, check that the device exists and the name is correct: don't just thrash around using /dev/ttyUSB, /dev/ttyACM0 etc. at random.

Second, it is conventionally owned by the dialout group. Make sure the normal user is a member of this, logout and log back in to have the new rights.

MarkMLl
Title: Re: Serial port
Post by: Lauriet on May 25, 2025, 03:44:12 am
From what i can make out socrat is a virtual serial port.....when i write to it nothing comes out of the real port.


I would like to use Serial.pp:

I am connecting an arduino uno board via the usb port.
It is showing up in /dev as 'ttyACM0'
I am a user of dialout group.
I have set permissions of ttyACM0 to include me:

the code is:

Code: Pascal  [Select][+][-]
  1. var
  2. SerFileHandle : LongInt;
  3.  
  4. begin
  5.   SerFileHandle := SerOpen('/dev/ttyACM0');
  6.   if SerFileHandle = -1 then
  7.     write('Error');
  8.   Flags := [];
  9.   SerSetParams(SerFileHandle, 9600, 8, noneparity, 1, Flags);
  10.  
  11. end.
  12.  

Still not opening the port ???????????????????????????

I've just read in serial.pp that seropen returnss 0 if not connected....so what does -1 indicate ???
Title: Re: Serial port
Post by: ccrause on May 25, 2025, 11:25:28 am
I've just read in serial.pp that seropen returnss 0 if not connected....so what does -1 indicate ???

SerOpen calls fpopen (https://www.freepascal.org/docs-html/rtl/baseunix/fpopen.html) which returns either a file descriptor or a negative value to indicate an error.  The man page for open(2) (https://www.man7.org/linux/man-pages/man2/open.2.html#RETURN_VALUE) basically agrees with this. Thus there is still an error with your code or setup.  Call fpgeterrno (https://www.freepascal.org/docs-html/rtl/baseunix/fpgeterrno.html) to read the underlying OS error code:
Code: Pascal  [Select][+][-]
  1. uses
  2.   BaseUnix;
  3.  
  4. var
  5.   SerFileHandle : LongInt;
  6.  
  7. begin
  8.   fpseterrno(0);  // optional, just to be paranoid
  9.   SerFileHandle := SerOpen('/dev/ttyACM0');
  10.   if SerFileHandle < 1 then
  11.   begin
  12.     write('Error: ', fpgeterrno);
  13.     Exit;
  14.   end;
  15.  
  16.   SerSetParams(SerFileHandle, 9600, 8, noneparity, 1, []);
  17.   // ...
  18.  end.

The description of the returned error number can be found by calling the errno command from a terminal:
Code: Bash  [Select][+][-]
  1. $ errno 42
  2. ENOMSG 42 No message of desired type
Title: Re: Serial port
Post by: Lauriet on May 25, 2025, 11:58:25 am
for some strange reason it is working now.
Don't know what i've done ???????????
Title: Re: Serial port
Post by: MarkMLl on May 26, 2025, 01:35:22 pm
for some strange reason it is working now.
Don't know what i've done ???????????

For completeness, note that some variants of Arduino (i.e. including clones, knockoffs and so on) appear as /dev/ttyACMn and others as /dev/ttyUSBn where n is a number.

If you have problems using serial.pp please could you continue here rather than staring a new thread, to make sure I see it.

MarkMLl
Title: Re: Serial port
Post by: Lauriet on May 27, 2025, 07:08:04 am
Yep, My arduino uno rev3 appears as ttyACM0

I'm not sure how it started working....I'm guessing it was somewhere with me adding me to "dialout" and/or setting the file permissions on /dev/ttyACM0 and/or rebooting for these to take affect.
Anywho, the next challenge is the get the arduino to output the right thing to program an at89s51 thru its ISP pins......Always problems to solve. ::)

Title: Re: Serial port
Post by: MarkMLl on May 27, 2025, 10:01:31 am
Yep, My arduino uno rev3 appears as ttyACM0

Watch out for things which are /nominally/ Unos but also appear on /dev/ttyUSB0. It all depends on whether whoever made it uses a second AVR chip to provide the TTY/serial -> USB interface, or a knockoff FTDI chip.

Quote
I'm not sure how it started working....I'm guessing it was somewhere with me adding me to "dialout" and/or setting the file permissions on /dev/ttyACM0 and/or rebooting for these to take affect.
Anywho, the next challenge is the get the arduino to output the right thing to program an at89s51 thru its ISP pins......Always problems to solve. ::)

I thought it indelicate to remind you that I'd specifically said you'd need to logout after adding yourself to the dialout group :-) You probably aren't able to make permissions/ownership of serial ports stick, since they're set from defaults when the device is plugged in (or a plugin is simulated when the computer boots)... there's a way round that described in the installation notes for things like Teensies.

I've not tried writing code to program an AVR chip, but at one point I was modifying the boot loader to work on a card I'd "upcycled" from a scrap washing machine and found it useful to write something to check what speed the target device was running at and what DTRt state reset it https://github.com/MarkMLl/ping-arduino-loader

There's a couple of demo programs at https://github.com/MarkMLl/serialcomms which might be useful, one of them simply echoes serial stuff and the other is a simple terminal emulator. However note that the second is somewhat topheavy on all the stuff needed to get a standard Linux console to work as expected (i.e. "raw" rather than "cooked").

Also the locateports.pas has SerOpenLocked() and SerAvailable(), the latter tries to accommodate various kernel quirks that I've learnt about the hard way. Apart from that, the serial.pp stuff has stood up fairly well.

MarkMLl
TinyPortal © 2005-2018