A cRIO I/O Engine Design Pattern for Machine Control
Overview
The cRIO I/O Engine (CIE) design pattern is an example of a configurable single-point I/O interface for CompactRIO-based applications. Single-point I/O is commonly used in machine and industrial control, as well as other control and simulation applications. The cRIO I/O Engine consists of FPGA code that is customized for a specific set of cRIO I/O modules, and a common set of LabVIEW Real-Time VIs that parse, calibrate, and scale data coming from the FPGA. After adapting the cRIO I/O Engine to a cRIO module configuration, acquisition of I/O channels data is configured using a simple channel list. The FPGA portion of the cRIO I/O Engine can be enhanced to add data preprocessing on the FPGA for sensor decoding/encoding, safety system implementations, and other operations. In an application the cRIO I/O Engine can be combined with other forms of I/O so that single-point I/O runs in conjunction with streaming data acquisition, motion control, and CAN communication.
Table of Contents
Introduction
The purpose of the cRIO I/O Engine (CIE) is to provide a configurable single-point I/O interface as part of the machine control reference architecture. In machine and other industrial control applications many of the monitoring and control processes are based on single-point I/O data. The data used in these processes represent the current value of a physical I/O channel. The processes are not concerned with the time history of the data, comparing the current value to any of the previous values or measuring the rate of change of a value. The CIE provides a common interface to all available I/O channels for a machine control application.

Figure 1: cRIO I/O Engine Architecture
The CIE uses the Current Value Table (CVT) component to store the current input values for access by other parts of the application. The CIE reads output data from the CVT to update the analog and digital output channels. The mapping of physical I/O channels between CIE and CVT tags is defined by a channel list provided to the CIE during initialization. This list is application-specific and can be placed directly in the application code as a constant value or can be loaded at run-time from a tag configuration file. The tag configuration file is created and edited using the Tag Configuration Editor (TCE) component. The TCE provides VIs to load the tag configuration file and extract the channel list to initialize the CIE and CVT.
The cRIO I/O Engine is placed as a VI in the machine controller code. It runs an internal loop that continuously updates data between the CVT and the cRIO I/O channels. It runs in parallel to other parts of the machine controller. The FPGA portion of the cRIO I/O Engine needs to be customized for the current set of cRIO modules and channels. As part of developing an application, the application project and FPGA VIs need to be updated for the cRIO modules used by the application.
Using the cRIO I/O Engine
The cRIO I/O Engine is integrated in the machine controller by placing the main CIE VI in parallel with the main control process of the application. The CIE runs an internal update loop and should therefore not be placed inside of the main control loop or any other loop. The CIE will run continuously until it is stopped using the command queue which is one of the input parameters to the CIE. The command queue data type is a TypeDef enumeration (cie_Commands.ctl) defined by the CIE component. The command queue is used to stop the CIE from another part of the application, so that it can be restarted with a different channel list.
Figure 2: Basic operation of the cRIO I/O Engine in a LabVIEW RT VI
In addition the command queue, the CIE requires the channel list which defines the mapping of physical cRIO I/O channels to CVT tags. In the diagram shown above the Channel List is defined using an array constant on the diagram. The channel list may also be read from a tag configuration file generated using the Tag Configuration Editor. Search the Developer Zone for “Tag Configuration Editor” for detailed information and an installer for this component.
In the channel list channels are addressed using slot and channel numbers, starting with Slot 1 in the chassis and Channel 0 in each module. The address uses the following format 'SxCx', for example 'S1C4'.
Before the cRIO I/O Engine is started, the Current Value Table needs to be initialized so that all of the channels used by the CIE are present as tags in the CVT. The example above shows how the channel list can be converted into a list of tags for the CVT Initialize function. You can add more entries to the list of CVT tags before you pass the array to CVT Init. If an application uses the Tag Configuration Editor to define the CVT tags and CIE channels, both lists are read from the same tag configuration file.
Theory of Operation
The CIE uses the FPGA to interface to all of the I/O channels provided by the current set of cRIO modules. As most applications will not use all of the available I/O channels, at some point in the CIE the list of available channels needs to reduced to the channels used by the application. This selection of application I/O values is performed in the RT portion of the CIE in order to simplify the CIE code and make code customization for different module configurations easier. Selection of values at run-time is configured using the application-specific channel list.

Figure 3: cRIO I/O Engine Update Architecture
With the selection of application I/O values performed in RT, the FPGA portion of the CIE interfaces to all of the I/O channels available in the current module configurations. This means that the CIE I/O FPGA VI acquires all channels from analog and digital input modules and updates all channels on analog and digital output modules. The basic CIE does not support other types of cRIO modules such as motion drives and CAN, but this functionality can be added by the developer for a specific application.
Due to the nature of the FPGA to cRIO modules and I/O channels we cannot create one generic FPGA VI that handles different cRIO module configurations. Therefore as the set of cRIO modules used in the chassis and application changes, the developer needs to adapt or customize the CIE FPGA code, as well as one VI in the RT code, to match the new set of cRIO modules. This process is described later in this document.
A list of the current cRIO modules for which the FPGA VIs have been customized is hard-coded into one of the FPGA VIs and used by the rest of the CIE as a reference to determine the list of available channels and how to select the application-specific channels.
Implementation
The cRIO I/O Engine can be placed as a single VI into the controller application code. The main CIE VI consists of three subVIs: Initialize, Update, and Close.
Figure 4: cRIO I/O Engine main LabVIEW diagram
Initialize
The CIE Initialize VI is called once at the beginning of the CIE and takes care of all setup tasks including processing the list of channels used by the CIE. At the end of the CIE Initialize VI the FPGA is running and exchanging data with all of the FPGA I/O channels defined in the current module configuration.
Figure 5: cRIO I/O Engine Initialization LabVIEW diagram
The CIE Initialize VI handles the following tasks:
-
Download and run the Calibration FPGA VI. This FPGA VI needs to be customized to match the cRIO module configuration.
-
Read calibration constants of all I/O channels from the FPGA
-
Read the list of cRIO modules used in the current configuration from the FPGA
-
Build a list of available I/O channels based on the current cRIO module configuration including calculating an index of each channel in the array of all channels.
-
Assign calibration constant to all available I/O channels. This VI needs to be customized to match the cRIO module configuration.
- Filter the list of all available channels based on the application-specific channel list provided to the CIE
- Download and run the Acquisition FPGA VI. This FPGA VI needs to be customized to match the cRIO module configuration.
- Return a FPGA reference cluster for use by the other CIE subVIs containing the FPGA HW Reference and the two lists of input and output channels
During this initialization, the CIE matches up the application-specific channels to the list of all physical I/O channels. This is done based on the address provided for each of the application channels and the list of modules in the current module configuration stored in the Get Calibration FPGA VI. This process is handled separately for input and output channels and two lists are generated.
Based on the module configuration a list of all available I/O channels is calculated by the CIE using an internal database of modules and associated channels. This list must correspond to the list of raw binary data exchanged with the FPGA in the update VIs. This list is matched up to the application channels using the channel address string in the channel list. Using the address string the index in the array of all channels is determined for each tag. This index value is used in the CIE update VIs to read the proper input channels and update the proper output channels. Therefore the list of cRIO modules in the current module selection (which is stored in the CIE Get Calibration FPGA VI) must match up to the address strings used in the channel list and must also match to the raw binary input and output values (front panel arrays) provided by the CIE I/O FPGA VI. These items must be matched up during customization of the CIE for a specific configuration of cRIO modules.
Update
The CIE Update VI performs one update of all the input and output channels and is placed in a timed loop in the CIE main VI. The update rate (timed loop period) of the cRIO I/O engine can be configured based on application needs. Typical loop rates are 10 - 50 ms (20 - 100 Hz).
The CIE reads all I/O channels on the FPGA and returns all data to LabVIEW RT. In RT the application channels are selected from the raw binary data based on the list of channels provided. These are then calibrated, scaled and placed in the CVT for use by the rest of the application. The input and output channel updates are handled in two separate VIs.
Figure 6: cRIO I/O Engine Update LabVIEW diagram
The input update VI reads the raw binary data for all input channels from one front panel array of the CIE I/O FPGA VI. Inside a For loop the application channel data is selected, calibrated, and scaled to nominal values (voltage or current for analog data) and written to the CVT. Scaling to other engineering units can be added here if necessary.
Figure 7: cRIO I/O Engine Input Update LabVIEW diagram
The output update VI needs to update an array control on the CIE I/O FPGA VI to set the values for all output channels in the current cRIO module configuration. Therefore this VI needs to assemble an array with number of elements equal to the total number of output channels in the module configuration, not just the number of application output channels. This array is defined as a constant in this VI and the array should be adjusted to the total number of output channels when customizing the CIE to a different module configuration. Inside the For loop the list of application channels is processed. Engineering or nominal values are read from the CVT, scaled and processed to raw binary data and then placed into the existing array of output values. This array is written to the FPGA for the next update of output channels.
Figure 8: cRIO I/O Engine Output Update LabVIEW diagram
Close
The CIE Close VI uses the FPGA HW Reference to stop the FPGA VI and close the connection to the FPGA. After this VI the FPGA no longer acquires or updates any of the I/O channels from the FPGA.

Figure 9: cRIO I/O Engine Close LabVIEW diagram
Customizing the CIE
When developing a new application or changing the selection of cRIO modules used in an application the cRIO I/O Engine must be updated manually by the developer to match several components of the CIE to the new selection of cRIO modules. This section documents all of the necessary VIs and components that need to be customized.
Project
The cRIO I/O Engine is an integral part of the machine control reference architecture and becomes part of the LabVIEW Real-Time and LabVIEW FPGA code of the application. Because the CIE uses LabVIEW FPGA to exchange data with the cRIO I/O channels through the FPGA, the LabVIEW project used for the application needs to be updated to have the proper configuration for the RT controller, FPGA target, cRIO modules and I/O channels. Update these configurations in the application project and then place the RIO I/O Engine in the main application LabVIEW RT code of the controller. It is a good practice to make a copy of the CIE code for each application and make the customizations only on the CIE code specific for each application.

Figure 10: LabVIEW project using the CIE
There are two FPGA VIs used by the CIE. Both of these need to be customized for the current module configuration. Before making any changes we recommend that you rename or make a copy of each FPGA VI with a name corresponding to the application or module configuration.
The first of these VIs (CIE Get Calibration) is used in the CIE to retrieve the calibration constants for all analog I/O channels in the current configuration and also returns a cluster describing the module configuration supported by the CIE.
Figure 11: CIE FPGA Get Calibration VI
In this VI the module configuration on the diagram needs to be updated to match the current module configuration. This information is used during the initialization of the CIE to build the list of available I/O channels based on the module configuration.
The list of chassis and modules that can be selected is defined in two TypeDef’d enumerations. As new modules are released for use with the cRIO platform it may be necessary to add them to the cie_Module.ctl Typedef. If a new module is added to this TypeDef it also needs to be added to cie_Get Module Description.vi so that the list of all channels can be properly built.
In addition the code of the Get Calibration FPGA VI needs to be updated to read back the channel calibrations constants for all analog modules listed in the module configuration. The constants should be read back and listed in the array of calibration constants in order of modules from slot 1 to N and channels from channel 0 to N per module. Depending on the I/O module, some modules use calibration constants per channel, while others have a calibration per range settings. In either case all calibration constants should be read and written to the array on the front panel. Calibration constants for input and output channels should be stored in separate front panel arrays.
The second FPGA VI (CIE I/O) is used to update all of the input and output channels in the current module configuration.
Figure 12: CIE FPGA I/O VI
This VI needs to be updated so that all of the channels corresponding to all of the modules listed in the current module configuration are acquired or updated. Input and output channels are handled separately, but analog and digital channels are combined in the same list. Digital channels are handled as numerical values with one value per channel and simple conversion VIs are included in the examples. All channels must be listed in order by Slot and Channel.
For the CIE to function properly the front panel arrays Input Data and Output Data must match the module configuration which the CIE reads from the Get Calibration FPGA VI. Therefore there is some room for customization of code within this VI as long as these two arrays still match the module configuration and are updated or read at a rate suitable for the application.
There are two VIs in the RT portion of the CIE that need to be updated to match the module configuration.
During the CIE initialization, the Assign Channel Calibration subVI assigns calibration constants to each entry in the list of all available I/O channels. The exact method for assigning calibration constants depends on the specific modules used in the application. In a situation where there is one set of calibration constants per channel this process can be very simple. In other cases it may be more difficult. This VI needs to be updated to match the proper calibration constant to each channel. This will alsodepend on the array of calibration constants returned from the Get Calibration FPGA VI.
Figure 13: CIE Assign Channel Calibration VI
In the Update Output Data VI used in the CIE Update VI, the size of the array that stores the raw binary output data must be adjusted to match the number of output channels used in the CIE I/O FPGA VI.
Figure 14: CIE Update Output Data VI
Tag Configuration Editor
If the Tag Configuration Editor (TCE) is used to create the tag configuration file to store the tag and channel list used by the application, the cRIO module configuration in the TCE must be updated to match the module configuration stored in the CIE Get Calibration FPGA VI. This must be done before the tag configuration file is updated for the new application. In the current version of the TCE the module configuration is not stored in the tag configuration file and must be checked or updated in the TCE before editing the tag configuration file. Consult the documentation for the Tag Configuration Editor on Developer Zone for more information.
Additional Considerations
The cRIO I/O Engine is a design pattern for implementing a consistent and configurable I/O interface for use across a wide range of machine control applications. This component provides a complete set of VIs that can be used to implement the I/O operations as described in this document.
The design of the CIE should be considered a starting point for the implementation of the application I/O, but in many cases it will need to be extended to meet all the needs of an application. The FPGA I/O VI may need to be adjusted to place more processing on the FPGA. This could include processing of sensor data (e.g. quadrature decoder), generating a control signal (e.g. PWM), implementing safety systems (e.g. disabling outputs on external triggers, EStop detection), digital filters on analog channels, etc. If an application requires additional I/O that cannot be handled using single point I/O such as waveform acquisition or motion control, it may be implemented using additional logic in the I/O FPGA VI. This additional I/O can be accessed from other portions of the RT application using the same FPGA HW Reference created in the CIE Initialize VI.
Where to Go From Here
To provide feedback on the cRIO I/O Engine design pattern please post a comment in the Component discussion forum.
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/).









