====== 61 VISA ====== The Virtual Instrument Software Architecture (VISA) is an API for standardized communication with instruments. VISA supports the following protocols: * Serial protocols like RS-232, RS 422 and RS-485 * GPIB (Hewlett-Packard Interface Bus) * PXI/PCI * TCP/IP * USB * VXI/VMW * FireWire ---- ===== FAQ ===== * [[https://knowledge.ni.com/KnowledgeArticleDetails?id=kA00Z000000kJW3SAM&l=de-DE|Stop NI-VISA from Automatically Scanning for LAN Instruments]] ---- ===== Abstraction ===== 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: * Open * Write * Read * Close ---- ===== VISA Serial ===== ==== ASCII Plain Text ==== === Open === To open the visa connection the necessary information must be wired: General settings: * Timeout (specifies the the timeout for accessing an instrument connection) Speed of communication: * ItemBaud Rate (Bits per second) Frame Settings * Start Bit (always there, not configurable) * Data bits (The number of bits per frame) * Parity Bits (check bit, even, odd, even, mark, space. E.g. even counts the "1" of the data bits and adds a 1 if number is even) * Stop Bits (Number of bits that indicates the end of a frame) Message Based Settings: * Termination character (specifies the termination **read only** character [Linefeed LF = \n = 0xA], [Carriage Return CR = \r = 0xD], [End of Line CR + LF = \r\n = 0xD 0xA]) * Termination Character enabled (specifies if the **read** operation terminates if the defined termination character occurs. This will NOT effect the write settings) * End Mode for Reads (Must be set two "Term Character" in case Termination Character is enabled) * End Mode for Writes (Do NOT use this, a workaround is described in the chapter write below) * Flow Control (process of managing the rate of data transmission between two nodes to prevent a fast sender from overwhelming a slow receiver. This topic is not defined here in any further) === Write === 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 - the usage of this property node will effect ALL instrument class e.g. TCP/IP or PCI/PCI - besides the property node can only handle on termination character so carriage return OR line feed 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]) {{:kb:labview:visa_serial_write_termination.png?600|}} This way it's possible to see the behavior on the first glance. === Read === 1. Rule: NEVER use "Bytes at Port", if you can avoid it in any way!!!! :-P The **Visa Read.vi** stops it`s read process if one of the following conditions matches: * The number of bytes to read is consumed * the defined termination character is hit (See settings in Open above) * the timeout expired So if you handle like the following * Enable termination character * Setup the defined termination character * read more byte than expected * ignore warning "1073676294" "The Number of Bytes Transferred is Equal to the Input Count. More data might be available. This is not an error message, but a status report indicating the value written to the input buffer has been successfully read and is now empty." {{:kb:labview:visa_serial_read_termination.png?600|}} 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 === 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. ---- ==== Binary Frames ==== 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 | * Header or Startbyte (predifined structure [Number of bytes and content] which is every time the same) * Message ID (Command identifier what the message is addressed to [Fixed number of bytes]) * Data Size (Defines the number of bytes of the data [Fixed number of bytes]) * Data (Message data which differs and will be interpreted due to the message ID [Various number of bytes defined in the data size before]) * (optional) Cyclic Redundancy Check (CRC) == Excursion CRC == * **Algorithm Overview:** The CRC algorithm indeed involves calculating a checksum (a fixed-size datum) based on the contents of a message. This checksum is then appended to the message. * **Receiver Side:** Upon receiving the message, the receiver recalculates the CRC using the same algorithm and compares it with the checksum attached to the message. If the checksums match, the message is considered to be error-free; otherwise, it indicates that the message might have been corrupted during transmission. * **Complexity and Variations:** CRC algorithms can vary significantly. Different CRC standards (e.g., CRC-8, CRC-16, CRC-32) use different polynomial functions, which can lead to varying levels of error detection capability and computational complexity. * **Tools:** There are online tools and libraries that help in generating and verifying CRC values, which can be very useful for implementing and testing CRC algorithms e.g. [[https://crccalc.com/|crccalc]] === Open === 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. === Write === == Building the message frame == 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: {{:kb:labview:header_constant.png?300|}} 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: {{:kb:labview:convert_u32_to_array_of_bytes.png?600|}} 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: {{:kb:labview:write_binary_data_to_visa.png?800|}} === Read ===