The VI Server


The VI Server is a powerful feature in LabVIEW that gives you the capability of programmatically accessing features in LabVIEW like opening and running VIs, changing the color or value of a front panel object, printing the front panel, and so on.

This is quite an advanced topic, so don't feel bad if much of this VI Server introduction confuses you. Almost everyone struggles to understand how to use VI Server functions at first. The good news is that, for simple LabVIEW applications, you might never need it. Once you get warmed up and comfortable with LabVIEW, though, you'll want to play with all the fun and powerful things you can do via the VI Servereventually you'll wonder how you ever programmed in LabVIEW without it.

You don't need to understand or use the VI Server for any of the other material in this book, so feel free to gloss over it if you want to move ahead.


Don't let the name confuse you: "VI Server" is much more than just some type of networking server built into LabVIEW (although it is that as well). The VI Server functionality is really a way of exposing the internal object structure LabVIEW uses for organizing VIs, controls, and a whole lot more.

For example, with VI Server, you can programmatically:

  • Load a VI into memory, run it, and then unload the VI, without the need to have it statically linked as a subVI in your block diagram.

  • Dynamically run a subVI that gets called at runtime, by only knowing its name and connector pane structure (this is known as calling a VI by reference).

  • Change properties of a particular VI, such as the size and position of the front panel window, whether it is editable, and so on.

  • Make LabVIEW windows move to the front of the screen.

  • From the block diagram, call a subVI without waiting for it to finish executing (one of the few places you can get away with not obeying the normal dataflow paradigm!).

  • Dynamically change the attributes (properties), such as color and size, of a front panel object.

Because LabVIEW's internal objects (VIs, controls, etc.) are designed using object-oriented programming (OOP) principles, you will see many OOP themes appear in the tools and mechanisms we use with VI Server. For example, the VI Server deals with objects having properties and methods. These objects are organized in a single inheritance hierarchy and are operated on by reference. Although we do not have time to show the relationship between the VI Server features and OOP, your programming will benefit greatly if you take the time to explore OOP on your own and read Appendix D, "LabVIEW Object-Oriented Programming."


In addition to all this cool stuff you can do, there's more: Everything we just mentioned works with network transparency. Network transparency means you can do all of the mentioned manipulation of a VI or of LabVIEW itself on another machine across the network (including the Internet) in just the same way as if it were on your own machinethe remote LabVIEW can even be running on a different operating system or be a built executable application. This means that, for example, you could have a data acquisition VI running at remote sites while your local analysis VI gets information from the remote machineswithout having to write any special networking and without using complex TCP/IP functions.

Figures 15.17 and 15.18 show you an example of how trivial it is to run a VI remotely. (Don't worry about what the functions are below if you haven't seen them before; they're from the Programming>>Application Control palette, and we'll examine them in detail shortly.)

Figure 15.17. This tells the local machine to run My Cool VI.vi.


Figure 15.18. This tells the LabVIEW across the Internet at the address lv.hot.lab to run My Cool VI.vi. The path to the VI refers to the remote drive.


The VI Server exposes its functionality in LabVIEW through block diagram functions like those in Figures 15.17 and 15.18. But it also allows its functionality to be accessed in Windows from external programs through an ActiveX automation client (e.g., a Visual Basic program or macro) and from a remote LabVIEW VI over TCP/IP. The diagram in Figure 15.19 illustrates this architecture. As you can see in the following figure, the VI Server functionality is accessible by block diagram functions, by external ActiveX programs, or by a remote LabVIEW VI over TCP/IP.

Figure 15.19. VI Server communication model


Enabling Remote Access to the VI Server

To enable LabVIEW on remote computers to access the VI Server on your local computer, select Tools>> Options . . . from the menu to open the LabVIEW Options dialog and then navigate to the VI Server: Configuration category (see Figure 15.20). You can allow access to VI Server via TCP/IP (on all platforms) and via ActiveX (on Windows). Also, pay attention to the various permissions settings for restricting access to certain functionality and VIs, as well as limiting access to certain remote machines and users. There are four options categories that begin with "VI Server:" that are used to configure these settings.

Figure 15.20. LabVIEW VI Server configuration options


You always have full access to the VI Server of the local LabVIEW environment in which your VIs are running (regardless of the VI Server settings configured in the Options . . . dialog). If you wish to access the local VI Server, use a local application reference. For example, if you call the Open VI Reference function and leave the application reference (local) input unwired, then the local application reference is used by default.


The functions for using the VI Server are in the Programming>>Application Control palette (see Figure 15.21).

Figure 15.21. Application Control palette


There are three very important classes of "objects" in LabVIEW that the VI Server functions let you manipulate:

  • Application class The LabVIEW environment itself.

  • VI class A specific VI in memory or on a disk.

  • Control class A front panel control or indicator.

We will discuss each of these in the coming sections.

Properties and Methods, "By Reference"

The term "by reference" means that we are passing around a reference (also called a "refnum," "pointer," or "handle") to objects that we wish to operate on. We learned how to perform operations "by reference" when we studied the file I/O functions in Chapter 14, "Advanced LabVIEW Data Concepts." There, we used the file refnum to tell the file I/O functions which file we wished to perform operations on.

VI Server is another example of performing operations by reference. We will open application, VI, and control references (similar to how we opened file references) and then read and write properties and invoke methods by reference (similar to how we called the file I/O functions to operate on a file by reference).

For operating on VI Server objects, we will primarily use the Property Node and Invoke Node (Programming>>Application Control palette).

The Property Node sets (writes) or gets (reads) property information for the object whose reference is passed into the reference input (see Figure 15.22). You can configure a Property Node to access multiple properties; each property can be configured as read or write. Pop up on a property terminal and use the Change To Read, Change To Write, Change All To Read, or Change All To Write options accordingly. You can resize a Property Node to show more or fewer terminals. Each terminal can be used to read or write one property.

Figure 15.22. Property Node


The Invoke Node invokes a method or action on the object whose reference is passed into the reference input (see Figure 15.23). Once you select the method, the associated parameters will appear below the method name. You can set and get the parameter values. Parameters with a white background are required inputs and parameters with a gray background are recommended inputs. You can only configure an Invoke Node to call a single method. The number of terminals is defined by the number of arguments and return valuesit cannot be resized.

Figure 15.23. Invoke Node


If the reference input is wired, the Property Node or Invoke Node will automatically adapt to the class of the object that is referenced. If the reference input is unwired, then you can select the class of object from the Select Class pop-up submenu. If you select the VI or Application class, you do not need to wire the reference inputLabVIEW assumes that you are referring to the calling VI or the local application (respectively).

Déjà Vu: Property Nodes and Invoke Nodes

In Chapter 13, "Advanced LabVIEW Structures and Functions," you also learned about Property Nodes and Invoke Nodes, but those were linked to controls. You create Property Nodes and Invoke Nodes by selecting a property or method from the Create>>Property Node or Create>>Invoke Node submenus (respectively) of a control's pop-up menu. This created a Property Node or Invoke Node on the block diagram that did not have a reference input or dup reference output terminal. It did not need those terminals, because the reference (or link) to the control was implicitly defined.

If you have explored the pop-up menu of a Property Node or Invoke Node that is linked to a front panel control, you may have noticed the option Disconnect From Control. This creates an unlinked property or Invoke Node that looks identical to the one on the Programming>>Application Control palette. (And, yes, conversely you can pop up on an unlinked property or Invoke Node and link it to a front panel control.)

You can see the difference between an implicit (linked) and explicit (unlinked) Property Node in Figure 15.24.

Figure 15.24. Implicit (linked) and explicit (by reference) Property Nodes


That is all we will say for the moment about control references. You'll learn more about them soon. First, you will learn about application references and VI references, in order to better understand how control references fit into the picture.

Application References

An application reference is a reference to an instance of the Application class in LabVIEW. What this means is that an application reference gives you access to read and write properties and to invoke methods on the LabVIEW application itself (as opposed to a single VI).

You can also open an application reference to a LabVIEW standalone executable application (both local and remote application references). But, you must configure the built application's INI file settings. The configuration file key-value pairs used for VI Server (and many other) settings in a built application are the same as those used by the LabVIEW development environment. Note that the INI file section must be the name of your built application (minus the file extension).


For example, suppose your program needs to know if your user's monitor resolution is the right size. With an application reference, you can read what monitor resolution LabVIEW is running by reading the "Display.AllMonitors" property. Or let's say your program launches an external application, such as Microsoft Excel, but you want to make sure the VI window comes back to the front of the screen. You can invoke the "Bring To Front" method, which tells LabVIEW to move its windows to the front of other windows.

Before you can read or write application properties using a Property Node, or call application methods using an Invoke Node, you will need to create (obtain) the application reference. Usually the application reference refers to the local LabVIEW installation, but it could refer to a LabVIEW installation on a remote machine. Obtaining a local application reference is easy and there are a few ways to do so.

One way is to use a VI Server Reference (Programming>>Application Control palette) and configure it for This Application from the menu by mouse-clicking on it with the Operating tool (see Figure 15.25).

Figure 15.25. VI Server Reference


Another way is to use an Application Property Node (Programming>>Application Control palette) and leave its reference input unwired, as shown in Figure 15.26. Doing so will cause LabVIEW to assume that you are referring to the local application and the dup reference output will be a local application reference.

Figure 15.26. Application Property Node


The last way to obtain a local application reference is to call the Open Application Reference function (see Figure 15.27) and leave the machine name unwired (causing the function to assume the default: local application).

Figure 15.27. Open Application Reference


You can also use the Open Application Reference function to obtain a remote application reference (a reference to the VI Server on a remote LabVIEW). To obtain a remote application reference, specify a machine name (host name or IP address). This will establish a TCP connection with the remote VI Server on the specified port number.

When you are done using a remote application reference that was created by Open Application Reference, you must close it by passing the reference to the Close Reference function (Programming>>Application Control palette), shown in Figure 15.28.

Figure 15.28. Close Reference


Close Reference is also used to close any refnum associated with an open VI, VI object, an open application instance, or an ActiveX or .NET object. You will see this function often when using VI Server.


Activity 15-4: Using the Application Class Properties

In this activity, you will use the VI Server to find out what operating system you are running, where LabVIEW is installed, and the username of who is logged on.

1.

With a new blank VI, create the following block diagram by making an Application Property Node (from the Programming>>Application Control palette). You will be programmatically reading the directory LabVIEW is in, the OS name, and the LabVIEW user name (see Figure 15.29).

Figure 15.29. Block diagram of the VI you will create during this activity


When you are referencing the local Application class, you can omit the Open Application Reference function that normally would precede the Invoke Node function.

2.

On the front panel, run the VI and observe the results (see Figure 15.30).

Figure 15.30. Front panel of the VI you will create during this activity, showing the results of running it


3.

Save your VI as AppClassDemo.vi.

Now let's look at how you can use the VI Server to create some "magic": Allow one VI to change the value of another VI's front panel control, without wiring the two together.

VI References

A VI Reference refers to an instance of the VI Class. This means you can read/write properties or invoke methods for a specific VI. You can obtain VI References in a similar fashion to application references.

One way is to use a VI Server Reference (Programming>>Application Control palette) and configure it for This VI from the menu by mouse-clicking on it with the Operating tool (see Figure 15.31).

Figure 15.31. Configuring a VI Server Reference to return a reference to This VI


Another way is to use a VI Property Node and leave its reference input unwired, as shown in Figure 15.32. Doing so will cause LabVIEW to assume that you are referring to the calling VI (the VI on whose block diagram the Property Node is placed) and the dup reference output will be a reference to the calling VI.

Figure 15.32. VI Property Node


To create a VI Property Node, place a Property Node (Programming>>Application Control palette) onto the block diagram of your VI and then choose Select Class>>VI Server>>VI>>VI from the pop-up menu of the Property Node.

The final way to obtain a VI Reference is to call the Open VI Reference function (see Figure 15.33). This function returns a reference to a VI specified by the vi path input. This input can be either a string or a path data type and can be either the VI Name (if it is already in memory) or the full path to the VI if it is not in memory.

Figure 15.33. Open VI Reference


When using Open VI Reference with a remote application reference, the vi path input must be specified relative to the remote machine's file system. The remote machine cannot (necessarily) access files in the local machine's file system.


The Open VI Reference function can be used to open references to custom control (.ctl files) or global variables, both of which are treated as VIsactually, they are special types of VIswithin the VI Server class hierarchy.


The options and type specifier VI Refnum inputs of the Open VI Reference function affect how you will be able to use the VI reference. We will describe the implications of these inputs, in context, as they relate to the features described in the coming sections.


Any reference created using the Open VI Reference function must be closed using the Close Reference function (see Figure 15.34). Failing to do so can result in your application gradually consuming more and more memory (and possibly degrade system performance).

Figure 15.34. Close Reference


Activity 15-5: Using the VI Class Methods and Properties

In this activity, you will manipulate one VI and toggle one of its controls through the VI Server interface from a "master" VI.

1.

Create the simple Chart.vi, as shown in Figures 15.35 and 15.36.

Figure 15.35. Front panel of the VI you will create during this activity


Figure 15.36. Block diagram of the VI you will create during this activity


2.

Now open the VI on the CD in EVERYONE\CH15, Master VI.vi and run it. Make sure that Chart.vi is still open and you are not running it.

3.

Run Master VI.vi. It will do the following:

i. Open the front panel of Chart.vi.

ii. Center the front panel on the screen.

iii. Run the Chart.vi.

iv. Allows the "new data?" control to be changed while running (see Figure 15.37).

Figure 15.37. Master VI.vi front panel


Study the block diagram to gain insight into how it accomplishes this (see Figure 15.38). Note the use of floating label comments to clearly describe the function of each portion of the code. (This is not overkill; this is good coding practice. Aren't you glad it's there for you to read?)

Figure 15.38. Master VI.vi block diagram


This example uses an Invoke Node to execute the VI's Run VI method, shown in Figure 15.39.

Figure 15.39. Invoke Node configured to execute a VI's Run VI method


Run Button

The Run VI method produces the same result as pressing the VI's Run button on the toolbar of its front panel or block diagram. The Run VI method of executing a VI is different from calling a subVI because we do not pass data into the VI, or receive data out of the VI, through its connector pane. Also, unlike calling a subVI, we can choose whether we want the Run VI method to wait until the VI finishes executing by passing the desired value to the Wait Until Done input argument.

When a VI is run this way, it uses the current values of all front panel controls for execution rather than using data passed in through its connector pane. This method also ignores the Execution:Show Front Panel On Call and Execution:Close After Call properties of a VI. And, you cannot use this method to run a VI that is already reserved for execution by another VI (used as a subVI in the hierarchy of a running VI).

If you use the Open VI Reference function and wire the type specifier VI Refnum input, you cannot use the reference returned by the function with the Run VI method. Instead, you must use the Call By Reference Node. We will learn about the Call By Reference Node next.


If you want to use the Run VI method to run a reentrant VI, set the option's parameter to 0x08 in the Open VI Reference function to prepare the VI for reentrant run.


Dynamic SubVIs: The Call By Reference Node

When you want to dynamically call a VI (by reference) as a subVI, you will need to use the Call By Reference Node (Programming>>Application Control palette). This is very similar to a subVI node, but it has reference and error terminals at the top of it (see Figure 15.40).

Figure 15.40. Call By Reference Node


The connector pane of the Call By Reference Node adapts to the connector pane of the VI reference wired into its reference input terminal. This connector pane association is defined at the time the VI reference is opened using the type specifier VI refnum input of the Open VI Reference function.

However, the Call By Reference Node can also be "statically linked" to a specific VI, in which case it does not require a VI reference to be wired into it. To statically link a VI to a Call By Reference Node, pop up on it and select Call Setup . . . (see Figure 15.41) to open the VI Call Configuration dialog (see Figure 15.42).

Figure 15.41. Selecting Call Setup . . . from the Call By Reference Node's pop-up menu to open its VI Call Configuration dialog


Figure 15.42. VI Call Configuration dialog


If you use the Call Setup . . . option and statically link to a VI, it is very similar to calling a subVI. If you select the "Reload for each call" option, though, the calling VI will load and unload the VI you are calling from memory (whereas a subVI always remains in memory until its calling VI is closed).

This may seem a bit confusing, so let's clarify it with a hands-on example.

Activity 15-6: Calling a VI by Reference

In this activity, you will use the Call By Reference Node to call a subVI by reference.

1.

Create Running average by reference.vi, as shown in Figures 15.43 and 15.44.

Figure 15.43. Front panel of the VI you will create during this activity




Figure 15.44. Block diagram of the VI you will create during this activity


2.

In order to define the connector pane of the Call By Reference Node, we must configure the Type Specifier VI Refnum to define the VI reference wire type. To create the Type Specifier VI Refnum, pop up on the type specifier VI Refnum terminal of the Open VI Reference function and select Create>>Constant. Note that you must make sure that your mouse is directly over the type specifier VI Refnum terminal in order to do this step.

OpenVI Reference

3.

The Type Specifier VI Refnum constant must now be associated with the connector pane of Running average.vi. To do this, pop up on the Type Specifier VI Refnum and choose Select VI Server Class>>Browse . . . . A file dialog will open. Browse to the location of Running average.vi (on the CD in EVERYONE\CH13), select Running average.vi, and press "OK." The connector pane of Running average.vi will appear in the Type Specifier VI Refnum constant. The Call By Reference Node will also assume the connector pane, if wired to the vi reference output of Open VI Reference.

Type Specifier VI Refnum

4.

Set the value of the Dynamic VI Path control to the path of Running average.vi, located in the EVERYONE\CH13 folder of the CD.

5.

Run Running average by reference.vi. You will see data appear on the waveform chart.

In the last step, you associated the Type Specifier VI Refnum constant with the connector pane of Running average.vi. This association does not create any "linkage" or "reference" to Running average.vi. It is simply a way for you to tell the Type Specifier VI Refnum constant the connector pane pattern of the VI that you will later call by reference (which may or may not be the same VI).

Figure 15.45 shows a Type Specifier VI Refnum and a Static VI Reference (which is discussed immediately following this activity), side-by-side, both of which have been "associated" with the same VI (Running average.vi). Make note of the symbol in the upper-left corner that distinctively identifies the Type Specifier VI Refnum. This symbol implies that it does not actually contain a referenceit is "empty"unlike the Static VI Reference, which does actually refer to a VI and contain a valid reference.

Figure 15.45. Type Specifier VI Refnum (top) and a Static VI Reference (bottom)


You are now calling Running average.vi dynamically! It does not get loaded into memory until you run Running average by reference.vi, and it gets unloaded when Running average by reference.vi stops running. We can think of Running average.vi as a plug-in component to our applicationvery cool!

Static VI References

In some instances it is desirable to open a reference to a VI staticallyfor example, when you know, at the time the application is being created, precisely which VIs you wish to open references to.

Here is how it works. Place a Static VI Reference (Programming>>Application Control palette) onto the block diagram. When the Static VI Reference is first placed onto the block diagram, it appears with a question mark icon (see Figure 15.46), signifying that it does not yet reference any VI.

Figure 15.46. Static VI Reference (Unconfigured)


To configure the Static VI Reference to reference a VI, choose Browse for Path . . . from its pop-up menu and use the resulting file dialog to select the VI that is to be referenced (see Figure 15.47). Once a VI is referenced by this node, its icon will replace the question mark icon and you can open its front panel by double-clicking the VI's icon.

Figure 15.47. Static VI Reference (Referencing a VI)


The Static VI Reference (Programming>>Application Control palette) acts similar to a subVI, in that the statically referenced VI appears in the hierarchy of its caller. However, when the Static VI Reference is called, it does not call the VI being referenced; it merely outputs a reference to the statically referenced VI.

By default, the Static VI Reference outputs a generic VI reference, but you can change it to be strictly typed (so that the reference contains connector pane information and may be used with the Call By Reference Node) by right-clicking the function and selecting Strictly Typed VI Reference from the shortcut menu. When configured as strictly typed, a Static VI Reference has a red star in its upper-left corner. You should note that when you create a strictly typed VI reference, you cannot use it with the Run VI method.

Control References

A Control Reference is similar to the Application Reference and VI Reference. It refers to a specific front panel object (for example, a numeric indicator). We can pass a control reference to a Property Node in order to get and set properties of the control. Or we can pass the control reference to an Invoke Node in order to call a method the control. Figure 15.48 shows a control reference being used to set properties and invoke a method of a control.

Figure 15.48. Using a control reference to set properties and invoke a method of a control


Control references can be passed into and out of subVIs using a Control Refnum (see Ctl Refnum and Ctl Refnum out in Figure 15.48).

The Control Refnum can be found on the Modern>>Refnum palette, shown in Figure 15.49.

Figure 15.49. Control Refnum, found on the Modern>>Refnum palette


VI Server References to Controls

The simplest way to create a control reference is to pop up on a control or indicator and select Create>>Reference, which will create a VI Server Reference on the block diagram that is linked to the control (see Figure 15.50). When a VI Server Reference node is linked to a control, its label text will always be the same as the control to which it is linked.

Figure 15.50. Numeric control with a linked VI Server Reference node next to it


The control reference may be wired to Property Nodes or Invoke Nodes, as shown in Figure 15.51.

Figure 15.51. VI Server Reference wired to a Property Node used to set properties of the numeric control


You can also create a VI Server Reference that is linked to a control by dropping a VI Server Reference node (Programming>>Application Control palette) onto the block diagram.

Once you have placed the VI Server Reference onto the block diagram, link it to the desired front panel control by mouse-clicking on it with the Operating tool and selecting the desired control from the list of front panel controls on the Pane submenu, as shown in Figure 15.52. Or you can pop up on the VI Server Reference and select the desired front panel control from the Link To>>Pane submenu.

Figure 15.52. Linking a VI Server Reference to a control on the front panel "pane" from its pop up menu


It is important not to confuse the VI Server Reference ( ) and the Class Specifier Constant ( ), which are on the same palette. The VI Server Reference is linked to a specific LabVIEW object (an Application Instance, a VI, or a front panel control or indicator) and outputs a reference that points to a specific LabVIEW object. The Class Specifier Constant, on the other hand, is not linked to any LabVIEW objectits value is null, and it is useful only for its type information. This distinction will be very important when we discuss the VI Server class hierarchy and how to convert control references to more specific or more generic types.


Obtaining References to All Controls on a Front Panel

Another way to obtain control references is by reading the value of the Controls[ ] property of a VI's Panel (the value of a VI's Panel property is a reference to its front panel). This method, illustrated in Figure 15.53, will return an array of control references: one for each control and indicator on a VI's front panel.

Figure 15.53. Programmatically obtaining references to all controls on a VI's front panel


Using this method, you can obtain an array of control referencesbut how in the world do you know which reference belongs to which control or indicator? Well, one way is to analyze each control reference, one by one, looking at the name, type, and other properties of the control or indicator that the reference points to. Figure 15.54 shows how we can read the Label.Text (Control/Indicator Name), ClassName (Type of Control), Indicator (Control or Indicator), and Value properties of each control on the front panel.

Figure 15.54. Programmatically building an array of properties for all controls on a VI's front panel


Another, sometimes easier, way you can determine which control references refer to which front panel objects in the Controls[] array is to examine the Tabbing Order of the front panel (the Tabbing Order is accessible from the Edit>>Set Tabbing Order menu option on the front panel; refer to the "Keyboard Navigation" section of this chapter). The Controls [] array returns references to the VI's front panel controls in the same order as they appear in the Tabbing Order.

Using the Tabbing Order to find the index of a control in the Controls[] array may be a useful trick, but it is bad style! The linkage between tabbing order and the control's position in the Controls[] array is quite obfuscated and will give you a headache when you have to figure out how your code works one month from now. If you need to create a reference to a specific control on the front panel, then use the Create>>Reference option from the pop-up menu.


Note that in the example illustrated in Figure 15.54, the Value property is a variantnot a Boolean or a numeric data type. The reason for this is that the control references that come out of the Controls[] property are generically typed. We do not necessarily know, until the moment that we run this code, what specific type of controls we have on the front panel (we will learn about the class hierarchy of control types next). So, we need a generic data type for passing the control's value that can accept any possible data type. This is exactly why variants are important and useful. Refer back to Chapter 12, "Instrument Control in LabVIEW," if you want to review the topic of variants.

Activity 15-7: Using VI Server References to Disable Controls While Busy

In this activity, you will create a VI that grays out (disables) a group of controls while data is being generated and sent to a waveform chart.

1.

Create Disable Controls While Busy.vi, as shown in Figures 15.55 and 15.56.

Figure 15.55. Front panel of the VI you will create during this activity


Figure 15.56. Block diagram of the VI you will create during this activity


2.

Create a VI Server Reference for each control you wish to disable by selecting Create>>Reference from its pop-up menu. Use the Build Array node to construct an array of these control references.

VI Server Reference

3.

Inside a For Loop (and before doing the work of sending data to a waveform chart), disable each of the controls by setting its Disabled property to 2 (grayed out).

4.

After doing the work, re-enable each by setting its Disabled property to 0 (enabled).

Run your VI and press the generate waveform button. Watch the controls become grayed out while data is being generated and become re-enabled after the data generation is complete!

Activity 15-8: Using the Panel.Controls[] Property to Disable Controls While Busy

In this activity, you will modify Disable Controls While Busy.vi, which you just created in the last activity, so that it grays out (disables) all of the front panel controls while data is being generated and sent to a waveform chart (not just a group of controls that you specify using VI Server Reference nodes).

1.

Open Disable Controls While Busy.vi and save a copy as Disable All Controls While Busy.vi. Modify its block diagram so that the code inside the While Loop looks like Figure 15.57 (the controls outside the While Loop are not shown in the illustration).

Figure 15.57. Block diagram of the VI you will create during this activity


2.

Obtain the VI's Panel reference and then obtain the Controls[] property, which is an array of references to controls on the front panel.

3.

Pass these control references into a For Loop and check whether the reference belongs to a control (not an indicator, because we do not want to disable indicators) and is not already disabled. If these conditions are met, then disable the control and build an array that is stored in a shift register. This array will store all of the controls that we have disabled.

Run your VI and press the generate waveform button. Watch the controls become grayed out while data is being generated and become re-enabled after the data generation is complete. Add more controls and indicators to the front panel and see that any control will be disabledyou don't have to write any additional code to handle the new controls!

Control Reference Types: The VI Server Class Hierarchy

When you configure a Property Node that is linked to a control, you might have noticed that there are horizontal dividers that group the various properties (the same is true of the grouping of the methods on Invoke Nodes). You will also notice that the top three groups of properties are common to all control types, but the groups below the first three depend on the specific type of control.

For example, Figure 15.58 shows the difference between the properties available for a generic control (left), a string control (middle), and a Boolean control (right). Note that all of these property lists have the top three groups of properties in common. However, the string control and Boolean control each have an additional group of properties that are specific to the string and the Boolean. This last group of properties is what makes them different from other types of controls.

Figure 15.58. Different control types add special properties to the "base" set of control properties common to all control types


Figure 15.58 highlights another important concept. When you access the properties of a control using a generic control reference, you cannot access any of the properties specific to a certain type of control. This concept is similar in nature to the example we saw in the last section where the Value property read from a generic control is a variant (generic) data type. If we do not know what type of control we might be accessing the properties of, the list of properties available to us can contain only those properties that are common to all control types.

However, this does not mean that we cannot access those specific properties. We can first read the Class Name property to determine which specific type of control is contained in a generic control reference (as we read the Indicator property to select only controls in Figure 15.58). By reading the Class Name property to determine the specific type of control, we can then intelligently convert a generic control reference to the appropriate more specific type of control reference.

Figure 15.59 shows an example of this technique. Note that we first check to see if the control's Class Name property is "String." Then we use the To More Specific Class function to convert the generic control reference to a control reference of type String. Using the String control reference, we can access properties and methods that are specific to string controls, such as the Vertical Scrollbar Visible property.

Figure 15.59. Intelligently converting a control reference type from generically typed to more specifically typed, in order to access specific control properties


The To More Specific Class function (see Figure 15.60) is used to convert a control reference to a more specific type. If the conversion is invalid, this function will return an error (which we neglected in the diagram shown in Figure 15.59 for the sake of simplicity, but at our peril). For example, if you read the Class Name property and find that the control is a Boolean type, and then you try to use To More Specific Class to convert the control reference to a String type, an error will result because the operation cannot be performedyou cannot convert a Boolean control's reference into a String typed reference.

Figure 15.60. To More Specific Class


The To More Specific Class function needs to know which class to convert our reference into. To specify this, we wire a Class Specifier Constant (Figure 15.61) to the target class input of the To More Specific Class function. This will define the type of the specific class reference output. This concept is very similar to how both the Unflatten From String and Variant to Data functions each convert generically typed LabVIEW data into specifically typed LabVIEW data. (And, note that these two functions also have type inputs.)

Figure 15.61. Class Specifier Constant


Mouse-click on the Class Specifier Constant using the Operating tool to select the class for the Class Specifier Constant. (You can also select a class from the Select VI Server Class pop-up submenu.) As you can see in Figure 15.62, the String class can be found at the following submenu: Generic>>GObject>>Control>>String.

Figure 15.62. Setting the type of a Class Specifier Constant to a String control type


This menu structure of control types is organized in a class inheritance hierarchy. This is just a fancy way of saying that a String is a specific type of Control, which is a specific type of GObject, which is a specific type of Generic. As we drill down the menu, we are getting more specific, and as we move up the menu, we are getting more generic (less specific).

Conversion of control references to more generic types can be done using the To More Generic Class function. This works in exactly the same way as the To More Specific Class function with the exception that To More Generic Class does not have an error input or output (see Figure 15.63). Conversion to a more generic type always worksthere is no way to make a mistake. (Well, really all the mistakes can be caught while you're wiring, because the LabVIEW editor will enforce the rules. Try to convert a Boolean control reference into a Panel control reference and you'll get broken wires.) For example, the statements "a Boolean control is a control" and "a string control is a control" are always correct. Boolean and string controls, are by definition, controls. However, the statement "a control is a Boolean" makes sense if, and only if, the control actually is a Boolean control. There is a possibility that it is another type of control, so we must be careful when converting to more specific classes and always check the Class Name property before performing the conversion.

Figure 15.63. To More Generic Class


Conversion of specific control reference types to more generic control reference types does not need to be done explicitly using the To More Generic Class function. This conversion can also be done using the coercion feature of LabVIEW. For example, Figure 15.64 shows how we can wire two VI Server Reference nodes, which are linked to specific controls on the front panel, into a Build Array node. The wire types of the Boolean and string references are different but, since String and Boolean are each a different type of Control, the Build Array node coerces the reference types to the more generic Control type. Note the coercion dots on the Build Array function's input terminals. This is where the specific control references are being converted to generic control references. (The coercion is always to the most specific class that is common to all the elements.)

Figure 15.64. Building an array of different, specific control references results in an array of generic control references


This is similar to how the Controls[] property of a VI's Panel outputs an array of generic control references (which you saw earlier in the "Obtaining References to All Controls on a Front Panel" section of this chapter).


We can configure a Control Refnum (Modern>>Refnum palette) on the front panel to be specifically typed in the same way that we configured the type of the Class Specifier Constant. Pop up on a control reference control or indicator and select a class type from the Select VI Server Class submenu. When you change the class type, the control reference will change its appearance to reflect the control type, as shown in Figure 15.65.

Figure 15.65. Several Control Refnums of different types shown on a front panel


The Value Property (Is Evil): The Worst Kind of Global Variables

Yes, the value of a control is, technically speaking, a property of the controlbut you should try to avoid reading or writing to the Value property. The first reason is that it is much slower than passing data by wire to a control's terminal or local variable. But another, and possibly more important, reason to avoid using the Value property, is that it causes all of the benefits of data flow to be lost (and we chose LabVIEW for the benefits of data flow)! And, yes, we do remember that locals and globals also subvert data flow.

When we use control references as a way to get and set the value of controls in our application, we are simply using an insidious form of global variable (and the haphazard use of global variables is not recommended). But using control references in this way is far worse than using regular global variables because there is no way to know where the read or write operations are occurring in the codethey could be happening anywhere in your application. At least with global variables, we can find the global referencesthe locations where the global variables are placed on the block diagram. (Well, strictly speaking, we could use the Find>>References pop up on the control and trace the wires to the offending Property Nodes, but that is no trivial task.)

Generally speaking, the standards for acceptable use of globals also apply to the use of the Value property. An additional acceptable use of the Value property is in the initialization of control and indicator values at application startup (and resetting them at shutdown).

The Value (Signaling) Property: Generating Value Changed Events Programmatically

In addition to the Value property, all controls have a Value (Signaling) property. The two are identical with the exception that writing to the Value (Signaling) property also generates a Value Change event that can be captured by an Event Structure (which you learned about in Chapter 12), just as if the user had interactively changed the value of the control on the front panel.

It is recommended that you use the Value (Signaling) property only when you need to generate an event in response to a programmatic value change, just as if the user had changed the value on the front panel.


Activity 15-9: Building an Emergency Abort Utility

When debugging an application, sometimes you will get yourself into situations where you cannot access the Abort button to stop the application. In fact, you may have already found yourself in such situations.

You will now build Emergency Abort VIs, a utility that uses VI Server to abort all VIs in memory that are running top-level.

1.

Open a new VI and build the block diagram shown in Figure 15.66.

Figure 15.66. Block diagram of the VI you will create during this activity


2.

Open the VI Properties dialog for this VI (from the File>>VI Properties menu item or the shortcut key <ctrl-I> [Windows], <command-I> [Mac OS X], or <meta-I> [Linux]), select the Execution category (drop-down list), and enable (check) the Run when opened checkbox.

3.

Save this VI as Emergency Abort VIs.vi in your MYWORK directory.

4.

Test your VI by first closing it, and then opening it again by double-clicking it from the desktop. LabVIEW automatically runs your VI, due to the Run when opened setting, and aborts all running VIs. Test Emergency Abort.vi again, but with other VIs running. Notice how the running VIs stop running.

When you get yourself into a jam and you cannot abort your application, often you will not be able to access the File>>Open menu option from any of your VIs. In this case, you will need to run Emergency Abort.vi by double-clicking it from File Explorer (Windows) or Finder (Mac OS X). On Linux, you will need to run the VI from the command line using the following commands:

cd "<folder containing emergency abort VI>" /usr/local/lv80/labview -launch " Emergency Abort.vi " 



Note that your LabVIEW install path might differ. Also note that the use of the launch option causes LabVIEW to check for an existing LabVIEW application instance already running on the same display. If an existing instance is running, the existing instance opens the VIs passed in the command line, and the new application instance quits silently. If an existing instance is not running, LabVIEW opens the VIs passed in the command line in the new instance.


Final Thoughts on VI Server

As we mentioned at the beginning of this section, don't worry too much if the VI Server seems perplexing or overwhelmingit's unlike anything you've encountered in LabVIEW before, and it breaks all the normal rules of how LabVIEW VIs interact with each other. Once you get comfortable with LabVIEW programming, you can always return to explore the numerous VI Server examples built into LabVIEW.




LabVIEW for Everyone. Graphical Programming Made Easy and Fun
LabVIEW for Everyone: Graphical Programming Made Easy and Fun (3rd Edition)
ISBN: 0131856723
EAN: 2147483647
Year: 2006
Pages: 294

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net