LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Stall Data Flow Between VISA Write and Read (Serial Communication)

I have an instrument with an RS-232 port. I use some USB-to-Serial converter to connect it to my laptop. I use the SCPI commands to communicate with it. The query command is implemented in LabVIEW with single VISA Write and VISA Read. Simple stuff, I guess most of you have done hundred times.

 

I also wrote this kind of code a couple of times, and often I needed to add a wait between write and read operations for SPCI queries. Without it, the read operation sometimes hangs. I would like to ask The Community how to avoid these fixed delays. It feels wrong to write it this way - it is not elegant. Is it always this way with serial communication and VISA? Or perhaps I will not see this issue when using GPIB? I'm almost certain that there is no such behavior with the TCP/IP-based instruments, but this is a different pair of shoes, IMHO.

 

I have some ideas, but I'm not sure they will work in the long run. The first idea is to use a while polling loop and wait until there is something to read available at the port. After the loop is exited, perform the VISA Read. The second idea is using VISA Read inside of while polling loop. A couple of the first iterations might return a VISA timeout error. Errors will be ignored for some time (time limit), and if there are no errors anymore, it will proceed with the actual read (or, to be more precise, it will extract the data from the polling loop).

 

VISA.png

Could any of this work better? How do you write this kind of VISA query? How can I know that it is ok to perform the read already?

 

I know that VISA Read/Write can be in asynchronous and synchronous modes. Is this something I should care about, or should I leave it as it is? What kind of synchronization is it? What is synchronized with what?

Is changing the execution system to instrument I/O or other might improve the code?

Michał Bieńkowski
CLA, CTA

Someone devote his time to help solve your problem? Appreciate it and give kudos. Problem solved? Accept as a solution so that others can find it faster in the future.
Make a contribution to the development of TestStand - vote on TestStand Idea Exchange.
0 Kudos
Message 1 of 13
(1,671 Views)

I used Idea No1 similar methodology... works great for me.

 

If no data is available takes Zero Case

 

LFBaute_1-1673964473337.png

 

and if data is available it runs through the case "1....." 

data gets added to the string shift register and then output in "Response" indicator

 

LFBaute_0-1673964415399.png

 

Also it measures time it took to wait for complete response at "Execution Time" indicator.
If no response is received in a defined amount of time ("Timeout")

exits without error (or you can add a custom one)
and sets Timeout? indicator.

It stops when the termination character is received.

 

For me this one has saved me for a lot of time in different devices...

     and the cool thing is you can also diagnose how long it took to wait for response,

          useful for stats and diagnostics.

I bet there are more ways, this is my contribution.

CLA, CTA
Message 2 of 13
(1,647 Views)

It doesn't make much sense that the VISA Read would stall, unless you configured the termination method wrong. But that should be fixed by configuring the termination character and/or mode for the session, not some arbitrary strange delays.

 

Asynchronous versus synchronous operation has nothing to do with synchronization of things in VISA. It means that the VISA Read (and to some degree the VISA Write too but that is pretty meaningless) will either call the synchronous viRead() function, which blocks the entire LabVIEW thread in the external VISA library, or the viReadAsync() function inside an internal loop (in the C code underneath the icon). Synchronous viRead() will wait (more or less efficiently in the VISA driver library) for either the number of requested bytes, an occurrence of the termination condition or an error, before it returns control back to LabVIEW. When calling viReadAsync() the loop waiting for these conditions is running inside the LabVIEW diagram context. It allows other asynchronous LabVIEW functions in the diagram to execute in quasi parallel using the same thread.

 

Before LabVIEW was supporting multi-threading in LabVIEW 5.0, synchronous operation of nodes that could block for a long time, was simply locking up the entire application. Since LabVIEW supports multithreading and multiple threads per execution system, synchronous operation is the prefered method since it is simple and the waiting mechanism in the VISA driver is fairly efficient, not burning unnecessary CPU cycles while doing nothing else than to wait. But if you end up with applications that need to handle lots of VISA connections in parallel it could get a blocking condition not allowing you to communicate with more than 4 or 8 instruments at the same time in parallel, without some involved execution system assignment to specific VIs.

 

Asynchronous does not have that problem but the arbitration with other asynchronous diagram nodes will take up CPU resources and generally make your application consume considerably more CPU.

Rolf Kalbermatter
My Blog
Message 3 of 13
(1,642 Views)

@bienieck wrote:

Could any of this work better? How do you write this kind of VISA query? How can I know that it is ok to perform the read already?

VIWeek 2020/Proper way to communicate over serial

 

The same concepts apply to GPIB and TCP, especially when using SCPI.


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
Message 4 of 13
(1,621 Views)

@rolfk wrote:

It doesn't make much sense that the VISA Read would stall, unless you configured the termination method wrong. But that should be fixed by configuring the termination character and/or mode for the session, not some arbitrary strange delays.


I thought I had it configured correctly and according to the instrument manual. I used VISA Configure Serial Port.vi with basically default input parameters and one additional property node as follows:

 

VISA2.png

 

AFAIK, my termination character (for read and write) is fine. But despite this, I have to use wait after write because if I do the read right away, my VISA might block. For example, sending *CLS? or setting something using values out of range (and checking STB right after) will block VISA.

 

Based on the replies I assume my cheap instrument is just too cheap 😄

 

Michał Bieńkowski
CLA, CTA

Someone devote his time to help solve your problem? Appreciate it and give kudos. Problem solved? Accept as a solution so that others can find it faster in the future.
Make a contribution to the development of TestStand - vote on TestStand Idea Exchange.
0 Kudos
Message 5 of 13
(1,581 Views)

@bienieck wrote:

Based on the replies I assume my cheap instrument is just too cheap 😄


That or you read/interpreted the manual wrong! That ASRL End Out = TermChar property is meaningless for the  behavior of VISA Read. It only controls if the VISA Write should automatically attempt to append the configured termination character to every byte sequence. I never use it but rather append the required termination character always explicitly to the commands I send out.

 

The Serial Port Init, by default enables Termination Character detection and configures the termination character to be the character 0xA (or Line Feed). Since you don't wire these two parameters, this is how the VISA session is configured in your case too. If your instrument doesn't send an LF or CR/LF at the end of every message, the VISA Read will not terminate unless the timeout occurs or the number of requested bytes have arrived (or an error occurs in the underlaying driver).

Rolf Kalbermatter
My Blog
0 Kudos
Message 6 of 13
(1,563 Views)

@rolfk wrote:
That or you read/interpreted the manual wrong! That ASRL End Out = TermChar property is meaningless for the  behavior of VISA Read. It only controls if the VISA Write should automatically attempt to append the configured termination character to every byte sequence. I never use it but rather append the required termination character always explicitly to the commands I send out.

I don't use it either.  I know some around here do like to use it.  I don't use it because it only works for serial instruments.  Move to a GPIB or LAN instrument and you suddenly need to append the termination character anyways.  So I let my driver (code I wrote using VISA) purposefully append the termination character in case I am suddenly forced to use a different bus to talk to my instrument.


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
0 Kudos
Message 7 of 13
(1,556 Views)

Hi Machal,

 

i also agree with rolf and have nothing to append. Using a delay between write and read is always nonsense. Shure, VISA has some quirks when it comes to serial communication. They may affect you in some rare situations - but not at this point.

Sometimes a small delay between the last read and the next write command is needed. This can happen if the other endpoint is a microcontroller with low performance (and/or with a bad program).

The worst are some devices which were not able to read the bytes fast enough. I needed to send one character after each other with a small delay in between. Using 2 stop bits instead of one stop bit may enough delay in some of these cases.

 

0 Kudos
Message 8 of 13
(1,486 Views)

@Martin_Henz wrote:

Sometimes a small delay between the last read and the next write command is needed. This can happen if the other endpoint is a microcontroller with low performance (and/or with a bad program).


In my experience, it is not the delay between a read and the next write that is required, but a delay between writes.  Fairly recently, I was working with a really old power supply and I somehow realized I needed to add a 10ms delay between commands.  I supposed it was the instrument's read buffer getting full when I sent too many commands to it.

 

With anything "modern", I have not had this issue.


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
0 Kudos
Message 9 of 13
(1,457 Views)

@crossrulz wrote:

@Martin_Henz wrote:

Sometimes a small delay between the last read and the next write command is needed. This can happen if the other endpoint is a microcontroller with low performance (and/or with a bad program).


In my experience, it is not the delay between a read and the next write that is required, but a delay between writes.  Fairly recently, I was working with a really old power supply and I somehow realized I needed to add a 10ms delay between commands.  I supposed it was the instrument's read buffer getting full when I sent too many commands to it.

 

With anything "modern", I have not had this issue.


I had an old power supply where the instructions actually told you to add at least x milliseconds (i forgot the value) wait after each command to ensure time for the command to process!

Bill
CLD
(Mid-Level minion.)
My support system ensures that I don't look totally incompetent.
Proud to say that I've progressed beyond knowing just enough to be dangerous. I now know enough to know that I have no clue about anything at all.
Humble author of the CLAD Nugget.
Message 10 of 13
(1,414 Views)