Getting Started with Labview Joseph Vignola, John Judge and Patrick O’Malley Spring 2010 2 Introduction In ME 392 we’ll use the PCs in the lab to acquire data from experiments, and, in some cases, to control experiments as well. There are a variety of computer codes that can allow computers to interface with experimental hardware; some companies or laboratories use custom codes of their own, others use commercially available software. The software we’ll be using is called LabVIEW, which is one of the more common commercial packages. The goal of using LabVIEW in ME 392 is to give you a little experience using LabVIEW itself (since it is a commonly used program) but mainly to give you an idea of how to use computers in general when performing laboratory work, so that you can be a proficient experimentalist no matter what software you may find yourself using in the future. The “textbook” for the course is LabVIEW 2009 Student Edition (ISBN 0132141299) by R. H. Bishop. This book provides 700-some pages of introduction to using this particular software, and is available both as a book alone and in a bundle that includes the student edition of the software. 3 4 Chapter 1 The Basic Idea LabVIEW is a software package/programming language designed for interacting with laboratory equipment. This software lets a user communicate from a PC to a wide variety of devices used in modern labs. There are Windows and Mac versions of LabVIEW, which is published by National Instruments (NI). The Lego Mindstorms software (both the original Robolab and the newer Mindstorms NXT) is based on LabVIEW, and in some ways the programs are similar. The PCs in the laboratory each have National Instruments data acquisition cards (NI-DAQ) installed, which allow them to communicate with external sensors and actuators. Many external instruments can also be controlled by LabVIEW using a GPIB (General-Purpose Interface Bus) card; one of these is installed in the PC in the back half of Pangborn B16 and used to control a variety of instruments used in experiments with the five-axis robotic scanning laser vibrometry system. These instruments include function generators, oscilloscopes, spectrum analyzers, and lock-in amplifiers. However, the power of LabVIEW is that many of the functions of such devices can be duplicated in software so that sophisticated experiments can be done with a minimum of expensive external hardware. For example, you can use LabVIEW to create a “virtual oscilloscope” that appears on the computer screen and has all the same functions as an actual, physical oscilloscope. 1.1 Two-window Programming LabVIEW is a graphical programming language. Each program is a “VI,” short for virtual instrument (not the Roman numeral representation for the number 6). You work from two windows. One window is the block diagram, which looks like a schematic wiring diagram or flow chart. In this window you build the logical flow of your VI by connection icons using lines that represent wire. A block diagram represents the “guts” of the VI: the internal circuitry of your “virtual instrument.” The other window is the front panel. The front panel 5 6 CHAPTER 1. THE BASIC IDEA is a display that you design, and can look like the front panel of an electrical instrument, the dashboard of a car, or the control panel of a video game. Once you’ve finished creating a VI, you (or any other user of your VI) need only interact with front panel to use the VI. Once you have made a VI it can also be used as a subVI or module by other VIs. When you first run the LabVIEW application, the “Getting Started” window, shown in Fig 1.1, appears. Click on “Blank VI” to open a new VI and empty front panel and block diagram windows will appear, as shown in Fig. 1.2. If you open an existing VI (from the “open panel” of the “Getting Started” window, or by finding and clicking on the icon for the existing VI using the computer’s operating system) you will only seen the front panel. You can open the block diagram using the “Window” pull down menu. Figure 1.1: The “Getting Started” window that appears after LabVIEW is started. This window can also be opened using the “view” pull-down menu. (a) Front Panel (b) Block Diagram Figure 1.2: A new vi 1.2. MENUS, TOOLBARS, AND PALETTES 1.1.1 7 Front Panel LabVIEW has a vast collection of controls and indicators you can choose from to build your virtual instruments. The front panel is where a user turns components on or off, changes experimental parameters, and where the VI displays measured operating conditions and data. LabVIEW controls are pictures of controls that you are familiar with like switches, knobs, buttons and dials. By clicking or moving the mouse on these controls the user can change settings while the program is running. Some controls are set by typing text or numbers into a box. All controls have some feedback to show the user the state they are in. It is possible for the programmer to set things up so that the system prevents a control parameter from being set to an invalid setting (or controls what happens when an invalid setting is attempted). For example, if you don’t want a user to set a certain voltage higher than 5, you can prevent that outright, or you can create an error message, have the computer make an alert noise, etc. Indicators provide information to the user and can take many forms. These include flashing LED indicators, numerical or character displays, bar level indicators, etc. Indicators might look like familiar objects like mercury thermometers, speedometers, voltmeters or the screen of an oscilloscope. 1.1.2 Block Diagram A block diagram represents the insides of an instrument you are constructing. Block diagrams can look very messy and complex, but can be kept more simple and orderly by creating program hierarchies, in which one VI calls others rather than performing all functions itself. Every element of the VI you are constructing has an icon and each of these icons are connected by different color lines representing wires or data streams. Control and indicator components appear in both the block diagram and the front panel (although, if desired, they can be hidden in the front panel). In the front panel, they appear as the desired control or indicator graphic, while in the block diagram, they are represented by an icon surrounded by a double line. The block diagram also contains programming structures such as if-else and loops that are familiar from other text-based programming languages, along with functions for mathematical operations, data acquisition, timing and others. 1.2 Menus, Toolbars, and Palettes The front panel has seven pull down menus and eleven pushbuttons at the top of the window, see Fig. 1.2a. The block diagram has the same seven pull down menus as the front panel and fifteen pushbuttons (eleven that are also on the front panel, and four more “debugging” buttons), see Fig. 1.2b. The functions of the pushbuttons are common commands for executing the code or formatting and arranging objects in the widow, and they are described in Section 1.5 of Bishop and are summarized briefly in Table 1.1 on page 9. The pull-down menus are not unlike menus in many other applications. They provide a wide array of 8 CHAPTER 1. THE BASIC IDEA (a) Tools (b) Controls (c) Functions Figure 1.3: Palettes for selecting cursor tools, front panel controls, and block diagram functions. options, and a brief description of each menu is given in Section 1.7 of Bishop. Additionally, pop-up menus are available by right-clicking on items in the front panel or the block diagram, and descriptions of the options available in the pop-up menus are available in Section 1.6 of Bishop. There are three palettes, described in Section 1.8 of Bishop, that contain various tools and objects used to create a VI. The tools palette has different options for the mouse cursor: each one allows you to do something different by pointing and clicking the mouse. In general, you can leave the “Automatic Tool Selection” button on, so that LabVIEW will change the cursor for you to be appropriate for whatever item you point at on the screen. The controls palette can be visible only when you are programming in the front panel window: it contains nested menus of all the possible controls, indicators, structures, and decorations that you can place in the front panel. The functions palette is visible only when the block diagram window is selected, and contains nested menus of functions, subroutines, programming structures, and constants that can be used in the block diagram. For both controls and functions palettes, there are several different “View” options available, which simply alter the way you navigate through the nested menus. 1.2. MENUS, TOOLBARS, AND PALETTES Table 1.1: Front Panel and Block Diagram pushbuttons. Execution buttons Run Executes VI once (changes during execution) Run continuously Executes VI repeatedly Abort Abruptly stops VI Pause Stops and restart VI from stopping point Appearance editing buttons Text Settings Format text objects (font, style, justification, etc.) Align Objects on the front panel Distribute Objects adjusts the spacing between objects Resize Objects adjusts the sizes of objects Reorder adjusts which objects appear “on top” when objects overlap on the screen Debugging buttons Highlight Execution Turns on “slow motion” execution so you can watch the flow of the program Retain wire values allows you to probe wires after execution has finished to find out most recent data values Step Into Move into a programming element to observe its operation step-by-step Step Over Execute an entire programming element without going through it step-by-step Step Out Immediately finish remainder of the element you were previously stepping through Other buttons Context Help Opens and closes the context help window. Block Diagram Cleanup attempts an automatic cleanup of the block diagram. Icon Editor Allows you to customize the icon for the VI, in case you use it as a subVI in another VI (may look different) 9 10 1.3 CHAPTER 1. THE BASIC IDEA Basic Programming Concepts Let’s perform a basic task: we’ll add two numbers. In the Functions palette, select the “Programming” menu and then the “Numeric” submenu, and drag the “Add” function into the block diagram. You need to send two numbers into the Add function, as shown at in Figure 1.4. For now, you can create these numbers either by right-clicking the edge of the Add triangle and selecting Create > Constant, or you can find a numeric constant in the Functions palette near the bottom of the Programming > Numeric menu. You can change the number by clicking in the constant box and typing a new number. When we execute the code, we need to display the answer somewhere: create an indicator that will show up in both the block diagram and front panel. To do this, you can right-click the right corner of the Add triangle and select Create > Indicator, or you can switch to the front panel window and find Figure 1.4: Adding a numeric indicator icon in the Controls palette under Modern > Numeric. The program above adds two constants, but you’d need to modify the code by clicking in the block diagram to change those constants if you wanted to add different numbers. If you replace the constants with controls, you’ll be able to alter the numbers in the front panel, without needing to modify the block diagram each time the program is run. To do this, right-click either or both of the numeric constants and select “Change to Control.” Figure 1.5 shows a simple block diagram and front panel for a VI that reads a temperature and can display the result in Fahrenheit or Celsius. You can do a search for the “Digital Thermometer.vi” program and open it to explore how this VI works. The front panel contains one control (a switch to select F or C) and one indicator (a gauge and numerical readout for the Temperature). The same two objects, labeled “Mode” and “Temperature,” appear in the block diagram, but they are connected to wires that carry information along as the VI executes. 1.4 Data Types In LabVIEW, as with MATLAB and other programming languages, values must be of a certain data type. In LabVIEW, the data type is generally readily identified by the color and style of the wire on the block diagram. Boolean values can carry true or false. They are represented on the block diagram by a green dotted line. Integers are represented by thin blue lines. Signed and unsigned integers come in 8-,16-,32-, and 64-bit sizes. The default is 32-bit signed. Real and Complex numbers are both represented by orange lines. Both real and complex sizes available are double- (the default), single-,and extended-precision. Real numbers also have a fixed-precision option. Strings contain alpha-numeric characters and are represented by thin pink lines. 1.4. DATA TYPES 11 (a) Front Panel (b) Block Diagram Figure 1.5: front panel and block diagram windows for a simple VI. 12 1.5 CHAPTER 1. THE BASIC IDEA Order of Execution The sequence of events, is typically a primary concern in a VI. In most programming environments (such as Matlab, Fortran, C++, etc.) the order of execution flows from the sequence of text commands in the code (with “if” statements and “for” and “while” loops capable of changing the sequence of events). The sequence of events in LabVIEW is a bit different and is dictated by the block diagram. A dataflow is established from icon to icon and an item is executed when all its inputs are available, that is, when all incoming wires are carrying the necessary information. This can leave some ambiguity in the order items are executed, and even implies that certain operations might be executed simultaneously (which is not precisely true). Careful layout of the block diagram can make it easier to ensure that items are executed in the desired order: think of the block diagram like a flowchart, where the flow of information from one icon to the next dictates the order in which the icons items are executed. The sequence of events tends to run left to right across the block diagram (there is no hard rule that the sequence of events must proceed from left to right, but most icons have inputs on the left and outputs on the right). To illustrate this idea, say we need a vi that has two indicator lights (call them A and B) and we need Light B to go on two seconds after Light A. To do this, we can drop two round LEDs (Controls > Modern > Boolean) onto our front panel. The front panel should look like Figure 1.6. On the block diagram, wire them with “True” constants (Programming > Boolean). We also need our delay function (Programming > Timing > Wait (ms)) with an input of 2000. Now the block diagram should look like Figure 1.7a. When this VI is run, you will notice that both lights go on at the same time, followed by a two second delay. This illustrates the point that even though the block diagram elements are laid out left to right, they are not executed left to right. Figure 1.6: Front Panel To correct this problem, we need a “Sequence,” which acts (and looks) like a filmstrip, executing frames sequentially. You can drop a sequence (Programming > Structures > Flat Sequence) on the block diagram and then drag the true constant and “A” indicator into it. To add a second frame, right-click on the border and choose “Add Frame After.” Drag in the delay, and add another frame for the “B” indicator. Your block diagram should now look like Figure 1.6b. To test it out, you’ll need to first go to the front panel and switch off the indicators by clicking them (they were left in the on state after the last run) and run the VI. You should now get the behavior we expected; light A goes on, then a two second delay, then light B goes on. 1.6. PROGRAMMING STRUCTURES 13 (a) Arbitrary Order (b) Defined Order Figure 1.6: Simple VI illustrating execution order 1.6 Programming Structures Many of the programming concepts you are already familiar with from MATLAB or other text-based languages are also found in LabVIEW. You can place an “if”, “for”, “while” loop or other programming structure in the block diagram by right clicking on the background on the block diagram and selecting “structures” in the functions palette and then whatever structure you need. Use the mouse to drag the structure to where you need it to be on the block diagram and to stretch the loop to the desired size. 1.6.1 Conditionals if-else The simplest form of the conditional is the if-else statement. LabVIEW implements this feature using a “Case Structure.” When dropped on the block diagram the case structure is set up to accept a boolean input to the connector on the outside of the rectangle. Clicking the right and left arrows on the top of the rectangle will toggle between true and false cases, only one of which will be executed depending on the value of the input. Figure 1.7 shows an example of a boolean case structure. switch The switch-type conditional also uses the case structure in LabVIEW, but takes a different input. The case structure can accept not only boolean values, but also strings and integers and error clusters. When you wire a nonboolean type to the input connector, you will be able to add additional cases to your case structure. If you wired an integer, for example, you could have a case for each possible integer if you needed. In general, however, there would only be 14 CHAPTER 1. THE BASIC IDEA if x ≥ 5, st = 'x is greater than or equal to 5'; else st = 'x is less than 5'; end msgbox(st) (a) Matlab (b) LabVIEW, True Case (c) LabVIEW, False Case Figure 1.7: A boolean case structure a few integers that you would be interested in matching and the rest you don’t care about. For non-boolean type inputs, there is a special designation you can put into the case selector named “Default” which will match any possibilities that you did not already specify. Note that for non-boolean type case structures, you must specify at least one default case. An example of an integer input to a case structure is shown in Figure 1.8. switch x case 0, case 1, case 2, otherwise, end msgbox(st) st st st st = = = = 'x 'x 'x 'x is is is is 0'; 1'; 2'; not 0,1,2'; (a) Matlab (b) LabVIEW, Case 0 (c) LabVIEW, Case 1 (d) LabVIEW, Case 2 (e) LabVIEW, Default Case Figure 1.8: A case structure with integer input 1.6.2 Looping Count-Controlled (“For”) Loops A “for” loop executes sequence of steps repeated a defined number of times. The number of times loop should be ex- 1.6. PROGRAMMING STRUCTURES 15 ecuted is fed to the icon. Sometimes, it is desirable to be able to “break” a for loop. To do this, drop a for loop on the block diagram, right click on its border and choose “Add conditional terminal.” This conditional terminal accepts a boolean value that instructs the for loop to execute the next iteration or break the loop without executing the next iterations. Sample for loops are shown in Figure 1.9. (a) For loop (b) Conditional Terminal Figure 1.9: For loops, without and with a conditional terminal. Condition-Controlled (“While”) Loops A “while” loop executes a sequence of steps repeated over and over while a condition is meet. The icon feeds out the number times the loop has been executed (it starts counting at zero) The condition is defined in the lower right corner of the while loop using this . This icon represents the “stop if true” condition. The condition can be changed by right clicking and selecting something else (select “continue if true” and the icon will change to ). A simple while loop is shown in Figure 1.10. while now < datenum(2010,4,1) end (a) Matlab (b) LabVIEW Figure 1.10: A simple while loop that will run until April 1, 2010 Shift registers Shift registers are used in “for” and “while” loops to hold a value from one loop iteration to the next. This is useful if you need the result from one iteration when performing the same operation the next time around. For example, we can use a “for loop” with shift registers to calculate the factorial 16 CHAPTER 1. THE BASIC IDEA of a number. The loop in Fig. 1.11 is run a number of times controlled by the input number. On the first time through, the constant “1” is multiplied by the because LabVIEW iteration number (one must be added to the result of starts counting iterations at zero). The second time through, however, the result of the previous calculation (in this case “1”) comes through the shift register and is multiplied by the iteration number. The result of this is “2,” which then passes through the shift register to be used in the third iteration and so on. Figure 1.11: Simple program to compute the factorial of a number Try using multiple shift registers to create a program to calculate Fibonacci numbers (the sequence 0,1,1,2,3,5,8,13,21,34,. . . ). Fibonacci numbers follow this rule: if n = 0 0 1 if n = 1 F (n) = F (n − 1) + F (n − 2) if n ≥ 2 1.7 An Example VI There are many example VIs you can look at that should be loaded on the lab computers. You can find them on the “open” panel of the “getting starting” window or browsing from the panel. These examples give the opportunity to see how LabVIEW handles familiar programming structures like “for” and “while” loops, “if” statements, and subroutines. The VI shown in Fig. 1.12 shows how LabVIEW handles familiar programming structures like “for” and “while” loops, “if” statements, and subroutines. Each of these can be seen in the “Temperature System Demo” which you can open from the “getting started” window. Figure 1.12 shows the front panel of this VI. The program is executed from the front panel by pressing the run button ( ) on the tool bar. Once you have started the VI with the run button you can start and stop the measurement process with the “Acquisition” toggle switch. The program plots made-up temperature data (there is no real temperature sensor in the system) as a function of time. The temperature is measured, or sampled, at even intervals of time set by the user by adjusting the slider next to the “system control” box. If you play with this VI from the front panel for a few minutes you’ll figure out what the program does. 1.7. AN EXAMPLE VI 17 (a) Front Panel (b) Block Diagram Figure 1.12: Front panel and block diagram windows for ”Temperature System Demo” VI. 18 1.8 CHAPTER 1. THE BASIC IDEA Common Block Diagram Elements The next several pages list common elements in the block diagram. The first table lists the representation on the block diagram of controls and indicators that also appear in the front panel, which varies in color depending on the type of data coming from the control or going to the indicator. The next table shows a variety of common objects, including different wire types and programming structures. The final table shows a few example programming constructs. Figure 1.13: Data format of controls and indicators based on color in the block diagram 1.9 Debugging Tools Highlight execution Build the VI you see in Fig 1.14 and run it a few times. Change parameters of the Express VI by double clicking the Express VI. Change the function so that the number of samples is not automatic and set it to 90. 1.9. DEBUGGING TOOLS 19 Table 1.2: Some common block diagram elements. Wires Thin lines Scalar wires, passing one thing at a time Thicker lines One dimensional array wires, passing an 1D array or vector of information Double lines Two dimensional array wires, passing a 2D array or matrix of information Dynamic data type wire For use with certain Express VIs Broken wire This is an indication that there is a problem with the wire. Put the cursor on the wire to get help. Thick dotted line A cable that carries a number of things bundled together in a cluster Double lined boxes Things that appear in both the front panel and block diagram. Numeric Constants Wait function The scalar input is the time in milliseconds. Random number generator Generates a random number between 0 and 1 , Text labels 20 CHAPTER 1. THE BASIC IDEA Table 1.3: A few simple programming examples Wait 500 milliseconds before proceeding to the next iteration of the loop Run through the loop 12 times, and at each time, wait a number seconds between iterations based on an input from the front panel. Run through the loop 12 times, wait 0 seconds during the first time through the loop, 1 second during the second, two seconds during the third, etc. 1.9. DEBUGGING TOOLS 21 (a) Block Diagram (b) Front Panel Figure 1.14: An example for using the debugging tools. 22 CHAPTER 1. THE BASIC IDEA Use the highlight execution function by clicking on the icon on the tool bar of the block diagram so it turns and run the VI. This is a good way to understand the flow in data within a VI. Single stepping The single stepping feature that let you walk thought a VI one step at a time. You can single step with the highlight execution on or off. Probe You can make a probe on a wire by right clicking on a wire and selecting . When “probe”. You will see a number appear on the wire like this: you single step through the VI, you can see the values on the wire change in the probe watch window. Breakpoint tool You can put a breakpoint on a wire to define a place to pause in the execution on the VI. Insert a breakpoint by right clicking on a wire and selecting “set breakpoint.” Debugging example Open “Debug Exercise (Main)” and be certain you have the windows shown in Fig. 1.15 If you try to run the VI you will notice that the run button appears broken and the VI will not run. In the block diagram you will notice that one of the wires has a red on it indicating a problem. The green subVI should add 100 to the input and output the square root of the sum. Try to find the three errors by clicking the broken run button. You will see the error list will appear after you try to run the VI. (a) Front Panel (b) Block Diagram Figure 1.15: Debug Exercise (Main).vi. 1.10. SUBVIS 1.10 23 SubVIs In LabVIEW subroutines are referred to as subVIs. Any existing VI can be configured for use as a subVI. The “Temperature System Demo” example has icon in the “for” many subVIs. To see an example, double click on the loop and the front panel of this subVI will appear. You can open the block diagram for this subVI using the window pull down menu. This subVI has its own subVIs, (click to see an example). There are two major advantages to making sub-vis. First, they can make your code more readable. For set of code that performs a single action, such as the factorial example above, it is convenient in the main program to see a single icon representing a factorial, rather than the for loop. Secondly, sub-vis allow you to re-use code without having to recreate it on the block diagram. Again using the factorial example, if you needed to take the factorial several times in your program, it would be cumbersome to reproduce the for loop every time. It is much easier to have the factorial be represented by a single icon. Let’s take our factorial code and convert it into a sub-vi. The easiest way to do this is to select the code (by clicking and dragging the rectangular box) that you would like to make into a sub-vi. In this case, since we only have the factorial right now, select the entire code, as in Figure 2.2a. Then, go to Edit > Create SubVI... LabVIEW will automatically put the selected code into a new vi (the sub-vi) and replace what you had with the icon for the sub-vi, as shown in Figure 2.2b. Note what happened, the original input and output to the loop have become inputs and outputs to the sub-vi. You can double-click the sub-vi to show its front panel and block diagram. If you right click on its icon, and select “Show Connector...” You can see that there are two blue rectangles , Figure 1.16: How to show the connector for a sub-vi. indicating that the terminal is wired to accept an integer input and pass an integer output. If you click on the left blue rectangle, you will see the “Input Number” control highlighted, indicating that whatever is connected to the left terminal will be passed to this control. Similarly, clicking on the right blue rectangle will highlight the “Factorial” indicator, meaning that whatever value ends up in this indicator will be passed out of the sub-vi through this terminal. 24 CHAPTER 1. THE BASIC IDEA (a) Selecting the code (b) The vi after creating the sub Figure 1.17: Creating a sub-vi. If you like, you can edit the default icon that is created by right-clicking on the icon in the sub-vi and choosing “Edit Icon...” You will then need to save the sub-vi. Once you have a saved sub-vi, you can drop a second instance on the block diagram by right-clicking on the block diagram and selecting “Select a VI...” or simply dragging its icon onto the main block diagram. 1.11 Script and Formula Nodes In some cases, it is simpler to perform mathematical operations using a textbased editor, rather than a graphical one. There are several ways to accomplish this in LabVIEW. Formula node One of the structures shown in the tables above is the formula node, which can be found in the function palette under Programming > Structures (or under Mathematics > Scripts & Formulas). The code shown at right performs the exact same function as the very first addition example we did, but in a more traditional, text-based way. Building this is a little more cumbersome for simple operations, since it requires right clicking the edges of the formula node to create various inputs and outputs. If the math you want to do is not very simple, however, the formula node may be a quicker way to accomplish it than wiring together a large number of “Add,” “Multiply,” “Subtract,” etc. blocks. Figure 1.18: A formula node. 1.12. EXPRESS VIS 25 MATLAB script node There is an additional VI called the “MATLAB script node” that is similar to the formula node, which we can use to perform calculations using the MATLAB software if it is also installed on the same computer. To open a Matlab script node, type “Matlab” in the search box of the function palette. (or, from the function palette, open “Mathematics” > “Scripts & Formulas” > “Script Nodes”.) To make an input or output to the Matlab script node, right-click the edge of the gray box and select “add input” or “add output,” and a small box will appear on the edge. Once the box appears you must define the type of variable that box represents. You do this by right clicking the box and selection the “choose data type”. There is one other important issue: you MUST save a VI containing a Matlab script node before running it. (a) Palette (b) Block Diagram Figure 1.19: The path to find the Matlab script node is shown with an example. The icon between the Matlab script node and the waveform graph bundles data of different types into a specific kind of cluster referred to as “waveform data”. 1.12 Express VIs Some of the more sophisticated commands in the controls and functions palettes are called “Express VIs.” These are subroutines for performing certain tasks in a streamlined way. The Express VIs are light blue in color and typically feature one or many options that can be set either using pop-up dialog boxes or menus accessible by double-clicking the Express VI icon. For example, the Formula Express VI brings up a “Configure Formula” window that allows you to create a formula in a little more streamlined way than the simple Formula node. Fig. 9 below shows this configuration window, as well as how the Express VI icon 26 CHAPTER 1. THE BASIC IDEA can be expanded to show various inputs and outputs once it is configured. Figure 1.20: Formula Express VI, and its configuration window. Try the following Exercises 1. Construct a VI to turn on a square light indicator on the front panel whenever a round push-button control on the front panel is pressed. (E2.2 in the Bishop). 2. Create a VI that compares the inputs from two numeric controls and turns on an LED indicator if the values are equal (E2.5 in Bishop). 3. Create a VI that uses a “for” loop to generate 100 random numbers. At each iteration, determine the maximum and minimum of all numbers so far, and display these on the front panel, along with the current random number. Include a “wait” of 100 msec or so in each iteration of the loop so that the program runs slowly enough for you to observe the changes in the maximum and minimum as the iterations progress. 4. Make the simple calculator shown in Fig. P1 and make sure it works with different numbers at the inputs. Try making it with these script node. and then try it again using a math Use the “alignment” push button to straighten things up. Add an “if” statement that makes a light come on if x+y is more then 13 Add a dial input, with a range form 50 to 100, that generates one of the inputs numbers. Add a gauge to display the output in addition to the numeric indicator. 5. Create a subVI that multiplexes four inputs into a single output. The subVI should have four floating-point (DBL) numeric controls (“In”1 through “In4”), one floating point numeric indicator (“Out”), and one unsigned 8-bit integer control (“Select”). If Select=1, then Out=In1; if Select=2 then Out=In2 and so on. You should make two different versions of this subVI. In the first, use the “Select” function from the Programming >> Comparison palette. In this case, make sure that the user entering a value other than 1-4 in the “Select” control is either handled or not possible. 27 28 For the second version of this subVI, use an Enumerated integer control (Controls >> Modern >> Ring and Enum >> Enum) as your “Select” input and use a case structure to select the output. Make sure to test both subVIs by placing the sub in a main VI an wiring all the inputs. Make sure to create an icon for your subVI. (Adapted from P4.3 in Bishop) Figure P1: Simple Calculator 29 Figure P2: Calculator with more indicators. 30 Chapter 2 Working with collections of data There are a number of different ways multiple pieces of information can be grouped together in LabVIEW. Data of the same type can be assembled into arrays of one or more dimension, while data of different types can be bundled together in clusters. These groups are described in detail in Chapter 6 of Bishop, and introduced briefly below. There are also several more advanced wire types specifically designed to handle the sort of data generated in an experiment. 2.1 Arrays Arrays are groups of data of the same type. A one-dimensional (“1D”) array is a group of data arranged in a row or column (a vector). A two-dimensional array is a collection of one-dimensional arrays of the same length arranged side by side or one atop the others, essentially forming a matrix. Arrays can be composed of integer, real, complex, boolean, string, waveform and cluster data types (and perhaps still others). Indexing of arrays in LabVIEW starts from zero: the first element in an array is referred to as the “zeroth” the second is the “first,” etc., so that if there are eight elements in an array, the index for the last one is element seven. To make an array, you begin with an array shell and then add a single item of the type the array will be filled with. On the front panel, you can use the Controls palette, enter the Modern > Array, Matrix & Cluster menu and select “Array”. This shell can hold any sort of control or indicator. You can create an array constant by going to the block diagram, using the Functions palette, and selecting Programming > Array > Array Constant, and then filling it with whatever sort of constant you wish (numeric, boolean, string, etc.). 31 32 CHAPTER 2. WORKING WITH COLLECTIONS OF DATA Collection-Controlled (“Foreach” or “Auto-Indexed”) Loops Another way to use for loops is to pass an array which “Auto Indexes” the loop. An example of this is shown in Figure 3.1. Each time through the loop, the i-th element of the input array will be passed along the wire. Figure 2.1: Auto-Indexed For loop. Note that if 5,3,6,1,8 were replaced with 0,1,2,3,4, this loop would behave the same as Figure 1.9a Auto-Indexed Tunnels Auto Indexed tunnels can be used on the output side of the loop as well. In many cases, as with the factorial example, we only care about the value after the loop is completed. In some cases, however, it is important to know what the value was after each iteration of the loop. In these cases, an auto-indexed tunnel on the output side assembles information from all iterations of a loop into an array upon completion of the loop. Make the VI shown in Fig. 3.2 to see how scalar data can be pulled from an array and then put back into an array and displayed. Note that the icon in the while loop does not need to be wired: the array enters the structure through an auto-indexing tunnel (it does this by default) so the loop will automatically execute a number of times equal to the size of the array. (a) Front Panel (b) Block Diagram Figure 2.2: Using auto-indexing tunnels with a for loop. 2.1.1 Array Functions Array functions are found in the Functions palette of the block diagram, under Programming > Array. Here are a few: 2.2. CLUSTERS 33 Table 2.1: Array Functions Creates a vector (1D array) of length 50, with 0.0 as the value for all 50 entries in the array. An equivalent MATLAB expression is A=zeros(1,50); Creates a 50 by 10 array with 0.0 as the value for all 500 entries in the array. An equivalent MATLAB expression is A=1.2*ones(50,10); Creates a 50 by 10 by 3 array with 0.0 as the value for all 1500 entries in the array. An equivalent MATLAB expression is A=zeros(50,10,3); Array Size returns a 1D array of integers for the number of elements in each dimension of the array. An equivalent MATLAB expression is size(A); Index array Outputs an individual element or a subset of the array Replace array subset Substitute elements into an array 2.2 Clusters A cluster is a group of data elements that are of different types. Imagine pulling together a green binary wire, a thick orange wire representing a one dimensional array of real numbers and two thin blue wires carrying integers, and wrapping them all into a single cable. Perhaps the most apparent reason to use clusters is that they simplify block diagrams by reducing clutter. A more important reason to use clusters is that they can keep together things that should stay together. For example if you are measuring the temperature in the lab (a real number) once per minute, you may like to keep track of other thing at the same time, such as whether the light or air conditioning is turned on (binary), the number of people in the room (integer), or the names of the people in the room (vector of strings). A cluster lets you group this information together naturally. Different clusters can be bundled together to make bigger clusters. To make a cluster control or indicator on the front panel, select “Cluster” from the Controls palette > Modern > Arrays, Matrix & Cluster menu. Like 34 CHAPTER 2. WORKING WITH COLLECTIONS OF DATA an array, the cluster is comprised of the cluster shell and the individual controls or indicators placed in it. A shell for creating a cluster full of constants in the block diagram can be found in the Functions palette > Programming > Cluster & Variant menu. This menu also contains functions for combining wires into clusters and extracting individual wires again, referred to as bundling and unbundling the wires: If a cluster has more than one wire of the same type, it can be useful to refer to each element by the label of the control or constant that created it. For example, in Fig. 3.3, the input cluster contains three controls, labeled Name, Age, and Height on the front panel, and the second two are the same type, double precision real numbers. If the standard “Unbundle” function is used, distinguishing between the Age and Height wires is problematic, but the “Unbundle By Name” function solves this problem. Figure 2.3: A cluster on the front panel containing three controls (left) and unbundling the three wires with (bottom right) and without (top right) referring to the labels on the controls. 2.3 Waveform Data Type The waveform data type is a type of wire used to carry information about a signal that is sampled at regular intervals in time (or some other independent variable). It is similar to a cluster, but it is hardwired to carry three specific components, named Y, t0, and dt, which store the data, start time, and sample interval (si or ∆t) respectively. The data Y is a 1D or 2D array of numerical values. The sampled interval dt is a single numerical value. The start time t0 contains a “time stamp” object. On the block diagram, the wire for a waveform resembles a pink cluster wire except the color is orange/brown. You can 2.4. DYNAMIC DATA TYPE 35 create a waveform with the Build Waveform function in the Functions palette > Programming > Waveform menu. Many of the VIs and functions you use to acquire or analyze waveforms accept and return waveform data by default. When you wire waveform data to a waveform graph or chart, the graph or chart automatically plots a waveform based on the data, start time, and delta t of the waveform. When you wire an array of waveform data to a waveform graph or chart, the graph or chart automatically plots all waveforms. (Plots and charts can also accept other forms of input, see the section on plotting below). Figure 2.4: The waveform data type. 2.4 Dynamic Data Type Many Express VIs accept and/or return the dynamic data type, which is another cluster-like form. In addition to the data associated with a signal, the dynamic data type includes attributes that provide additional information about the signal, such as the name of the signal and the date and time the data was acquired. You can wire the dynamic data type to most indicators or inputs that accepts numeric, waveform, or Boolean data, such as a graph, chart, or numeric indicators. The additional attributes included in the dynamic data can help specify how the signal appears on a graph or chart. For example, if you use the DAQ Assistant Express VI to acquire a signal and plot that signal on a graph, the name of the signal appears in the plot legend of the graph, and the x-scale adjusts to display timing information associated with the signal in relative or absolute time based on the attributes of the signal. If you use the Spectral Measurements Express VI to perform an FFT analysis on the signal and plot the resulting value on a graph, the x-scale automatically adjusts to plot the signal in the frequency domain based on the attributes of the signal. Right-click a dynamic data type output terminal of a VI or function on the block diagram and select Create > Graph Indicator to display the data in a graph or select Create > Numeric Indicator to display the data in a numeric indicator. Since most other (non-Express) VIs do not accept this data type, you must convert the dynamic data type to something else to use a built-in VI or function to analyze or process the data. The function for this conversion can be found in the Functions paletter > Express > Signal Manipulation menu, and is called Convert from Dynamic Data (“From DDT” for short). It allows you to convert the dynamic data type to a variety of things, including a single waveform data type, an array of multiple waveforms, and 1D and 2D arrays of 36 CHAPTER 2. WORKING WITH COLLECTIONS OF DATA numbers. There is a corresponding “To DDT” that lets you convert these other data types to the dynamic data type for use by Express VIs. Figure 2.5: The dynamic data type. 2.5 Plotting Data There are many different ways to visualize data with LabVIEW. We will start with looking at three ways to create traditional two-dimensional plots (LabVIEW also has means to visualize three dimensional data that we will not cover here). Each of these plotting functions can be added to the front panel from the Modern > Controls menu in the Controls palette (see Fig. 3.6). Charts and graphs are described in Chapter 7 of Bishop. Figure 2.6: The graph menu on the controls palette. 2.5.1 Plotting with the Chart Recorder A waveform chart is a plot that moves along as new data is added like an oldfashioned strip chart recorder. Create the VI in Fig. 3.7 and then explore how it works. Right click on the plot in the front panel and select “Properties”. Find the “Plots” tab and try changing then way the different curves appears. Make visible (by right-clicking the plot and pointing the mouse to the “Visible Items”) the 2.5. PLOTTING DATA (a) Block Diagram 37 (b) Front Panel Figure 2.7: The chart recorder adds data points one at a time and the plot moves to the right. These plots represent the time history of a sequence of discrete measurement (each made at an instant in time) “Plot Legend,” “Scale Legend,” “Graph Palette,” etc., and explore what these additional options can do. 2.5.2 Plotting Data with the Waveform Graph When data is already in the form of an array, it is often best to use the “waveform graph” to plot. The waveform graph assumes that you have collected data with an evenly spaced sampling interval. The waveform graph accepts several data types. If it receives a single array of values, it interprets the data as points on the graph (y values), and uses x values corresponding to the index of the points in the array (that is, the x axis will contain integers 0, 1, 2, 3, 4. . . ). The graph can also be given a cluster containing an initial x value, a delta x, and an array of y data. This same information could be delivered via the waveform data type or the dynamic data type. Recall that, n addition to the data associated with a signal, the dynamic data type includes attributes (such as the name of the signal or the date and time the data was acquired) that specify how the signal appears on the waveform graph. Figure 3.8 shows these four different inputs to the Waveform Graph function. The same waveform graph function can be used to display multiple curves, and there are a variety of ways to accomplish this. If given a 2D array of numerical values, each row of the array is interpreted as data for a single plot (you can right-click the graph, and select Transpose Array from the shortcut menu to handle each column of the array as a single plot instead). The waveform graph also accepts a cluster containing an initial x value, a delta x value, and a 2D array of y data. It will also create multiple plots if given an array in which each element is a cluster containing the data for a single plot (y data, initial x, and delta x). Finally, it is possible for the dynamic data type to carry more than one signal simultaneously. These different arrangements are shown in Fig. 3.9. Create a VI that uses two copies of the “Simulate Signal” Express VI to create two signals carried by “dynamic data” type wires. Combine the two signals 38 CHAPTER 2. WORKING WITH COLLECTIONS OF DATA Figure 2.8: Different input formats for the Waveform Graph function. Top to bottom: (1) a 1D array, (2) a cluster containing a 1D array, initial x and ∆x, (3) a waveform, and (4) dynamic data. into a single wire and connect it to a Waveform Graph indicator. Then, try converting the dynamic data into an array of waveforms using the “From DDT” Express VI in the Functions palette > Express > Signal Manipulation menu. Plot the signals contained in the array with another Waveform Graph indicator and observe how the results are different. Try to convert the dynamic data to a 2D array of numbers as well, and observe how the graph is different for this input form. 2.5.3 Plotting Data with XY Graph The “xy graph” indicator is used when the x data is not evenly spaced. For each line in the plot, the input is a cluster of two arrays, and the result is a plot of one versus the other. 2.5. PLOTTING DATA Figure 2.9: Several ways to create a multi-line waveform graph. 39 40 CHAPTER 2. WORKING WITH COLLECTIONS OF DATA Chapter 3 Data Acquisition 3.1 The DAQ Assistant There are a variety of functions in LabVIEW for acquiring data from a data acquisition card (DAQ) or sending a signal out to an experiment via the same card. The most user-friendly method is to use Express VIs. The DAQ Assistant is an express VI found from the Functions palette, under the Express > Input or Express > Output menus. When you drag this express VI onto a block diagram, a startup window (see Fig. 4.1) will appear. After you make selections related to how you will use the DAQ, you will see the DAQ Assistant properties window (see Fig. 4.2). (a) Mode Selection (b) Type Selection (c) Channel Selection Figure 3.1: The DAQ Assistant express VI If you want to reconfigure the DAQ after you’ve closed this properties window, double-clicking the DAQ Assistant Express VI will bring up the DAQ Assistant properties window once again. The properties window has buttons at the top that allow you to add additional channels, remove channels, and test to see if a channel is working properly. By right clicking on one of the channels listed in the top-left corner, you can rename the signal corresponding to that channel, reassign it to a different physical channel, etc. The properties window also allows you to configure various options, such as timing of the data collection (number of samples to acquire and at what rate), scaling of the units (conversion 41 42 CHAPTER 3. DATA ACQUISITION Figure 3.2: The DAQ Assistant properties window. from measured voltage into some other units appropriate to whatever sensor is being used), and triggering for the data acquisition to begin at specific times relative to other events. The two “1 Sample” options under Acquisition Mode on the Task Triggering tab cause the DAQ Assistant to acquire (or send) a single piece of data on each channel every time the flow of the LabVIEW program reaches the DAQ Assistant Express VI. Typically, the “N Samples” option is used instead, to send or receive a specified number of data points at a specified rate. The number of samples and the sampling rate are set in the fields just to the right, under Clock Settings. When using the DAQ Assistant to send a signal out from the computer to an experiment, an option can be checked to “use waveform timing,” which means the number of samples and the rate at which they are sent will be dictated by whatever signal is wired into the DAQ Assistant icon on the block diagram. The number of samples and sampling rate can also be provided to the DAQ Assistant express VI as inputs from elsewhere in your block diagram, and if this is done, any incoming information overrides information entered in the properties window. For example, Fig. 4.3 contains a simple VI that reads data from the DAQ at a sampling rate that is specified by a wire on the block diagram that connects to on numerical control on the front panel. The output data from the DAQ Assistance express VI is wired into a Waveform Graph indicator to be displayed. The Input Setup tab to the right of the list of channels in the DAQ Assistant properties window allows you to select the range used by the digitizer when acquiring data, as well as to scale the measured voltages to convert them into units 3.1. THE DAQ ASSISTANT 43 (a) Block Diagram (b) Front Panel Figure 3.3: Usage of the DAQ Assistant to record data at a specified rate more appropriate to whatever device the signal is being read from. Note that this tab might be hidden if the “Show Details” button at the top of the channel list has been pressed – pressing “Hide Details” returns the tab to visibility. The values entered for Min and Max under “Signal Input Range” dictate the range used by the digitizer. A typical data acquisition card has several fixed ranges that can be used: in this case the smallest range that completely encompasses the Min and Max entered by the user will be the range used. If custom scaling is employed, these values should be entered in the scaled units, not as voltages, but keep in mind that the range selected for use may not exactly match the range you enter. For example, let’s say you’re acquiring data from a microphone that has a sensitivity of 0.053 V/Pa. You can pull down the “Custom Scaling” menu and select the option to create a new scale. In the window that appears, you could name the scaled units “Pa” for Pascals, and set set the slope of the linear scaling relationship to be 18.87, which is the reciprocal of 0.053. Once you close this window and make sure your newly created scale is the one selected, the acquired data will have units of Pascals instead of Volts. Now, to select a value to enter for Min and Max, you should consider the highest and lowest sound pressure levels you expect the experiment to involve. If you create a table like the one shown below, you can determine what range the digitizer will actually use (and thus at what pressure the digitized signal would be clipped). Table 3.1: Example showing scaled units. Digitizer Range [Volts] Digitizer range [Pascals] -200 mV to +200 mV -1 V to +1 V -5 V to +5 V -10 V to +10 V -3.774 -18.87 -94.34 -188.7 Pa Pa Pa Pa to to to to +3.774 +18.87 +94.34 +188.7 Pa Pa Pa Pa The four fixed digitizer ranges of a National Instruments PCI-6221 data 44 CHAPTER 3. DATA ACQUISITION acquisition card, converted to Pa using a sensitivity of 18.87 Pa/V. Other data acquisition card models may have different fixed ranges available. For instance, if you set the Min and Max to –4 Pa and 4 Pa respectively, the range exceeds the limits given in the table for the first range, so the second range will be used, and the signal will not be clipped unless it exceeds (18.87 Pa. If –3.5 and 3.5 were entered for Min and Max, however, the signal would clip when it exceeded about 3.774 Pa. The “Triggering” tab in the DAQ Assistant properties window allows the VI to be configured so that the acquisition will be hardware triggered: when the flow of the LabVIEW program reaches the DAQ assistant, it will set things up to perform the data acquisition, but the data acquisition will not actually begin until the triggering event occurs. 3.2 Triggering We will create a digital pulse that can be used as a trigger for the data acquisition to occur. To send the trigger signal, you can configure another copy of the “DAQ Assistant” Express VI to send the digital pulse, as shown in the bottom loop in Fig. 4.4. Create the VI shown in Fig. 4.4 and configure each DAQ Assistant so that the program runs properly. Configure the triggering DAQ Assistant to send data out on Digital Port 0 Line 0. Then configure the other DAQ assistants, via the “triggering” tab in the properties window, to begin on the rising edge of a digital pulse on the PFI0 channel. (Trigger type should be digital edge.) On the DAQ’s connector block, you can connect the PFI0 input port to the P0.0 output using a cable. Then, whenever the flow of the LabVIEW code reaches the DAQ Assistant that sends the digital pulse, the PFI0 channel will see this pulse and both other DAQ Assistant tasks will begin (assuming, of course, that the LabVIEW code flow had previously reaches those icons and therefore set up those tasks). It is also possible to perform software triggering, by sending a previously recorded signal into the Trigger and Gate express VI found in the Express > Signal Manipulation submenu, and shown below in Fig. 4.5. This VI extracts a portion of the incoming signal beginning whenever a specific threshold is reached on a specified channel. As shown in Fig. 4.5, the extracted portion can include a certain number of samples, or can last until another “Stop Trigger” threshold in reached. The extracted portion can also be configured to include an additional fixed number of samples before the Start Trigger, by entering a certain number of “Pre-samples.” It is even possible to make this number negative, so that the extracted portion does not begin until a specified number of samples after the trigger threshold is reached. 3.2. TRIGGERING 45 Figure 3.4: A VI to simultaneously send and record signals to/from the DAQ, with both events triggered to occur simultaneously. Figure 3.5: Trigger and Gate express VI, for software triggering. 46 CHAPTER 3. DATA ACQUISITION Figure 3.6: Configuration window for the “Trigger and Gate” express VI. 3.3 Writing data to a file Measurement data can be written to or read from files in a number of different ways, and different file formats are supported. The file I/O functions are assessed from the “File I/O” menu in the Functions palette. You can find functions to change directories, change file names, move files and more form this menu. 3.3. WRITING DATA TO A FILE (a) File IO Menu (b) VI Express 47 (c) Measurement File Properties Figure 3.7: Usage of the DAQ Assistant to record data at a specified rate 48 CHAPTER 3. DATA ACQUISITION Try the following Exercises 1. Create a LabVIEW vi that takes a 2D array of numbers and returns a 1D array that contains the average of each of the columns or rows. The front panel should have: Two Controls: a 2D array of numbers and a Boolean control (switch or button) to determine whether to average by row or by column One Indicator containing a 1D array with the results of the averaging Configure this VI for use as a subVI by connecting both controls and the indicator to terminals on the “connector” diagram, then save the VI. Test your program by creating an array of numbers and making sure that the averaging is successful, in both “row” and “column” configurations. 2. Write a second LabVIEW VI that creates a sinusoidal signal contaminated by noise and then averages multiple instances of the signal to remove the noise. You can use the “Simulate Signal” Express VI to create the signal, placed within a “for loop” structure so that the signal is created many times. Your front panel should feature: Controls for the signal’s amplitude, the amplitude of the noise, and the number of averages used to suppress the noise (the number of times to run the “for” loop). Indicators including: – one graph displaying a single instance of the signal, changing each time through the loop – a second graph that displays the current averaged signal (updated each time through the loop, it should look less and less noisy because more and more measurements are being averaged) – an indication of how many averages have taken place so far Helpful Hints The output of the “Simulate Signal” VI is a wire of type “Dynamic Data,” which you will need to convert to a wire carrying an array of numbers in order to use. 49 50 You can use Shift Registers to assemble the 1D arrays generated by the “Simulate Signal” vi into a larger and larger 2D arrays as the loop repeats. Call the subVI you created in step 1 to perform the averaging calculation. Make sure the labels on your graphs are correct. Plot amplitude vs. time if you can, otherwise, be sure to indicate the plots are amplitude vs. sample number. Test Your Program Configure the “Simulate Signal” vi so that there are roughly five cycles of the sinusoid in each instance of the signal (you may wish to adjust the signal’s frequency, the sample rate, and/or the number of samples). Begin with a strong signal and weak noise, and use a small number of averages. Decrease the signal amplitude or increase the noise amplitude. It should then take a larger number of averages to suppress the noise. Try a situation in which the noise amplitude is a factor of 10 or 20 greater than the signal amplitude. Your graph of an individual signal should look like mere noise (the signal itself should be impossible to see). With a sufficient number of averages, you should be able to recover the signal in the graph that displays the averaged version. √ Remember that averaging suppresses noise according to N , so to suppress noise twice as much as 10 averages, you need to increase to 100 averages, not 20. 3. Modify your code so that instead of simply averaging the signal you created, it sends that signal to the DAQ, and then reads another (corresponding) signal back from the DAQ and performs the averaging on that signal. Test Your Program On the DAQ connector box, connect the output directly to the input so that your code will be sending and receiving essentially the same signal. Adjust the amplitude of the signal and the noise and perform the same tests as step 2. Set the amplitude of the signal and the artificially created noise to zero and try to figure out how much noise is introduced by passing the signal through the DAQ and the coaxial cable. This noise should be pretty low. 51 Then, try sending a very weak signal (without any artificial noise) through the DAQ and use multiple averages to extract it from the noise that gets introduced along the way. With enough averages, you should be able to measure a signal that is significantly smaller than the noise in the system. 4. Add code that will save the averaged data to an external file that can be read by other software. Test Your Program by running the VI and then try opening the resulting data file in Word, Excel, or MATLAB.