Academic Company Events NI Developer Zone Support Solutions Products & Services Contact NI MyNI

Document Type: Tutorial
NI Supported: Yes
Publish Date: Jan 10, 2007


Feedback


Yes No

Related Categories

Related Links - Developer Zone

Related Links - Products and Services

Nonlinear Waveform Generation with CompactRIO and LabVIEW FPGA

2 ratings | 4.50 out of 5
Print

Overview

Reconfigurable I/O (RIO) enabled hardware from National Instruments allows developers to create custom hardware to perform many tasks with a rugged, portable, and modular platform. One such task easily implemented with RIO hardware is analog waveform generation. This tutorial describes different methods to output nonlinear waveforms using CompactRIO hardware and the LabVIEW FPGA Module. For information on other types of waveform generation with the LabVIEW FPGA Module visit the larger Waveform Generation with Compact RIO tutorial.

Nonlinear Waveform Description

A nonlinear waveform is any waveform that cannot be defined by an equation with a linear slope. Nonlinear waveforms can be described with an equation and can be output on a point-by-point basis with CompactRIO analog output modules. Nonlinear waveforms can be sampled at a given rate and represented by individual points. An example of a nonlinear waveform is shown in Figure 1. It is the waveform that is the result of the following equation:




Figure 1. Example of a Nonlinear Waveform

Nonlinear waveforms include a wide range of waveforms including periodic waveforms and arbitrary waveforms. There are special features in the LabVIEW FPGA Module that allow you to perform unique operations on these two types of nonlinear waveforms. Each of these waveforms is addressed in separate tutorials to accent some of the features available in the LabVIEW FPGA Module that make these types of generation unique. Links to these tutorials can be found from the "Waveform Generation with Compact RIO" tutorial.
See Also:
Waveform Generation with CompactRIO

Nonlinear Waveform Applications with CompactRIO


CompactRIO gives engineers and scientists a customizable, rugged, and portable hardware solution for nonlinear waveform generation. The LabVIEW FPGA Module and CompactRIO hardware, provides maximum flexibility for the test and control engineers. With CompactRIO, developers can build hardware modules that provide custom tasks, timing, and triggering. By using nonlinear waveforms, scientists and engineers are able to perform many tasks such as frequency sweeps, sensor simulation, and sinusoidal stimulation. As an example, a scientist or engineer could simulate different sensors such as thermocouples or LVDTs with the LabVIEW graphical programming and modular CompactRIO hardware to develop a system that simulates real world conditions that are difficult to replicate during product development.

The flexibility of Compact RIO enables developers to customize waveform generation with the ability to continuously change the update rate, gain, and even the waveform during execution. In addition, the LabVIEW FPGA Module allows developers to easily customize timing and triggering of CompactRIO hardware with 25 nanosecond resolution. This functionality is beneficial if an application requires the tight synchronization of a nonlinear response to another factor, such as an external signal.

Voltage Output with CompactRIO Analog Output Modules


The LabVIEW FPGA Module utilizes integer math for all mathematical operations; therefore, analog output operations with CompactRIO must utilize the binary code representation of the desired output voltage. The binary code representation of a desired voltage is determined by dividing the desired voltage by the code width of the module. The code width (or step size) of a module is defined as the smallest change in voltage that the system can output. Code width is calculated according to the following equation:



For example, the cRIO-9263 analog output module has 16-bit analog output channels with a range of -10V to 10V. Therefore the code width of the module is .305176mV/step (20V / 2^16 steps). Therefore, to output 5.0V, you would need to divide 5.0V by .305176mV. This division yields a binary value of 16384.

National Instruments has included a VI with each analog output module that will do this conversion for you. This VI will be named Convert to Binary (cRIO-XXXX), where XXXX is the model number of the module. It will be included in the cRIO-XXXX Support Files LLB located in the \examples\FGPA\CompactRIO\cRIO-XXXX\ directory under your LabVIEW folder. This VI, shown in Figure 2, is often used in host VIs with FPGA programs to convert desired voltage values into the binary code representation of that voltage. You will supply it the voltage you want to output in the Nominal Value (V) terminal. The Calibration terminal is a cluster that includes two different controls: Offset (nV) and LSB Weight (nV/LSB). These controls are used to determine the binary code representation of the voltage, which is returned through the Binary Value terminal. The LSB Weight (nV/LSB) control is the code width of the module, and the Offset (nV) control corresponds to any offset you may want to recognize.

Figure 2. Convert to Binary (cRIO-9263) VI

Nonlinear Waveform Generation with Array Operations

There are many ways to perform nonlinear waveform generation in CompactRIO. The different methods range from array operations to the more advanced memory read and write operations. This range of different methods gives developers many different options that can be utilized in various applications. One quick, easy way to generate any waveform is by including points in an array and indexing through those points at specific time intervals. Arrays in the LabVIEW FPGA Module Arrays can be created with the LabVIEW FPGA Module; however, you can only use fixed-size, one dimensional arrays. You can make any array constant, control, or indicator fixed-size, by right-clicking on the array index and selecting Set Dimension Size. If your values will always remain the same, use arrays of constants because they are more efficient in FPGA VIs.

Note: To optimize compile time, avoid using arrays larger than 32 elements because they require space on the FPGA.

Creating a LabVIEW FPGA VI to Output an Array The first step in developing any application in the LabVIEW FPGA Module is to develop a VI that will be run on the FPGA. An FPGA VI that cycles through an array is shown in Figure 3. This VI (Array Output) utilizes the auto-indexing feature of LabVIEW to index through the array point-by-point. The output values are extracted from the array and then are output on analog output channel 0 of a cRIO-9263 analog output module.

This program uses a Sequence Structure as recommended in the LabVIEW FPGA Module User Manual for timed I/O operations. In the first sequence we are taking advantage of the Loop Timer function to control the update rate of the analog output. With CompactRIO all of the hardware timing is defined in our software, therefore we can change the update rate during execution by simply changing the value in the Update Period (mSec) control. This loop will execute at a rate defined by 1/Update Period (mSec). The cRIO-9263 has a minimum update period of 3 microseconds when outputting data to one analog output channel. This corresponds to a maximum update rate of 333,333 updates/sec. In the second sequence of the program we are using the Analog Output function to output the desired voltage to channel 0 on a cRIO-9263.


Figure 3. Array Output VI

Creating a Host VI to Execute the Targeted VI

The second step of most LabVIEW FPGA applications is creating a host interface VI to access data from the RIO hardware target. The Execute Array Output VI, shown in Figure 4, opens a reference to the Array Output VI that has been downloaded to the FPGA with the Open FPGA Reference function. It then sets the values for the Points to Output and Update Period (mSec) controls of the VI with the Read/Write Control function. The VI is then run on the FPGA by using the Invoke Method function with the Run method. It waits until the VI is through running, then it closes the reference with the Close FPGA VI Reference function and checks for errors.



[+] Enlarge Image
Figure 4. Execute Array Output VI


Indexing through arrays for waveform generation is perfectly acceptable for waveforms that are defined by a relatively small number of points. Remember that each element in the array consumes gates on the FPGA; therefore, large arrays are not practical with the LabVIEW FPGA Module. However, the FPGAs do have 16KB of memory that can be utilized for storage. This memory can be accessed using the Memory Read and Memory Write VIs located on the Functions>>FPGA Device I/O>>Advanced FPGA Device I/O pallette. More information about these functions is included later in this tutorial. You can also read other tutorials that are included in the "Waveform Generation with Compact RIO" tutorial as well as the LabVIEW FPGA Module User Manual for more information.
See Also:
Product Manuals: LabVIEW FGPA Module User Manual
Developer Zone Example: Finite Waveform Generation With Array Storage on CompactRIO

Nonlinear Waveform Generation with Look-up Tables


Performing waveform generation by indexing through array values is a simple solution, but it also consumes a large number of gates on the FPGA. However, the FPGA also includes 16KB of memory that can be accessed to store data values for FPGA VIs. The LabVIEW FPGA Module includes a Look-Up Table 1D VI, shown in Figure 5, that allows the user to create a look-up table and write that table to the FPGA memory. A look-up table in the LabVIEW FPGA Module is an array of values in the FPGA memory that is indexed through an address. The Look-up Table 1D VI can easily be used for waveform generation to create a table that includes each individual point on a waveform. The addressing scheme for a look-up table is identical to the indexing used for array operations. The VI returns the value in the look-up table (data out terminal) that corresponds to the value in the table at the address supplied in the address control. You can also do linear interpolation with the Look-Up Table 1D VI by using the fractional index (x 2^16) terminal, but that is beyond the scope of this tutorial. This functionality is similar to the x (fractional) control with the Linear Interpolation VI, discussed in the "Linear Waveform Generation with Compact RIO and LabVIEW FPGA" tutorial.


Figure 5. Look-Up Table 1D VI

Configuring the Look-Up Table

The first step in using the Look-up Table VI is to define the actual look-up table. Configuring the table can be done manually or by calling a LabVIEW VI. When you place the Look-up Table 1D VI on your block diagram, a configuration dialog box, shown in Figure 6, will be loaded that allows you to configure the look-up table. In this page, you can configure the size of the look-up table (Number of Elements), data type of the elements (Data type), name for the VI (Function Name), and whether or not you want to enable interpolation between the points in the table (Interpolate Data). There is also a Table Preview graph to display a preview of the look-up table data. To define the actual values in the look-up table, you must click the Define Table button.


[+] Enlarge Image
Figure 6. Look-Up Table 1D Configuration Dialog Box

When you click the Define Table button, another dialog box, entitled Define Table, shown in Figure 7, will appear. This dialog box is used to help you define the actual values in the look-up table. You can manually type in each individual data point by clicking in the corresponding Value cell in the Data Points table. This can be a quick way to define the look-up table if you have a relatively small number of points.


[+] Enlarge Image
Figure 7. Define Table Dialog Box Before Look-Up Table Initialization

If you do not want to type each individual value in the Data Points table, you can configure the look-up table in two other ways. First, you can click the Define Segments button and the Populate Memory Block dialog box, shown in Figure 8, will appear. This dialog box assists you in configuring the memory blocks in the look-up table according to one of four modes: Constant, Linear, Sine Wave, and Cosine Wave. With each of these modes you can define the portion of the look-up table from the Starting Address to the End Address that will match the Mode. You can use this functionality to define individual segments or the entire look-up table.


Figure 8. Populate Memory Block Dialog Box

Another option for defining the table is to actually create or use an existing VI that will create an array that can be imported into the look-up table. This feature is an extremely powerful way to configure the look-up tables. It enables you to automate the process of creating the look-up table. You can create a VI on the host machine that will generate the look-up table for you. This method allows you to use floating point math and any of the other functions in the host to determine the values on your look-up table. To define a table using an initialization VI, you click the Call Initialization VI button from the Define Table dialog box. When you click this button the Call Initialization VI dialog box, shown in Figure 9, will be displayed. This dialog box gives you three options in the Mode control. You can Run/Load Existing Initialization VI, Edit Existing Initialization VI, and Create New Initialization VI From Template. You can select the mode, then navigate to the VI and perform the appropriate action.


Figure 9. Call Initialization VI Dialog Box
Creating an Initialization VI
The first step in using a VI to populate the look-up table is to create an initialization VI, if one does not exist. If you select the Create New Initialization VI from Existing Template option in the Mode control, you can create a VI at the path supplied in the Existing Initialization VI path control. When you have defined the path to the new VI, you can click the OK button. This will create the new VI. The VI that is created for you is shown in Figure 10, and consists of a For Loop that runs once for each point in the look-up table and stores a value, through auto-indexing, into the Init Data Out array indicator. This VI should create a value for each of the addresses in the look-up table; therefore, the value wired to the Count terminal of the For Loop should be the size of the look-up table. You can customize the code inside the For Loop to perform the desired mathematical operation to determine the values in the look-up table.


Figure 10. Blank Look-Up Table Initialization VI

You can create your own initialization VI to populate a look-up table based on a waveform where each point's voltage is based on the following equation:



This nonlinear equation can easily be implemented in the initialization VI. The arithmetic operations available on the host can be used by switching the Execution Target back to the host for the creation and execution of this VI. Remember that the CompactRIO analog output voltages are in binary code format as described in the Voltage Output with CompactRIO Analog Output Modules section; therefore, each of these voltages must be converted to its corresponding binary code representation before output. The conversion can be done with the Convert to Binary (cRIO-9263) VI, described in the aforementioned section. The initialization VI after these modifications can be seen in Figure 11. This VI implements the equation and then converts each result to its binary code representation with the Convert to Binary (cRIO-9263) VI. The Calibration cluster is used to determine the parameters necessary for conversion to the binary code representation. The LSB Weight (nV/LSB) is the code width of the analog output module, as described earlier. Running this VI while targeted to the host will populate the look-up table that will be downloaded to the FPGA upon compilation.


[+] Enlarge Image
Figure 11. Create Look-up Table for Nonlinear Waveform Output VI

Running the Initialization VI

Once this VI has been created and saved, you can go back to the Call Initialization VI dialog box and select Run/Load Existing Initialization VI from the Mode control. When you click the OK button the initialization VI will be executed and the results of the calculation (values stored in the Init Data Out array) are copied into the look-up table and the Define Table dialog box is displayed. It will now show the new look-up table values in the Data Points table and the Preview graph as shown in Figure 12.


[+] Enlarge Image
Figure 12. Define Table Dialog Box After Look-Up Table Initialization

Using the Look-up Table for Waveform Generation

After we have defined the look-up table, we click the OK button to go back to the Configure Look-up Table 1D dialog box and click the OK button to return to programming. We can then create a program that will index through the look-up table to perform the nonlinear waveform output. An easy way to implement a VI that performs this action is shown in Figure 13. A For Loop is used to output the waveform one point at a time by extracting the values from the look-up table. The value that is output is the current value at the address of the look-up table, which is supplied from the Iteration terminal. The loop is executed once for each element in the look-up table and is controlled from the Number of Points control. To output the entire waveform, this value should match the size of the look-up table. This VI also utilizes the Loop Timer VI to control the update rate of the waveform with the Update Period (mSec) control, which can be changed during the execution of the VI.


[+] Enlarge Image
Figure 13. Nonlinear Waveform Output with the Look-Up Table VI

This example highlights the ease of use and robustness of the Look-up Tables in LabVIEW FPGA. This example focuses on outputting each value in the look-up table, which may not be necessary for many operations. For instance, you may want to use the look-up table as a reference and output a waveform based on select points in the look-up table. To identify individual points in the look-up table you can create an array of values to output that you could change from a host VI. You could also write a list of desired values to the FPGA memory and then output the voltages that correspond to these values by reading from the memory. Each of these methods is shown in the next section with an example that simulates a thermocouple.
See Also:
Developer Zone Example: Finite Waveform Generation with a Look-Up Table on CompactRIO
Developer Zone Example: Continuous Waveform Generation with a Look-Up Table on CompactRIO

Simulating a Nonlinear Sensor with CompactRIO and the LabVIEW FPGA Module


One application of waveform generation with CompactRIO is simulating sensors. By simulating sensors you are able to simulate conditions on your Unit Under Test (UUT) that may be difficult to replicate in a testing environment. With the principles discussed in this document you can simulate many nonlinear sensors, including thermocouples. Thermocouples are widely used temperature sensors that have a nonlinear response. Thermocouple tables are widely used tables that display the output voltage of thermocouples at different temperatures. Thermocouple tables for Type J,K,T, and S thermocouples can be found at the tutorial linked at the end of this section.

To simulate thermocouples you can generate a look-up table for each temperature in the range of a thermocouple and store the corresponding analog output voltage values for each temperature in the table. This technique effectively creates a thermocouple table on the FPGA. The Generate Table (1 Per Degree) initialization VI that performs this action is shown below in Figure 14. This VI will create a thermocouple table for B, E, J, K, R, S, T, N type thermocouples. This VI utilizes the Temperature to Volts VI that comes with the NI-DAQ driver and is included with the accompanying example programs. This VI converts a temperature to the voltage value that the thermocouple would output. That voltage value is then converted to the binary code representation by the Convert to Binary (cRIO-9263) VI. This particular initialization VI will create an entry in the look-up table for each degree in range defined by the values in the Low Temp and High Temp controls.


[+] Enlarge Image
Figure 14. Generate Table (1 Per Degree) VI.

Once you have a thermocouple table in the FPGA memory, you can use the table to simulate temperature conditions by generating values from the look-up table. This functionality allows you to create predefined conditions and temperature settings that you can simulate with CompactRIO hardware. For instance, you could load an array of temperatures to the VI and have your CompactRIO system output a custom waveform that simulates the thermocouple's response over a potential temperature range at a certain rate of change.

The Thermocouple Output VI, shown in Figure 15, is a VI that utilizes the thermocouple table. It takes a temperature reading from the Thermometer control, and then outputs the corresponding voltage according to the thermocouple table. This VI utilizes the Generate Table (1 Per Degree) VI to create the look-up table for the thermocouple. It assumes that one value is stored in the table for each degree between Low Temp and High Temp. Therefore, to determine the index in the look-up table for the current reading, you simply subtract the value in Low Temp value, which should be the same as the value in the initialization VI, because that value is at address 0 of the look-up table. You can also change the type of thermocouple that it simulates by changing the values in the look-up table by running the Generate Table (1 Per Degree) VI again in the Look-Up Table 1D configuration.


[+] Enlarge Image
Figure 15. Thermocouple Output VI

This VI allows the user to interactively determine the temperature that will be simulated. However, in many cases it will be necessary to have a predefined set of values that are simulated. These values can be stored in the FPGA in two major ways: an array or the memory on the FPGA. Recall that you should not create arrays of larger than 32 elements to optimize compile time and FPGA fabric. If you need more points, then you can use the FPGA memory to store the values of the waveform you want to output. You can use the Memory Read and the Memory Write VIs, included with the LabVIEW FPGA Module, to access these memory locations. You can only have one VI on the FPGA at any given time, so to access the memory you need to have a single VI that includes both the Memory Read and Memory Write VIs. Often, a VI that implements both of these operations is structured with a case structure. One case is used to write to the memory and another case is used to read from the memory and perform necessary operations. The VI can be called from the host with the action (case) set to "write" to write to the memory and the action (case) set to "read" to read from the memory.

This functionality can be used to improve the thermocouple simulation by adding both write and read memory functionality. This functionality can be added by creating a Case Structure and restructuring the Thermocouple Output VI. After the conversion, one case will be Output Waveform and the other will be Write Values. The Write Values case will be used to write the values to memory that we want to output in the Output Waveform case. The Thermocouple Output (Memory) VI implements these two cases and is shown below in Figures 16 and 17. When this VI is executed, it uses the value in the Action control to determine the action it will perform. When the action is set to Write Values, the value in the Value control is stored in the Address location with the Memory Write VI.


[+] Enlarge Image
Figure 16. Thermocouple Output (Memory) VI - Write Values Case

The Output Waveform case uses a method similar to the Thermocouple Output VI to output the temperatures. Each desired output temperature is read from memory using the Memory Read VI. The address that is read corresponds to the iteration of the loop, so it assumes that the desired output values are written beginning at address 0. The desired temperatures are read from the memory locations and the Low Temp value is subtracted to get the address in the Look-up table to be output This value is then output to analog output channel 0 on a cRIO-9263 module with the Analog Output function.


[+] Enlarge Image
Figure 17. Thermocouple Output (Memory) VI - Output Waveform Case

A Host VI can also be developed that will programmatically run the VI in the Write Values case to load up the desired temperatures and then run the VI in the Output Waveform case to output the simulate result of the predefined temperatures. The Execute Thermocouple Output (Memory) VI, shown in Figure 18, is developed and run on the host machine. It opens a reference to the Thermocouple Output (Memory) VI that has been downloaded to the FPGA with the Open FPGA Reference function. It then sets the values of the Low Temp, Number of Points, and Update Period (mSec) controls with Read/Write Control function. The VI is then actually run once for every desired temperature with the Action set to Write Values to write the temperature to the appropriate address. The Action is then set to Output Waveform and the VI is run to output the waveform defined by the temperatures stored in memory. It waits until the VI is through running, then it closes the reference with the Close FPGA VI Reference function and checks for errors. This method allows you the freedom of quickly modifying the temperatures and number of temperatures to simulate. You could even take this VI and use it in other VIs to perform output on the cRIO-9263 as part of a larger project.


[+] Enlarge Image
Figure 18 - Execute Thermocouple Output (Memory) VI

See Also:
NI Developer Zone Tutorial: Thermocouple Tables

Conclusion

CompactRIO gives engineers and scientists a customizable, rugged, and portable solution for nonlinear waveform generation. The LabVIEW FPGA Module and RIO enabled hardware, provides maximum flexibility for the developer. It gives developers the freedom to create unique modules with hardware-timed functionality. By taking advantage of array operations and look-up tables in the LabVIEW FPGA Module, a developer can easily create a waveform generator that will output nonlinear waveforms. Nonlinear waveforms encompass a wide range of waveforms including periodic waveforms and arbitrary waveforms. There is more functionality in the LabVIEW FPGA Module that allows you to perform output of these special nonlinear waveforms. Tutorials on using other waveforms can be found from the larger "Waveform Generation with Compact RIO" tutorial.
Related Links:
Developer Zone Tutorial: Waveform Generation with CompactRIO
Developer Zone Tutorial: Linear Waveform Generation with CompactRIO and LabVIEW FPGA
Developer Zone Tutorial: Periodic Waveform Generation with CompactRIO and LabVIEW FPGA
Developer Zone Tutorial: Arbitrary Waveform Generation with CompactRIO and LabVIEW FPGA
Product Manuals: LabVIEW FPGA Module User Manual
2 ratings | 4.50 out of 5
Print

Reader Comments | Submit a comment »

 

Legal
This tutorial (this "tutorial") was developed by National Instruments ("NI"). Although technical support of this tutorial may be made available by National Instruments, the content in this tutorial may not be completely tested and verified, and NI does not guarantee its quality in any way or that NI will continue to support this content with each new revision of related products and drivers. THIS TUTORIAL IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND AND SUBJECT TO CERTAIN RESTRICTIONS AS MORE SPECIFICALLY SET FORTH IN NI.COM'S TERMS OF USE (http://ni.com/legal/termsofuse/unitedstates/us/).