LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

How to check if data is ready on visa/serial

Solved!
Go to solution

I am reading data from an instrument using VISA Read. My problem is that the data is only sent sporadically and I don't want the program execution to freeze while waiting for data to appear. I tried using the timeout on the read (setting the timeout low as an indication that data had not been sent yet), but this gets interpreted as an error. 

 

Is there a way to probe the serial connection and check if there is data ready to be read, and if not then don't wait for it just move on? 

 

Sorry if this is a duplicate question, but I couldn't find it. 

0 Kudos
Message 1 of 52
(2,066 Views)
Solution
Accepted by AlexGSFC

This is one of the few places where the Bytes At Port should be used.  Get the bytes in the port and then see if it is greater than 0.  If yes, do a proper read.  If no, wait and try again.  Just do not use the Bytes At Port to tell the VISA Read how many bytes to read.


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 2 of 52
(2,059 Views)

Ah, thanks! that was so deep in there, I didn't know it existed... 

0 Kudos
Message 3 of 52
(2,054 Views)

Try using Bytes at Port. Have a look at the example. If there are no bytes to read, the VI will simply go through and do nothing, without blocking the execution or wasting time.

 

EDIT: Nevermind, got beaten to it.

 

"Good judgment comes from experience; experience comes from bad judgment." Frederick Brooks
0 Kudos
Message 4 of 52
(2,053 Views)

@AlexGSFC wrote:

Ah, thanks! that was so deep in there, I didn't know it existed... 


🤣 You're one of the few. It seems that a LOT of people find that and want to use it to tell their program how many bytes to read.

 

Your timeout approach will work as well. Just ignore the timeout error (you can use Clear Errors to clear just that error code).

0 Kudos
Message 5 of 52
(2,037 Views)

@Dobrinov wrote:

Try using Bytes at Port. Have a look at the example. If there are no bytes to read, the VI will simply go through and do nothing, without blocking the execution or wasting time.

 

EDIT: Nevermind, got beaten to it.

 


Note that this is NOT the way to use bytes at port. If using bytes at port do it the way crossrulz said - check to see if there are bytes at port but don't use that value as the number of bytes to read.

0 Kudos
Message 6 of 52
(2,031 Views)

@johntrich1971 wrote:

@Dobrinov wrote:

Try using Bytes at Port. Have a look at the example. If there are no bytes to read, the VI will simply go through and do nothing, without blocking the execution or wasting time.

 

EDIT: Nevermind, got beaten to it.

 


Note that this is NOT the way to use bytes at port. If using bytes at port do it the way crossrulz said - check to see if there are bytes at port but don't use that value as the number of bytes to read.


There are perfectly valid reasons to do it EXACTLY this way. And the requested solution seemed as one of them.

"Good judgment comes from experience; experience comes from bad judgment." Frederick Brooks
0 Kudos
Message 7 of 52
(2,017 Views)

@Dobrinov wrote:

@johntrich1971 wrote:

@Dobrinov wrote:

Try using Bytes at Port. Have a look at the example. If there are no bytes to read, the VI will simply go through and do nothing, without blocking the execution or wasting time.

 

EDIT: Nevermind, got beaten to it.

 


Note that this is NOT the way to use bytes at port. If using bytes at port do it the way crossrulz said - check to see if there are bytes at port but don't use that value as the number of bytes to read.


There are perfectly valid reasons to do it EXACTLY this way. And the requested solution seemed as one of them.


No, the requested solution did NOT need a race condition as would be introduced with your approach. With your code it is entirely possible to read a partial message. The bytes at port reads before the entire message has arrived, and only part of the message is read. While this approach may work most of the time it is certainly NOT the right thing to do. The only reason that I know of to use bytes at port to tell the read function how many bytes to read is if you don't know how many bytes to read and there is not a termination character (perhaps crossrulz who is a serial communications expert, could think of some other situation where it might be appropriate). For this application use bytes at port to determine that there are bytes at port and then use a large number of bytes to read to allow the read all of the way to the termination character, eliminating the possibility of the race condition.

0 Kudos
Message 8 of 52
(1,997 Views)

@johntrich1971 wrote:

@Dobrinov wrote:

@johntrich1971 wrote:

@Dobrinov wrote:

Try using Bytes at Port. Have a look at the example. If there are no bytes to read, the VI will simply go through and do nothing, without blocking the execution or wasting time.

 

EDIT: Nevermind, got beaten to it.

 


Note that this is NOT the way to use bytes at port. If using bytes at port do it the way crossrulz said - check to see if there are bytes at port but don't use that value as the number of bytes to read.


There are perfectly valid reasons to do it EXACTLY this way. And the requested solution seemed as one of them.


No, the requested solution did NOT need a race condition as would be introduced with your approach. With your code it is entirely possible to read a partial message. The bytes at port reads before the entire message has arrived, and only part of the message is read. While this approach may work most of the time it is certainly NOT the right thing to do. The only reason that I know of to use bytes at port to tell the read function how many bytes to read is if you don't know how many bytes to read and there is not a termination character (perhaps crossrulz who is a serial communications expert, could think of some other situation where it might be appropriate). For this application use bytes at port to determine that there are bytes at port and then use a large number of bytes to read to allow the read all of the way to the termination character, eliminating the possibility of the race condition.


I'm not sure you understand what "race condition" means.

 

The example demonstrates that a thing called "bytes at port" exists, nothing more. As a rule of thumb one would need a shift register to gather everything that came at port and scan it for whatever the stop criteria would be, or simply not read at all until a certain amount of bytes is there to read. Not any number of bytes, but a certain amount of them, and then read as many out. Without any termination character. Either way one can iterate through the loop without blocking execution, as per thread request. Or ever getting a VISA Read timeout for that matter. I can implement my own timeouts or scan loop stop conditions based on whatever criteria suits the application instead, since I don't need to wait until a predetermined timeout no matter what (which in my case is sometimes minutes).

 

And in my applications I can get hundreds of termination characters before I need to stop scanning; they are basically useless to me when working with UARTs. Also I usually need to display everything that comes from a UART console for 0.5-4min before whatever I'm scanning for arrives, as user feedback, thus this allows me to do exactly that while waiting. The "right" way to do VISA Read wouldn't.

"Good judgment comes from experience; experience comes from bad judgment." Frederick Brooks
0 Kudos
Message 9 of 52
(1,989 Views)

@Dobrinov wrote:

@johntrich1971 wrote:

@Dobrinov wrote:

@johntrich1971 wrote:

@Dobrinov wrote:

Try using Bytes at Port. Have a look at the example. If there are no bytes to read, the VI will simply go through and do nothing, without blocking the execution or wasting time.

 

EDIT: Nevermind, got beaten to it.

 


Note that this is NOT the way to use bytes at port. If using bytes at port do it the way crossrulz said - check to see if there are bytes at port but don't use that value as the number of bytes to read.


There are perfectly valid reasons to do it EXACTLY this way. And the requested solution seemed as one of them.


No, the requested solution did NOT need a race condition as would be introduced with your approach. With your code it is entirely possible to read a partial message. The bytes at port reads before the entire message has arrived, and only part of the message is read. While this approach may work most of the time it is certainly NOT the right thing to do. The only reason that I know of to use bytes at port to tell the read function how many bytes to read is if you don't know how many bytes to read and there is not a termination character (perhaps crossrulz who is a serial communications expert, could think of some other situation where it might be appropriate). For this application use bytes at port to determine that there are bytes at port and then use a large number of bytes to read to allow the read all of the way to the termination character, eliminating the possibility of the race condition.


I'm not sure you understand what "race condition" means.

 

The example demonstrates that a thing called "bytes at port" exists, nothing more. As a rule of thumb one would need a shift register to gather everything that came at port and scan it for whatever the stop criteria would be, or simply not read at all until a certain amount of bytes is there to read. Not any number of bytes, but a certain amount of them, and then read as many out. Without any termination character. Either way one can iterate through the loop without blocking execution, as per thread request. Or ever getting a VISA Read timeout for that matter. I can implement my own timeouts or scan loop stop conditions based on whatever criteria suits the application instead, since I don't need to wait until a predetermined timeout no matter what (which in my case is sometimes minutes).

 

And in my applications I can get hundreds of termination characters before I need to stop scanning; they are basically useless to me when working with UARTs. Also I usually need to display everything that comes from a UART console for 0.5-4min before whatever I'm scanning for arrives, as user feedback, thus this allows me to do exactly that while waiting. The "right" way to do VISA Read wouldn't.


I've not implemented code with UARTS, so perhaps for your application using bytes at port is appropriate, but you are also implementing code to alleviate the race condition. In most cases (and the original request is one of them - entirely the opposite of the problem that you described) there's no need to take multiple loops to do what can be done in a single loop. The original post indicated that the problem was that he was having to wait for data to arrive as data is only sent out sporadically. Adding the complexity of making sure that all of the message was read is overkill for this application.

0 Kudos
Message 10 of 52
(1,982 Views)