Recent

Author Topic: How to disable the LineBuffer of LazSerial/Synapse  (Read 16936 times)

tetrastes

  • Hero Member
  • *****
  • Posts: 762
Re: How to disable the LineBuffer of LazSerial/Synapse
« Reply #30 on: March 04, 2022, 09:46:38 pm »
Code: Pascal  [Select][+][-]
  1. var
  2. s, t: AnsiString;   // to be precise
  3. begin
  4.    s := '';
  5.    repeat
  6.        t := serSensor.RecvPacket(100);   // Choose appropriate timeout
  7.        s := s + t;
  8.    until t = '';
  9. end;

I tried this but this kills the serial connection immediately.  serSensor.LastError becomes 9997.
What does it mean specifically? For me this works. I suppose that you have set somewhere
Code: Pascal  [Select][+][-]
  1. serSensor.RaiseExcept := True;
It will raise exception for Error 9997, but does not kill connection.

Quote
serSensor.LastError becomes 9997.
This is as should be. This error means 'Timeout during operation'.
 

Muso

  • Sr. Member
  • ****
  • Posts: 362
Re: How to disable the LineBuffer of LazSerial/Synapse
« Reply #31 on: March 04, 2022, 10:15:58 pm »
Many thanks for having a look.
For me when error 9997 occurs, serSerial becomes unavailable. I can then for example not close the connection. For example when i have error 9997 and do
Code: Pascal  [Select][+][-]
  1. serSensor.CloseSocket;
  2.     serSensor.free;
I get an error from Windows that the COM port is not accessible.

How do I have to handle error 9997 that I can then close the socket?

For now this is my solution:
Code: Pascal  [Select][+][-]
  1.  dataString:= '';
  2.  dataString:= serSensor.RecvPacket(100);
  3.  // convert string to a byte array
  4.  SetLength(tempArray{%H-}, Length(dataString));
  5.  Move(dataString[1], tempArray[0], Length(dataString));

This will now run over the weekend and then I know if this is stable for hours.

tetrastes

  • Hero Member
  • *****
  • Posts: 762
Re: How to disable the LineBuffer of LazSerial/Synapse
« Reply #32 on: March 04, 2022, 10:45:43 pm »
Too few info. You have not even answered about RaiseExcept.

tetrastes

  • Hero Member
  • *****
  • Posts: 762
Re: How to disable the LineBuffer of LazSerial/Synapse
« Reply #33 on: March 05, 2022, 05:33:59 am »
To get rid of error 9997 (and better):

Code: Pascal  [Select][+][-]
  1. var
  2. s: AnsiString;
  3.  
  4. begin
  5.    s := '';
  6.    while serSensor.CanRead(100) do
  7.        s := s + serSensor.RecvPacket(100);
  8. end;

But there is something wrong with your code, as timeout during operation is rather trivial situation.
« Last Edit: March 05, 2022, 06:32:58 am by tetrastes »

Muso

  • Sr. Member
  • ****
  • Posts: 362
Re: How to disable the LineBuffer of LazSerial/Synapse
« Reply #34 on: March 08, 2022, 02:49:33 pm »
This will now run over the weekend and then I know if this is stable for hours.

The correct code I run is this:
Code: Pascal  [Select][+][-]
  1.  dataString:= '';
  2.  dataString:= serSensor.RecvPacket(100);
  3.  
  4.  // in case the read failed or not 25 bytes received
  5.  if (serSensor.LastError <> 0) or (Length(dataString) < 25) then
  6.  begin
  7.    MainForm.ReadTimer.Enabled:= False;
  8.    if serSensor.LastError <> 0 then
  9.     MessageDlgPos(MainForm.ConnComPortSensM.Lines[0] + ' error on reading signal data: '
  10.      + serSensor.LastErrorDesc, mtError, [mbOK], 0, MousePointer.X, MousePointer.Y)
  11.    else
  12.     MessageDlgPos(
  13.      'Error: Could not read 25 bytes. Got only ' + IntToStr(Length(dataString)) + ' bytes.',
  14.      mtError, [mbOK], 0, MousePointer.X, MousePointer.Y);
  15.    HaveSerialSensor:= False;
  16.    exit;
  17.  end;
  18.  
  19.  // convert string to a byte array
  20.  SetLength(tempArray{%H-}, Length(dataString));
  21.  Move(dataString[1], tempArray[0], Length(dataString));

This run stable for more than 3 days now.

Muso

  • Sr. Member
  • ****
  • Posts: 362
Re: How to disable the LineBuffer of LazSerial/Synapse
« Reply #35 on: March 08, 2022, 02:55:06 pm »
To get rid of error 9997 (and better):
   while serSensor.CanRead(100) do

But the fact that I cannot do this was the cause of my troubles. CanRead often tells me there are no data despite there are. Meanwhile I found out that the USB plug soldered to the sensor is causing this. With a new batch of sensors, it happens up to 3 times per hour that the COM port say there is nothing to read but there is. With an older sensor batch this happens up to 10 times per hour.

Muso

  • Sr. Member
  • ****
  • Posts: 362
Re: How to disable the LineBuffer of LazSerial/Synapse
« Reply #36 on: March 08, 2022, 02:57:46 pm »
Too few info. You have not even answered about RaiseExcept.

Yes because I had to run the sensor over the weekend and could not code. Today I will try our proposal with RaiseExcept and report back hopefully tomorrow.

tetrastes

  • Hero Member
  • *****
  • Posts: 762
Re: How to disable the LineBuffer of LazSerial/Synapse
« Reply #37 on: March 08, 2022, 06:08:59 pm »
To get rid of error 9997 (and better):
   while serSensor.CanRead(100) do

But the fact that I cannot do this was the cause of my troubles. CanRead often tells me there are no data despite there are. Meanwhile I found out that the USB plug soldered to the sensor is causing this. With a new batch of sensors, it happens up to 3 times per hour that the COM port say there is nothing to read but there is. With an older sensor batch this happens up to 10 times per hour.

But I did not see in your code fragments that you used CanRead anywhere.

tetrastes

  • Hero Member
  • *****
  • Posts: 762
Re: How to disable the LineBuffer of LazSerial/Synapse
« Reply #38 on: March 08, 2022, 06:16:10 pm »
Too few info. You have not even answered about RaiseExcept.

Yes because I had to run the sensor over the weekend and could not code. Today I will try our proposal with RaiseExcept and report back hopefully tomorrow.

This is not proposal, this is question about whether you set RaiseExcept to True. I did not advice to do so. Sorry for my English.

Muso

  • Sr. Member
  • ****
  • Posts: 362
Re: How to disable the LineBuffer of LazSerial/Synapse
« Reply #39 on: March 08, 2022, 11:03:38 pm »
But I did not see in your code fragments that you used CanRead anywhere.

I debugged that the issue is that
Code: Pascal  [Select][+][-]
  1. serSensor.WaitingDataEx
and also
Code: Pascal  [Select][+][-]
  1. serSensor.WaitingData
tells me from time to time "0", but nevertheless has 25 bytes that I can read.

I doubt that serSensor.CanRead  behaves differently. Should it be and why/how?

 I don't trust these routines anymore. I logged one sensor for 4 days now, and it never lost a single byte telegram. So after 2.0 seconds I always got at least 25 bytes. However also with the new batch of sensor USB plugs, once or twice the hour serSensor.WaitingData tells me "0".

Muso

  • Sr. Member
  • ****
  • Posts: 362
Re: How to disable the LineBuffer of LazSerial/Synapse
« Reply #40 on: March 08, 2022, 11:05:34 pm »
This is not proposal, this is question about whether you set RaiseExcept to True.

No, I don't. However the issue remains that whenever I get error 9997, I cannot close the socket but get an access violation from Windows.
So a method to keep the serial connection alive also in case of a 9997 error is highly appreciated.

tetrastes

  • Hero Member
  • *****
  • Posts: 762
Re: How to disable the LineBuffer of LazSerial/Synapse
« Reply #41 on: March 09, 2022, 08:59:54 am »
But I did not see in your code fragments that you used CanRead anywhere.

I debugged that the issue is that
Code: Pascal  [Select][+][-]
  1. serSensor.WaitingDataEx
and also
Code: Pascal  [Select][+][-]
  1. serSensor.WaitingData
tells me from time to time "0", but nevertheless has 25 bytes that I can read.

I doubt that serSensor.CanRead  behaves differently. Should it be and why/how?

 I don't trust these routines anymore. I logged one sensor for 4 days now, and it never lost a single byte telegram. So after 2.0 seconds I always got at least 25 bytes. However also with the new batch of sensor USB plugs, once or twice the hour serSensor.WaitingData tells me "0".

Read this once more carefully:
RecvBuffer(buffer: pointer; length: integer) has nothing to do with the result of WaitingData, unless you put it in length parameter. It waits for length (in your case 25) bytes and returns after receiving them all or after some timeout, which may be even infinite. In Windows it calls WaitForSingleObject(FHandle, FDeadlockTimeout), and by default FDeadlockTimeout = 30000(ms).
 
WaitingData returns 0, but then you call RecvBuffer(@dataArray[0], 25), and it waits for all 25 bytes. It does not return immediately, if there are no bytes or less than 25 bytes at the moment of calling it.
« Last Edit: March 09, 2022, 09:03:45 am by tetrastes »

tetrastes

  • Hero Member
  • *****
  • Posts: 762
Re: How to disable the LineBuffer of LazSerial/Synapse
« Reply #42 on: March 09, 2022, 09:18:40 am »
This is not proposal, this is question about whether you set RaiseExcept to True.

No, I don't. However the issue remains that whenever I get error 9997, I cannot close the socket but get an access violation from Windows.
So a method to keep the serial connection alive also in case of a 9997 error is highly appreciated.

Using synaser for about 20 years, I never saw that error 9997 leads to this. There is something wrong in your code, or may be in drivers or hardware (???).
As I had written, timeout during operation is rather trivial situation.

avra

  • Hero Member
  • *****
  • Posts: 2586
    • Additional info
Re: How to disable the LineBuffer of LazSerial/Synapse
« Reply #43 on: March 09, 2022, 12:30:25 pm »
Using timer for synaser is so wrong and no wonder you have problems. You should use synaser in a separate communication thread and synchronize with main GUI thread.

Alternatively you could use some event based component for serial communication, but they mostly run in the GUI thread and with heavy communication your GUI will be frozen (not responding) for short periods of time while communicating. Not every use case can tolerate that. Application.ProcessMessages can help to some extent, but not that much.
« Last Edit: March 09, 2022, 12:34:04 pm by avra »
ct2laz - Conversion between Lazarus and CodeTyphon
bithelpers - Bit manipulation for standard types
pasettimino - Siemens S7 PLC lib

Muso

  • Sr. Member
  • ****
  • Posts: 362
Re: How to disable the LineBuffer of LazSerial/Synapse
« Reply #44 on: March 09, 2022, 04:32:11 pm »
Read this once more carefully:
RecvBuffer(buffer: pointer; length: integer) has nothing to do with the result of WaitingData, ...

I understood this. however, I used WaitingData to check if i can read something and this way also if the serial connection is still alive.
My question was now that when I use CanRead if i must fear that also CanRead sometimes tell me that I cannot while in fact I can. I fear this and want to avoid another hour-long debug session to maybe realize that this is the case.

Concerning the error 9997 issue, I think this is a hardware thing. When I got this error I can also not access the COM port using the Arduino serial monitor, even when only try to read data. I also used the Arduino IDE's serial monitor and when I send with this e.g. every second a read command the COM connection got lost and then there is no other way than to replug the USB cable.
And it is sometimes even more strange: despite nobody is at the desk and I can be sure that nothing is moving at the setup, suddenly the serial connection times out and Windows re-initiates the connection but using a doubled registry entry. For example the COM port was "COM29", then there are in the Windows registry two "COM29" entries. The funny thing is that sometimes it doesn't matter what of the two ports one accesses (I rely here always on the Arduino Serial monitor), sometimes it does and sometimes both are inaccessible. There are cases in which even replugging the USB cable does not clean the registry entries. I thought it is dependent on the particular Laptop, bit meanwhile I tested even using an old 32bit Win 7, desktop PCs, brand new laptops, in total 7 different PCs and  the situation is the same. And not only the USB plug soldered to the sensor has an influence, also the used USB hub.
Since January I am fighting this issue. It seems serial connections via USB are not very robust.  :'(

 

TinyPortal © 2005-2018