Recent

Author Topic: Error on using hardware Raspberry Pi Inno-Maker RS485&CAN Module with TLAZserial  (Read 7664 times)

MarkMLl

  • Hero Member
  • *****
  • Posts: 6676
using serial.pp opens and closes both devices (/dev/ttySC0 & /dev/ttySC1) and returns a handle.

Right, so that narrows it down quite a lot.

I use serial.pp exclusively, but I'm not necessarily suggesting that you do since it's really intended for lower-level use: it doesn't return neat component-style events and so on and you'd probably need to get to grips with threads for anything non-trivial.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

sstvmaster

  • Sr. Member
  • ****
  • Posts: 299
Can this help?
Code: Pascal  [Select][+][-]
  1.   if pos('/DEV/TTYSC', uppercase(Value)) = 1 then
  2.     FComNr := StrToIntdef(copy(Value, 11, Length(Value) - 9), PortIsClosed - 1);
  3.  

Add this after line 866 of lazsynaser.pas
greetings Maik

Windows 10,
- Lazarus 2.2.6 (stable) + fpc 3.2.2 (stable)
- Lazarus 2.2.7 (fixes) + fpc 3.3.1 (main/trunk)

MarkMLl

  • Hero Member
  • *****
  • Posts: 6676
This doesn't directly help OP's problem, but TBH I think that any attempt to have a "whitelist" of known names is hazardous. My own code uses a regex like   r.Expression := '(tty\D+)\d+'; to find out what major devices are represented (plus /dev/rfcomm* as a special case), sorts by major device number, then for each of those gets the minor devices... the result of that is that the display order is comparatively sane with ttyS0 preceding ttyAMA0 (RPi console) and so on.

MarkMLl

« Last Edit: March 16, 2021, 08:34:41 am by MarkMLl »
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

sstvmaster

  • Sr. Member
  • ****
  • Posts: 299
@MarkMLl, Thank you.

Quote
So wie ich es verstanden habe sind die Seriellen Ports vorhanden, nur kann LazSerial nicht damit umgehen.
Mit der serial.pp und "/dev/ttySC*" funktioniert es ja.

Vielleicht kann Jurassic Pork LazSerial dahin gehend erweitern. Eventuell kann er auch deinen Regex nutzen.
greetings Maik

Windows 10,
- Lazarus 2.2.6 (stable) + fpc 3.2.2 (stable)
- Lazarus 2.2.7 (fixes) + fpc 3.3.1 (main/trunk)

Jurassic Pork

  • Hero Member
  • *****
  • Posts: 1228
hello,
When I use the Demo GPS Simulator application, I can select both /dev/ttySC0 & /dev/ttySC1 devices.
But when I try to open the port, I get the following error message:
"Could not open device /dev/ttyS-2"
i have found where there is a problem to use a port like /dev/ttySC0
it is in the procedure  connect of the TBlockSerial class in lazsynaser.pas here  (lines 15,26):
Code: Pascal  [Select][+][-]
  1. procedure TBlockSerial.Connect(comport: string);
  2. {$IFDEF MSWINDOWS}
  3. var
  4.   CommTimeouts: TCommTimeouts;
  5. {$ENDIF}
  6. begin
  7.   // Is this TBlockSerial Instance already busy?
  8.   if InstanceActive then           {HGJ}
  9.   begin                            {HGJ}
  10.     RaiseSynaError(ErrAlreadyInUse);
  11.     Exit;                          {HGJ}
  12.   end;                             {HGJ}
  13.   FBuffer := '';
  14.   FDevice := comport;
  15.   GetComNr(comport);
  16. {$IFDEF MSWINDOWS}
  17.   SetLastError (sOK);
  18. {$ELSE}
  19.   {$IFNDEF FPC}
  20.   SetLastError (sOK);
  21.   {$ELSE}
  22.   fpSetErrno(sOK);
  23.   {$ENDIF}
  24. {$ENDIF}
  25. {$IFNDEF MSWINDOWS}
  26.   if FComNr  <> PortIsClosed then
  27.     FDevice := '/dev/ttyS' + IntToStr(FComNr);
  28.   // Comport already owned by another process?          {HGJ}
  29.   if FLinuxLock then

With the procedure GetComNr :
Code: Pascal  [Select][+][-]
  1. [procedure TBlockSerial.GetComNr(Value: string);
  2. begin
  3.   FComNr := PortIsClosed;
  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. end;

when the device is /dev/ttySC0 or /dev/ttySC1 or /dev/ttySD0  for example  we have -2 in the FComNr variable, it is why you have :
Quote
"Could not open device /dev/ttyS-2"

what you can try, it is to replace this line in lazsynaser.pas :
Code: Pascal  [Select][+][-]
  1.  if FComNr  <> PortIsClosed then
  2.  
with this one :
Code: Pascal  [Select][+][-]
  1.  if FComNr  > PortIsClosed then
  2.  
Not sure that it is the better solution but for /dev/ttySCx  it doen't change the name of the device.
recompile the package Lazserial after the change.
Don't forget that lazsynaser.pas come from synaser.pas then there is the same problem in synaser.
Friendly, J.P
« Last Edit: March 16, 2021, 02:21:20 am by Jurassic Pork »
Jurassic computer : Sinclair ZX81 - Zilog Z80A à 3,25 MHz - RAM 1 Ko - ROM 8 Ko

ThomasK

  • New Member
  • *
  • Posts: 48
@Jurassic Pork

Code: Pascal  [Select][+][-]
  1. procedure TBlockSerial.GetComNr(Value: string);
  2. begin
  3.   FComNr := PortIsClosed;
  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. end;
  9.  
I wonder if the FComNr is correctly extracted the length of /DEV/TTYSC0 is 11, and 2 chars will be copied. (11-9).
Anyway the device never can be found because:
Code: Pascal  [Select][+][-]
  1. $IFNDEF MSWINDOWS}
  2.   if FComNr  <> PortIsClosed then
  3.     FDevice := '/dev/ttyS' + IntToStr(FComNr);
  4.  
will always produce a FDEVICE string like 'dev/ttys' + number' but not a  'dev/ttysc' + number

I try to modify both procedures to differentiate between different length of device basic names:
I found quite a large variety in the mentioned device list:


/dev/ttySnnn   UART serial port device

/dev/ttySAn      Strong ARM builtin serial port
/dev/ttySCn      SC26xx serial port
/dev/ttySCn      SCI serial port
/dev/ttySGn      SGI Altix console port
/dev/ttySIn      SmartIO Port
/dev/ttySRnnn   RIO port

/dev/ttySMXn   Motorola i.MX - port

/dev/ttySIOCnn   Altix ioC3 serial card
« Last Edit: March 16, 2021, 11:14:58 am by ThomasK »
Started Pascal on a Siemens 4004/151 in 1977. TurboPascal 1.0 in 1984 on PC-Dos.

Jurassic Pork

  • Hero Member
  • *****
  • Posts: 1228
hello,
I try to modify both procedures to differentiate between different length of device basic names:
I found quite a large variety in the mentioned device list:

/dev/ttySnnn   UART serial port device

/dev/ttySAn      Strong ARM builtin serial port
/dev/ttySCn      SC26xx serial port
/dev/ttySCn      SCI serial port
/dev/ttySGn      SGI Altix console port
/dev/ttySIn      SmartIO Port
/dev/ttySRnnn   RIO port

/dev/ttySMXn   Motorola i.MX - port

/dev/ttySIOCnn   Altix ioC3 serial card

have you try only  my change :
Code: Pascal  [Select][+][-]
  1. if FComNr  > PortIsClosed then
with devices like :
Quote
/dev/ttySAn      Strong ARM builtin serial port
/dev/ttySCn      SC26xx serial port
/dev/ttySCn      SCI serial port
/dev/ttySGn      SGI Altix console port
/dev/ttySIn      SmartIO Port
/dev/ttySRnnn   RIO port

/dev/ttySMXn   Motorola i.MX - port

/dev/ttySIOCnn   Altix ioC3 serial card
FcomNr value is -2 and you doesn't alter the device name

FComNr seems to be used only to have the port number for  legacy serial ports  (COM on windows /dev/ttySxx on linux) .
For example when i use the USB serial ports /dev/ttyUSB00 and /dev/ttyUSB01 , i have no problem using TLazserial component while the FComNr value is -1.

Friendly, J.P
« Last Edit: March 16, 2021, 01:04:48 pm by Jurassic Pork »
Jurassic computer : Sinclair ZX81 - Zilog Z80A à 3,25 MHz - RAM 1 Ko - ROM 8 Ko

MarkMLl

  • Hero Member
  • *****
  • Posts: 6676
I try to modify both procedures to differentiate between different length of device basic names:
I found quite a large variety in the mentioned device list:

/dev/ttySnnn   UART serial port device

/dev/ttySAn      Strong ARM builtin serial port
/dev/ttySCn      SC26xx serial port
/dev/ttySCn      SCI serial port
/dev/ttySGn      SGI Altix console port
/dev/ttySIn      SmartIO Port
/dev/ttySRnnn   RIO port

/dev/ttySMXn   Motorola i.MX - port

/dev/ttySIOCnn   Altix ioC3 serial card

Plus /dev/rfcomm*, plus /dev/AMA0 for an RPi. See message #17, the only reliable way of doing this is to match /dev/tty, then process the letters and digits that follow separately.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

ThomasK

  • New Member
  • *
  • Posts: 48
Hello,


have you try only  my change :
Code: Pascal  [Select][+][-]
  1. if FComNr  > PortIsClosed then

Friendly, J.P

I have only a device which shows up as

/dev/ttySC0 and /dev/ttySC1      

which can be succesfully opened with the mod.
Since I can't test the other devices I would only adapt for these.

and as I already wrote an USB device, which already is working.

Kind Regards,

ThomasK
Started Pascal on a Siemens 4004/151 in 1977. TurboPascal 1.0 in 1984 on PC-Dos.

ThomasK

  • New Member
  • *
  • Posts: 48

Plus /dev/rfcomm*, plus /dev/AMA0 for an RPi. See message #17, the only reliable way of doing this is to match /dev/tty, then process the letters and digits that follow separately.

MarkMLl

I showed only the devices with varieties of /dev/ttyS, because they cause trouble with the TLazserial which tries to retrieve the numbering of the ttyS devices.

The proposed mod works.

But there are still problems with the hardware: When the device is not opened, it blocks the traffic on the RS485 Bus, I can receive data but not send. For me it seems, that there are some details in handling of RTS CTS which are not documented very well.
I am in contact with the supplier. Hopefully the CAN part of the board works better.

Rgds,

ThomasK
Started Pascal on a Siemens 4004/151 in 1977. TurboPascal 1.0 in 1984 on PC-Dos.

tetrastes

  • Sr. Member
  • ****
  • Posts: 473

With the procedure GetComNr :
Code: Pascal  [Select][+][-]
  1. procedure TBlockSerial.GetComNr(Value: string);
  2. begin
  3.   FComNr := PortIsClosed;
  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. end;


when the device is /dev/ttySC0 or /dev/ttySC1 or /dev/ttySD0  for example  we have -2 in the FComNr variable, it is why you have :
Quote
"Could not open device /dev/ttyS-2"

what you can try, it is to replace this line in lazsynaser.pas :
Code: Pascal  [Select][+][-]
  1.  if FComNr  <> PortIsClosed then
  2.  
with this one :
Code: Pascal  [Select][+][-]
  1.  if FComNr  > PortIsClosed then
  2.  
Not sure that it is the better solution but for /dev/ttySCx  it doen't change the name of the device.
recompile the package Lazserial after the change.
Don't forget that lazsynaser.pas come from synaser.pas then there is the same problem in synaser.
Friendly, J.P

Yes, this problem was always presented in synaser. You must change in GetComNr
Code: Pascal  [Select][+][-]
  1.   if pos('/DEV/TTYS', uppercase(Value)) = 1 then
  2.     FComNr := StrToIntdef(copy(Value, 10, Length(Value) - 9), PortIsClosed);
  3.  

so it will return the expected value in considered case (i.e. PortIsClosed, not PortIsClosed - 1).

ThomasK

  • New Member
  • *
  • Posts: 48
In the meantime I checked the Python samples and found that they are using:

Code: Pascal  [Select][+][-]
  1. TIOCGRS485 = 0x542E
  2. TIOCSRS485 = 0x542F
  3. SER_RS485_ENABLED         = 0b00000001
  4. SER_RS485_RTS_ON_SEND     = 0b00000010
  5. SER_RS485_RTS_AFTER_SEND  = 0b00000100
  6. SER_RS485_RX_DURING_TX    = 0b00010000
  7.  
Unfortunately TIOCGRS485 = 0x542E ff. definitions are not included in the termios.inc in the section ARM CPU. So I will continue Jugend forscht.
Started Pascal on a Siemens 4004/151 in 1977. TurboPascal 1.0 in 1984 on PC-Dos.

MarkMLl

  • Hero Member
  • *****
  • Posts: 6676
In the meantime I checked the Python samples and found that they are using:

Code: Pascal  [Select][+][-]
  1. TIOCGRS485 = 0x542E
  2. TIOCSRS485 = 0x542F
  3. SER_RS485_ENABLED         = 0b00000001
  4. SER_RS485_RTS_ON_SEND     = 0b00000010
  5. SER_RS485_RTS_AFTER_SEND  = 0b00000100
  6. SER_RS485_RX_DURING_TX    = 0b00010000
  7.  
Unfortunately TIOCGRS485 = 0x542E ff. definitions are not included in the termios.inc in the section ARM CPU. So I will continue Jugend forscht.

Presumably you're running the standard 32-bit OS (whatever they call it these days). If those actually work on that platform I suggest raising it as a bug via Mantis; they're probably omitted since nobody has had a report of that hardware combination.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

alpine

  • Hero Member
  • *****
  • Posts: 1038
I've not read this thread entirely, but seeng:
Code: Pascal  [Select][+][-]
  1. procedure TBlockSerial.GetComNr(Value: string);
  2. begin
  3.   FComNr := PortIsClosed;
  4.   if pos('COM', uppercase(Value)) = 1 then
  5. ...
  6.  

Just wanted to note that on Windows, the general form is '\\.\COMxx' and the above code will have troubles with that.

Regards,
"I'm sorry Dave, I'm afraid I can't do that."
—HAL 9000

sstvmaster

  • Sr. Member
  • ****
  • Posts: 299
...
the general form is '\\.\COMxx' and the above code will have troubles with that.
...

Not quite, in lazsynaser.pas (from LazSerial package) on line 982 there is the following:
Code: Pascal  [Select][+][-]
  1. FDevice := '\\.\COM' + IntToStr(FComNr + 1);
so it is correct in the end.
greetings Maik

Windows 10,
- Lazarus 2.2.6 (stable) + fpc 3.2.2 (stable)
- Lazarus 2.2.7 (fixes) + fpc 3.3.1 (main/trunk)

 

TinyPortal © 2005-2018