The Virtual Instrument Software Architecture (VISA) is an API for standardized communication with instruments.
VISA supports the following protocols:
We recommend encapsulating all required functions in a LabVIEW class. This way, the visa resource is private and can only be accessed by member functions, which helps to prevent misusage.
This class could implement the following methods:
To open the visa connection the necessary information must be wired:
General settings:
Speed of communication:
Frame Settings
Message Based Settings:
How to Send Data in proper way? - do NOT use the property node for instrument class to enabled and add the termination characters for VISA write
Instead just encapsulate the read function in subVI and add a concentrate string with desired termination characters with the LabVIEW constants. [Linefeed LF = \n = 0xA], [Carriage Return CR = \r = 0xD], [End of Line CR + LF = \r\n = 0xD 0xA])
This way it's possible to see the behavior on the first glance.
1. Rule: NEVER use “Bytes at Port”, if you can avoid it in any way!!!!
The Visa Read.vi stops it`s read process if one of the following conditions matches:
So if you handle like the following
Note for slow baud rates:
For slow baud rates (e.g. 2400 especially on old devices) there is way to use the “Bytes at Port” to check if there new bytes incoming or the buffer stays the same for time period. After the amount of bytes at port are stable the message can be read. With this setup you can avoid long timeouts. This is just one solution for this particular problem, there might be better around!
Close each VISA connection reference. Otherwise this can cause strange runtime behavior.
That's why the VISA Close should be executed independently if there is an error in or not. This behavior is provided by the “VISA Close” method itself: “Error I/O operates uniquely in this function. The function closes the device session regardless of whether an error occurred in a preceding operation.” So keep this in mind when you classes to remove the “No Error/Error” case structure.
Most the time your binary data consists of a message frame in certain protocol. The basic setup is like the following:
Header | Payload | CRC |
fixed bytes size | various bytes size | fixed bytes size |
And the Payload itself contains of
Message ID | Data Size | Data |
fixed bytes size | fixed bytes size | various bytes size |
The same settings for the binary can be set up like for the ASCII, see above. It is important to disable the “Termination Character enabled”! The default termination character [Linefeed LF = \n = 0xA] can be part of your data which leads to loss of data because the read operation will be terminated due to the defined termination character is hit.
There a various ways building this binary message frame in LabVIEW. One of them we want to introduce here. The approach uses an array of unsigned integer 8 which is displayed HEX as a Radix. Most of the time the frame protocols are documented in HEX which makes this more easy. For the header you can use a constant SubVI which stores the information:
To convert values to an array of bytes the “Flatten to String” method is used. This method has the advantage to change the byte order in case the device expects a different one:
The boolean to prepend the size must be set to false.
Besides this implementation you can use string constants with radix changes to hex and use concatenate string function to build your frame
This shows how an implementation of the sending a frame via VISA: