Nuno
Junior Member
Posts: 64
|
Post by Nuno on Mar 28, 2023 14:46:19 GMT -5
Quoted from some Mr. Rod's old post "(...) Ports do take a few seconds to establish, once established transmission is in my experience instant."
I was searching this forum for a way to check if my data, sent through a COM port, had already been sent before proceding with further transmissions. I think I found that bit of info. I should check if the Tx buffer is empty. Makes sense, but how do I go about that?
In the above quote from Mr. Rod, the bit of "take a few seconds to establish" was unknown to me. Thank you for helping me again with this bit of info Rod. It actually solved a problem I had, but was not looking for a solution at the moment.
Do you know exactly how long? I think it could get critical in my case, as I have to start transmissions as fast as possible.
I disagree on the "instant", as I can see my Rx/Tx LED's flashing longer or shorter depending on the size of my MODBUS packet.
Thank you
|
|
|
Post by Rod on Mar 29, 2023 2:19:52 GMT -5
You can open the port and send a message all at the same time. The message will queue in the output buffer and be sent automatically as soon as the connection is established. If the connection is already established it will be sent immediately.
All messages take time to send, longer messages take longer. But it starts instantly.
The bit you have to wait for is the response, this will be faster if the port is open already and a bit slower if the port has to be opened for each message. So keep the port open.
The response is entirely down to the module you are communicating with. The article discusses how best to read the input buffer in sync with the likely response time. If you know the length of the message it is easy just poll the buffer with lof() till it has the correct length then suck it out the buffer.
If each output message gets a fixed response message that’s easy to just look for the correct length of message.
If the response is of variable length you need to use the buffering technique and poll at twice the message frequency.
There is a command to read the output buffer called txcount() but it is pretty useless in terms of getting the response. The response is the important bit not the transmission, the transmission is queued, fast and automatic. Knowing when you have a response and processing that is the key to quick message turn round.
|
|
Nuno
Junior Member
Posts: 64
|
Post by Nuno on Mar 29, 2023 5:20:57 GMT -5
Hi Rod,
Again. Very nice tips there. My congratulations on your expertise.
Will try that and let you know how it goes.
Thank you
|
|
|
Post by held12345 on Mar 30, 2023 8:54:00 GMT -5
if you want to do it with liberty basic, it only makes sense to send packets with a final byte to rx, then rx will respond again if the final byte matches the sender and the sender can then send packets again.
since you don't know the other system rx in terms of performance, packages make more sense.
|
|
|
Post by Rod on Mar 30, 2023 9:50:24 GMT -5
That would be great if you have control over how the attached module responds. But often we are dealing with old quirky software that followed no real standard. So we have to adapt and live with what the module sends us. Still very doable.
|
|
|
Post by held12345 on Mar 30, 2023 12:05:28 GMT -5
with the packages also works well on older models. I do it with me so that I take "hex 20 20" as the end of the packet. if the last two ale arrive at rx after 512 bytes, i return "hex 20 20" to the tx, which then knows that a next packet can come. my packets are 512 bytes in size, if after counting 512 bytes there are no "hex 20 20" at rx bytes, bytes have disappeared. i use my method for basic languages. greeting.
|
|
Nuno
Junior Member
Posts: 64
|
Post by Nuno on Apr 2, 2023 4:53:20 GMT -5
if you want to do it with liberty basic, it only makes sense to send packets with a final byte to rx, then rx will respond again if the final byte matches the sender and the sender can then send packets again. since you don't know the other system rx in terms of performance, packages make more sense. L.B. is the only high level language I could find, at acceptable prices, that works well under windows environment. agreed that is not the ideal environment for this. C or assembly language would be a much better choice. But these low level languages under windows is well above my level.
I'm afraid I don't quite follow on your suggestion of "a final byte to rx". Care to explain further? Thank you
|
|
Nuno
Junior Member
Posts: 64
|
Post by Nuno on Apr 2, 2023 5:11:07 GMT -5
You can open the port and send a message all at the same time. The message will queue in the output buffer and be sent automatically as soon as the connection is established. If the connection is already established it will be sent immediately. All messages take time to send, longer messages take longer. But it starts instantly. The bit you have to wait for is the response, this will be faster if the port is open already and a bit slower if the port has to be opened for each message. So keep the port open. The response is entirely down to the module you are communicating with. The article discusses how best to read the input buffer in sync with the likely response time. If you know the length of the message it is easy just poll the buffer with lof() till it has the correct length then suck it out the buffer. If each output message gets a fixed response message that’s easy to just look for the correct length of message. If the response is of variable length you need to use the buffering technique and poll at twice the message frequency. There is a command to read the output buffer called txcount() but it is pretty useless in terms of getting the response. The response is the important bit not the transmission, the transmission is queued, fast and automatic. Knowing when you have a response and processing that is the key to quick message turn round. Hi Rod,
Implemented some code following your idea of waiting for a response. The whole thing works much smother now. However, I come across the problem of when do I know the response package is fully received.
I'm using a wait cycle long enough, and then read the Rx buffer using the lof() function to find out the message size. All goes well. But I know I'm waiting probably too long. Especially if the module has a short response.
Just to clarify: There's several possible answers from the modules (There's 6 of them, ID's from 1 to 6), they can be as short as 6 bytes, or as long as 68. A wait cycle calculated for the 68 byte response is in place. But this longer response is the exception, that can happen anytime during the whole transaction process, that consists of several packets back and forth. I can predict the size of the response packet, and adjust the timeout cycle accordingly. Just wondering if a smarter way of shortning the buffer reading time exists.
Thank you
|
|
|
Post by held12345 on Apr 2, 2023 5:26:13 GMT -5
my method works exactly on new and old computers, also on foreign computers.
your method can always change with the transmission time, especially with windows with the various background programs.
|
|
Nuno
Junior Member
Posts: 64
|
Post by Nuno on Apr 2, 2023 5:51:11 GMT -5
I realize the many implications a windows environment can have on timing. I can see the problems happen if I shorten my delay cycle too much. And even this migth not work at times, if windows gets stuck on some internet thingy. That's why I asked if theres a clever way of knowing when the Rx message is fully received.
held12345, I didn't quite understood your method. Do you send a specific sequence of bytes directly to the rx buffer? How does that help? Do you mind explainig further on your method, please? Thank you
|
|
|
Post by Rod on Apr 2, 2023 7:49:44 GMT -5
I don't think held12345 realises that you have no control over the message format. I have put this pseudo code together. Dont know if it will run but it is intended to set a specific wait for each response and once that has expired it polls the port till the correct message length is there. Suck it and see kinda code. Not sure if it will work but it gives you something to think about. The timer needs encased in a sub else you will get errors.
'send for packet 1 #com "1" buffer$=getbuffer$(50,5) 'pause for response in ms, expected length of message
'send for packet 6 #com "6" buffer$=getbuffer$(250,68) 'pause for response in ms, expected length of message
function getbuffer$(p,L) call pause p while lof(#com)<L and timeout<10 timeout=timeout+1 call pause 16 wend if timeout<10 then getbuffer$=input$(#com,L) else getbuffer$="error" end function
sub pause ms timer ms,[done] wait
[done] timer 0 end sub
sub quit h$ timer 0 close #com end end sub
|
|
Nuno
Junior Member
Posts: 64
|
Post by Nuno on Apr 2, 2023 8:02:48 GMT -5
That's very similar to what I have, written other way, more or less. Guess time control is the critical factor. For when windows gets stuck doing something else, and messes up the Tx/Rx packets, the failed sent packet ID is recorded, and retried later, after another specified, much longer, time interval.
Note: I only use 1 COM port. The packet contains the destination address (MODBUS RTU implemented on RS485, 6 devices)
Thank you
|
|
|
Post by Rod on Apr 2, 2023 9:22:23 GMT -5
Yep, #com is the handle to the single com port, “1” and “6” were just representing what you might send as the packet to get responses.
|
|