LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

LabVIEW RS485 timing challenges with VISA Flush function

Solved!
Go to solution

Hi,

 

I have a sample project where I want to send RS485 command packets at a high transmit rate.  I observed a VISA Flush command taking 40 ms from time to time, which didn't make any sense to me and prevents me from sending command at my desired 100 Hz rate.

 

I'm trying to transmit a 31 byte command packet at a 100 Hz rate over a RS-485 port.  I am running the code on a NI Chassis PXIe-1092 (firmware version 20.5.2f1), using a RS485 card PXIe-8431/8.   I'm using LabView version 21.0.1f2(64 bit).

 

I've attached a VI that can be used to demonstrate my challenges.

 

My RS485 port is configured as shown in below excerpt of block diagram:

RS485VISAConfigure.PNG

 

 

I've created a byte array that represents the command I want to send out at a fast rate.  I then have created a loop that runs periodically and calls the VISA Write function followed by a VISA Flush command.   I added timers between the write function and flush function to understand how long these functions took to execute.  Here's a screen snapshot of my block diagram for reference

RS485WriteFlush.PNG

 

I was surprised when I found out that the flush function would often take up to 40 ms to complete.  I would not be able to send data at 100 Hz if the flush command would take this long.  Here's a screen shot showing my chart of measured times for write vs flush functions.

TimeInfo_TXBuffer128bytes.PNG

 

 

So after some searching, I found a NI article that reducing the serial buffer sizes might improve real time performance. Using NI MAX I saw that the initial TX buffer size was 128 bytes.,  I used NI MAX to reduce the TX buffer size for the RS485 port I was transmitting on.   I kept cutting the TX buffer size in half until I saw some improvement.  I was finally able to reduce the flush time by changing the TX buffer size to 2 bytes, but in this case the serial write time increased to 5 or 6 ms.   So there was a tradeoff, but this at least let me transmit my command at a fast rate.

 

Here's a new screen shot showing my chart of measured times for write vs flush functions.

TimeInfo_TXBuffer2bytes.PNG

 

 

My question is why does the flush command takes so long with the larger buffer size?  It doesn't seem like it should take this long. I wonder if there's some other RS485 setting I may want to make?

 

I also played around with a shorter command packet (4 bytes) and saw large flush times with a small TX buffer which made no sense to me either.

 

 

0 Kudos
Message 1 of 6
(550 Views)

The good news is that you shouldn't be trying to flush the transmit buffer in the midst of operations anyway.  In general, "flushing" a comm connection is for error recovery or maybe initialization.  Once the connection is established, just write and let the RS485 port do its work.

 

The bad news is that the troubleshooting you did and the things you learned aren't going to come in handy.

 

 

-Kevin P

ALERT! LabVIEW's subscription-only policy came to an end (finally!). Unfortunately, pricing favors the captured and committed over new adopters -- so tread carefully.
0 Kudos
Message 2 of 6
(528 Views)
Solution
Accepted by topic author ChuckHerscovici

Flush is not doing what you think it does. It does not force data to be send out any faster or through special means. It is mainly to guarantee that all the data currently in the buffer is send out before you do something else.

So it is much more like a "Wait until the buffer is empty" than anything like, "Push this data out even faster than you ever could otherwise!"

The VISA Write will transfer the bytes to a buffer and then VISA at the earliest possible time will transfer it to the OS, which again will put it in some buffer and then feed it to the serial port FIFO independent of you using Flush or not.

Basically Flush simply does all kind of checks, querying the OS for status of its own buffers and what else until everybody down the line reports: Nope, there is no data to transfer anymore. Then Flush returns to the caller.

It does not speed up the writing of the data significantly at all but has extra overhead to do all these kind of checks.

 

I'm not sure what your Short Test Cmd contains, but it seems to take at least 25ms at 115kBaud to transmit. 😁 So that would be something like 250 bytes?

 

Basically your assumption about what Flush does is wrong and your debugging of the process is accordingly useless as it was based on bad assumptions. Also your Flatten function is totally useless. A Byte Array to String function does the same but without any extra overhead as it is basically nothing more than a typecast.

 

If you want to write data as fast as possible, you should write the data as fast as possible and not try to add artificial synchronization barriers that only can slow down things.

That all said I wonder if your serial device is really expecting to get thrown a never ending stream of bytes at it. Usually serial protocols work on a command response model but that of course adds exactly more of above mentioned synchronization barriers into the mix.

Rolf Kalbermatter
My Blog
0 Kudos
Message 3 of 6
(494 Views)

Rolf,

the short cmd only contains about 4 bytes.  I noticed that it does take awhile to transmit when my tx buffer size was set to 2 bytes, but if I increase the tx buffer to the max size possible the short command does transmit faster.

0 Kudos
Message 4 of 6
(459 Views)

@ChuckHerscovici wrote:

Rolf,

the short cmd only contains about 4 bytes.  I noticed that it does take awhile to transmit when my tx buffer size was set to 2 bytes, but if I increase the tx buffer to the max size possible the short command does transmit faster.


Depending on the exact chipset and associated driver, you may be able to use the Windows Device Manager to set the "Latency Timer."

 

Writes will be sent to the device when the first of 2 conditions are met: 1 The buffer is filled or 2 The buffer is not filled and the Latency Timer expires.  For short messages you will have improved throughput by using a lower value for the Latency timer.   I am uncertain if this value is available for your hardware but, I am aware that it IS available on MOXA devices.

 

Latency Timer values are never set within a Session and must be configured at the kernel level from the hardware driver interface.

 

As always,  RTM to confirm. 


"Should be" isn't "Is" -Jay
0 Kudos
Message 5 of 6
(436 Views)

Another thing that you COULD try even on your current hardware.

I noticed that your VISA Write lacks the "Return Asynchronously" glyph in the lower right corner! (Small clock. Maybe top right corner?) Right click on the node and you should see an option to set the call instance to this non-default mode. VISA defaults to Return Synchronously meaning: wait until the data transfers out of the buffer. By choosing the Asynchronous option the Write WILL return as soon as all data is written to the buffer and possibly before the data is sent across the PHY layer!!! This CAN (buffer size and Latency timing depending) permit additional Writes to the same buffer when the buffer is larger, message sizes are smaller and the Writes are more frequent and hardware handshake lines are not asserted

 

how's that for hard and painfully  earned trivial knowledge?  I ought to Kudos myself!


"Should be" isn't "Is" -Jay
0 Kudos
Message 6 of 6
(428 Views)