Recent

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

Muso

  • Sr. Member
  • ****
  • Posts: 362
Re: How to disable the LineBuffer of LazSerial/Synapse
« Reply #45 on: March 09, 2022, 04:39:03 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.

OK. how exactly does this work?
What I currently do is this:
- I run a timer, when it finished, I read all data the serial connection delivers.
- I checked the received data, if their checksum is incorrect, I don't use the data
- directly after the timer finished, I run Application.ProcessMessages;

How does this introduce issues?

tetrastes

  • Hero Member
  • *****
  • Posts: 762
Re: How to disable the LineBuffer of LazSerial/Synapse
« Reply #46 on: March 09, 2022, 08:52:49 pm »
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.

I think that CanRead is more reliable, as it has timeout. As for "in fact I can", consider this: your data arrive with period 1.7 s, and you use timer with 2 s period to receive data and clear port's buffer; suppose at the first moment they are synchronized; after 34 s timer can trigger a few ms earlier than new data arrives, so and if there was no previous data due to some reason (e.g. sensor was off), then WaitingData returns 0, but some milliseconds later it will return 25 bytes. So you have to use check with appropriate timeout to avoid such case.
But if your problem is hardware, my experience tells that it's impossible to solve hardware/firmware problems reliably with software. It will be one or another kind of crutch.

Quote
It seems serial connections via USB are not very robust.
It depends on devices and drivers (and USB cables  ;)). It seems that you are unlucky.
« Last Edit: March 09, 2022, 09:47:57 pm by tetrastes »

dseligo

  • Hero Member
  • *****
  • Posts: 1683
Re: How to disable the LineBuffer of LazSerial/Synapse
« Reply #47 on: March 10, 2022, 01:28:26 am »
If you are not sure if hardware or software cause you problems, and if you are struggling with this for so long, I would suggest that you find a computer with two real serial ports and write 'sender' program that imitates your sensor. Connect serial ports together (GND-GND, Rx-Tx, Tx-Rx).

Then you can test various cases and rule out software issues.
« Last Edit: March 10, 2022, 01:37:08 am by dseligo »

af0815

  • Hero Member
  • *****
  • Posts: 1409
Re: How to disable the LineBuffer of LazSerial/Synapse
« Reply #48 on: March 10, 2022, 06:33:54 am »
If i read the thread, it looks you have to seperate reading from device (com) and reading your data. You can use a TQuece or a other FIFO or round about buffer.
So you can use the events from synapse if data arrive. This data have to be stored in the FIFO (first in, first out). In your timer you can check if the fifo is filled in the meantime. If the fifo is more than the nedded bytes, you can read this chunk of data you need. Meaningless if the fifo is filled in the meantime or not.

This FIFO breaks the trouble of the time issue. Sometime you will have no chunk in FIFO, normal you have one chunk of data and maybe sometimes you have two chunks inside. But if it is decoupled (com to timer) you can handle this inside timer. If you want to avoid more than one chunk, than you must shorten your timer. SO you can have only one or no chunk of your data.
regards
Andreas

avra

  • Hero Member
  • *****
  • Posts: 2586
    • Additional info
Re: How to disable the LineBuffer of LazSerial/Synapse
« Reply #49 on: March 10, 2022, 09:02:04 am »
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.

OK. how exactly does this work?
What I currently do is this:
- I run a timer, when it finished, I read all data the serial connection delivers.
- I checked the received data, if their checksum is incorrect, I don't use the data
- directly after the timer finished, I run Application.ProcessMessages;

How does this introduce issues?

One of the examples could be that when your app starts reading serial data, device has already sent few bytes, so your first received byte is not first in the message. Since you wait for fixed 25 bytes, you will get big part of one message and small part of another. If you don't know how to make it all thread based and you need to deal with it the way you do, then you should parse receiving data and recognize start of the message and then read 25 following bytes from that start. As already said, synaser is great and rock solid, but not ideal for the way you use it. It would be much better if you use some async event based serial lib or component.

And if you think that there is just a small chance that your app starts reading in the middle of the message, then think about pc UART and device UART clock synchronization which is very rarely perfect, so after a while mentioned problem will show up since desynchronized UART clock error accumulates over time. Timer firing interval error is also several magnitudes higher then that, so you get the picture...
ct2laz - Conversion between Lazarus and CodeTyphon
bithelpers - Bit manipulation for standard types
pasettimino - Siemens S7 PLC lib

mig-31

  • Sr. Member
  • ****
  • Posts: 307
Re: How to disable the LineBuffer of LazSerial/Synapse
« Reply #50 on: March 10, 2022, 11:01:25 am »
I also recommend your to use a separate communication thread to talk with sensor. In case of using timer for that, you go into troubles. I have several applications in production with serial communication(RS232/422/485) using Synaser in separate communication thread for different propose: control the equipment, log data temperature, pressure ... from equipment etc. All work prefectly.
 
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 #51 on: March 11, 2022, 02:51:31 pm »
Concerning the error 9997 issue, I think this is a hardware thing.
This is damn true and sad because this cost me so many hours. With the new UART to USB plug that are nowadays soldered to the sensor, I don't have these problems. I removed now all error 9997 handling from my code and forced the timeout exception and this works now as it should.

Muso

  • Sr. Member
  • ****
  • Posts: 362
Re: How to disable the LineBuffer of LazSerial/Synapse
« Reply #52 on: March 11, 2022, 03:17:15 pm »
consider this: your data arrive with period 1.7 s, and you use timer with 2 s period to receive data and clear port's buffer; suppose at the first moment they are synchronized; after 34 s timer can trigger a few ms earlier than new data arrives, so and if there was no previous data due to some reason (e.g. sensor was off), then WaitingData returns 0, but some milliseconds later it will return 25
This is clear to me. The situation is also more complex since according to the datasheet I should get sensor data ever 1.7 s, but I measured out that most sensors have a cycle between 1.8 to 2.0 s, one even 2.2s.
Therefore I checked if WaitingData returned 0 three times in a row. With the old UART to USB plug this happened once about every 5 minute, with the new plug about every 20 minutes.
Therefore I am happy with my method to just everything available ad then check if I got really 25 byte and if their checksum are OK. If not, I wait another cycle. Up to know - after almost 7 days continuous measuring, I can say it works as it should.

Jurassic Pork

  • Hero Member
  • *****
  • Posts: 1290
Re: How to disable the LineBuffer of LazSerial/Synapse
« Reply #53 on: March 11, 2022, 03:24:33 pm »
hello,
What is your sensor (brand/reference) ?
Friendly, J.P
Jurassic computer : Sinclair ZX81 - Zilog Z80A à 3,25 MHz - RAM 1 Ko - ROM 8 Ko

Muso

  • Sr. Member
  • ****
  • Posts: 362
Re: How to disable the LineBuffer of LazSerial/Synapse
« Reply #54 on: March 11, 2022, 03:59:30 pm »
So you can use the events from synapse if data arrive. This data have to be stored in the FIFO (first in, first out).
But this was the issue -  relied on synapse's WaitingData.
I have to measure the vital values of cell cultures and a measurement failure can kill the culture. So it is crucial to get sensor data for weeks.
At first I relied on WaitingData or WaitingDataEx but then got approximately after 2 hours the case that WaitingData reported for minutes there were no data. I must in this case issue an error that a persons goes to the lab to look what is going on.

Then I changed it so that when I got 3 cycles in a row the info that there were no data, I read out nevertheless. This worked since I always got valid data and also WaitingData gave me for the next 5 - 20 minutes the correct result.
Now I read every cycle all data I can get. For example when I get 32 bytes, I evaluate the last 25 bytes. If their checksum is incorrect, I evaluate bytes 7 to 32 and so on.
« Last Edit: March 11, 2022, 10:35:23 pm by Muso »

Muso

  • Sr. Member
  • ****
  • Posts: 362
Re: How to disable the LineBuffer of LazSerial/Synapse
« Reply #55 on: March 11, 2022, 04:14:01 pm »
What is your sensor (brand/reference) ?
The sensors are different, depending on the application. But they are all read via this device: https://www.jobst-technologies.com/products/instrumentation/
I don't know what the buggy UART to USB plug was, the new one that does not die on a serial timeout error (error 9997) is this one:
https://www.adafruit.com/product/954 (soldered by us).
However also with this I got on my test laptop about 2 to 3 times an hour three cycles in a row from synapse's WaitingData the info that there were no data.
Since I could in this case anyways always readout data, I performed a test over 4 days, and reading out every 2.2 s, there was not a single time where there were actually no data available when I read them. So the sensor readout device works and delivers data, but the UART to USB is apparently to blame.
If someone knows another UART to USB plug, please tell me and I will try it out.
« Last Edit: March 11, 2022, 04:31:56 pm by Muso »

Jurassic Pork

  • Hero Member
  • *****
  • Posts: 1290
Re: How to disable the LineBuffer of LazSerial/Synapse
« Reply #56 on: March 11, 2022, 05:58:02 pm »
it seems that your sensors use a communication protocole (see six Data communication manual) with start and stop bytes. You can synchronyze your receiving program with that.
« Last Edit: March 11, 2022, 06:02:11 pm by Jurassic Pork »
Jurassic computer : Sinclair ZX81 - Zilog Z80A à 3,25 MHz - RAM 1 Ko - ROM 8 Ko

tetrastes

  • Hero Member
  • *****
  • Posts: 762
Re: How to disable the LineBuffer of LazSerial/Synapse
« Reply #57 on: March 11, 2022, 10:19:00 pm »
At first I relied on WaitingData or WaitingDataEx but then got approximately after 2 hours the case that WaitingData reported for minutes there were no data.
I have understood your problem at last. Did you check LastError/LastErrorDesc after WaitingData in this case?

Also at Windows WaitingData simply calls ClearCommError(FHandle, err, @stat), but err is not checked. It would be useful to do this.

tetrastes

  • Hero Member
  • *****
  • Posts: 762
Re: How to disable the LineBuffer of LazSerial/Synapse
« Reply #58 on: March 11, 2022, 10:32:12 pm »
it seems that your sensors use a communication protocole (see six Data communication manual) with start and stop bytes. You can synchronyze your receiving program with that.
I doubt in that, because format of message is binary, and those $68 and $16 bytes can be in data bytes. So you will need time synchronization anyway.
« Last Edit: March 11, 2022, 10:39:40 pm by tetrastes »

Muso

  • Sr. Member
  • ****
  • Posts: 362
Re: How to disable the LineBuffer of LazSerial/Synapse
« Reply #59 on: March 11, 2022, 10:45:11 pm »
Did you check LastError/LastErrorDesc after WaitingData in this case?
Yes, every cycle I checked if LastError was zero, if not I issues an error message. But LastError was never <> 0.

Concerning the sync, of course use the stop byte (to find the checksum):
Quote
For example when I get 32 bytes, I evaluate the last 25 bytes. If their checksum is incorrect, I evaluate bytes 7 to 32 and so on.

Interesting is that for many hours now, I always get exactly 25 bytes. More than 25 bytes occurs only for the very first readout. So the sensor readout device is rock solid. I spoke with the supplier and also other customers complained about the UART to USB plug and they meanwhile changed it to the Adafruit one too. However, as I wrote, this plug also has some false reports. But since the connection does no longer die on a simple timeout, I am happy.

I am now convinced I solved the issue. Many, many thanks to you all and your patience with me!

 

TinyPortal © 2005-2018