01-31-2021 01:19 AM
After opening a serial line setting 500ms of timeout
int SerialOpen (void)
{
int err = 0;
err = OpenComConfig (A, "COMA", 19200, 0, 8, 1, 1024, 1024); // open Serial Com
if (err>0)
err = SetComTime (COMA, 0.50);
return err;
}
using the following statements
err = ComWrt (COMA, msg, strlen(msg)); // send a message to a devisce which responds within 100ms with a frame of 10 bytes terminated // with TERM_CHAR
if (err<0)
return err;
else
rec_num = ComRdTerm (COMA, rsp, MAX_BUFF_RX, TERM_CHAR); // waiting for receiving any buffer terminated with TERM_CHAR // within 500ms
the ComRdTerm doesn't wait for timeout elapsed and returns 0.
So I have to insert Delay (0.5) before reading.
Do you know if there is any bug in such call and workaround ?
01-31-2021 06:21 PM
I don't understand that COMA you are using in your code, which is a string in Open statement and a variable (or a macro?) afterwards and doesn't follow the usual COMx notation. I wonder whether it can confuse the compiler also.
I would try to rewrite the code with an empty string in Open function (OpenComConfig (1, "", 19200....) and using the simple port number in all other calls.
Apart from this, how is your TERM_CHAR defined?
02-01-2021 02:05 AM - edited 02-01-2021 02:07 AM
Hi,
Timeout is not a "must wait" duration.
It waits for a maximum of timeout duration IF there are not enough bytes and/or the terminating character in the receive buffer.
Can you check your buffer contents using the GetInQLen function?
02-01-2021 11:48 AM
Thank you for your response.
what you write is known to me. My problem is that after a ComWrt() to which I expect a response within 100ms, having set a timeout of 500ms, the RdComTerm exits without reading anything because it doesn't wait 500ms, while if I set esplicitely a Delay of 500ms before the ComRdTerm I read what I expect
See below an extract of my code
/* opening the serial line with timeout of 500ms */
OpenComConfig (COMA, COMA_str, 19200, 0, 8, 1, 1024);
SetComTime (COMA, 0.50);
......
/* sending message and receiving response */
ComWrt (COMA, msg, strlen(msg));
Delay(0.5); /* with Delay it works; without Delay nothing received */
rec_num = ComRdTerm(COMA, rsp, MAX_BUFF_RX, TERM_CHAR);
According to me the SetComTime() doesn't work. Can it depend from Window 10 incompatible with Labwindows 2013 Service Pack 1?
02-01-2021 11:51 AM
These are my define
#define COMA 8
#define COMA_str "COM8"
#define TERM_CHAR 0
Marco
02-02-2021 02:46 AM
#define TERM_CHAR 0 😳😲
It's not clear to me what the driver can do with 0 as a termination byte, but I don't know any instrument that terminates messages with (ASCII)0!
In my opinioni this explains because your ComRdTerm exits immediately without reading nothing.
CHeck the documentation for your device and find the correct termination byte to use.
02-02-2021 03:01 AM
Roberto, you are right, 0x00 is an uncommon choice for termination byte.
But it should be OK theoretically. 0x00 has a valid binary representation and can be transmitted and received on the serial bus just like any other byte.
Am I missing something? 🤔
Maybe there is an undocumented and different behaviour for 0x00 as a term char?
02-02-2021 04:47 AM - edited 02-02-2021 04:53 AM
I think the termination character with value 0 may actually trigger a side effect from how C handles data buffers. If there is anywhere a standard C string function involved inside that function it will fill the buffer with a null byte even if there is technically no byte at all in the buffer. ComRdTerm then sees that NULL byte, determines that there must be an end of message indicator, and returns and as is documented, this termination character is NOT included in the returned message, so it effectively returns a zero length message. Technically this would be a bug as the function should not attempt to interpret any data in the buffer beyond the currently received number of bytes, but it may never have been discovered so far as it is VERY uncommon for devices to use a NULL byte as termination character. The other possibility is that 0 as termination character indeed triggers a special, intended but not fully documented code path.
Does your device really use a 0 byte as termination?
02-02-2021 05:40 AM
Thank you Rolf.
you have hit the target. The 0 highlights a potential bug of the SetComTime. Changing the terminator character makes the timeout work. Unfortunately the protocol I have to implement uses a variable size message exchange and the most efficient method is to use a terminator character to establish the end of the message: they chose 0. Of course COBS encoding is used to rreceive real zeros within the message.
Regards
Marco
02-02-2021 07:13 AM
well, it's been a while since I have treated binary data with embedded zero bytes with ComRdTerm, but I seem to remember that, provided the termination character is not the zero byte itself, an embedded zero does not prevent the function to correctly read the entire message including bytes following the zero one.
Anyway, since you cannot use a different terminator you could try to install the callback for any byte received in the buffer (LWRS_RXCHAR event mask) and iterate inside the callback up to emptying the input buffer, checking for zero bytes to determine packet boundaries.