Recent

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

Muso

  • Sr. Member
  • ****
  • Posts: 362
How to disable the LineBuffer of LazSerial/Synapse
« on: February 21, 2022, 05:24:22 pm »
I have a strange issue with serial connections I only partly understand and for which I now only found a hack:

- I have a serial device that sends me every 1.7 seconds 25 bytes. depending on the device, this time can also be 2.2 seconds.
- therefore I run a timer fixed to 3.0 seconds to be safe and do this:

Code: Pascal  [Select][+][-]
  1. procedure TMainForm.ReadTimerTimerFinished(Sender: TObject);
  2. type
  3.      TDataArray = array[0..24] of byte;
  4. var
  5.  k: integer;
  6.  dataArray : TDataArray;
  7.  
  8. begin
  9.   k:= 0;
  10.   dataArray:= default(TDataArray); // clear array
  11.   k:= serSensor.RecvBufferEx(@dataArray[0], 25, 100);
  12. end;
  13.  

(Then I of course check if I got 25 bytes and the I check the received date, etc.)

The problem is that after some time I don't get the most recent data from the device but from some minutes before. I found out that Synapse/LazSerial use a internal buffer called LineBuffer. And looking into this, it indeed stored there any date that came once from the device.

To fix my problem, I only need a way to disable the LineBuffer but I cannot find how this is done. Can anybody help me?

For now I use this hack:

Code: Pascal  [Select][+][-]
  1. procedure TMainForm.ReadTimerTimerFinished(Sender: TObject);
  2. type
  3.      TDataArray = array[0..24] of byte;
  4. var
  5.  k: integer;
  6.  dataArray, wasteArray : TDataArray;
  7.  
  8. begin
  9.   k:= 0;
  10.   dataArray:= default(TDataArray); // clear array
  11.   k:= serSensor.RecvBufferEx(@dataArray[0], 25, 100);
  12.   // Fixme: LineBuffer should not be used at all
  13.   // empty internal LineBuffer of serSensor
  14.   while serSensor.WaitingDataEx > 24 do
  15.    serSensor.RecvBufferEx(@wasteArray[0], 25, 100);
  16. end;
  17.  

mig-31

  • Sr. Member
  • ****
  • Posts: 307
Re: How to disable the LineBuffer of LazSerial/Synapse
« Reply #1 on: February 21, 2022, 06:01:34 pm »
Hi,

It is not hack. This is the correct way of 25 bytes reading: check if there are 25 bytes in the buffer than read it.    ;)
Lazarus 4.0 - OpenSuse Leap 15.4, Mageia 8, CentOS 7

Muso

  • Sr. Member
  • ****
  • Posts: 362
Re: How to disable the LineBuffer of LazSerial/Synapse
« Reply #2 on: February 21, 2022, 06:14:59 pm »
Hi,

It is not hack. This is the correct way of 25 bytes reading: check if there are 25 bytes in the buffer than read it.    ;)

Then you misunderstoofd the problem:
- at time 0.0 I wait until there are 25 bytes to read
- when there are 25 bytes I read them, then I wait 3.0 seconds
- then I check if there are 25 bytes available and read them

But since a fast device delivers every 1.7 seconds 25 bytes, the LineBuffer hast after 17 seconds 250 bytes and I read only  125 of them. So bit by bit I am drifting off the actual measurement bytes of my device.

What I need is this:
- at time 0.0 I wait until there are 25 bytes to read
- when there are 25 bytes I read them, then I wait 3.0 seconds
- then I check if there are 25 NEW bytes available from the device

The bytes I read are measurement values and I need the most recent bytes.
So maybe when i cannot turn off the LineBuffer, I can at least read the last 25 bytes of the LineBuffer?

dseligo

  • Hero Member
  • *****
  • Posts: 1683
Re: How to disable the LineBuffer of LazSerial/Synapse
« Reply #3 on: February 22, 2022, 12:44:56 am »
Don't wait 3 seconds.

Check every 0.5 second if you got more than 24 bytes in buffer. Read buffer as long as you have more than 24 bytes.

Muso

  • Sr. Member
  • ****
  • Posts: 362
Re: How to disable the LineBuffer of LazSerial/Synapse
« Reply #4 on: February 22, 2022, 01:55:05 pm »
Don't wait 3 seconds.

Check every 0.5 second if you got more than 24 bytes in buffer. Read buffer as long as you have more than 24 bytes.

This was my first attempt. But the user must be able to set the readout time. There are cases where only every hour there should be readout the measurement bytes.

Therefore the best would be to disable the LineBuffer but I don't know how.

tetrastes

  • Hero Member
  • *****
  • Posts: 762
Re: How to disable the LineBuffer of LazSerial/Synapse
« Reply #5 on: February 22, 2022, 02:18:46 pm »
Set MaxLineLength to 25? No, it will not help.
« Last Edit: February 22, 2022, 02:47:06 pm by tetrastes »

Jurassic Pork

  • Hero Member
  • *****
  • Posts: 1290
Re: How to disable the LineBuffer of LazSerial/Synapse
« Reply #6 on: February 22, 2022, 02:49:09 pm »
hello,
with Tlazserial you don"t need a timer to read data. When something is received on the serial line a serial data event is triggered.
For your case, you have only to wait 25 bytes before to do something.
Example :
Code: Pascal  [Select][+][-]
  1. procedure TFMain.SerialRxData(Sender: TObject);
  2. var Str,HexaS : string;
  3.     I: integer;
  4. begin
  5.   if Serial.Synser.WaitingDataEx < 25 then exit;
  6.   Str :=  Serial.ReadData;
  7.   for I := 1 to Length(Str) do
  8.        begin
  9.            HexaS := HexaS + InttoHex(Ord(Str[I]),2)+ ' ';
  10.        end;
  11.   Memo.Lines.BeginUpdate;
  12.   Memo.Lines.Add(HexaS);
  13.   Memo.Lines.EndUpdate;
  14.   Memo.SelStart := Length(Memo.Lines.Text)-1;
  15.   Memo.SelLength:=0;
  16. end;            
  17.  

and the  data serial simulator :
Code: Pascal  [Select][+][-]
  1. procedure TFMain.Timer1Timer(Sender: TObject);
  2. type
  3.      TDataArray = array[0..24] of byte;
  4. var
  5.   Str: String;
  6.   I: Integer;
  7.   dataArray: TDataArray;
  8. begin
  9.   For i := 0 to 24  do
  10.      begin
  11.        dataArray[i] := Random(255);
  12.      end;
  13.   Serial.WriteBuffer(dataArray ,25);
  14. end;          
  15.  
if you have  special start and stop bytes in your frames it is more safe to be synchronized with them.

Friendly, J.P
 
« Last Edit: February 22, 2022, 04:09:34 pm by Jurassic Pork »
Jurassic computer : Sinclair ZX81 - Zilog Z80A à 3,25 MHz - RAM 1 Ko - ROM 8 Ko

mig-31

  • Sr. Member
  • ****
  • Posts: 307
Re: How to disable the LineBuffer of LazSerial/Synapse
« Reply #7 on: February 22, 2022, 03:01:57 pm »
Don't wait 3 seconds.

Check every 0.5 second if you got more than 24 bytes in buffer. Read buffer as long as you have more than 24 bytes.

This was my first attempt. But the user must be able to set the readout time. There are cases where only every hour there should be readout the measurement bytes.

Therefore the best would be to disable the LineBuffer but I don't know how.

In this case:
1) clear the buffer,
2) wait for 25 bytes,
3) read it.
Lazarus 4.0 - OpenSuse Leap 15.4, Mageia 8, CentOS 7

tetrastes

  • Hero Member
  • *****
  • Posts: 762
Re: How to disable the LineBuffer of LazSerial/Synapse
« Reply #8 on: February 22, 2022, 06:01:03 pm »
I would do so:
- check for new data at port faster than 1.7 s
- rewrite some buffer with every new 25 bytes
- when user requests data, check port if there is any new data (I prefer CanRead). If there is, then read from port, else give him data from your buffer.

And I would place communications in separate thread.

Muso

  • Sr. Member
  • ****
  • Posts: 362
Re: How to disable the LineBuffer of LazSerial/Synapse
« Reply #9 on: February 22, 2022, 07:40:39 pm »
with Tlazserial you don"t need a timer to read data. When something is received on the serial line a serial data event is triggered.
For your case, you have only to wait 25 bytes before to do something.

This is how I do it now, but it feels like a hack. I mean I empty now all the time the LineBuffer whenever I got 25 bytes, only when the time is to actually take the measurement bytes, I store them.
Therefore I workaround not to have a LineBuffer and I thought there is a way to simply disable this buffer. Then I could just ready out the newest 25 bytes directly from the device whenever I like.
« Last Edit: February 22, 2022, 08:51:28 pm by Muso »

tetrastes

  • Hero Member
  • *****
  • Posts: 762
Re: How to disable the LineBuffer of LazSerial/Synapse
« Reply #10 on: February 22, 2022, 08:50:19 pm »
with Tlazserial you don"t need a timer to read data. When something is received on the serial line a serial data event is triggered.
For your case, you have only to wait 25 bytes before to do something.

This is how I do it now, but it feels like a hack. I mean I empty now all the time the LineBuffer whenever i got 2 bytes, only when the time is to actually take the measurement bytes, I store them.
Therefore I workaround not to have a LineBuffer and I thought there is a way to simply disable this buffer. Then I could just ready out the newest 25 bytes directly from the device whenever I like.
How you will do that? You think, port knows which bytes are the newest? LineBuffer is only a space for reading data from port. If you do that once a hour, you will have to read 3600/1.7*25 = 52 941 bytes (or the amount of bytes of internal port buffer, whatever is smaller) from port.
But you can follow mig-31 answer if you not simply clear the buffer, but use Purge to discard buffers of a communication resource every time you want to read from port, and then wait for new 25 bytes.
« Last Edit: February 22, 2022, 09:04:21 pm by tetrastes »

Muso

  • Sr. Member
  • ****
  • Posts: 362
Re: How to disable the LineBuffer of LazSerial/Synapse
« Reply #11 on: February 22, 2022, 08:56:59 pm »
How you will do that? You think, port knows which bytes are the newest? LineBuffer is only a space for reading data from port. If you do that once a hour, you will have to read 3600/1.7*25 = 52 941 bytes (or the amount of bytes of internal port buffer, whatever is smaller) from port.

That's why I wrote, I need either no buffer at all, just read out the latest values from the device. For example this way:
- ask the device if it has bytes to send. If so, I know it has 25 bytes because it has no internal buffer larger than the 25 bytes. So when the next measurement is performed 1.7 seconds later, it overwrites the 25 byte buffer by the new values. So all I need is to read them out when I want. No buffering necessary at all.

The LineBuffer only makes problems, since it is not endless in size. I see that it sizes changes quite randomly in the range not larger than 8000 bytes.
« Last Edit: February 22, 2022, 08:58:39 pm by Muso »

tetrastes

  • Hero Member
  • *****
  • Posts: 762
Re: How to disable the LineBuffer of LazSerial/Synapse
« Reply #12 on: February 22, 2022, 09:20:22 pm »
Don't confuse LineBuffer, and internal input buffer of your port, and the buffer of your device. Your device has 25 bytes buffer, but the port through it communicates (USB virtual COM port, I suppose?) has larger one. And I think LineBuffer does not make problems, because there is no problem for modern OS to allocate enough memory for reading from any port's buffer. Use Purge to discard all unneeded data from port's buffer, as I wrote.
But I still think that my first advice is better, as you need not think if internal buffer overflows and what happenes if it does.
« Last Edit: February 22, 2022, 09:31:11 pm by tetrastes »

Muso

  • Sr. Member
  • ****
  • Posts: 362
Re: How to disable the LineBuffer of LazSerial/Synapse
« Reply #13 on: February 22, 2022, 11:34:30 pm »
Don't confuse LineBuffer, and internal input buffer of your port, and the buffer of your device.

Thanks. maybe this is my mistake.

But I still think that my first advice is better, as you need not think if internal buffer overflows and what happenes if it does.

What do you refer to? - you stroke-through your first post.

tetrastes

  • Hero Member
  • *****
  • Posts: 762
Re: How to disable the LineBuffer of LazSerial/Synapse
« Reply #14 on: February 22, 2022, 11:40:11 pm »
Sorry, not first but second:
I would do so:
- check for new data at port faster than 1.7 s
- rewrite some buffer with every new 25 bytes
- when user requests data, check port if there is any new data (I prefer CanRead). If there is, then read from port, else give him data from your buffer.

And I would place communications in separate thread.
« Last Edit: February 22, 2022, 11:42:53 pm by tetrastes »

 

TinyPortal © 2005-2018