Recent

Author Topic: [Solved]LazSerial and Synaser, serial port already in use  (Read 10434 times)

Arctic_Eddie

  • Jr. Member
  • **
  • Posts: 93
[Solved]LazSerial and Synaser, serial port already in use
« on: January 24, 2016, 09:53:43 pm »
 O:-)I'm trying to collect data from an Arduino Mega2560 via an FTDI rs232/usb adapter on Serial1. I'm using Synaser to get the connect serial ports list and LazSerial for setting/reading the handshake lines. I can find mine by toggling RTS/CTS and reading DTR/DSR with jumpers on the FTDI. The problem is that when I try to open a port on the available list that's already in use, I get an exception error. Is there a way of testing an existing port to see if it's already in use? The one that usually causes the problem is the Arduino serial monitor that I need for testing.
« Last Edit: January 27, 2016, 01:47:36 pm by Arctic_Eddie »

Jurassic Pork

  • Hero Member
  • *****
  • Posts: 1290
Re: LazSerial and Synaser, serial port already in use
« Reply #1 on: January 25, 2016, 03:11:09 am »
hello,
you can manage exception when you try to open your serial port like this (Serial is a TLazserial component) :
Code: Pascal  [Select][+][-]
  1. try
  2.   Serial.Open;
  3. except
  4.    On E :Exception do begin
  5.      ShowMessage(  E.Message);
  6.    end;
  7. end;  

You can't open a serial device when :
1 - Already in use
2 - Doesn't exist
3 - Hardware Malfunction
4 - Bad parameters
5 - Other possibilities ?

Friendly, J.P
« Last Edit: January 25, 2016, 03:27:49 am by Jurassic Pork »
Jurassic computer : Sinclair ZX81 - Zilog Z80A à 3,25 MHz - RAM 1 Ko - ROM 8 Ko

mig-31

  • Sr. Member
  • ****
  • Posts: 308
Re: LazSerial and Synaser, serial port already in use
« Reply #2 on: January 25, 2016, 10:24:20 am »
Hi,

I think you do not close serial port after using a Synaser to get port list and try to open it again with Lazserial.
Lazarus 4.0 - OpenSuse Leap 15.4, Mageia 8, CentOS 7

Arctic_Eddie

  • Jr. Member
  • **
  • Posts: 93
Re: LazSerial and Synaser, serial port already in use
« Reply #3 on: January 25, 2016, 01:44:58 pm »
JP
I tried that before but the exception window comes up before my part runs so it did not help. I'll try it again using your example for the Serial.open part only. Maybe I did not have it coded correctly.

M31
The ports were not open after Synaser got the port list. It gives the same list as another routine I used which queries the registry for connected ports. It's just a CSV list and does no queries.

The problem is that if the Arduino programming port is connected, I see it as existing but not connected. When the serial monitor is open and I try to test it then I get the exception. What I would really like to see in LazSerial is another function that just tells you if a port is open to another application, such as.

Code: Pascal  [Select][+][-]
  1. LazSerial.device := Comx;   // The port to be tested
  2. busy := LazSerial.isBusy;   // True if port Comx already in use
  3. //or
  4. busy := LazSerial.isBusy( Comx );  // True if port Comx already in use, preferred function
  5.  

I don't like modifying libraries as I might mess it up, and, it becomes unique to my computer. I would rather see the author make the changes so we can all use it.

Arctic_Eddie

  • Jr. Member
  • **
  • Posts: 93
Re: LazSerial and Synaser, serial port already in use
« Reply #4 on: January 25, 2016, 05:56:50 pm »
The try/exception scheme works and doesn't work. Here is my code.

Code: Pascal  [Select][+][-]
  1. function TForm1.ComportIsBusy( comport :String ): boolean;
  2. begin
  3.      Result := false;
  4.      try
  5.         LazSerialPort.Device := comport;
  6.         LazSerialPort.Open; // This triggers the exception ***************
  7.      except
  8.            On E :EInOutError do begin
  9.               Result := true;
  10.            end;
  11.      end;
  12.      LazSerialPort.Close;
  13. end;
  14.  

The exception triggers in the debugger with the first popup. If I click 'Continue' then I get the LazSerial second window. Clicking 'OK' goes to my code where it works as I want. If I could make the two popups not appear or automatically click the two buttons then it would work nicely. The final program version won't have the debugger embedded but the LazSerial exception will still be there.

I'm now looking at the LazSerial code to see if I can duplicate part of it to detect the busy condition.

Code: Pascal  [Select][+][-]
  1.  
  2. procedure TLazSerial.DeviceOpen;
  3. begin
  4.   FSynSer.Connect(FDevice);
  5.   if FSynSer.Handle=INVALID_HANDLE_VALUE then // This line is the test I need **************************
  6.     raise Exception.Create('Could not open device '+ FSynSer.Device);
  7.   ----
  8. end;
  9.  
  10.  

You can see the line I need. If the author puts this line in a separate function and return true or false then the problem would be solved.

Arctic_Eddie

  • Jr. Member
  • **
  • Posts: 93
Re: LazSerial and Synaser, serial port already in use
« Reply #5 on: January 25, 2016, 06:16:51 pm »
JP
I see you're the author of LazSerial. Can you suggest an addition to the library that would add a function such as below?

Code: Pascal  [Select][+][-]
  1. function LazSerial.isBusy( Comx :String ): boolean;
  2.   // True if port Comx already in use, false if not busy or not exist
  3.  


Jurassic Pork

  • Hero Member
  • *****
  • Posts: 1290
Re: LazSerial and Synaser, serial port already in use
« Reply #6 on: January 26, 2016, 04:30:29 am »
hello,
i will not add your ComportisBusy in LazSerial Component because when you can't access to a serial device, you can have other reasons :
1 - Already in use
2 - Doesn't exist
3 - Hardware Malfunction
4 - Bad parameters
Then you must manage exception on serial device access.

if i write this in my sertest example  for the code of the open button :
Code: Pascal  [Select][+][-]
  1. procedure TFMain.BOpenClick(Sender: TObject);
  2. begin
  3.   Serial.Device := EditDevice.Text;
  4. try
  5.   Serial.Open;
  6. except
  7.    On E :Exception do begin
  8.     Memo.Lines.Add(E.ClassName + ' : ' +  E.Message);
  9.    end;
  10. end;
  11. end;

when exception comes , i have no exception window (see Attachment). To avoid exception window while you are debugging , add the exception in

Tools/Options/Debugger/Language Exceptions and check the exception (ignore these exceptions) See Attachment.

If you don't want to manage exception , you can do this :
Code: Pascal  [Select][+][-]
  1.   Serial.Synser.Connect(Serial.Device);
  2.   If Serial.SynSer.Handle = THandle(-1) then
  3.   begin
  4.   Memo.Lines.Add(Serial.Device  + ' is busy');
  5.   exit;
  6.   end
  7.   else Serial.Close;    
  8.  

Friendly, J.P
 


« Last Edit: January 26, 2016, 04:38:36 am by Jurassic Pork »
Jurassic computer : Sinclair ZX81 - Zilog Z80A à 3,25 MHz - RAM 1 Ko - ROM 8 Ko

Arctic_Eddie

  • Jr. Member
  • **
  • Posts: 93
Re: LazSerial and Synaser, serial port already in use
« Reply #7 on: January 26, 2016, 01:40:54 pm »
Thank you both, I'll test the solutions today.

The exception I know I'll see is the case where the Arduino IDE is connected to the serial monitor and the FTDI is connected to Serial1 and my incoming data port. At run time, I don't know which ports they're on. I just want to know if a port is already busy so I can skip it in my search for the FTDI and it's RTS/CTS and DTR/DSR jumpers.

mig-31

  • Sr. Member
  • ****
  • Posts: 308
Re: LazSerial and Synaser, serial port already in use
« Reply #8 on: January 26, 2016, 03:19:27 pm »
Hi you can get it by using TBlockSerial from Synaser instend of LazSerialPort (LazPortSerial use Synaser library):

property LastError;

function GetErrorDesc;

or implement it to LazSerialPort. It is easy.

« Last Edit: January 26, 2016, 03:21:26 pm by mig-31 »
Lazarus 4.0 - OpenSuse Leap 15.4, Mageia 8, CentOS 7

Arctic_Eddie

  • Jr. Member
  • **
  • Posts: 93
Re: LazSerial and Synaser, serial port already in use
« Reply #9 on: January 26, 2016, 04:42:01 pm »
This function now works. My purpose is to test existing ports to see if one is already connected to something. I only want to interrogate an existing/not connected port to see if it's the FTDI connected to my Arduino. After finding the jumpers, I can test it further, if needed. The laptop and the Arduino are not necessarily powered up at the same time so the jumper idea works fine as the FTDI is powered by the laptop and not the Arduino.

Here's the modified code that works. It tests an existing comport and returns true if busy or false if available.

Code: Pascal  [Select][+][-]
  1. function TForm1.ComportIsItBusy( comport :String ): boolean;
  2. begin
  3.      // Try opening an existing port, true if busy, false if available
  4.      LazSerialPort.SynSer.Connect( comport );  // Try opening this port
  5.      if( LazSerialPort.SynSer.Handle = THandle(-1) ) then
  6.      begin
  7.           Result := true;    // Port cannot be opened
  8.           exit;              // No need to contine
  9.      end
  10.      else                    // It can be opened
  11.      begin
  12.           LazSerialPort.SynSer.CloseSocket;  // No need to stay open, close it
  13.           Result := false;                   // Caller needs to know
  14.      end
  15. end;
  16.  

 

TinyPortal © 2005-2018