NI LabVIEW For CompactRIO
NI LabVIEW For CompactRIO
Developers Guide
Recommended LabVIEW Architectures and Development Practices
for Control and Monitoring Applications
This document provides an overview of recommended architectures and development practices when designing control
and monitoring applications using LabVIEW Real-Time and LabVIEW FPGA software with NI CompactRIO controllers.
CONTENTS
OVERVIEW AND BACKGROUND .........................................................................................1
CompactRIO Architecture...............................................................................................................1
LabVIEW..........................................................................................................................................1
Real-Time Controller.......................................................................................................................2
Reconfigurable FPGA ....................................................................................................................3
I/O Modules.....................................................................................................................................3
SystemConfigurations....................................................................................................................4
CHAPTER 1
DESIGNING A COMPACTRIO SOFTWARE ARCHITECTURE...................................6
CompactRIO Reference Architectures ......................................................................................6
Processes........................................................................................................................................6
Data Communication .....................................................................................................................7
Typical CompactRIO Architecture.................................................................................................8
Common Variant Architectures.....................................................................................................9
ExampleBioreactor................................................................................................................... 11
CHAPTER 2
CHOOSING A COMPACTRIO PROGRAMMING MODE...........................................14
When to Use LabVIEW FPGA ....................................................................................................15
Using LabVIEW FPGA Interface Mode .....................................................................................16
CHAPTER 3
DESIGNING A LabVIEW REAL-TIME APPLICATION....................................................21
Designing a Top-Level RTOS VI ..................................................................................................21
Deterministic and Nondeterministic Processes ...................................................................22
Implementing Deterministic Processes...................................................................................23
Setting the Priority of a Deterministic Task...............................................................................23
CHAPTER 4
BEST PRACTICES FOR NETWORK COMMUNICATION...........................................47
Network Communication ............................................................................................................47
Selecting a Networking Protocol................................................................................................47
Communication Model ................................................................................................................47
Network Configuration ................................................................................................................48
Interfacing to OSs and Third-Party Applications........................................................................48
Version of LabVIEW......................................................................................................................49
Security .........................................................................................................................................49
Ease of Use Versus Performance and Reliability......................................................................49
Network Streams............................................................................................................................57
Using Network Streams to Send Messages and Commands................................................58
Installing Network Stream Support to CompactRIO................................................................60
ii
CHAPTER 5
CUSTOMIZING HARDWARE THROUGH LabVIEW FPGA........................................72
Field-Programmable Gate Array (FPGA) Technology ............................................................72
Accessing I/O ..................................................................................................................................73
Reading From an I/O Node .........................................................................................................73
Use LabVIEW Structures and Logic to Set Acquisition Rates and Triggering.......................75
Interprocess Communication...................................................................................................... 76
Variables ........................................................................................................................................ 76
Memory Items.............................................................................................................................. 76
FIFOs..............................................................................................................................................77
iii
CHAPTER 6
TIMING AND SYNCHRONIZATION OF I/O....................................................................108
LabVIEW FPGA Communication Nodes................................................................................. 108
I/O Nodes..................................................................................................................................... 109
Method Nodes............................................................................................................................ 109
Property Nodes........................................................................................................................... 109
Module Classifications.................................................................................................................111
Direct FPGA Communication.....................................................................................................111
SPI Bus Communication............................................................................................................ 112
CHAPTER 7
ADDING I/O TO THE COMPACTRIO SYSTEM...........................................................122
Adding I/O to CompactRIO .......................................................................................................122
MXI-Express RIO .........................................................................................................................123
Ethernet RIO .................................................................................................................................124
EtherCAT RIO.................................................................................................................................125
Tutorial: Accessing I/O Using the EtherCAT RIO Chassis ....................................................126
CHAPTER 8
COMMUNICATING WITH
THIRD-PARTY DEVICES.........................................................................................................131
Overview.........................................................................................................................................131
Serial Communication From CompactRIO.............................................................................131
Serial Communications From LabVIEW...................................................................................133
iv
CHAPTER 9
DESIGNING A TOUCH PANEL HMI..................................................................................146
Building User Interfaces and HMIs Using LabVIEW..........................................................146
Basic HMI Architecture Background.........................................................................................146
CHAPTER 10
ADDING VISION AND MOTION......................................................................................... 151
Machine Vision/Inspection..........................................................................................................151
Machine Vision Using LabVIEW Real-Time.............................................................................154
Machine Vision Using Vision Builder AI....................................................................................158
Motion Control...............................................................................................................................161
Getting Started With Motion on CompactRIO........................................................................164
LabVIEW Example Code............................................................................................................ 177
CHAPTER 11
DEPLOYING AND REPLICATING SYSTEMS.................................................................179
Application Deployment.............................................................................................................. 179
Deploying Applications to CompactRIO.................................................................................. 179
Deploying LabVIEW FPGA Applications..................................................................................184
Method 2: Storing the Application in Nonvolatile Flash Memory on the FPGA Target.....186
Deploying Applications That Use Network-Published Shared Variables..............................187
Recommended Software Stacks for CompactRIO................................................................190
System Replication.......................................................................................................................191
The Real-Time Application Deployment Utility (RTAD)..........................................................192
CompactRIO Architecture
CompactRIO is a rugged, reconfigurable embedded system containing three components: a processor running a
real-time operating system (RTOS), a reconfigurable field-programmable gate array (FPGA), and interchangeable
industrial I/O modules. The real-time processor offers reliable, predictable behavior and excels at floating-point math
and analysis, while the FPGA excels at smaller tasks that require high-speed logic and precise timing. Often CompactRIO
applications incorporate a human machine interface (HMI), which provides the operator with a graphical user interface
(GUI) for monitoring the systems state and setting operating parameters.
LabVIEW
LabVIEW is a graphical programming environment used by millions of engineers and scientists to develop sophisticated
control systems using graphical icons and wires that resemble a flowchart. It offers integration with thousands of
hardware devices and provides hundreds of built-in libraries for advanced control, analysis, and data visualizationall for
creating user-defined systems more quickly. The LabVIEW platform is scalable across multiple targets and OSs, and,
in the case of CompactRIO, LabVIEW can be used to access and integrate all of the components of the reconfigurable
I/O (RIO) architecture.
Real-Time Controller
The real-time controller contains a processor that reliably and deterministically executes LabVIEW Real-Time applications
and offers multirate control, execution tracing, onboard data logging, and communication with peripherals. Additional
options include redundant 9 to 30 VDC supply inputs, a real-time clock, hardware watchdog timers, dual Ethernet
ports, up to 2 GB of data storage, and built-in USB and RS232 support.
Run loops with nearly the same timing on each iteration (typically within microseconds)
Reliability
In addition to offering precise timing, RTOSs can be set up torun reliably for days, months, or yearswithout stopping.
This is important not only for engineers building systems that need 24/7 operation but also for any application where
downtime is costly. A watchdog feature is also typically included in real-time systems to automatically restart an
entire computer if the user program stops running. Furthermore, hardware used in a real-time system is often designed
to be rugged to sustain harsh conditions for long periods.
Reconfigurable FPGA
The reconfigurable FPGA chassis is the center of the embedded system architecture. The RIO FPGA is directly
connected to the I/O for high-performance access to the I/O circuitry of each module and timing, triggering, and
synchronization. Because each module is connected directly to the FPGA rather than through a bus, you experience
almost no control latency for system response compared to other controller architectures. By default, this FPGA
automatically communicates with I/O modules and provides deterministic I/O to the real-time processor. Out of the
box, the FPGA enables programs on the real-time controller to access I/O with less than 500 ns of jitter between
loops. You can also directly program this FPGA to further customize the system. Because of the FPGA speed, this
chassis is frequently used to create controller systems that incorporate high-speed buffered I/O, fast control loops, or
custom signal filtering. For instance, using the FPGA, a single chassis can execute more than 20 analog proportional
integral derivative (PID) control loops simultaneously at a rate of 100 kHz. Additionally, because the FPGA runs all
code in hardware, it provides the highest reliability and determinism, which is ideal for hardware-based interlocks,
custom timing and triggering, or eliminating the custom circuitry normally required with nonstandard sensors and
buses. For an overview of FPGA technology, see Chapter 5: Customizing Hardware Through LabVIEW FPGA.
I/O Modules
I/O modules contain isolation, conversion circuitry, signal conditioning, and built-in connectivity for direct connection
to industrial sensors/actuators. By offering a variety of wiring options and integrating the connector junction box into
the modules, the CompactRIO system significantly reduces space requirements and field-wiring costs. You can
choose from more than 50 NIC Series I/O modules for CompactRIO to connect to almost any sensor or actuator.
Module types include thermocouple inputs; 10 V simultaneous sampling, 24-bit analog I/O; 24 V industrial digital I/O
with up to 1 A current drive; differential/TTL digital inputs; 24-bit IEPE accelerometer inputs; strain measurements;
RTD measurements; analog outputs; power measurements; controller area network (CAN) connectivity; and secure
digital (SD) cards for logging. Additionally, you can build your own modules or purchase modules from third-party
vendors. With the NIcRIO-9951 CompactRIO Module Development Kit, you can develop custom modules to meet
application-specific needs. The kit provides access to the low-level electrical CompactRIO embedded system
architecture for designing specialized I/O, communication, and control modules. It includes LabVIEW FPGA libraries
to interface with your custom module circuitry.
Figure 4. You can choose from more than 50 NIC Series I/O modules for CompactRIO
to connect to almost any sensor or actuator.
SystemConfigurations
The simplest embeddedsystem consists of a single controller running in a headless configuration.This
configuration isused in applications that do not need an HMI except for maintenance or diagnostic purposes.
However, a majority of control and monitoring applications requires an HMI to display data to the operator or to allow
the operator to send commands to the embedded system. A common configuration is 1:1, or 1 host to 1 target, as
shown in Figure 5. The HMI communicates to the CompactRIO hardware over Ethernet through either a direct
connection, hub, or wireless router.
The next level of system capability and complexity is either a 1:N (1 host to N targets) or N:1 (N hosts to 1 target
configuration). The host is typically either a desktop PC or an industrial touch panel device. The 1:N configuration,
shown in Figure 6, is typical for systems controlled by a local operator. The N:1 configuration is common when
multiple operators use an HMI to check on the system state from different locations.
Figure 6. A 1:N (1 host to N targets) configuration is common for systems controlled by a local operator.
Complex machine control applications may have an N:N configuration with many controllers and HMIs (Figure 7).
They often involve a high-end server that acts as a data-logging and forwarding engine. This system configuration
works for physically large or complex machines. Using it, you can interact with the machine from various locations or
distribute specific monitoring and control responsibilities among a group of operators.
This guide walks through recommended implementations for a variety of FPGA, controller, and HMI architecture
components. It also offers example code and, in some cases, alternative implementations and the trade-offs
between implementations.
CHAPTER 1
DESIGNING A COMPACTRIO
SOFTWARE ARCHITECTURE
Almost all CompactRIO systems have a minimum of three top-level VIs executing asynchronously across three
different targets: the FPGA, the real-time operating system (RTOS), and a host PC. If you begin your software
development without having some sort of architecture or flowchart to refer to, you may find keeping track of all of
the software components and communication paths to be challenging. Having a diagram that describes all of the
system pieces at a high level helps guide development and communication about the design with stakeholders. This
section describes several common CompactRIO architectures that you can use as a starting point for many
applications. You also can use them as a guide for creating your own architecture.
The example architectures in the following sections were created using a vector-based drawing program called the
yEd Graph Editor, which is a free design tool downloadable from yworks.com.
Processes
The first step in identifying the processes that your application contains is to create a list of tasks that your
application needs to accomplish. Common tasks include PID control, data logging, communication to an HMI,
communication to I/O, and safety logic or fault handling. The next step is deciding how the tasks are divided into
processes. An application with a large number of processes requires more time to be spent on interprocess data
communication. At the same time, breaking your tasks into individual processes makes your program more scalable.
For example, you might have a real-time application during the first phase of a project that is communicating across
the network to a user interface (UI) built with LabVIEW, but later on the application needs to communicate to a web
browser. If you separate the network communication task from other tasks within the application, you can redesign
your network communication process without impacting your control process. More information on designing
processes in LabVIEW Real-Time can be found in Chapter 3: Designing a LabVIEW Real-Time Application.
Data Communication
Once youve diagrammed your processes, the next step is to identify data communication paths. Data
communication is one of the most important factors to consider when designing an embedded system. LabVIEW,
LabVIEW Real-Time, and LabVIEW FPGA include many different mechanisms for transferring data between
processes on a single target as well as processes that communicate across targets.
Choosing a data communication mechanism depends on several factors, with the primary factor being the data
communication model. Most CompactRIO applications can contain at least two or more of the data communication
models listed below:
Command-/message-based communication
Streaming/buffered communication
Updates
Each model has different data transfer requirements. These models apply to both interprocess communication and
intertarget communication. Later chapters refer to these data communication types when recommending LabVIEW
mechanisms for data transfer between processes on a Windows target, real-time target, or FPGA target in addition
to communication between the CompactRIO device and a host PC.
Command-/Message-Based Communication
Command- or message-based communication is something that happens relatively infrequently and is triggered by
some specific event. An example is a user pushing a button on an HMI to stop a conveyor belt. In message-based
communication, it is important to guarantee delivery of the message in a timely manner or with low latency. In the
previous example, when the operator pushes the stop button, the operator expects an immediate response (a
humans perception of immediate is on the order of tenths of a second). It is often desirable to synchronize a
process to the incoming message or command to conserve processor resources. This involves blocking until a
message is received or a timeout occurs.
Streaming/Buffered Communication
Streaming or buffered communication involves the high-throughput transfer of every data point, where throughput is
more important than latency. Typically, one process writes data to another process that reads, displays, or processes
that data. An example is an in-vehicle data logger that sends data from the FPGA to the RTOS for data logging.
Streaming often requires multilayer buffering, during which each end (the sender and the receiver) has its own
uniquely sized buffer. This is ideal when you have a processor loop that wants to read large chunks of data at a time
and a data acquisition loop that writes smaller chunks of data at shorter intervals.
Updates
Updates are like a combination of tags and messages. Instead of periodically polling the current value like you would
with a tag, you want to wait until the value changes. For example, if you are monitoring the heartbeat of another device
on the network, you only are interested in knowing when the value of the heartbeat (dead or alive) changes. It is
often desirable to have broadcasting capabilities when dealing with updates.
A summary of the different types of data communication models and their features is shown in Table 1.1. Keep these
features in mind when selecting a data communication model.
Communication Type
Fundamental Features
Optional Features
Performance
Message-Based
Low latency
Nonhistorical
Low latency,
high-channel count
Updates
Broadcasting
Low latency
Streaming/Buffered
Multilayer buffering
High throughput
On the RTOS_Main.vi, the communication task and control task are designed as two separate loops. This is generally
a good practice since the network communication could impact the determinism of the control algorithm if the tasks
are executed within a single loop. Also, the modularity makes it easier to simulate parts of the system. For example,
you could easily swap out the actual control loop with a simulated control loop to test the network communication.
Embedded Monitoring
Embedded monitoring applications typically require data to be streamed at high rates from the C Series I/O modules
up to a host user interface where the data is displayed to an operator. The user interface also allows the operator to
configure the hardware, requiring a mechanism for sending commands from the host down to the RTOS.
10
ExampleBioreactor
abVIEW example code
L
is provided for this section.
An example of a bioreactor control system demonstrates how the control and monitoring architecture in Figure 1.6
could apply to an actual application. A bioreactor is a mechanical vessel in which organisms are cultivated and
materials are transformed through chemical reactions. The vessels environmental conditions like gas, flow rates,
temperature, pH levels, and agitation speed need to be closely monitored and controlled. A diagram of a basic
bioreactor is shown in Figure 1.7.
11
Phase 2
Phase 3
Temp 35 C
Temp 40 C
Temp 38 C
pH 1.5
pH 1.2
pH 1.2
Agitator ON
Agitator OFF
Agitator ON
Intake: ON
Intake: OFF
Intake: OFF
Waste: OFF
Waste: ON
Waste: OFF
Time: 5 minutes
Time: 2 minutes
Time: 5 minutes
To create an architecture for the bioreactor system, start with the control and monitoring architecture shown in
Figure 1.8.
Since this application interfaces to single-point I/O and does not require update rates faster than 500 Hz, the I/O was
implemented using the RIO Scan Interface. The RIO Scan Interface, included in the LabVIEW Real-Time Engine,
helps you access your I/O channels as variables within the LabVIEW Real-Time development environment. Find more
information on using the RIO Scan Interface versus LabVIEW FPGA in Chapter 2: Choosing a CompactRIO
Programming Mode.
Figure 1.9 shows an example of a design diagram for the bioreactor application. Data communication mechanisms
are labeled on each arrow. The following process components were reused from the example control and monitoring
architecture in Figure 1.8:
UI UpdateReceives the latest pH and temperature values as network-published I/O variables (IOVs) from the
RIO Scan Interface and displays them to a user interface.
UI Event HandlerUses an event structure to handle user events, such as Run Recipe or Temperature
Override.
Command SenderSends any commands received from the UI Event Handler to the CompactRIO controller
using network streams.
Command ParserReceives commands from the Command Sender process and sends them to the Recipe
Engine process using queues (Q). It sends override commands to the control task using single-process shared
variables (SP-SV). Queues are not used because they impact control-loop synchronization.
12
Control TaskControls the pH and temperature using a PID algorithm; is executed at a higher priority than
other processes on the real-time system.
Recipe EngineManages and executes incoming recipes. It shares recipe data (temperature setpoint = 25,
pump ON, and so on) with the control loops using single-process shared variables.
Pump ON/OFFControls the state of the pumps and agitation.
To view and run the actual bioreactor application, download the Bioreactor Example from Section 1 Downloads.
13
CHAPTER 2
CHOOSING A COMPACTRIO
PROGRAMMING MODE
The CompactRIO architectures presented in Chapter 1 provide you with the option to implement your I/O by
customizing the FPGA hardware through LabVIEW FPGA or by using the NIRIO Scan Interface. If you have LabVIEW
Real-Time and LabVIEW FPGA on your development computer, you are prompted to select which programming
mode you would like to use when you add a CompactRIO target to your LabVIEW project. RIO Scan Interface
support was added in LabVIEW 8.6.
Figure 2.1. If you have LabVIEW FPGA installed, you are prompted to select a programming mode
when adding a CompactRIO system to your LabVIEW project.
14
Figure 2.2. With LabVIEW FPGA, you can create custom FPGA VIs for high-speed data acquisition,
control loops, or custom timing and triggering.
15
Encoding/decoding sensors
Tachometers
Data reduction
Third-party IP integration
Sensor simulation
Hardware-in-the-loop simulation
16
Figure 2.3. Block Diagram Description of the RIO Scan Interface Software Components
When deciding to use the RIO Scan Interface for a CompactRIO application, you should consider the required
performance or loop rates and channel count. The graph in Figure 2.4 shows benchmarking that was completed
using the RIO Scan Interface for a PID control loop, including one analog input and one analog output. The data
shows that PID loop rates higher than 100 Hz combined with a high-channel count have a significant impact on CPU
usage. Generally, you should not use the RIO Scan Interface when you require loop rates faster than 500 Hz.
Figure 2.4. When using the RIO Scan Interface, high-channel counts combined with
high-loop rates have a significant impact on CPU.
Although you should not use the RIO Scan Interface for high-speed data acquisition or control loops, it does offer
several benefits:
Ease of ProgrammingDrag and drop your I/O variables directly into your LabVIEW Real-Time VI during
development.
Ability to Dynamically Detect I/O ModulesSlots not configured through the project automatically detect
inserted modules. You can then configure these modules through the variable API.
17
Fault EngineThe NIScan Engine features the built-in NIFault Engine that throws errors deterministically.
Diagnostics and DebuggingWith the Distributed System Manager, you can view current values and
faults as well as override current I/O values while your program is running.
Not all CompactRIO hardware works with the RIO Scan Interface. For a list of C Series I/O modules that feature RIO
Scan Interface support, see C Series Modules Supported by CompactRIO Scan Mode. CompactRIO targets with
1M gate FPGAs cannot fully support the scan interface. You can implement some scan interface features on
unsupported targets, but you must use LabVIEW FPGA. The KnowledgeBase article Using CompactRIO Scan Mode
with Unsupported Backplanes describes how to use LabVIEW FPGA to build a custom Scan Mode interface for an
unsupported FPGA target.
Figure 2.5. Drag and drop I/O variables onto your Real-Time VI block diagram.
The Scan Engine also provides a Timed-Loop timing source, so you can synchronize code with I/O updates for low-jitter
control applications.
18
Figure 2.6. Use a Timed Loop with the clock source set to Synchronize to Scan Engine
to synchronize the loop to I/O updates.
You can find example programs for the RIO Scan Interface at \LabVIEW\examples\ScanEngine.
Figure 2.7. After activating Hybrid Mode, write an FPGA VI to interface with the module
and pass data to the real-time host.
19
In Hybrid Mode, you can continue using the RIO Scan Interface on some modules while programming others directly
on the FPGA. You can use the FPGA programming model to handle high-speed operations, inline processing,
waveform buffered acquisition, and certain modules that do not feature Scan Mode support. Activate FPGA
programming for a particular module by dragging and dropping the module project item from under the CompactRIO
chassis to under the FPGA target. By doing this, you can program the FPGA for custom code running in parallel with
the scan interface for other modules. You can access the FPGA I/O from the real-time VI by using either the FPGA
Host Interface Functions or User-Defined Variables.
Figure 2.8. Activate FPGA programming for a particular module by dragging and dropping the module
project item from under the CompactRIO chassis to under the FPGA target.
You need to note a few important limitations when using Hybrid Mode. First, the compile time significantly increases
because the compiler has to combine the default RIO Scan Interface bitfile as well as the FPGA code that was
created into one bitfile. Secondly, the number of DMA channels that you can use in the FPGA code is reduced since
the Scan Engine uses two channels. Most FPGAs have three DMA channels, so most applications have only one
DMA channel left to use in the FPGA code.
20
CHAPTER 3
DESIGNING A LabVIEW REAL-TIME
APPLICATION
When creating a LabVIEW Real-Time application for CompactRIO, start with a design diagram as described in
Chapter 1: Designing a CompactRIO Software Architecture. If you begin your software development without
having some sort of architecture or flowchart to refer to, you may have difficulty keeping track of all software
components and communication paths. Once you have created a design diagram, the next step is to implement your
LabVIEW Real-Time code.
Figure 3.1. Creating a top-level VI with the general structure of the program filled out is
a good starting point for developing a LabVIEW Real-Time application.
21
Once you have designed your top-level RTOS VI, the next step is to implement each of your processes. This chapter
provides best practices for designing processes in LabVIEW Real-Time, including deterministic versus
nondeterministic processes, interprocess data communication, design patterns, and memory management.
Figure 3.2. Jitter is a measure of how much the execution time of a task differs over subsequent iterations.
CompactRIO helps you bound the amount of jitter, which may be a requirement for mission-critical applications. You
can choose from two options for designing a deterministic application with one or more processes that require a
hard bound on the amount of jitter:
1. Implement critical tasks using LabVIEW FPGASince your LabVIEW FPGA code is running in hardware rather
than within an OS, you can guarantee that a critical task does not crash or hang. An RTOS is more
deterministic and reliable than a general-purpose OS, but it is still subject to software crashes if not
programmed correctly.
2. Implement critical tasks using Timed Loops in LabVIEW Real-TimeSlightly more complex than a While Loop,
a Timed Loop is designed to execute deterministic tasks with minimal jitter.
The next section describes implementing deterministic processes using Timed Loops and VI priorities. If your
application does not contain any tasks that require bounded jitter, use While Loops with timing functions instead of
Timed Loops. Timed Loops offer many useful built-in features but also involve more overhead and complexities than
While Loops. You can benefit from the reliability of an RTOS without using Timed Loops, but you cannot place a
bound on or minimize jitter.
22
Nondeterministic Tasks
Closed-loop control
File I/O
Decision-making logic
Safety logic
Timed Loops
A Timed Loop is similar to a While Loop but includes additional features for executing code deterministically. With a
Timed Loop, you can specify the period and priority at which your code executes. The higher the priority of a Timed
Loop, the greater the priority the structure has relative to other timed structures on the block diagram. The Timed
Loop on your block diagram with the highest priority is referred to as your time-critical loop. You can configure the
priority and period dynamically on the block diagram or through a configuration window that you launch when you
double-click the left input node on the Timed Loop.
23
Figure 3.3. You can specify the period and priority of a Timed Loop through
the Timed Loop configuration dialog.
When using Timed Loops on an RTOS, timing is important. When a time-critical loop is called, it is the only loop on
the block diagram that executes. If a time-critical loop is set to run 100 percent of the time and never go to sleep, it
completely monopolizes one core of your system. Be sure to specify a period that is reasonable for your time-critical
loop but allows other background tasks within your application to execute.
One way to prevent undesired timing behavior is to create a time budget for your application. Time budgeting involves
determining the amount of time required to execute each loop in the application and setting the rates of the loops
accordingly. Your timing budget should restrict your application to using no more than 80 percent of the available CPU.
Find instructions for creating a time budget in the LabVIEW Real-Time Help file Avoid Jitter (Real-Time Module).
VI Priorities
You can also set the priority of a deterministic section of code by placing it within a subVI and modifying the VI
priority through the VI Properties dialog. Be cautious about using Timed Loops and VI priorities in the same
application, and try to avoid if possible. If you must use both, you should have a solid understanding of how they
relate. If you have a VI with a priority that contains a Timed Loop with a priority, the Timed Loop ignores the VI
priority. In comparison to the VI priorities shown in Figure 3.4, Timed Loops execute at just below time-critical priority
(highest) and at just above VIs with high priority. VIs with time-critical priority settings take precedence over Timed
Loops. The While Loop executes at normal priority.
24
Figure 3.4. You can specify the priority of a VI through the VI Properties dialog
under the Execution category.
Description
Data Transfer
Mechanism
Single-Process
Shared Variable or
Current Value Table
Updates
Notifier Functions
RT FIFOs
Streaming
RT FIFOs
RT FIFOs
Command-/
Message-Based
Queue Operations
RT FIFOs
Table 3.2. Recommended Interprocess Data Communication Mechanisms for Each Communication Model
Note that the transfer type is only one of the considerations when picking a data communication mechanism. You
may have valid use cases for implementing an update using a command-based mechanism or vice versa based on
the other considerations mentioned such as ease of implementation, scalability, or performance. The next section
offers best practices for implementing each type of communication model in LabVIEW Real-Time.
25
Figure 3.5. You can use single-process shared variables for tag communication
between multiple processes.
To create a single-process shared variable, right-click a real-time target in the Project Explorer window and select
NewVariable from the shortcut menu. In the Shared Variable Properties dialog box, you can set the variable type as
Single Process (a single-process shared variable is a global variable).
26
If your application contains a relatively large number of variables and you require tag management features such as
dynamic tag lookup, you should consider the current value table, which is designed to handle a large number of
tags efficiently.
Since single-process shared variables are based on global variables, they act as a shared resource, which can
introduce jitter if used within a time-critical loop. If you are interested in using single-process shared variables within
a time-critical loop, be sure to enable RT FIFOs in the variable properties dialog. Single-process shared variables with
RT FIFOs enabled are discussed in the upcoming section titled RT FIFOs.
The basic API writer example is shown in Figure 3.8. In the API call, the variable name is used to look up the index of
the variable, and then the value is accessed from the CVT using the index. This example assigns random number
data to Var0 Var4 tags and writes to the Stop and Index tags. You can initialize the tags using a cluster array, as
shown in Figure 3.8, or load them from a file using the CVT Load Tag List VI.
27
The Basic CVT Reader example in Figure 3.9 reads the current value of the tags within another instance of the
application. Both examples use the Format Into String function to dynamically look up Var0 Var4 tags.
You can find more information on the CVT in the NIDeveloper Zone document Current Value Lookup Table
Reference Library.
Instructions for Installing the CVT Library
Step 1: Navigate to ni.com/labviewtools
Step 2: Download and install the VI Package Manager
Step 3: Within VI Package Manager, search for CVT
Queue Operations
Queues are the recommended protocol for command- or message-based communication between two
nondeterministic processes because they are flexible, easy to use, and allow you to transfer buffered data. When
sending messages, you might need to send multiple data types within a single packet. Queues support the Cluster
data type, which you can use to bundle together different data types, both fixed size and variable size such as
strings. You can use queues on both real-time and Windows OSs.
The block diagram in Figure 3.10 shows a loop that performs a data acquisition task. The data acquisition loop shares
the acquired data with the second loop using queues. The second loop logs the acquired data that it reads from the
queueto disk on the real-time target.
28
Figure 3.10. You can use queues to transfer buffered data between two nondeterministic loops.
The Queue Operations palette is included in LabVIEW and can be found on the Functions Palette under
SynchronizationQueue Operations. You can find example programs using queues in the NIExample Finder.
RT FIFOs
RT FIFOs are first-in first-out buffers that behave deterministically. You can implement them using RT FIFO functions
that are similar to the Queue Operations functions, or with an RT FIFO-enabled shared variable. Both mechanisms are
the same under the hood. While RT FIFO-enabled shared variables have a simpler implementation than RT FIFO
functions, RT FIFO functions give you more control. For example, with RT FIFO functions, you can decide when the
FIFOs are created and when they are shut down. A shared variable is automatically created when it is first called, and
it is shut down when the application is stopped. You also have control over configuration options such as polling versus
blocking for optimizing performance, and you can use more complex data types such as clusters (as long as they
contain fixed-size elements). This section discusses both RT FIFO functions and RT FIFO-enabled shared variables.
RT FIFO Functions
RT FIFO functions are similar to Queue Operations but are less flexible and more deterministic. They are recommended
for streaming data between any two processes on an RTOS because they always preallocate memory and have a
maximum buffer size. RT FIFOs are also recommended for transferring commands or messages to or from a timecritical loop. They provide a deterministic data transfer method that does not add jitter. Queues and RT FIFOs differ in
the following ways:
Queues can handle string, variant, and other variable-sized data types, but RT FIFOs cannot.
RT FIFOs are fixed in size, so they can communicate data between Timed Loops without dynamically allocating
new memory. Queues can grow as elements are added to them.
Queues use blocking calls when reading/writing to a shared resource, which can block another loop from
running and impact determinism. RT FIFOs do not use blocking calls.
RT FIFOs execute regardless of errors at input to maintain determinism; queues do not execute on error.
29
The block diagram in Figure 3.11 is similar to the previous example using queues, but since the data acquisition loop
is now deterministic, you use RT FIFO functions to share data. The deterministic loop with a priority of 100 shares
the acquired data with the nondeterministic loop using an RT FIFO function. The nondeterministic loop logs the
acquired data that it reads from the RT FIFOto disk on the real-time target. You can download a more advanced
example of RT FIFOs from Chapter 4: Best Practices for Network Communication.
Figure 3.11. You can use RT FIFOs to transfer buffered data to or from a time-critical loop.
Because of the fixed-size restriction, an RT FIFO can be a lossy communication method. Writing data to an RT FIFO
when the FIFO is full overwrites the oldest element. You must read data stored in an RT FIFO before the FIFO is full
to ensure the transfer of every element without losing data. Check the overwrite output of the RT FIFO Write
function to ensure that you did not overwrite data. If the RT FIFO overwrites data, the overwrite output returns a
TRUE value.
The RT FIFO palette is included in LabVIEW Real-Time and can be found on the Functions Palette under LabVIEW
Real-TimeRT FIFO. You can find example programs featuring RT FIFOs in the NIExample Finder.
30
Figure 3.12. You can use RT FIFO-enabled shared variables to transfer buffered data
to or from a time-critical loop.
To enable the RT FIFO on a shared variable, navigate to the RT FIFO page of the Shared Variable Properties dialog
box and place a checkmark in the Enable Real-Time FIFO checkbox.
Figure 3.13. By enabling the RT FIFO, you can read and write to a shared variable
from multiple parallel loops without inducing jitter.
Use a single-element RT FIFO to transfer the latest values (tags or updates) and use a multi-element RT FIFO to
transfer the buffered values (messages or streams). A multi-element FIFO features a buffer for which each write adds
31
another element to the buffer and each read removes an element from the buffer. As long as the worker loop checks
the FIFO frequently, you can leave the buffer at the default of two elements and not miss any triggers/commands.
To check the FIFO, the worker task must read the shared variable and check the error status. If the FIFO is empty,
the shared variable returns the warning -2220. If this warning is not returned, then the FIFO was not empty and the
returned value is a valid command.
Each time the shared variable is read, one element is removed from the FIFO (assuming the FIFO is not empty).
Because of this, you cannot have multiple workers receive a command from the same FIFO, but you can have
multiple commanders putting commands into the FIFO.
Numeric Commands
Commands can also be more complex than a simple trigger. The shared variable works with multiple data types, and, if
you set it to a numeric, you can use it to pass a number of different commands. An enumerated type definition, in the
form of a LabVIEW enum, is an effective way to define commands that can be directly passed to the shared variable.
Notifier Operations
Notifiers are recommended for sending updates between two nondeterministic loops. Updates vary from tags since
they usually require blocking until new data is received to conserve processor resources. With tags, the receiver is
periodically polling data, whether or not it has changed. Notifiers also offer the ability to broadcast data to multiple
receivers.
Figure 3.16 features a good example of notifiers. The elevators should remain on the first floor until a user presses
one of the buttons on the front panel1st, 2nd, 3rd, or 4th floor. Since the timing of when the user presses a button
is intermittent, you should block instead of poll to conserve processor resources. You can find this example in the
NIExample Finder. The Wait on Notification function is used for blocking until one of the elevator buttons is pressed.
You also can implement notifiers to share current value data, which involves polling, by using the Get Notifier
function instead of the Wait on Notifier function. This is an efficient method for sharing the value of a Stop button
between multiple loops on a single target.
32
Note that the transfer type (tag, update, command/message, or stream) is only one of the considerations when picking
a data communication mechanism. For example, you may need to implement an update using a command-based
mechanism, based on the other considerations mentioned such as ease of implementation, scalability, or performance.
Greater reliability
Easier debugging
Enhanced maintainability
Before viewing some common design patterns, you need to understand your options for synchronizing loops in
LabVIEW Real-Time. Synchronization is the foundation of any design pattern.
33
Periodic Loop
A periodic loop runs continuously at a defined period. The temperature and pH control loop in the bioreactor
application is periodic. The temperature and pH control loop is synchronized to the Scan Engine, which executes
periodically. You can set the scan period through the Real-Time CompactRIO Properties dialog by right-clicking the
CompactRIO controller in the LabVIEW project and selecting Properties from the drop-down menu.
Figure 3.17. Configure the scan period of the Scan Engine when programming
with the RIO Scan Interface.
In the example shown in Figure 3.18, the temperature and pH control loop executes at a period of 10 ms or 100 Hz.
The pH task and temperature control task are implemented as a single process because they share the same period
and the same priority (time critical). Timed Loops are single-threaded, so you can serialize your tasks using error
wires to guarantee that the data nodes execute in the same order every time the loop is called. If you implement
these tasks as two separated Timed Loops with equal priority, they still execute in the same thread, but you cannot
guarantee the order of execution. The benefit is that switching to multirate PID control loops is easier. You should
base a decision like this on your application requirements.
You also can implement periodic loops by using a While Loop with timing functions or by controlling the period input
of a Timed Loop. Be careful not to add any functions that would introduce blocking or other types of synchronization
(for example, queues with no timeout). You generally should use Timed Loops only when implementing a periodic
task since any type of blocking introduces jitter.
34
Figure 3.18. The temperature and pH control task executes at a period of 10 ms.
Event-Driven Loop
An event-driven loop executes only when an event occurs. Often the event is receiving a message from another
process. The command parser loop in the bioreactor application is event driven. In the command parser example, the
synchronization source is the Read Single Element from Stream function. The timeout is set to default (-1), which
means the function never times out and the loop executes only when a command is received from the host. Other
commonly used functions that force an event-driven architecture include the following:
Queues
Notifiers
RT FIFOs
When using an event-driven design pattern, you can block until a message is received or until a timeout occurs.
When blocking with no timeout, you are efficiently using the CPU, but you are also preventing any background tasks
from running. If you add a timeout to any of these functions, you can have a timeout state during which you can
execute background tasks while waiting on messages.
35
Scheduled Loop
A scheduled loop executes at an absolute time. An example is a maintenance routine that executes every day at
midnight. This type of synchronization is less common.
Design Patterns
The design patterns common in LabVIEW Real-Time applications are similar to those used in LabVIEW for Windows
applications. This section examines two design patterns: state machine and producer consumer.
State Machine
A state machine is a common and useful design pattern. You can use a state machine to implement any algorithm that
can be explicitly described by a state diagram or flowchart. A state machine usually illustrates a moderately complex
decision-making algorithm, such as a diagnostic routine or a process monitor. To learn the basics of the state machine
architecture in LabVIEW, see the NIDeveloper Zone document Application Design Patterns: State Machine.
A state machine design pattern may contain both periodic and event-based synchronization. An example of a state
machine is the bioreactor recipe engine, which is described by the flowchart in Figure 3.20.
The state machine starts in the Wait for Cmd state, shown in Figure 3.21. This state waits on a command from the
command parser loop. It uses a queue with a default timeout (-1) to block until a command is received.
36
The Load Phase state does not involve any type of synchronization. It simply executes a task and moves to the next
state when that task is complete. The Load Phase state checks how many phases are in the recipe and loads one
phase each time it is called.
The Run Phase state features periodic synchronization. It uses a Sequence Structure with a Wait until Next ms
Multiple function to control the timing. This state holds each tag at the value defined by the recipe until the specified
time has elapsed. When the time has elapsed, the recipe engine loads the next phase. If there are no more phases
to execute, it returns to the Wait for Cmd state.
37
Producer Consumer
A producer consumer design pattern is used to transfer data between processes that produce and consume data at
different rates. On Windows OSs, a producer consumer is commonly implemented with queue functions. In
LabVIEW Real-Time, it can be implemented with queues or RT FIFOs. You can implement a producer consumer
design pattern so that it shares data between two loops or it shares events.
Use a data-sharing producer consumer design pattern when you need to execute a process such as data analysis,
when a data source, such as a triggered acquisition, produces data at an uneven rate and you need to execute the
process when the data becomes available.
Use an event-sharing producer consumer design pattern when you want to execute code asynchronously in
response to an event without slowing the user interface responsiveness.
An example of a producer consumer event-sharing design pattern is the HMI included in the bioreactor application,
shown in Figure 3.23. This application has one loop dedicated to receiving events from the user interface and a
second loop that processes the commands and sends them across the network to the CompactRIO controller. Since
network communication functions rely on a resource (the network), they could impact the UI performance if placed
in a UI Event Handler loop.
Because this application runs on a Windows host PC, you use queues to share data between the two loops. A real-time
application can use either queues or RT FIFOs to share data depending on whether a time-critical loop is involved.
38
Figure 3.24. Disk space, RAM, and CPU bandwidth are typically limited in embedded application design.
39
Figure 3.25. Check free disk space and memory within MAX.
To programmatically obtain the free disk space, use the Get Volume Info function when targeted to the controller.
You can find this function on the Advanced File Functions palette (ProgrammingFile I/OAdvanced File
FunctionsGet Volume Info).
40
Figure 3.27. Statically Allocating a Large Block of Memory by Initializing a Large Array
If your LabVIEW code does not fit onto your real-time target, you can eliminate memory copies, eliminate
unnecessary drivers, or choose a hardware target with more onboard memory.
Check for memory copies
You can use the Show Buffer Allocations Window to identify where LabVIEW can create copies of data. To display
the Show Buffer Allocations Window, selectToolsProfileShow Buffer Allocations. Place a checkmark next to the
data type(s) you want to see buffers for and click theRefresh button. The black squares that appear on the block
diagram indicate where LabVIEW creates buffers to allocate space for data.
Once you know where LabVIEW creates buffers, you might be able toedit the VI to reduce the amount of
memoryLabVIEW requires to run the VI. For tips on reducing memory copies, see the NIHelp document
VI Memory Usage starting at the section Determining When Outputs Can Reuse Input Buffers.
41
Figure 3.29. Uninstall software drivers that you are not using to increase memory.
42
Avoid memory leaks by closing all of the references that you open during initialization. It is also a safe practice to
replace the terminals of any reference with shift registers.
Avoid overallocation by using fixed-size data
Overallocation occurs when the program tries to store too much data in RAM. It typically results from a queue or
buffer without a fixed size. The graph in Figure 3.30 shows a situation where a buffer is expanding. Note that once a
buffer expands, it generally does not contract. The buffer could be getting periodically emptied as the code runs, but
it still retains the size of its largest value.
Variable-sized strings
Variants
Two methods for sharing data between processes on a real-time target are discussed in this chapter. By default,
queues have a variable-sized buffer. Even with a fixed number of elements, a queue that contains variable-sized data
(strings, variants) is still variable sized. This is also true for network streams and shared variables. If you are working
on an application for which dynamic memory allocation is a concern, use RT FIFOs for transferring data between
processes. RT FIFOs limit you to a fixed-sized buffer and fixed-sized data types.
43
Figure 3.31. Memory on an RTOS becomes fragmented over time, making it difficult for the memory
manager to locate a large block of contiguous memory.
You can keep your contiguous memory healthy by minimizing dynamic memory allocations and preallocating space
for arrays equal to the largest expected array size. Figure 3.32 shows how you can preallocate memory for an array
by using the Initialize Array and Replace Array Subset functions. The array is created only once and Replace Array
Subset can reuse the input buffer for the output buffer. You should preallocate an array if you can determine the
upper size limit of the array.
44
Figure 3.33. Programmatically monitor memory with the RT Get Memory Usage VI.
You should also include a safe shutdown routine that performs the following functions:
Check out the NIDeveloper Zone document Fail-Safe Control Reference Design for more information on this topic.
You can also monitor the memory usage using the NIDistributed System Manager in LabVIEW under the Tools menu.
Figure 3.34. Monitor CompactRIO memory usage with the NIDistributed System Manager.
45
Figure 3.35. Monitor CPU usage with the RT Get CPU Loads VI.
46
CHAPTER 4
BEST PRACTICES FOR NETWORK
COMMUNICATION
Network Communication
For embedded CompactRIO applications, communication with a remote client is often a critical part of the project.
Embedded applications typically function as data servers because their primary role is to report information
(status, acquired data, analyzed data, and so on) to the client. They are also usually capable of responding to
commands from the client to perform application-specific activities.
Communication Model
The communication models discussed in chapters 1 and 3 pertain to both interprocess communication and network
communication. These models are current value data (tags), updates, streaming, and command-/message-based
communication. Understanding the type of data transfer you need is the most important consideration when
choosing a networking mechanism. Table 4.1 provides examples of when you might use current value data (tags),
updates, streaming, or command-based data communication for networked applications.
47
Communication
Model
Description
Example
Updates
Streaming
Command/
Message-Based
Network Configuration
The network configuration is another important consideration. In multiclient applications, clients may connect and
disconnect at random times. The TCP/IP protocol requires you to implement a connection manager to dynamically
accept and service any number of incoming connections in addition to tracking client requirements and servicing
each client individually. While this is possible, it requires a decent amount of work on the development side. On the
other hand, network-published shared variables feature the Shared Variable Engine with a built-in connection manager,
which handles any incoming client connections for you. Since TCP/IP Messaging (STM) and CVT Client Communication
(CCC) are both based on TCP, they also require you to develop a connection manager.
Network streams grow even more complicated when dealing with a 1:N or N:1 configuration because they are
implemented as a point-to-point communication model. This means that an application based on network streams
that connects to 10 clients requires at least 10 streams. However, since network streams are the most reliable and
easy-to-use mechanism for streaming data, they are still a good choice for streaming. For messages and commands,
consider using shared variables over network streams.
Figure 4.2. Consider your system configuration when choosing a networking protocol.
48
Network Streams
Shared Variables
No
NILabWindows/CVI and
Measurement Studio only
No
Yes
Version of LabVIEW
Several of the data transfer mechanisms recommended in Table 4.3 do not work in all versions of LabVIEW:
If you have selected one of these three mechanisms but are not using a compatible version of LabVIEW, use the
mechanism recommended for the same communication model and network configuration that can communicate
with a third-party UI.
Security
If you require security features such as built-in encryption and authentication, you should consider the HTTP standard
Web Services protocol that you can use to implement any type of communication. Web services support data
communication to LabVIEW UIs, third-party UIs, and web browsers.
The mark LabWindows is used under a license from Microsoft Corporation. Windows is a registered trademark
of Microsoft Corporation in the United States and other countries.
49
Network Configuration
Message or
Command
Update
Stream
Network Streams
(flushed)
Shared Variable
(blocking)
Network
Streams
Network-Published Shared
Variable or CCC
1:1 (CompactRIO to
Third-Party UI)
Simple TCP/IP
Messaging (STM)
UDP
TCP/IP
Network Streams
(flushed)
Shared Variable
(blocking)
Network
Streams
Network-Published Shared
Variable or CCC
Simple TCP/IP
Messaging (STM)
UDP
TCP/IP
Web Services
Web Services
Web Services
Web Services
The next section explains how to implement each of the networking protocols described in Table 4.3 and features
instructions for downloading and installing the protocols that are not included in LabVIEW.
Figure 4.3. Network shared variables are ideal for tag communication in a 1:N or N:1 configuration.
Three important pieces make the network variable work in LabVIEW: network variable nodes, the Shared Variable
Engine, and the NIPublish-Subscribe Protocol.
50
51
Figure 4.6. Ensure that buffering is disabled when using shared variables for tag communication.
Determinism
Network-published shared variables are extremely flexible and configurable. You can create a variable that features a
real-time FIFO to include a network communication task within a time-critical loop. When you do this, LabVIEW
automatically runs a background loop to copy the network data into a real-time FIFO, as shown in Figure 4.7.
52
Figure 4.7. When you enable the real-time FIFO for network-published shared variables, a hidden
background loop runs on the real-time target to copy the network value into a real-time FIFO.
This feature can simplify your program, but it has some limitations:
Some capabilities of network-published shared variables are not available when you enable the real-time FIFO
Error management is more difficult because network errors are propagated to the individual nodes throughout
the program
Future modification of the program to use different network communications is more difficult
Another option for applications that involve both network communication and a time-critical loop is to use regular
network-published shared variables for network communications and maintain a separate loop for network
communication tasks. You can communicate between these two loops using the interprocess communication
mechanisms discussed in Chapter 3: Designing a LabVIEW Real-Time Application.
Lifetime
All shared variables are part of a project library. By default, the Shared Variable Engine deploys and publishes that
entire library of shared variables as soon as you run a VI that references any of the contained variables. Stopping a VI
does not remove the variable from the network. Additionally, if you reboot a machine that hosts the shared variable,
the variable is available on the network again as soon as the machine finishes booting. If you need to remove the
shared variable from the network, you must explicitly undeploy the variable or library from the Project Explorer
window or the NIDistributed System Manager.
SCADA Features
The LabVIEW Datalogging and Supervisory Control (DSC) Module provides a suite of additional SCADA functionality
on top of the network-published shared variables including the following:
User-based security
Scaling
53
Published I/O variables are optimized for I/O monitoring. They do not work with all network-published shared variable
features and all LabVIEW devices. For maximum flexibility when sharing data between LabVIEW applications, you
should use network-published shared variables.
54
Reliability
Some of the hosted process variables may be critical to the distributed application, so they benefit from running on a
reliable embedded OS such as LabVIEW Real-Time to increase the overall reliability of the system.
Determinism
If you want to use network variables to send data directly to or from a time-critical loop on a real-time target, you
must have the RT FIFO enabled to ensure deterministic data transfer. You can only host RT FIFO-enabled network
variables on the real-time target.
The path name used to dynamically access network variables is similar to a Windows network share name, such as
//machine/myprocess/item. Below are additional examples of network variable references:
//localhost/my_process/my_variable
//test_machine/my_process/my_folder/my_variable
//192.168.1.100/my_process/my_variable
Monitoring Variables
The NIDistributed System Manager offers a central location for monitoring systems on the network and managing
published data. From the system manager, you can access network-published shared variables and I/O variables
without the LabVIEW development environment.
55
With the NIDistributed System Manager, you can write to network-published shared variables so you can remotely
tune and adjust process settings without the explicit need for a dedicated HMI. You can also use the NIDistributed
System Manager to monitor and manage controller faults and system resources on real-time targets. From LabVIEW,
select ToolsDistributed System Manager to launch the system manager.
56
Figure 4.11. Initialize variables to known values and serialize variable execution.
Figure 4.12. Use a timeout to prevent reading the same value repeatedly in a loop.
Network Streams
Network streams were designed and optimized for lossless, high-throughput data communication. They feature
enhanced connection management that automatically restores network connectivity if a disconnection occurs due to
a network outage or other system failure. Streams use a buffered, lossless communication strategy that ensures
data written to the stream is never lost, even in environments that have intermittent network connectivity.
Because streams were built with throughput characteristics comparable to those of raw TCP, they are ideal for highthroughput applications for which the programmer wants to avoid TCP complexity. You also can use streams for
lossless, low-throughput communication such as sending and receiving commands.
Network streams use a one-way, point-to-point buffered communication model to transmit data between
applications. This means that one of the endpoints is the writer of data and the other is the reader. Figure 4.13
shows a basic network streams implementation. One process executes on the real-time target, and the other
process executes on the host computer. You can follow three basic steps to set up a network stream:
1. Create the endpoints and establish the stream connection
2. Read or write data
3. Destroy the endpoints
57
Figure 4.13. Basic Implementation of Network Streams to Stream Data Across a Network
58
When using network streams to send commands, you should do two things to ensure low latency:
1. Specify a small buffer size (the example uses a buffer size of 10 elements)
2. Use the Flush Stream VI to flush the buffer immediately after a command is sent
You can implement the commander architecture for events that originate on a UI by using the standard LabVIEW
UI-handling templates. Translate the UI event into the appropriate command by building the command message and
writing it to the network stream. Be sure to flush the buffer after the command is sent to ensure low latency.
59
60
You can find more information on network streams in the NIDeveloper Zone white paper Lossless Communication
with Network Streams: Components, Architecture, and Performance.
61
Metadata
Metadata is implemented as an array of clusters. Each array element contains the data properties necessary to
package and decode one variable value. Even if you have defined only the Name property, you can use a cluster to
customize the STM by adding metaproperties (such as data type) according to your application requirements. The
metadata cluster is a typedef, so adding properties should not break your code.
Figure 4.18 shows an example of the metadata cluster configured for two variables: Iteration and RandomData.
Before each data variable is transmitted, a packet is created that includes fields for the data size, the metadata ID,
and the data itself. Figure 4.19 shows the packet format.
The metadata ID field is populated with the index of the metadata array element corresponding to the data variable.
The receiving host uses the metadata ID to index the metadata array to get the properties of the message data.
API
The STM API is shown in Figure 4.20. For basic operation, it consists of a Read VI and a Write VI. It also features two
supplemental VIs to help with the transmission of the metadata, but their use is not mandatory. Each of the main VIs
is polymorphic, which means you can use them with different transport layers. This document discusses STM
communication based on the TCP/IP protocol, but STM also works with UDPand serial as transport layers.The API
for each layer is similar.
62
63
As you can see, you can customize the protocol and expand it to fit your application requirements. As you add
variables, simply add an entry to the metadata array and a corresponding STM Write Message VI for that variable.
Receiving data is also simple. The design pattern shown in Figure 4.22 waits for the metadata when the connection
is established with the server. It then uses the STM Read Message VI to wait for incoming messages. When it
receives a message, it converts the data and assigns it to a local value according to the metadata name.
The Case structure driven by the data name provides an expandable method for handling data conversion. As you
add variables, simply create a case with the code to convert the variable to the right type and send it to the right
destination.
Note that an outer Case structure handles timeout events.
One advantage of this design pattern is that it centralizes the code that receives data and assigns it to local values.
Another advantage is that the STM Read Message VI sleeps until it receives data (or a timeout occurs), so the loop is
driven at the rate of incoming data. This guarantees that no data is lost and no CPU time is wasted polling for
incoming data.
Note:Since the client has no knowledge of the metadata until run time, you must be sure that the application
handles all possible incoming variables. It is a good practice to implement a default case to trap any unknown
variables as an error condition.
64
For more information on STM, view the following white papers on ni.com:
LabVIEW Simple Messaging Reference Library (STM)
Command-Based Communication Using Simple TCP/IP Messaging
A Multiclient Server Design Pattern Using Simple TCP/IP Messaging
If you attempt to resume the connection immediately after termination, you see an error dialog with error code 60
from the TCP Listen.vi that is similar to the error dialog in Figure 4.23. This inability to reestablish the listening TCP
socket is caused by an orphaned socket. The orphaned socket is the socket that initiated the termination. If you wait
for 60 seconds before attempting to reestablish the connection, the error message goes away. However, many
systems cannot afford to be down for 60 seconds.
Figure 4.23. Error Code 60 is generated when the client/server connection is terminated.
The 60 second timeout is intentional. When an orphaned socket is identified, TCP/IP makes the socket unavailable for
60 seconds so that no other sockets can communicate with it. If you compare TCP/IP to a postal service, a
65
termination is equivalent to a family moving out of its home. The postal service temporarily takes down that mailbox
so that if new people move in, they do not receive mail that does not belong to them. TCP/IP makes the socket
unavailable intentionally so that it can send data reliably over the network.
Preventing Orphaned Sockets
This section provides two methods for preventing orphaned sockets.
Design your application so that only the client can terminate the connection
In most cases, the orphaned socket issue is more severe on the server side. Typically, the client port is assigned
dynamically but the server port is fixed. When the server closes the connection, the server port becomes locked out. If
the connection is always terminated from the client side, you can significantly reduce the risk of dealing with error 60.
When designing your server application, you need to follow three rules:
1. Do not close the connection in the event of a timeout by ignoring the timeout error.
2. If you want to stop the server application, send a message to the client and let the client terminate the
connection. Wait for a non-timeout error (62 or 56) and close the server application upon error.
3. Do not close the server application upon an event. If an event occurs that should stop the application, send a
message to the client and have the client terminate the connection. Then close the server application upon error.
Figure 4.24. This example VI prevents the server from closing the network connection
66
Implementation
The underlying implementation of CCC is TCP/IP. Specifically, it is an adaptation of STM, which offers a platformindependent way of sending messages by name while maintaining the performance and throughput of raw TCP
communication. In applications involving hundreds or perhaps thousands of tags, the importance of efficient
communication is obvious.
TheCCC interface is made up of two separate elements. Theserver portion of the interface acts as a TCP server and
consists of a command parser that processes requests for data from the client. Theclient portion of the interface
acts as the TCP client and initiates the communication with the server. It then sends commands to theserver for
configuring and sending/receiving data.
TheCCC protocol implementation emphasizes performance optimization by configuring as much as possible on the
first call, leaving the repetitive operations with less work to do. Accordingly, the protocol is implemented in such a
way that theclient must first identify all of the tags of interest using the Bound Address parameter. On the first
execution, theserver looks up the tags by their index in the CVT. From that point forward, only the CVT index API is
used to ensure the highest possible performance.
On both theclient andserver components, all of the repetitive operations are implemented with determinism in mind.
They allocate all of the necessary resources on the first call of each function and use a functional global variable to
store blocks of data between iterations. This ensures that no memory allocation takes place after the first iteration.
67
In the corresponding client application, shown in Figure 4.28, you can see that the CCC write and read operations
are implemented in series with the rest of the HMI code. This ensures that the values for both the read and the write
tags are updated on each iteration. The client application includes the following steps:
1. Initialize the client-side CVT
2. Initiate a connection with the server
3. Use the CVT API functions (tags) to read and write data to and from the client-side CVT
4. Use the CCC Client Read and Write VIs to transfer data between the client-side CVT and the server-side CVT
5. End a connection with the server
68
For more information on CCC, see the NIDeveloper Zone white paper
CVT Client Communication (CCC) Reference Library.
Web Services
LabVIEW web services, introduced in LabVIEW 8.6, offer an open and standard way to communicate with VIs over
the web. Consider a LabVIEW application deployed across a distributed system. LabVIEW provides features such as
network streams for establishing communication, but many developers need a way to communicate with these
applications from devices that do not have LabVIEW using standard web-based communication. With LabVIEW web
services, you can
Remotely monitor and control LabVIEW applications using custom thin clients
Stream any standard MIME data types, such as text, images, and videos
Figure 4.29. You can use web services to communicate data over the web.
69
Web services act as a web API to any type of software, whether that software is controlling a complex embedded
system or simply a database store. To use a web service, a client sends a request to the remote system hosting the
service, which then processes the request and sends back a response (typically an XML, or eXtensible Markup
Language, message). The client can choose to display the raw XML data, but it is more common to parse the data
and display it to the user as part of a GUI.
Using this approach, you can create one or more VIs for your CompactRIO LabVIEW Real-Time target and build them
as web services. These web service VIs provide a standard interface for exchanging data between your embedded
devices and any computer connected via a network.
Figure 4.30. You can host and execute web services on a remote system
and access them via the standard HTTP protocol.
70
The bioreactor application uses network streams to send commands from the host PC to the CompactRIO controller.
Since this application uses the RIO Scan Interface to handle I/O, network-published I/O variables are used to send
raw I/O data to the UI update process.
71
CHAPTER 5
CUSTOMIZING HARDWARE THROUGH
LabVIEW FPGA
This chapter covers several best practices in addition to advanced tips and tricks for developing high-performance
control and monitoring systems with the LabVIEW FPGA Module and CompactRIO. It examines recommended
programming practices, ways to avoid common mistakes, and numerous methods to create fast, efficient, and
reliable LabVIEW FPGA applications.
The logic blocks are a collection of digital components such as lookup tables, multipliers, and multiplexers where
digital values and signals are processed to generate the desired logical output. These logic blocks are connected with
programmable interconnects that route signals from one logic block to the next. The programmable interconnect can
also route signals to the I/O blocks for two-way communication to surrounding circuitry.
FPGAs are really just blank silicon canvases that you can program to be any type of custom digital hardware.
Traditionally, programming these FPGA chips has been difficult and, therefore, only possible by experienced digital
designers and hardware engineers. NIhas simplified programming these devices through graphical system design
with LabVIEW FPGA so that nearly anyone can take advantage of these powerful reconfigurable chips.
Because LabVIEW FPGA VIs are synthesized down to physical hardware, the FPGA compile process is different from
the compile process for a traditional LabVIEW for Windows or LabVIEW Real-Time application. When writing code for
the FPGA, you write the same LabVIEW code as you do for any other target, but when you select the Run button,
LabVIEW internally goes through a different process. First, LabVIEW FPGA generates VHDL code and passes it to
72
the Xilinx compiler. Then the Xilinx compiler synthesizes the VHDL and places and routes all synthesized components
into a bitfile. Finally, the bitfile is downloaded to the FPGA and the FPGA assumes the personality you have
programmed. This process, which is more complicated than other LabVIEW compiles, can take up to several hours
depending on how intricate your design is. Later in the chapter, learn more about debugging and simulating your
FPGA VI so that you can compile less often.
Figure 5.2. Behind the scenes, the LabVIEW FPGA compiler translates LabVIEW code into VHDL and
invokes the Xilinx compile tools to generate a bitfile, which runs directly on the FPGA.
Accessing I/O
This section covers the basics of accessing I/O through a LabVIEW FPGA VI. For more detailed information on
timing and synchronization with analog and digital I/O modules using LabVIEW FPGA, see Chapter 6: Timing and
Synchronization with I/O.
73
Figure 5.3. Emulate the FPGA target to reduce the number of compilations during development.
To create a new FPGA VI, right-click the FPGA target in the project and create a new VI under the FPGA target. Drag
and drop an I/O channel on the block diagram to get an I/O node.
74
Figure 5.4. Drag and drop an I/O node to the FPGA block diagram.
Use LabVIEW Structures and Logic to Set Acquisition Rates and Triggering
The FPGA I/O Node returns single-point data when called. Use LabVIEW structures and logic to specify the sampling
rate and triggering.
Use a loop with a loop timer to set the sampling rate. The general guideline for sampled acquisition is to put a Loop
Timer Express VI in the first frame of a sequence structure and the FPGA I/O Node in the second frame enclosed by
a loop structure to repeatedly gather samples. The Loop Timer Express VI behaves differently from the LabVIEW Wait
until Next Multiple function. For more information on the Loop Timer Express VI, see the NIHelp document NILoop
Timer Express VI.
An example using the Loop Timer Express VI to time an acquisition is shown in Figure 5.5. The Sample Delay control sets
the rate in ticks. Ticks are the pulses on the FPGA clock, which runs at 40 MHz. For example, implementing a sample
delay of 20,000 ticks of the 40 MHz clock renders a sampling rate of 2 kHz. You can also specify the sample delay in
microseconds or milliseconds by double-clicking the loop timer and adjusting the configuration panel. Of course, no
matter what you specify, the module samples up to only the maximum rate specified in the module documentation.
Figure 5.5. The Acquisition Scheme for a Standard Analog Input Module
75
To implement a triggered application, use a Case structure gated on the trigger condition. This trigger condition can
be an input from the host processor or it can be derived from logic directly on the FPGA. Figure 5.6 shows the
simplest case of a one-shot trigger. With LabVIEW FPGA, you can implement more complex triggering schemes
such as retriggering, pause triggering, or any type of custom triggering.
This basic programming model is not applicable to all types of C Series analog I/O modules. Delta-sigma-based
modules include a built-in clock and have a different programming model. For more information on the timing and
synchronization of analog and digital I/O with LabVIEW FPGA, see Chapter 6: Timing and Synchronization of I/O.
Interprocess Communication
If you have multiple loops on your FPGA target, you might want to share data between them like you would in a realtime or Windows-based program. LabVIEW FPGA includes several mechanisms for sharing data between loops.
Variables
LabVIEW FPGA features local and global variables for sharing current values or tags between two or more loops.
With variables, you can access or store data in the flip-flops of the FPGA. Variables store only the latest data that is
written. They are a good choice if you do not need to use every data value you acquire.
Memory Items
Another method for sharing the latest values is to use available memory items. Taking advantage of memory items
consumes few logic blocks but uses the onboard memory. LabVIEW FPGA devices have two types of memory
items: target scoped and VI defined. You can access target-scoped memory items through all VIs under the FPGA
target. VI-defined memory items are scoped to the VI that defines them. Figure 5.7 shows a block diagram using a
Memory Method Node configured for a target-scoped memory item. This VI reads data from memory, increments
the data, and then overwrites the same memory location with the new data.
Figure 5.7. Read and write to a memory item using a Memory Method Node.
76
For more information on using memory items on an FPGA target, see the NILabVIEW Help documents listed below.
Additional References
FIFOs
If you are communicating messages or updates, or streaming data between two or more loops, consider using
FIFOs for data transfer. A FIFO is a data structure that holds elements in the order they are received and provides
access to those elements using a first-in, first-out access policy.
Figure 5.8. Use FIFOs to share buffered data between two parallel loops.
Similar to memory items, you have two types of FIFOs to choose from: target scoped or VI defined. You can access
target-scoped FIFOs through all VIs under the FPGA target, and VI-defined FIFOs are scoped to the VI that defines them.
When you configure a FIFO, you must specify the implementation that determines which FPGA resources hold and
transfer data in the FIFO. The following recommendations can help you choose one implementation over another.
Flip-flopsFlip-flops use gates on the FPGA to provide the fastest performance. They are recommended
only for very small FIFOs (less than 100 bytes).
Lookup tableYou can store data to two lookup tables per slice on the FPGA. Lookup tables are
recommended only for small FIFOs (less than 300 bytes).
Block memoryIf you are trying to preserve FPGA gates and lookup tables for other parts of your
application, you can store data in block memory.
77
For more information on using FIFOs on an FPGA target, see the LabVIEW Help document below.
Additional References
Figure 5.9. Read and write to front panel controls and indicators
for sharing the latest values between targets.
Programmatic front panel communication has low overhead relative to other methods for transferring data between
the FPGA and host processor. Read/Write nodes are good candidates for transferring multiple pieces of information
between the FPGA and host processor given their relatively low overhead. DMA FIFOs, shown in Figure 5.10, can
provide better throughput when streaming large amounts of data, but they are not as efficient for smaller and
infrequent data transfers.
Transferring data between the FPGA and host processor using front panel controls and indicators requires more
involvement of the host processor than the DMA FIFOs. As a result, the speed of data transfer is highly dependent
on the speed and availability of the host processor. A slower processor or lack of processor availability results in
slower data transfer from the FPGA target to the host. A disadvantage of programmatic front panel communication
is that this method transfers only the most current data stored on the control or indicator of the FPGA VI. For
example, data could be lost if the FPGA VI writes data to an indicator faster than the host VI can read the data. Also,
each control or indicator on the FPGA VI uses resources on the FPGA. Best practices in FPGA programming
recommend limiting the number of front panel objects in FPGA VIs.
Additional LabVIEW Help References
78
DMA FIFOs
If you need to stream large amounts of data between the FPGA and real-time processor, or if you require a small
buffer for command- or message based-communication, you should consider using DMA FIFOs for data transfer.
DMA does not involve the host processor when reading data off the FPGA; therefore, it is the fastest method for
transferring large amounts of data between the FPGA target and the host.
Figure 5.10. DMA uses FPGA memory to store data and then transfer it at a high speed
to host processor memory with very little processor involvement.
The following list highlights the benefits of using DMA communication to transfer data between an FPGA target and
a host computer:
Frees the host processor to perform other calculations during data transfer
Reduces the use of front panel controls and indicators, which helps save FPGA resources, especially when
transferring arrays of data
Automatically synchronizes data transfers between the host and the FPGA target
While DMA FIFOs are a great mechanism for streaming data, they quickly become complicated when streaming
data from more than one channel, optimizing your throughput, or scaling your data on the real-time host VI. If your
application requires streaming analog data from one or more analog channels, it is recommended to use the
NICompactRIO Waveform Acquisition Reference Library discussed at the end of this section as a starting point.
This library includes an FPGA template and a DAQmx-like API for streaming data, and has many benefits including
optimized performance and built-in scaling.
79
DMA FIFO from the FPGA target to the real-time host. You can also set data type and FPGA FIFO depths. Clicking
OK puts this new FIFO into your project, which you can drag and drop to the FPGA block diagram.
Tip: You can use the fixed-point to single conversion function shown in Figure 5.11 to convert fixed-point data to
floating-point data on the FPGA. Offloading this conversion to the FPGA can save significant processor resources.
You can obtain this function through the downloadable example or the NIDeveloper Zone document Fixed-Point
(FXP) to Single (SGL) Conversion on LabVIEW FPGA.
You can use the same DMA channel to transfer multiple streams of data, such as that collected from I/O channels.
Most CompactRIO systems have three DMA channels. In hybrid mode, CompactRIO systems have only one DMA
channel available. To pack multiple data streams or I/O channels into one DMA FIFO, use an interleaving technique as
shown in Figure 5.12, and unpack using decimation on the host.
Figure 5.12. You can use build array and indexing on a For Loop to implement
an interleaved multichannel data stream.
When passing multiple I/O channels into one DMA FIFO, the channels are stored in an arrangment similar to that
shown in Table 5.1. This table assumes that four I/O channels are being interleaved into one DMA FIFO. The table shows
that the upacking algorithm on the host VI is expecting the elements to arrive in a specific order. If the FIFO overflows
and one or more elements are lost, then the unpacking algorithm on the host VI fails to assign data points to their
correct I/O channel. Therefore, it is extremely important to ensure lossless data transfer when using DMA FIFOs.
80
Array Index
Element
AI 0
AI 1
AI 2
AI 3
AI 0
AI 1
AI 2
Table 5.1. When writing multiple channels to one DMA FIFO, the host VI expects
the elements to arrive in a specific order.
81
Whenever you are reading data from a DMA FIFO, you must be able to detect and recover from buffer overflows, or
timeout cases, to maintain data correctness. The next section provides a recommended architecture for ensuring
lossless data transfer when using DMA FIFOs.
82
FPGA VI
RT Host VI
In Figure 5.14, the timeout event of the DMA FIFO is being monitored on the FPGA VI. When a timeout event
occurs, the Timed Out? register is set to True. Once the Timed Out? register is set to True, it is latched until the host
VI clears the buffer and sets the Reset register to True. The timeout case on the RT Host VI flushes the buffer by
reading the remaining elements. Once the buffer is cleared, the Reset register is set to true and the acquisition on
the FPGA VI resumes. By using this method of dealing with the DMA FIFO timeout event, you can detect and
recover from buffer overflow so that you can avoid bugs created from missing data points.
Avoiding Buffer Overflows
If you are receiving buffer overflows, you need to either increase the DMA FIFO buffer size on the host, read larger
amounts on the host, or read more often on the host. Keep in mind that many control and monitoring applications
need only the most up-to-date data, so losing data may not be an issue for a system as long as it returns the most
recent data when called.
If you are experiencing buffer overflows, you can increase the host FIFO buffer by using a DMA Configure call as
shown in Figure 5.15. For FPGA to RT transfers, an overflow often occurs because the host FIFO buffer, not the
FPGA FIFO buffer, is not large enough. The size of the DMA FIFO set through the FIFO properties page determines
83
only the size of the FPGA FIFO buffer that uses up FPGA memory. By default, the host FIFO buffer size is 10,000
elements or twice the size of the FPGA FIFO buffer, whichever is greater.
Figure 5.15. Increasing the DMA FIFO size on the host is one way of eliminating
buffer overflow issues (DMA RT.vi).
Increasing the size of the buffers can help reduce buffer overflow conditions caused by sporadic events such as
contention for buses and the host processor. But if the average transfer rate is higher than what the system can
sustain, the data eventually overflows the buffer regardless of the buffers size. One way to reduce buffer overflow
conditions with appropriately-sized buffers is to try to read larger amounts of data at a time, which leads to lower
overhead per data unit and therefore increases overall throughput.
The CompactRIO Waveform Reference Library includes a DAQmx-like API that executes in LabVIEW Real-Time, and
converts raw analog data into the waveform datatype. The waveform datatype makes it simple to display multiple
channels of I/O to a user interface, and makes it easier to interface with common data logging APIs such as TDMS.
The API also converts your data to the appropriate engineering units depending on the scale that you configure.
84
Figure 5.17. When using the CompactRIO Waveform Reference API you can quickly stream data
and display multiple channels of I/O to a user interface
This library includes an FPGA VI that you need to make small modifications to for the VI to reference the I/O modules
used in your system. For most applications, you only need to modify the FPGA VI. The FPGA VI has been designed to
offer optimal streaming performance when using DMA FIFOs, and includes mechanisms for monitoring and handling
buffer overflow conditions. It is recommended to use this FPGA VI template as a starting point whenever you are
streaming data from one or more analog channels using DMA FIFOs.
You can find more information including installation files in the NIDeveloper Zone white paper NICompactRIO
Waveform Reference Library.
elta Sigma Acquisition.lvpj and SAR Acquisiton.lvpj are available at
D
\Program Files\National Instruments\LabVIEW[Version]\user.lib\cRIO Wfm\_exampleProjects
after installing the library.
Additional References
For more information on using DMA FIFOs on an FPGA target, see the following LabVIEW Help document.
Additional References
85
Figure 5.18. Basic LabVIEW FPGA Programming Structure for Sending an Interrupt
Interrupts offer simple code with a straightforward API, but you should be aware of the following caveats:
Handling the interrupt on the host side involves overhead usually on the order of 5 to 50 s. This response
latency may be acceptable depending on the application or the frequency of the event.
If you do not want the FPGA VI to block until the interrupt is acknowledged, you should add a separate FPGA
loop for sending the interrupt.
Interrupts are not the lowest latency option on multicore targets. The fastest response time is obtained by
dedicating a CPU core to continuously monitor an FPGA register (no sleep).
Additional References
86
processing the digital signals from a quadrature encoder sensor on a motor, and the lower loop is performing pulsewidth modulation (PWM) to control the amount of power sent to the motor. This application is written for the NI9505
motor drive module, which controls brushed DC motors. The application on the right is running two different loops at
a 40 MHz clock rate.
Figure 5.19. SCTLs take up less space on the FPGA and execute faster than While Loops.
The results from your compile report are also shown. The application built with SCTLs uses fewer slices, but it takes
longer to compile because the compiler has to work harder to meet the timing constraints applied by the SCTL.
Now examine how the SCTL works in more depth. When code is compiled in a normal While Loop, LabVIEW FPGA
inserts flip-flops to clock data from one function to the next, thereby enforcing the synchronous dataflow nature of
LabVIEW and preventing race conditions. The flip-flops are marked in Figure 5.20 with the FF boxes drawn at the
output of each function.
Figure 5.20. When code is compiled in a normal While Loop, LabVIEW FPGA inserts flip-flops
(marked as FFs) to clock data from one function to the next.
Figure 5.21 shows the same code compiled into an SCTL. Only the inputs and outputs of the loop have flip-flops. The
internal code is implemented in a more parallel fashion, and more logic reduction is implemented to optimize the
code in between the inputs and outputs of the loop.
87
Figure 5.21. The Code From Figure 5.18 Compiled Into an SCTL
As you can see, SCTLs are a simple way to optimize your LabVIEW FPGA code, but there are some limitations to
using them, as shown in Table 5.2.
Items Not Allowed in SCTL
Suggested Alternative
Make the code more parallel. Insert feedback nodes in the wires to add pipelining.
Use a Scale by Power of 2 to do integer division or use the fixed-point math library.
Place in a separate While Loop and use local variables to send data.
While Loops
To use the SCTL, all operations inside the loop must fit within one cycle of the FPGA clock. In the beginning of the
compile process, the code generator emits an error message if the SCTL cannot generate the proper code for the
compiler. That means that long sequences of serial code may not be able to fit in an SCTL. Serial code is code in
which the results of one calculation are needed by the next operation, preventing parallel execution of the
calculations. To fix this, you can rewrite the code to make it more parallel. For example, you can insert a feedback
node (
) to pass the results from one calculation to the next on the following iteration of the loopthis is known
as pipelining. You can use the pipelining technique to reduce the length of each run through the SCTL by breaking up
the code among multiple iterations of the loop.
You cannot use the Quotient and Remainder function in an SCTL. If you need to divide a number by an integer value,
you can use the Scale by Power of 2 function instead. With this function, you can multiply or divide by powers of
two, that is, 2, 4, 8, 16, 32, and so on. For a fixed-point result, you can use the High Throughput Math Library
included with LabVIEW FPGA. Figure 5.22 shows the fixed-point divide subVI and configuration panel including the
Execution Mode control that enables the function to be used within an SCTL.
88
The High Throughput Math Library contains LabVIEW FPGA IP blocks that implement a variety of elementary and
transcendental math functions. These functions use the fixed-point data type introduced in LabVIEW 8.5, which
extends the functions to include divide, sine, and cosine. All functions are verified for usage inside and outside an
SCTL as well as in Windows and FPGA simulations on the development computer.
If you are trying to create a subVI to implement inside an SCTL, you can use a feedback node to hold state
information in the subVI. This eliminates the need to use a While Loop inside an SCTL. The LabVIEW FPGA example
in Figure 5.23 calculates one of the differential equations for a DC motor using functions from the High Throughput
Math Library. After each fixed-point math function, you use a feedback node to pipeline the result and thereby pass
the value from one iteration to the next. Then you use the Tick Count function (in the upper right corner) with a
feedback node to calculate the loop rate of the subVI execution.
89
In Figure 5.24, you can see the top-level SCTL in the FPGA application, which calls the motor simulation subVI.
Because the subVI is nested within an SCTL, the Loop Rate (Ticks) value returned is always equal to 1. However,
pipelining causes a six-tick latency from the voltage (V) input to the i (A) current output of the subVI.
Figure 5.24. Pipelining causes a six-tick latency from the voltage (V) input
to the i (A) current output of the subVI.
In addition to pipelining, you can use a state machine within the SCTL to better organize your code and run through a
sequence of steps. The basic component of the state machine is a Case structure, with each case containing one
state. A shift register is used to determine the next state after each loop iteration. Each state must be able to run in
one clock cycle if the subVI is to be placed in an SCTL. In addition, you can use shift registers and a counter value to
implement the functionality of a For Loop or add a specific number of wait states to your program execution.
Note: Adding a loop timer or wait function causes the code to execute slower than one tick, so you cannot use it in
an SCTL. Analog input and analog output functions also take more than one clock tick to execute and cannot be used
in an SCTL. However, you can put them in a normal While Loop and use interprocess communication mechanisms to
share data with the SCTLs.
Tip: Creating Counters and Timers
If you need to trigger an event after a period of time, use the Tick Count function to measure elapsed time as shown
in Figure 5.25. Do not use the iteration terminal that is built into While Loops and SCTLs because it eventually
saturates at its maximum value. This happens after 2,147,483,647 iterations of the loop. At a 40 MHz clock rate, this
takes only 53.687 seconds. Instead, make your own counter using an unsigned integer and a feedback node as well
as the Tick Count function to provide time based on the 40 MHz FPGA clock.
Figure 5.25. Use the Tick Count function to measure elapsed time.
Because you used an unsigned integer for the counter value, your elapsed time calculations remain correct when the
counter rolls over. This is because if you subtract one count value from another using unsigned integers, you still get
the correct answer even if the counter overflows.
Another common type of counter is an iteration counter that measures the number of times a loop has executed.
Unsigned integers are typically preferred for iteration counters because they give the largest range before rolling
90
over. The unsigned 64-bit integer data type you are using for the counter provides a huge counting rangeequivalent
to about 18 billion-billion. Even with the FPGA clock running at 40 MHz, this counter will not overflow for more than
14,000 years.
Figure 5.26. Unsigned integers are typically preferred for iteration counters
because they give the largest range before rolling over.
Now examine another technique to create well-written and efficient LabVIEW FPGA code.
Figure 5.27. Front Panel of a SubVI Designed to Be Placed Inside a Normal While Loop
Without Affecting Its Execution Speed
The function is used in the application example in Figure 5.28. The subVI is placed inside another loop to measure
the execution rate of the top-level code.
91
Figure 5.28. The subVI is placed inside another loop to measure the execution rate of the top-level code.
Review some of the top benefits of writing code this way in Table 5.3.
Benefit
Explanation
Table 5.3. Benefits of Writing Your FPGA Code as Modular, Reusable SubVIs
Writing modular code is almost always a good idea, whether you are designing an application for a Windows, realtime, or FPGA-based system. SubVIs make code easier to debug and troubleshoot, easier to document and track
changes, and typically cleaner, easier to understand, and more reusable.
The options you want to offer the programmer are typically made available as terminals on the subVI. Most often
users do not need to modify the underlying codethey can just use the parameters you provide, such as in this
Pulse Width Modulation (FPGA). vi example.
Figure 5.29. Programmers can use the parameters you provide in this VI.
Now consider some tips for creating modular, reusable subVIs for LabVIEW FPGA.
Tip: Separate Logic From I/O
The first tip is to keep I/O nodes out of your subVIs. This makes them more modular and portable and makes the
top-level diagram more readable. Particularly for control and monitoring applications, you should have all of the I/O
92
operations clearly visible when viewing the top-level diagram for the application, as shown in the PWM loop written
for the NI9505 motor drive module in Figure 5.30.
Figure 5.30. Keep I/O nodes out of your subVIs and make sure they are clearly visible
in the top-level diagram for your application.
Rather than embedding the I/O node in the subVI, a terminal is used to pass the data from the subVI to the top-level
diagram. This makes the FPGA code easier to debug because you can test the subVI individually in Windows using
simulated I/O.
Figure 5.31. Rather than embedding the I/O node in the subVI, a terminal is used
to pass the data from the subVI to the top-level diagram.
Taking this approach also reduces extraneous I/O node instances that might otherwise be included multiple times in
the subVI, resulting in unnecessary gate usage due to the need for the compiler to add the extra arbitration logic
necessary to handle multiple callers accessing the same shared resource.
This approach makes the top-level application more readableall I/O read and write operations are explicitly shown
on the top-level diagram and not hidden from view.
Often when you are writing function blocks like this, the subVI needs some local memory capability so it can hold
state values, such as elapsed time, and pass that information from one iteration to the next.
Tip: Hold State Values in a Function Block
Figure 5.32 shows how you can add shift register nodes to your loop to pass information from one iteration of the
loop to the next. The Iteration counter increments each time the function block is called.
Notice that the Loop Condition terminal has a constant wired to it that causes the loop to run for only one iteration
each time it is called. You are not really looping in this caseyou are simply using the SCTL to optimize the code and
hold the state values with shift registers.
93
Figure 5.32. Add shift register nodes to your loop to pass information
from one iteration of the loop to the next.
Note: The shift register must be uninitialized for the subVI to hold state this way. On first call, the shift register value
is the default value for the data typefor integers that is 0, for Booleans that is False. If you need to initialize the
value to something else, use a First Call? function and a Select function.
You may be wondering how to create a modular function block that works inside an SCTL because you are not
allowed to nest one SCTL within another.
You can use feedback nodes to accomplish the same task, as shown in Figure 5.31. The main benefit of this approach
is that you can easily initialize the feedback nodes and place the subVI within a top-level SCTL because it contains no
nested loop structure.
A third option is the use of VI-scoped memory. This is a block of memory that the subVI can use locally and that does
not have to be manually added to the project. This makes the code more modular and portable when moving it
between projects.
94
Figure 5.34. Use the subVI with VI-scoped memory to make the code more modular and portable.
In this simple example, using VI-scoped memory is probably overkill for the application. You have only two memory
locations and are storing only one data point in each memory location. However, VI-scoped memory is a powerful
tool for applications that need to store arrays of data. In general, you should always avoid using large front panel
arrays as a data storage mechanismuse VI-scoped memory instead.
95
Figure 5.35. FPGA-Based LUT Configured to Store 10,000 Fixed-Point Values and Perform Linear
Interpolation Between Stored Values
Now examine the configuration pages for the VI-scoped memory block in this example. You can configure the depth
and data type and even define initial values for the memory elements.
Figure 5.36. Configuration Pages for the VI-Scoped Memory Block in This Example
Consider another tip for creating modular FPGA subVIs that involves the timing of how the code runs.
Tip: Do Not Place Delay Timers in the SubVI
In general, it is a good idea to avoid using Loop Timer or Wait functions within your modular subVIs. If the subVI has no
delays, it executes as fast as possible, thereby making inherent the timing properties of the calling VI rather than slowing
down the caller. Also, you can typically more easily adapt in an SCTL if it has no internal functions that cause delays.
96
The left side of Figure 5.38 shows how you can adapt PWM code to use a Tick Count function rather than a Loop Timer
function. Using a feedback node to hold an elapsed time count value, you turn the output on and off at the appropriate
times and reset the elapsed time counter at the end of the PWM cycle. The code may look a bit more complicated, but
you can drop it inside a top-level loop without affecting the overall timing of the loopit is more portable.
Now examine one more tip before moving on to the next topicmake code so that you can place multiple copies of
a subVI in the same application and each copy is independent of the others.
Tip: Take Advantage of Reentrancy
Reentrancy is a setting in the subVI Execution properties that you can use to execute multiple copies of the function
block in parallel with distinct and separate data storage.
Figure 5.39. Use reentrant execution to make multiple copies of the function block
in parallel with distinct and separate data storage.
97
Figure 5.38 illustrates an example. In this case, your subVI is set to reentrant, so all four of these loops run
simultaneously and any internal shift registers, local variables, or VI-scoped memory data are unique to each instance.
Figure 5.40. A subVI is set to reentrant, so all four of these loops run simultaneously, and any VI-scoped
memory data, internal shift registers, or local variables are unique to each instance.
In the case of LabVIEW FPGA, this also means that each copy of the function uses its own FPGA slicesso
reentrancy is effective for code portability, but it does use more gates.
If you are really squeezed for FPGA gates, you can make your function multiplexed rather than reentrant. This
advanced topic is not covered in this section, but it basically involves using local memory to store the register values
for each of the calling loops, which identify themselves with an integer ID tag value. Because the loops all use the
same underlying FPGA slices (with different memory addresses for the data), each caller blocks the other callers,
resulting in slower execution. However, gate usage is much less since the same hardware SLICE logic is reused. For
many control applications where the FPGA is already much faster than the I/O, this is a nice option for saving gates.
Several functions on the LabVIEW FPGA palette use multiplexing techniques to enable high-channel-count operation
with minimal FPGA gate usage. These include the PID, Butterworth Filter, Notch Filter, and Rational Resampler
functions. To see how this works, drop one of these functions onto the block diagram and configure it for multiple
channels. Then right-click on the function and select Convert to SubVI to reveal the underlying code.
Now take a look at a major development benefit you get from writing your LabVIEW FPGA code as described in the
previous sections.
98
is the speed at which the code runs and whether the targets support true parallel processing like an FPGA or
simulated parallel processing like a multithreaded OS for a microprocessor.
LabVIEW FPGA includes the ability to run the entire LabVIEW FPGA application in simulation mode, which you can
do in conjunction with the host processor application for testing purposes with either random data used for FPGA
I/O read operations or with a custom VI to generate the simulated I/O signals. This is particularly useful for testing
FPGA-to-host communication including DMA data transfers.
However, the disadvantage of this approach is that the entire FPGA application is simulated. For the development
and testing of new LabVIEW functions, you may benefit from testing the code one function at a time. This section
focuses on a capability called functional simulation, which enables a divide and conquer approach to debugging so
you can test each function individually before compiling to the FPGA. Figure 5.41 features screens from two
functional simulation examples running on Windows that were used for testing and debugging purposes.
Figure 5.41. These screens from two functional simulation examples running on Windows
were used for testing and debugging purposes.
The example in Figure 5.42 shows the front panel and block diagram of a test application used to debug a LabVIEW
FPGA subVI for PWM. The test application is located in the My Computer section of the LabVIEW project, and when
it is opened, it runs in Windows.
Figure 5.42. This front panel and block diagram of a test application were used to debug
a LabVIEW FPGA subVI for PWM.
99
Figure 5.43. A Tick Count function is executed when the code is compiled for the FPGA,
and a front panel control is implemented when the code is executed on Windows.
As you have seen, you can use functional simulation to test, iterate, and be confident in your FPGA logic before you
compile. It also helps you use the full LabVIEW debugging toolset while the code is running, and you can create
test patterns to verify the code under a variety of conditions that otherwise might be hard to test. Using
simulation as a step in your development process, you can do the following:
Use full LabVIEW debugging capabilities (probes, highlight execution, and so on)
100
Figure 5.44. Motor Control Example With Two Different Clock Signals
Now consider the LabVIEW FPGA code used to monitor these signals and trigger on either the rising or falling edge.
Typically triggering a loop based on a Boolean clock signal works like this: first wait for the rising or falling edge to
occur and then execute the LabVIEW FPGA code that you want to run when the trigger condition occurs. Engineers
often implement a sequence structure for which they use the first frame of the sequence to wait for the trigger and
the second frame to execute the triggered code, as shown in Figure 5.45.
Rising Edge Trigger: In this case, you are looking for the trigger signal to transition from False (or 0) to True (or 1).
This is done by holding the value in a shift register and using the Greater Than? function. (Note: A True constant is
wired to the iteration terminal to initialize the value and avoid an early trigger on the first iteration.)
Falling Edge Trigger: In this case, use a Less Than? function to detect the transition from True (or 1) to False (or 0).
(Note: A False constant is wired to the iteration terminal to initialize the value.)
101
Analog Level Trigger: Use a Greater Than? function to detect when the analog signal is greater than your analog
threshold level, and then use the Boolean output of the function as your trigger signal. This case actually is a rising or
falling edge detector because you are using the Not Equal? function to detect any transition.
Now examine another common triggering use caselatching the value of a signal when a trigger event occurs.
Tip: Latch Values
In this case, you use a rising edge trigger to latch the Analog Input value from another loop into the Latched Analog
Input register. This value is held constant until the next trigger event occurs. In this example, the actual analog input
operation is occurring in another loop, and you are using a local variable for communication between the loops.
(Note: Local variables are a good way to share data between asynchronous loops in LabVIEW FPGA.)
Figure 5.48. In this example, the actual analog input operation is occurring in another loop,
and you are using a local variable for communication between the loops.
102
Figure 5.49. Each of these three independent loops is completely dedicated to its own task,
resulting in the highest level of reliability.
103
Quotient and Remainder: This function implements integer division. The quotient output, floor(x/y), is x divided by
y, rounded down to the closest integer. The remainder output, x-y*floor(x/y), is whatever is left over. For example,
23 divided by 5 gives a quotient of 4 and a remainder of 3. This function is gate-intensive and takes multiple clock
cycles to execute, so you cannot use it in an SCTL. Be sure to wire the minimum data type you need to the
terminals when working with this function and use constants rather than controls when possible.
Scale by Power of 2: If the n terminal is positive, this function multiplies the x input by 2 to the power of n (2^n). If
n is negative, the function divides by 2^n. For example, setting n to +4 would multiply by 16, while setting it to -4
would divide by 16. This function is much more efficient than the Quotient and Remainder function. However, use a
constant of the minimum data size needed for the n terminal whenever possible.
Note: DMA is a better way to send an array of data to the host than creating a front panel indicator for the array and
using the FPGA Read/Write method. Arrays are useful for collecting a set of simultaneously sampled data to be fed
into a DMA buffer for transfer to the host computer. It is OK to use an array to collect the data points for indexing
into the DMA Write function as long as you do not create a front panel indicator for the array. Using autoindexing on
the For Loop used to write the data into the DMA buffer is fine as long as you do not create a front panel indicator
for the array because the compiler does a good job of optimizing arrays passed into For Loops for indexing purposes.
Tip: Avoid Front-Panel Arrays for Data Transfer
When optimizing your code for the amount of space it uses on the FPGA, you should consider the front panel
controls and indicators you are implementing. Each front panel object and the data it represents takes up a
significant portion of the FPGA space. By reducing the number of these objects and decreasing the size of any arrays
used on the front panel, you can significantly reduce the FPGA space required by the VI.
Figure 5.53. Creating Large Arrays to Store Data and Transfer It to the Host Application
104
Instead of creating large arrays to store data and transfer it to the host application (shown in Figure 5.53), use DMA
to transfer an array of analog input samples to the host processor as shown in Figure 5.54.
Figure 5.54. Using DMA to Transfer an Array of Analog Input Samples to the Host Processor
Figure 5.55. Use an unsigned 8-bit integer (U8) to index a Case structure because
it works for up to 256 different cases.
105
The application uses an array to store sine wave data. The array is indexed to get a value. In addition, four previous
points are stored in shift registers. The previous four values are averaged. This VI is too large to compile. What can be
done to help optimize this code?
The code contains the following gate hogs: large front panel arrays and Quotient and Remainder functions.
To improve the application, replace the array with an LUT as shown in Figure 5.57.
Figure 5.57. Improve the application by replacing the array with an LUT.
With this change alone, you can compile the program so it uses only 18 percent of a 1M gate FPGA. Can you further
optimize the program?
Next remove both Quotient and Remainder functions. One of them was used to index through the LUT. Replace this
with a shift register counter operation, which is a common technique in FPGA. Replace the other Quotient and
Remainder function by a scale by 2 to the power of n. Because the scale by 2 has a constant input, it uses little
FPGA space. Note: Scale by 2^ -2 is equal to dividing by 4.
106
Figure 5.58. Remove both Quotient and Remainder functions to further optimize the program.
107
CHAPTER 6
TIMING AND SYNCHRONIZATION OF I/O
Understanding how data travels between module hardware components and the LabVIEW FPGA block diagram can
help you develop better programs and debug faster. This section introduces you to the different hardware architectures
of analog and digital C Series I/O modules and how to communicate with each one. These modules are typically used
for measurement or control signals and feature model numbers that follow this style: NI92xx, NI93xx, or NI94xx.
Some basic terminology used in this section is listed below.
ADCAnalog-to-digital converter. Discrete component that converts an input analog signal (usually voltage)
into a digital representation. Front-end circuitry, also known as signal conditioning, is used to convert real-world
analog signals into voltage levels within the set range of the ADC.
DACDigital-to-analog converter. Discrete component that converts a digital value into an analog value.
Analog output is usually a voltage, but, if you add circuitry, you can convert it into a current value.
ArbitrationThe process of providing one request priority while causing all other requests to wait.
JitterInconsistent periods between multiple iterations of a looping program structure. Measured as the
difference between the longest period experienced and the nominal period requested.
Figure 6.1. The I/O node, method node, and property node for LabVIEW FPGA
visually have subtle differences.
108
I/O Nodes
Are designed to be thin interfaces to the module (in other words, minimal data or timing manipulation)
Cannot be used in SCTLs (except I/O nodes for parallel digital lines)
Figure 6.2. I/O Node Selection Menu (left) and an I/O Node Set to Channel AI0 (right)
Method Nodes
Examples include
Property Nodes
Examples include
Calibration constants
Serial number
Module ID
Vendor ID
109
Figure 6.4. Property nodes for some modules feature several options.
110
Module Classifications
This section describes the different types of C Series I/O modules. You need to understand how these modules are
designed to properly implement timing and synchronization. The basic types of module classifications are presented
in Figure 6.6.
Parallel Digital
Because each of the digital lines on a direct FPGA communication module is programmed as a separate entity, digital
modules with eight or fewer channels are also referred to as parallel digital modules. The parallel design of these
modules makes them the easiest to program in LabVIEW. I/O nodes for parallel digital modules can be called from
SCTLs, which make programming more efficient, and individual channel lines can be called simultaneously from
separate loops, as seen in Figure 6.7, with no concern for arbitration.
Figure 6.7. You can call lines on the same parallel digital module from separate loops.
111
Be aware that a call for direction change, at any time, on the DIO lines of an 8-channel parallel module causes an
interrupt that you must handle appropriately on the LabVIEW block diagram to prevent a glitch or jitter on other lines
in use at the time of direction change. The NI9402 does not have this problem. Four lines are used for DIO and the
other four lines are used to control the direction. Direction changes can happen independently of data transfer. The
NI9401, one of the most popular DIO modules, uses all eight DIO lines and must switch modes to communicate
line states. This mode change affects all DIO lines regardless of which ones are changing state.
Simultaneous Modules
Modules that are simultaneous have one ADC per channel and acquire data with no appreciable skew between
channels. The two subcategories of simultaneous modules, on-demand and delta-sigma, transfer data via the SPI
bus and are subject to all of the specifications and challenges of other SPI bus modules.
112
On-Demand Conversion
NIC Series On-Demand Simultaneous Modules
Model Number
Description
NI9215
NI9263
NI9265
NI9219
NI92221
NI92231
1These
modules are simultaneous modules and can be programmed with FPGA I/O nodes, similar to other modules listed in this
table. However, to run at higher speeds, you need to program them with the user-controlled I/O sampling API as outlined in the Data
on Demand section below. The maximum sampling rates achievable when using both FPGA I/O nodes and the user-controlled I/O
sampling API can be found in the Maximum Sampling Rate section of the user manual.
On-demand modules, like the ones listed in Table 6.1, have few specific challenges when it comes to programming
with LabVIEW FPGA. This makes them some of the easiest modules to program. The biggest caveat involves
arbitration, which is shared by all modules that use SPI communication.
Data on Demand
Data on demand is less of a caveat and more of a feature. On-demand simultaneous C Series modules have the
ability to return data when the I/O node is called at any interval down to the minimum conversion time as listed in
the manual. This means that the acquisition can be clocked by external, irregular clocks. The t does not need to be a
constant for an acquisition with an on-demand simultaneous module.
Pipelined Simultaneous Data or User-Controlled I/O Sampling
Some modules designed for high-speed measurements exceed the data throughput capabilities of the FPGA I/O
node. In these situations, you can apply user-controlled I/O sampling functions to communicate with a module. These
add complexity to the program but dramatically increase the bandwidth from the module.
Figure 6.8. You can use the User-Controlled I/O Sampling palette for higher
bandwidth communication to some modules.
When programming with the user-controlled sample method, you may find it easier to start with an existing example
program that is shipped with LabVIEW. Figure 6.9 is the block diagram from the NI9223 User-Controlled IO
Sampling.lvproj, which you can find in the NIExample Finder.
113
To program with the user-controlled I/O sample method, follow these steps that reference the example program in
Figure 6.9.
Initialize the Process
1. Call the Reset I/O function. When this call completes, the module is ready to perform an acquisition using the
user-controlled I/O sampling functions. You must call the Reset I/O function first to prepare the NI9223 to use
the other user-controlled I/O sampling functions.
2. Set the Stopped Boolean to false. This Boolean provides synchronization between the While Loops in the last
sequence frame. If any loop stops, it causes the others to stop as well.
3. Use an interrupt to signal the host that the FPGA is ready to begin acquiring data and wait to start the
acquisition until the host acknowledges it. This is necessary to ensure that the DMA FIFO has been started
prior to acquiring data.
Loop 1
4. Call the Generate I/O Sample Pulse function to begin acquiring data. The rate at which this function is called
determines the sample rate for the acquisition, so a loop timer is used to enforce the desired sample period.
Loop 2
5. Call the Read I/O function to read data acquired from the module. This function is configured to read a single
sample from each channel on the module. Because this function waits for data to become available, a generous
but noninfinite timeout is provided. In the case of the default 40 MHz top-level clock, the timeout is 1 second.
6. Write the acquired data into the DMA FIFO.
7. If a timeout occurred either while waiting for data from the module or waiting to write the data to the DMA
FIFO, then report the timeout to the host and stop the VI.
114
Loop 3
8. Call the Get Read I/O Status function at the same rate you call the Generate I/O Sample Pulse function. This
checks the status of every sample you acquire. If an overwrite or sample gated occur (output = true), then
report the status to the host and stop the VI. In the example, this loop is encased in a diagram disable
structure to make it easily removable from the application. Calling the Get Read I/O Status function is useful
for development and debugging but not strictly necessary for deployment if the application does not feature
variable timing in the application. In the Figure 6.9 example, you cannot obtain a sample gated status unless
the top loops sample period is less than the minimum sample period supported by the module. However, this
application could produce an overwrite status if the host VI cannot read from the DMA FIFO fast enough.
Delta-Sigma Modulation
NIC Series Simultaneous Modules with Delta-Sigma Modulation
Model Number
Description
NI9229
NI9239
NI9233
NI9234
NI9235
NI9236
NI9237
NI9225
NI9227
Many C Series modules designed for high-speed, dynamic measurements use delta-sigma () converters. To better
understand how these modules work, you must first know the fundamentals of delta-sigma modulation. The Greek
letters delta and sigma are mathematical symbols for difference and sum respectively. The modulation circuit of a
delta-sigma converter compares the running sum of differences between the desired voltage input, Vin, and a known
reference voltage, Vref. The output from the comparator becomes a bitstream that is sent into a digital filter and a
1-bit DAC. Because of this negative feedback, the differences oscillate around 0 V, or ground. The digital filter
effectively keeps track of how many times the difference is above 0 V, and, based on this count along with the
reference voltage, you can determine the input voltage. This modulation loop runs at a much higher frequency than
the actual output frequency of the converter.
C Series modules with delta-sigma converters feature an oversample clock that runs the modulation circuitry.
Oversample clocks, which run at 12 MHz or faster, affect timing, synchronization, and programming paradigms. The
following list provides insight into the specific challenges of C Series modules that use delta-sigma modulation.
Need a Sync Pulse to ResetOversample clocks need to be reset before they are used. This is why there
is a LabVIEW FPGA I/O node to send a start event to the module.
Time to Data Ready Is Non-ZeroThe time between the start event and data availability is specified as
time to first data. This time may vary slightly between different delta-sigma-based modules and greatly
between modules of other types. On-demand modules have a time to first data of zero. You can find
documentation on how to align the data sets in KnowledgeBase 4DAEUNNQ: How do I Compensate for
Different Group Delays with C Series Modules in LabVIEW FPGA? and Knowledgebase 53CHLD6C: What
is the Best Method to Synchronize Two Different DSA Modules in LabVIEW FPGA?
115
Sample Rates Are Discrete and SpecificBecause of the oversample clock and the digital filter, delta-sigma
modules can run only at discrete sample rates. These sample rates are a function of a divisor and the
oversample clock. This is why the rate input for a delta-sigma module is an enumerated data type of
predetermined sample rates. If you try to input a sample rate that is not supported, it is rounded to the next
highest available sample rate.
Minimum Sample Rates Are Greater Than 1 kThe minimum sample rate for delta-sigma modules is often
over 1 kHz. Use averaging, filtering, or some form of decimation to further reduce your data set beyond the
rate the digital filter on the module outputs.
No Irregular or External ClocksDelta-sigma modules cannot report data on demand and thus do not
work with irregularly timed I/O node calls because the iterative process must complete a large number of
loops before returning accurate data. The I/O node for a delta-sigma module always blocks for the exact (t) for
which the module has been set to acquire. An I/O node call at an interval less than t must wait until the full
sample period is complete. This gives the oversample circuitry enough time to calculate an accurate value. To
compensate for this, implement a resampling algorithm on the FPGA before processing your data or using it in
a control loop.
Physically Share Oversample Clock to Synchronize ModulesTwo delta-sigma modules that need to be
synchronized must share the same oversample clock. To synchronize modules, the oversample clock from one
module must be exported from the right-click properties menu of the source module in the LabVIEW
project. It must be imported from the same menu of the other client modules. Any module can be a
source or a client moduleit is up to the programmers discretion. Remember, changes made to a
module property window from the project view cause a recompile and cannot be changed at run time.
You can see many of these caveats in the block diagram of the example program NI9234 Getting Started.lvprj shown
in Figure 6.10.
You can find example programs for all of the delta-sigma modules in the NIExample Finder.
Multiplexed
One of the more expensive components of a module is the ADC. By using a multiplexer, also known as a mux, to
route multiple channels through a single ADC, multiplexed modules offer higher channel counts at lower per channel
prices than simultaneous modules.
Before learning how to program these modules, you need to know some specification-level details. First, the sample
rates are often listed as the total rate of all channels put together, also known as an aggregate rate. From the module
hardware standpoint, all channels selected must run at the same rate (aggregate rate divided by number of
channels), but from the program standpoint, you can remove samples from select channels with FPGA processing.
Second, it is important to note that there is an interchannel delay, or skew, between all channels in a multiplexed
module. You can implement processing in the FPGA to compensate for this skew via shifting or data resampling, but
116
most systems that incorporate multiplexed modules are not impacted by this small offset. If hardware-based phase
alignment is important to your system, you should select a module with multiple ADCs.
You can choose from two main subsets of multiplexed modules: high speed and low speed.
High Speed
High-speed multiplexed modules implement a double pipeline to increase the throughput of data to the chassis. With
a double pipeline, the first valid data cannot be returned until the process has run two complete iterations. Once the
first two iterations have run to prime the pipeline, the subsequent iterations begin to yield valid data. When using
an I/O node to sample channels, the pipeline is automatically managed by the FPGA I/O node, and the channels
within the FPGA I/O node are sampled in numerical order regardless of the order they appear in the node. If the first
two channel requests in the FPGA I/O node do not match the two channel requests stored in the module pipeline,
there is a delay before the first channel sample occurs. This delay is caused by the FPGA I/O node automatically
updating the module channel sample pipeline, which takes two channel sample cycles. This situation could happen if
you have I/O nodes addressing the same module from different parts of the block diagram. For example, if in an
init case of a Case structure, you read channels 0, 1, and 2 from an I/O node and then in the acquire case you
read from channels 5, 6, and 8, you incur the pipeline updating penalty because the module is already primed for
channels 0, 1, and 2 and needs to flush the pipeline. If this delay causes problems, the workaround is to acquire all
of the channels in the same step and place data from channels 5, 6, and 8 into a FIFO to be called upon later.
NIC Series High-Speed Multiplexed Modules
Model Number
Description
NI9205
NI9206
NI9201
NI9221
NI9203
117
Low Speed
Low-speed modules do not require the same amount of bandwidth as high-speed modules and do not implement a
pipeline. This makes the LabVIEW implementation straightforward. You face SPI bus module caveats when you work
with low-speed multiplexed modules.
NIC Series Low-Speed Multiplexed Modules
Model Number
Description
NI9211
NI9213
NI9214
NI9217
NI9207
NI9208
SPI Digital
Digital modules that feature more than eight lines exceed the number of pins allowed for direct FPGA
communication and, thus, communicate over the SPI bus. These modules operate with a convert pulse, and they
latch inputs and update outputs simultaneously with each convert. As with any other SPI bus module, all of the lines
on a 32-channel digital I/O module are routed through the same communication lines to the backplane. You should
control the I/O node calls to SPI bus modules with data flow to prevent simultaneous calls resulting in jitter. These
calls include normal I/O calls as well as commands to change line direction from input to output.
118
Synchronizing Modules
Some applications, such as vibration or sound measurement, require a high level (sub 100 nS) of synchronization
between channels. This section discusses timing and synchronization of both delta-sigma-based modules and
scanned (SAR) modules. Any NIC Series I/O module that is not classified as delta sigma is classified as SAR.
Figure 6.11. Export the clock from the chosen master module (left) and then select it
from all subsequent modules to be synchronized (right).
2. On the block diagram, create a property node for each I/O module and use the Data Rate enum to specify the
rate, as shown in Figure 6.12. Note that even though the I/O modules share the same sampling rate, you must
create a unique Data Rate enum for each property node (right-click on the property node for each module and
select create constant). This ensures that the enum integer is properly matched to the expected rate for the
specific I/O module.
3. Create a Start Trigger for each I/O module and place them into the same I/O node. This ensures the start
triggers are properly routed.
4. Place all channel reads from all synchronized modules in the same I/O node as seen in Figure 6.12. Using this
process, you can mix and match any of the existing simultaneous delta-sigma modules.
119
The best method for synchronizing different delta-sigma modules in LabVIEW FPGA is to have the I/O nodes for each
module in the same While Loop. If you place the I/O nodes for the different modules in parallel While Loops, you
must address additional startup delays. You also need to take into account thegroup delayfor each module because
the modules acquire data at the same time when in the same loop. KnowledgeBase 4DAEUNNQ: How to
Compensate for Different Group Delays with C Series Modules in LabVIEW FPGA provides tips on how to
compensate for different group delays within C Series modules in LabVIEW FPGA.
120
An application becomes more complicated when it requires multirate synchronization between delta-sigma and SAR
modules. Since these modules have different timebases, they cannot share a clock when they are separated into two
or more loops executing at multiple rates. The best option is to separate them into multiple loops and then expect
some drift between the timebases over time, in addition to a phase offset caused by the varying startup times.
121
CHAPTER 7
ADDING I/O TO THE COMPACTRIO SYSTEM
Adding I/O to CompactRIO
NIRIO products are increasingly adopted for system-level applications that require high-channel counts, intensive
processing, and distributed I/O. Adding RIO expansion I/O to the NIRIO product offering enables a 1:N system
topology with one controller and many FPGA I/O nodes for flexible, high-channel-count systems that can perform
both distributed control and centralized processing.
NIoffers three types of expansion chassis systems for expanding your I/O. Each expansion chassis features an FPGA
and is based on the same C Series module architecture. The main differences between expansion I/O options stem
from the choice of bus, with each bus best suited for a subset of expansion I/O applications. The NII/O expansion
chassis systems include the following:
MXI-Express RIO
Ethernet RIO
EtherCAT RIO
Each expansion chassis has unique capabilities. Choose an expansion chassis depending on your application
requirements. Table 7.1 provides a quick comparison of the three different types of expansion chassis.
122
MXI-Express RIO
Ethernet RIO
EtherCAT RIO
NI9157, 9159
NI9148
NI9144
Slots
14
FPGA
Spartan 2M
Spartan 2M
Daisy chain
Same as Ethernet
Daisy chain
7 m between nodes
FPGA-based DIO
FPGA-based DIO
<10s
No Spec
<1 s
250 MB/s
100 Mbit/s
100 Mbit/s
API Support
Host
Windows/Real-Time
Windows/Real-Time
Real-Time Only
Network Topology
Distance
Multichassis Synchronization
Communication Jitter
Bus Throughput
MXI-Express RIO
Featuring a high-performance Xilinx Virtex-5 FPGA and a PCI Express x1 cabled interface, an NI9157/9159
MXIExpress RIO 14-slot chassis for C Series I/O expands the RIO platform for large applications requiring high-channel
counts and a variety of signal conditioning and custom processing and control algorithms. You can use these
MXIExpress RIO expansion chassis with high-performance NIcRIO-9081/9082 CompactRIO systems in addition to
industrial controller and PXI systems. When using a MXI-Express RIO expansion chassis, you interface to the expansion
chassis I/O within your main controller VI using LabVIEW FPGA Host Interface functions.
NIcRIO-9081/9082 Systems
123
Ethernet RIO
When expanding your I/O using the standard Ethernet protocol, you can use the NI9148 Ethernet RIO expansion
chassis. Programmers can take advantage of the existing network infrastructure such as switches and routers.
Although full duplex switch networks eliminate packet collisions, switches introduce jitter, and you should use
general Ethernet only in applications that do not require deterministic communication. If you need synchronization
between the local I/O and expansion I/O, see the EtherCAT RIO section for more information.
When using the Ethernet RIO expansion chassis, the main controller is responsible for running the real-time control
loop using I/O from its own chassis in addition to the I/O from one or more Ethernet RIO chassis. The expansion
chassis provides expansion or distributed I/O for the main controller.
The Ethernet RIO expansion chassis works with both LabVIEW FPGA and the Scan Engine. If you use LabVIEW
FPGA with the expansion chassis, you can embed decision-making capabilities to quickly react to the environment
without host interaction. The FPGA can also offload processing from the main controller by conducting inline analysis,
custom triggering, and signal manipulation.
When using LabVIEW FPGA, you should create a regular While Loop or a Timed Loop with a lower priority to handle
the communication since Ethernet is nondeterministic (see Figure 7.4). This allows your control task to run
deterministically and reliably because it is not affected by the possibly high-jitter I/O device. When using LabVIEW
FPGA, you interface to the I/O within your real-time VI using the FPGA Host Interface functions.
Figure 7.4. Add a new process to handle the I/O expansion task when using LabVIEW FPGA Interface Mode.
124
The Ethernet RIO expansion chassis also works with the Scan Engine. You have the option to choose Scan Mode or
FPGA Interface Mode when adding the Ethernet RIO chassis to your LabVIEW project. When using Scan Mode, your
design diagram might look like Figure 7.5, where you have all of your system I/O accessible from the Scan Engine.
When using Scan Mode, you interface to the I/O within your real-time VI using the Scan Engine I/O variables.
Figure 7.5. You can use the NIScan Engine to handle I/O with the NI9148 Ethernet RIO chassis.
To get started with the NI9148 Ethernet RIO expansion chassis, see the NIDeveloper Zone tutorial Getting Started
With the NI9148 Ethernet RIO Expansion Chassis.
EtherCAT RIO
In certain applications, the main I/O and expansion I/O systems require tight synchronizationall of the inputs and
outputs must be updated at the same time. Using a deterministic bus allows the main controller to know not only
when the expansion I/O is updated but also exactly how long the data takes to arrive. You can easily distribute
CompactRIO systems with deterministic Ethernet technology using the NI9144 expansion chassis.
The NI9144 is a rugged expansion chassis for expanding CompactRIO systems using a deterministic Ethernet
protocol called EtherCAT. With a master-slave architecture, you can use any CompactRIO controller with two
Ethernet ports as the master device and the NI9144 as the slave device. The NI9144 also has two ports that permit
daisy chaining from the controller to expand time-critical applications.
125
NI cRIO-9074
NI 9144
(EtherCAT)
(TCP/IP)
Figure 7.7. Hardware Setup for Ethernet RIO Tutorial
126
5. If the controller already has LabVIEW Real-Time and NI-RIO installed on it, select Custom software
installation and click Next. Click Yes if a warning dialog box appears. Click the box next to NI-Industrial
Communications for EtherCAT. The required dependences are automatically checked. Click Next to continue
installing software on the controller.
6. Once the software installation is finished, select the controller under Remote Systems in the Configuration
pane. Navigate to the Network Settings tab in the bottom right portion of the window. In the Network
Adapters window, select the secondary Ethernet Adapter (the one that does not say primary). Next to Adapter
Mode, select EtherCAT in the drop-down box and hit the Save button at the top of the window.
Figure 7.9. Select EtherCAT as the mode for the second Ethernet port of the CompactRIO controller.
127
3. By default, the I/O channels show up in the project as Scan Engine I/O variables. The Scan Engine
automatically manages I/O synchronization so that all modules are read and updated at the same time once
each scan cycle.
Note: For high-channel-count systems, you can streamline the creation of multiple I/O aliases by exporting and
importing .csv spreadsheet files using the Multiple Variable Editor.
Step 2: Add Deterministic I/O (Option 2LabVIEW FPGA)
1. In the LabVIEW Project Explorer window, right-click on the CompactRIO controller and select NewTargets
and Devices.
2. In the Add Targets and Devices dialog window, expand the category EtherCAT Master Device to autodiscover
the EtherCAT port on the master controller. Select your EtherCAT device and click OK. The LabVIEW project
now lists the master controller, the NI9144 chassis, their I/O modules, and the physical I/O on each module.
By default the I/O channels show up in the project as Scan Engine I/O variables.
3. Right-click the EtherCAT device in the LabVIEW project and select NewFPGA Target. You can now create a
LabVIEW FPGA VI to run on the EtherCAT target. By default the chassis I/O is added to the FPGA target but
not the I/O modules. To program the C Series module I/O using LabVIEW FPGA, drag the C Series modules
from the EtherCAT device target onto the FPGA target in the LabVIEW Project Explorer window.
128
Figure 7.11. Drag C Series I/O modules under the FPGA target
to access them with LabVIEW FPGA.
4. Create an FPGA VI under the EtherCAT device target and program using the EtherCAT I/O. The Figure 7.12
example uses the FPGA on an EtherCAT chassis to output a PWM signal.
Note: There is a limit to the number of user-defined I/O variables that you can create in FPGA Mode. The NI9144 can
hold a total of 512 bytes of input data and 512 bytes of output data for both I/O variables in Scan Mode and userdefined I/O variables in FPGA Mode. For example, if you are using four 32-channel modules in Scan Mode and each
channel takes up 32 bits of data, then Scan Mode I/O variables are using 256 bytes of input data. With the remaining
256 bytes of input data, you can create up to 64 input user-defined I/O variables (also of 32-bit length) in FPGA Mode.
5. The next step is creating an interface that allows the Real-Time VI to communicate to the FPGA VI on the EtherCAT
expansion chassis. For example, you need the user to be able to control the pulse width of the PWM signal,
along with the invert pulse input. To transfer data to or from an FPGA on an EtherCAT chassis to a Real-Time VI,
you use a new mechanism called user-defined I/O variables. To create a user-defined I/O variable, right-click the
EtherCAT device target and select NewUser-Defined Variable.
129
6. In the Properties dialog box, specify the variable name, data type, and direction (FPGA to host or host to
FPGA). Drag and drop the user-defined I/O variables onto your FPGA VI.
Figure 7.14. Drag and drop user-defined I/O variables onto the FPGA VI.
Note: These user-defined I/O variables transfer single-point data to and from the master controller at each scan cycle,
so they are best used for passing processed data from the NI9144 FPGA.
7. Drag and drop the same variables onto your Real-Time VI to communicate between the two targets.
130
CHAPTER 8
COMMUNICATING WITH
THIRD-PARTY DEVICES
Overview
This section examines different methods for communicating with third-party devices from a CompactRIO controller.
Because CompactRIO has built-in serial and Ethernet ports, it can easily work Modbus TCP, Modbus Serial, and
EtherNet/IP protocols. You can find information on using the Ethernet port to communicate to an HMI in
Chapter 4: Best Practices for Network Communication.
When interfacing to a third-party device in LabVIEW Real-Time using RS232, USB, or Ethernet ports, you should
consider adding a separate process for handling the communication since these protocols are nondeterministic.
This allows the control task to run deterministically and reliably because it is not affected by the possibly high-jitter
I/O device.
Figure 8.1. Add a separate process for handling any nondeterministic communication to a third-party device
over serial or Ethernet.
131
This section covers how to program byte-level communications for the serial port built into CompactRIO real-time
controllers using the NI-VISA API.
As a single-ended bus, RS232 is ideal for shorter-distance communications (under 10 m). Shielded cables reduce
noise over longer runs. For longer distances and higher speeds, RS485 is preferred because it uses differential
signals to reduce noise. Unlike buses such as USB and IEEE 1394, RS232 is not designed to power end devices.
CompactRIO controllers have an RS232 port that features the standard D-SUB 9-pin male connector (also known as
a DE-9 or DB-9). You can use this port to monitor diagnostic messages from a CompactRIO controller when the
console out switch is engaged or to communicate with low-cost RS232 devices in your application.
RS232 Wiring and Cabling
RS232 ports feature two standard pinouts. You can classify RS232 devices as data terminal equipment (DTE), which
is like a master or host, and data communications equipment (DCE), which is similar to slaves. DCE ports have
inverted wiring so that DCE input pins connect to DTE output pins and vice versa. The serial port on CompactRIO
controllers is a DTE port, and the serial port on a device such as a GPS, bar code scanner, modem, or printer is a
DCE port.
When connecting a CompactRIO DTE RS232 port to a typical end device with a DCE RS232 port, you use a regular
straight-through cable. When connecting two DTE or DCE devices together, such as a CompactRIO controller to a
PC, you need to use a null modem cable, which swaps the transmit and receive signals in the cabling.
132
Device 1
Device 2
Cable Type
DTE
DTE
DTE
DCE
Straight-through cable
DCE
DTE
Straight-through cable
DCE
DCE
Loopback Testing
A common technique for troubleshooting and verifying serial port functionality is loopback testing. At a basic level, all
you need to do is connect the TXD to the RXD pin. Use a standard RS232 straight-through or loopback cable and a
small bent paper clip to short pins 2 and 3. With the loopback cable installed, bytes sent from the read function can
be read by the read function. You can verify that software, serial port settings, and drivers are working correctly with
this technique.
133
For most simple instrument applications, you need only two VISA functions, VISA Write and VISA Read. Refer to the
Basic Serial Write and Read VI in the labview\examples\instr\smplserl.llb for an example of how to use VISA functions.
Most devices require you to send information in the form of a command or query before you can read information
back from the device. Therefore, the VISA Write function is usually followed by a VISA Read function. Because serial
communication requires you to configure extra parameters such as baud rate, you must start the serial port
communication with the VISA Configure Serial Port VI. The VISA Configure Serial Port VI initializes the port identified
by the VISA resource name.
It is important to note that the VISA resource name refers to resources on the machine for which the VI is targeted.
Figure 8.5. You can directly browse to the VISA resource name from
the VISA resource control in LabVIEW or from MAX.
Check the bottom left corner of the VI to determine which target the VI is linked to. For CompactRIO, use COM1 to use
the built-in port. COM 1 on a CompactRIO controller is ASRL1::INSTR. If you are connected to the CompactRIO
controller, you can directly browse to the VISA resource name from the VISA resource control in LabVIEW or from MAX.
Timeout sets the timeout value for the serial communication. Baud rate, data bits, parity, and flow control specify
those particular serial port parameters. The error in and error out clusters maintain the error conditions for this VI.
While the ports work at the byte level, the interfaces to the read and write functions are strings. In memory, a string
is simply a collection of bytes with a length attached to it, which makes working with many bytes easier to program.
The string functions in LabVIEW provide tools to break up, manipulate, and combine data received from a serial
port. You can also convert string data to an array of bytes for using LabVIEW array functions to work with low-level
serial data.
Because serial operations deal with varying-length strings, these tasks are nondeterministic. Additionally, serial
interfaces by nature are asynchronous and do not have any mechanisms to guarantee timely delivery of data. To
maintain the determinism of your control loops, when programming serial applications keep any communications
code in a separate loop from the control code.
134
The VISA Read function waits until the number of bytes requested arrives at the serial port or until it times out. For
applications where this is known, this behavior is acceptable, but some applications have different lengths of data
arriving. In this case, you should read the number of bytes available to be read, and read only those bytes. You can
accomplish this with the Bytes at Serial port property accessible from the Serial palette.
You can access serial port parameters, variables, and states using property nodes. If you open the VISA Configure
Serial Port VI and examine the code, you see that this VI simply makes a call to many property nodes to configure the
port. You can use these nodes to access advanced serial port features, including the auxiliary data lines, bytes
waiting to be read/written, and memory buffer sizes. Figure 8.7 shows an example of using a property node to check
the number of bytes available at the port before reading.
Figure 8.7. Using a VISA Property Node to Read the Number of Bytes
In general, working with devices can range from simply reading periodically broadcasted bytes such as GPS data to
working with complex command structures. For some devices and instruments, you can find preprogrammed
instrument drivers on ni.com/idnet, which can simplify development. Because these drivers use NI-VISA functions,
they work with the onboard CompactRIO serial port.
135
In LabVIEW, place aVISA Configure Serial PortVI or aVisa Property Nodeto configure the settings of your individual ports.
136
Figure 8.9. Program an NI987x with the VISA API when using Scan Mode.
Once you have set the serial port to match that of the connected device, use theVISA APIas you would when using
any other VISA device.
Note: This maximum nonstandard baud rate for the NI9871 module (3.6864 Mbit/s) can only be achieved while
using the FPGA interface. The maximum baud rate while using either module in with the RIO Scan Interface is
115.2kbit/s.
Using NI987x Serial Modules With LabVIEW FPGA
You also can access NI987x serial modules with LabVIEW FPGA. See the Figure 8.10 example titled NI987x Serial
Loopback.lvproj in the NIExample Finder. This example demonstrates communication to the NI987x serial port and
streaming serial data to a real-time VI.
Figure 8.10. You can find the NI987x serial loopback example for LabVIEW FPGA in the NIExample Finder.
137
Figure 8.11. Three Methods for Connecting a CompactRIO Controller to an Industrial Device
138
Industrial protocols take a low-level bus like RS232 or TCP/IP and add predefined techniques for communication on
top. This is similar to how HTTP, the protocol for web content delivery, sits on top of TCP/IP. It is possible to write
your own HTTP client like Internet Explorer or Firefox, but it takes a large effort and may not accurately connect to all
servers without hours of testing and verification. Similarly, devices and controllers that support industrial networking
standards are much easier to integrate at the program level and abstract the low-level communication details from
the end user, so engineers can focus on the application.
Because CompactRIO has built-in serial and Ethernet ports, it can easily work with many protocols including Modbus
TCP, Modbus Serial, and EtherNet/IP. You also can use plug-in modules for communication with most common
industrial protocols such as PROFIBUS and CANopen.
When you cannot use native communication, another option is gateways. Gateways are protocol translators that can
convert between different industrial protocols. For example, you can connect to a CC-Link network by using a
gateway. The gateway can talk Modbus TCP on the PAC end and translate that to CC-Link on the other end.
Modbus Communications
Modbus is the most common industrial protocol in use today. Developed in 1979, it supports both serial and
Ethernet physical layers. Modbus is an application layer messaging protocol for client/server communication
between devices connected on a bus or network. You can implement it using asynchronous serial transmission to
communicate with touch screens, PLCs, and gateways to support other types of industrial buses. Modbus works
with a CompactRIO controller and its onboard serial or Ethernet modules. Note that the onboard serial port of
CompactRIO hardware uses RS232 while some Modbus devices may use the RS485 electrical layer. In this case,
you can use a common RS485-to-RS232 adapter.
The Modbus serial protocol is based on a master/slave architecture. An address, ranging from 1 to 247, is assigned to
each slave device. Only one master is connected to the bus at any given time. Slave devices do not transmit information
unless a request is made by the master device, and slave devices cannot communicate to other slave devices.
139
Information is passed between master and slave devices by reading and writing to registers located on the slave device.
The Modbus specification distinguishes the use of four register tables, each capable of 65,536 items and differentiated
by register type and read-write access. Register address tables do not overlap in this implementation of LabVIEW.
Tables
Object Type
Type of Access
Comments
Discrete Inputs
Single-Bit
Read Only
Coils
Single-Bit
Read-Write
Input Registers
16-Bit Word
Read Only
Holding Registers
16-Bit Word
Read-Write
Table 8.2. Information is passed between master and slave devices by reading
and writing to registers located on the slave device.
Before starting with Modbus programming, you must determine several important parameters of your Modbus
device by consulting its documentation:
1. Master or slave? If your Modbus device is a slave, configure your CompactRIO controller as a master. This is
the most common configuration. Likewise, connecting to a Modbus master (such as another PLC) requires
configuring the CompactRIO controller as a slave.
2. Serial or Ethernet? Modbus Ethernet devices are sometimes called Modbus TCP devices.
3. For Modbus serial
RS232 or RS485? Many Modbus devices are RS232, but some use the higher power RS485 bus for longer
distances. RS232 devices can plug directly into a CompactRIO system, but an RS485 device needs an
RS232-to-RS485 converter to function properly.
RTU or ASCII mode? RTU/ASCII refers to the way data is represented on the serial bus. RTU data is in a
raw binary form, whereas ASCII data is human readable on the raw bus. This parameter is required by the
Modbus VIs.
4. What are the register addresses? Every Modbus device has a mapping of its I/O to registers, coils, and
discrete inputs for reading and writing that is represented by a numerical address. Per Modbus convention, a
register address is always one less than the register name. This is similar to the first element of an array being
element 0. The Modbus LabVIEW Library requires register addresses, not register names.
Modbus Tutorial
The NIDeveloper Zone document How to Turn an RT Target Into a Modbus Slave Using I/O Servers walks you
through the steps of turning your CompactRIO controller into a Modbus slave. It also shows you how to read from
this server with LabVIEW for Windows if you do not have a third-party Modbus server. Before starting the tutorial,
install the Modbus I/O Server onto your CompactRIO target through MAX.
EtherNet/IP
EtherNet/IP is a protocol built on the Common Industrial Protocol (CIP) for communications with EtherNet/IP devices.
This protocol, developed and commonly found on Rockwell Automation (Allen-Bradley) PLCs, uses standard Ethernet
cabling for communications with industrial I/O. EtherNet/IP is an application layer protocol that uses TCP for general
messages and User Datagram Protocol (UDP) for I/O messaging and control.
140
Figure 8.14. With EtherNet/IP, you can directly read and write to tags on a Rockwell PLC from CompactRIO.
The LabVIEW Driver for EtherNet/IP provides both explicit messaging API and implicit I/O data communication with a
wide range of PLCs and other EtherNet/IP devices. With this driver, the CompactRIO controller supports direct
communication to Rockwell Automation PLCs, allowing for easy integration into a new or existing system.
141
You can use the LabVIEW Driver for DNP3 Outstation Support to program a real-time target, such as a CompactRIO
system, as an outstation device with advanced functionality like power quality monitoring, phasor measurements, and
other smart grid-related analysis. The DNP3 software driver supports Ethernet and serial communication, file transfer,
and time synchronization between the master and outstation. Multiple communication channels per outstation and
multiple sessions (logical devices) per channel also work with this driver.
OPC
OPC, or OLE for process control, is a common protocol used in many applications with high channel counts and low
update rates, which are common in process industries such as oil and gas and pharmaceutical manufacturing. OPC is
designed for connecting HMI and SCADA systems to controllersit is not generally used for communication between
controllers. A common use for OPC is to integrate a CompactRIO controller into a third-party system for HMI and
SCADA applications.
The OPC specification is a large collection of standards that span many applications. This section focuses on OPC Data
Access, the core specification that defines how to universally move data around using common Windows technologies.
The network-published shared variable in LabVIEW provides a gateway to OPC.
Figure 8.16. Communicate OPC data items with network-published shared variables.
OPC is a Windows-only technology and the CompactRIO controller cannot directly communicate using the OPC
protocol. Instead, a Windows PC can communicate to the CompactRIO controller using the NI-PSP protocol and can
translate and republish the information via OPC. When running on a Windows machine, the Shared Variable Engine
functions as an OPC server and performs this translation and republishing automatically. This means other OPC
clients, such as third-party SCADA packages or process control software, can access and retrieve data from the
CompactRIO device.
142
1. The CompactRIO controller publishes data onto the network using networked-published shared variables
hosted on the CompactRIO controller. In this example, the network shared variable is named SV_PID_SetPoint.
2. To publish the variables as OPC data items, bind each variable hosted on the CompactRIO controller to a
variable hosted on the Windows PC. To create variables hosted on a Windows PC, right-click My Computer in
the LabVIEW Project and select NewVariable.
3. In the Shared Variable Properties window, give the variable a useful name such as SV_PID_SetPoint_OPC.
Check the Enable Aliasing box and click the Browse button to browse to the SV_PID_SetPoint variable on the
CompactRIO controller.
143
4. Save the new library you create with a useful name, such as OPC Library.lvlib.
5. Deploy the variables to the Shared Variable Engine by right-clicking the library and selecting Deploy.
6. The shared variable is now published as an OPC item. Other OPC clients can now connect to the Windows PC
and use the data for display, HMI, and so on. You can verify the variable is working correctly by launching an
OPC client such as the NIDistributed System Manager
(StartProgramsNationalInstrumentsNIDistributed System Manager).
Figure 8.20. The OPC clients, such as the NIDistributed System Manager,
can read and write to the OPC item.
144
7. If you have an OPC client, such as the LabVIEW DSC Module, you can verify the variable is working from that
client as well. NIshared variable OPC items are published under the National Instruments.Variable Engine.1
server name.
8. Once variables are deployed in the Shared Variable Engine, they stay deployed with subsequent reboots of the
OPC server machine.
9. Find more information on the Shared Variable Engine and OPC in the LabVIEW Help file Connecting to OPC
Systems using LabVIEW (Windows Only)
Additional Resources
For information on other industrial communications protocols supported by NI, visit ni.com/comm.
145
CHAPTER 9
DESIGNING A TOUCH PANEL HMI
Building User Interfaces and HMIs Using LabVIEW
This chapter examines one software design architecture for building an operator interface with a scalable navigation
engine for cycling through different HMI pages.
You can use this architecture to build an HMI based on LabVIEW for any HMI hardware targets including the
NITPC2512 touch panel computer running the Windows XP Embedded OS or the NITPC-2106 running the
Windows CE OS and the NIPPC-2115 panel PC running the Windows XP OS. LabVIEW is a full programming
language that provides one solution for a variety of development tasks ranging from HMI/SCADA systems to reliable
and deterministic control applications. The LabVIEW Touch Panel Module offers a graphical programming interface
that you can use to develop an HMI in a Windows development environment and then deploy it to an NItouch panel
computer (TPC) or any HMIs running Windows CE. This chapter offers a framework for engineers developing HMIs
based on both Windows Vista/XP and Windows CE.
146
Navigation Loop
With a Windows CE-based touch panel, you do not have individual windows like you do in a Windows XP or
Windows 7 application. Instead, the top-level VI occupies the entire screen. In addition, the tab control is not
supported in Windows CE. Therefore, to switch between different panels (UIs) in the application, you need to add
support in your UI such as buttons to switch to other panels.
The navigation loop handles the management and organization of different UIs in your application. You can implement
a navigation loop as a simple state machine built with a While Loop and a Case structure. Each case encloses an
HMIpage VI that, when called, is displayed on the HMI screen. Figure 9.2 is an example of a navigation loop.
147
This example uses the HMI Navigation Engine (HNE) reference library, which was created for HMI page
management and navigation. The HNE is based on VIs included with the LabVIEW Touch Panel Module, but it
features an additional history cache so the user can define a button to jump backward toward the previously viewed
screen. The HNE also includes basic templates and examples for getting started. Refer to theNIDeveloper Zone
documentHMI Navigation Engine (HNE) Reference Libraryto download the HNE library.
The HNE installs a page manager APIpalette named HNE to the User Libraries palette in LabVIEW.
HNE Page Manager (Init)This VI initializes the HNE by setting the navigation history depth and setting the
name of the first page to be displayed.
HNE Page Manager (Next) This VI returns the name of the next page and passes it to the Case structure
in the HNE.
HNE Page Manager (Set)This VI sets the name of the next page to be displayed. It is used within HMI
pages to support navigation buttons.
HNE Page Manager (Back)This VI returns the name of the previous page from the page history. It is used
within HMI pages to support the operation of a back navigation button.
Examples subpaletteThis is a subpalette that contains the example VI for the HNE API.
Templates subpaletteThis is a subpalette that contains two template VIs for the HNE API. The first is a
template VI for the navigation loop called HMI_NavigationEngine VI and the second is a template for an
HMIpage called HMI_Page VI.
The navigation engine uses VIs from the Touch Panel Navigation palette.
148
TPC Initialize NavigationThis VI initializes the navigation engine by setting the navigation history depth
and the name of the first page to be displayed.
TPC Get Next PageThis VI returns the name of the next page and passes it to the Case structure in the
HMI navigation engine.
TPC Set Next PageThis VI sets the name of the next page to be displayed. Use it within HMI pages to
support navigation buttons.
TPC Set Previous Navigation PageThis VI returns the name of the previous page from the page history.
Use it within HMI pages to support the operation of a back navigation button.
The page state and history are stored in a functional global variable that each of these VIs access.
UI Pages
As stated above, the navigation loop contains all of the HMI pages for an application. Each HMI page is a LabVIEW VI
created to monitor and configure a specific process or subprocess in the machine. The most common elements on a
page front panel are navigation buttons, action buttons, numeric indicators, graphs, images, and Boolean controls
and indicators. Figure 9.5 shows an example page containing a typical set of front panel elements.
149
The page block diagram uses the event-based producer consumer design pattern to implement a responsive, eventdriven UI. The example in Figure 9.6 uses the Asynchronous Message Communication (AMC) reference library for
interprocess communication. You can download the AMC reference library, which uses queues for interprocess
communication, from the NIDeveloper Zone document Asynchronous Message Communication (AMC)
Reference Library. The AMC library also has an API based on UDP that you can use to send messages across the
network. You can implement the Figure 9.6 example using queue functions for communicating between the Event
Handler process and the Message process.
For more information on creating UI pages, see the NIDeveloper Zone document Creating HMI Pages for the
LabVIEW Touch Panel Module.
150
CHAPTER 10
ADDING VISION AND MOTION
Machine Vision/Inspection
Machine vision is a combination of image acquisition from one or more industrial cameras and the processing of the
images acquired. These images are usually processed using a library of image processing functions that range from
simply detecting the edge of an object to reading various types of text or complex codes.
Often more than one of these measurements is made on one vision system from one or more images. You can use
this for many applications including verifying that the contents of a container match the text on the front of the bottle
or ensuring that a code has printed in the right place on a sticker.
The information from these processed images is fed into the control system for data logging, defect detection,
motion guidance, process control, and so on.
For information on the algorithms in NIvision tools, see the Vision Concepts Manual.
151
NIalso offers plug-in image acquisition devices called frame grabbers that provide connectivity between industrial
cameras and PCI, PCI Express, PXI, and PXI Express slots. These devices are commonly used for scientific and
automated test applications, but you also can use them to prototype a vision application on a PC before you
purchase any industrial vision systems or smart cameras.
All NIimage acquisition hardware uses the same driver software called NIVision Acquisition software. With this
software, you can design and prototype your application on the hardware platform of your choice and then deploy it
to the industrial platform that best suits your application requirements with minimal code changes.
The lens used in a machine vision application changes the field of view. The field of view is the area under inspection
that is imaged by the camera. You must ensure that the field of view of your system includes the object you want to
inspect. To calculate the horizontal and vertical field of view (FOV) of your imaging system, use Equation 10.1 and the
specifications for the image sensor of your camera.
Where
152
Working distance is the distance from the front element (external glass) of the lens to the object
under inspection
Focal length measures how strongly a lens converges (focuses) or diverges (diffuses) light
For example, if the working distance of your imaging setup is 100 mm, and the focal length of the lens is 8 mm, then
the FOV in the horizontal direction of an NISmart Camera using the VGA sensor in full Scan Mode is
Based on the result, you can see that you may need to adjust the various parameters in the FOV equation until you
achieve the right combination of components that match your inspection needs. This may include increasing your
working distance, choosing a lens with a shorter focal length, or changing to a high-resolution camera.
Software Options
Once you have chosen the hardware platform for your machine vision project, you need to select the software
platform you want to use. NIoffers two application development environments (ADEs) for machine vision. Both
NICompact Vision Systems and NISmart Cameras are LabVIEW Real-Time targets, so you can develop your
machine vision application using the LabVIEW Real-Time Module and the NIVision Development Module.
The Vision Development Module is a library of machine vision functions that range from basic filtering to pattern
matching and optical character recognition. This library also includes the NIVision Assistant and the Vision Assistant
Express VI. The Vision Assistant is a rapid prototyping tool for machine vision applications. With this tool, you can use
click-and-drag, configurable menus to set up most of your application. With the Vision Assistant Express VI, you can
use this same prototyping tool directly within LabVIEW Real-Time.
153
Another software platform option is NIVision Builder for Automated Inspection (AI). Vision Builder AI is a configurable
machine vision ADE based on a state diagram model, so looping and decision making are extremely simple. Vision
Builder AI features many of the high-level tools found in the Vision Development Module. Both hardware targets work
with Vision Builder AI as well, giving you the flexibility to choose the software you are most comfortable with and the
hardware that best suits your application.
Figure 10.4. NIoffers both configuration software and a full programming environment
for machine vision application development.
154
Figure 10.5. You can add NISmart Camera systems to the same LabVIEW project
as CompactRIO systems.
155
Upon deployment, this VI resides in smart camera storage and runs on the smart camera during run time.
To simplify the process of acquiring and processing images, NIincludes Express VIs in the Vision palette. Use these
Express VIs in this example to acquire images from the smart camera (or vision system) as well as process the
images. To access these Express VIs, right-click on the block diagram and choose VisionVision Express.
The first step is to set up an acquisition from your camera. Or, if your camera is not available or not fixtured correctly
yet, you also can set up a simulated acquisition by opening images stored on your hard drive.
Start by dropping the Vision Acquisition Express VI onto the block diagram. This menu-driven interface is designed so
that you can quickly acquire your first image. If you have any recognized image acquisition hardware connected to
your computer, it shows up as an option. If not, you have the option on the first menu to open images from disk.
156
Figure 10.8. The Vision Acquisition Express VI guides you though creating a vision application in LabVIEW.
Next, choose which type of acquisition you are implementing. For this example, select Continuous Acquisition with
inline processing so you can sit in a loop and process images. Next, test your input source and verify that it looks
right. If it does, then click the finish button at the bottom.
Once this Express VI generates the LabVIEW code behind the scenes, the block diagram appears again. Now drop
the Vision Assistant Express VI just to the right of the Vision Assistant Express VI.
With the Vision Assistant, you can prototype your vision processing quickly. You can deploy this same tool to realtime systems, although traditional LabVIEW VIs are usually implemented to provide greater efficiency in the real-time
systems. For an overview of the tools in this assistant, view the NIVision Assistant Tutorial.
Step 3. Communicate With the CompactRIO System
Once you have set up the machine vision you plan to conduct with the Vision Assistant Express VI, the last thing to
do is communicate the data with the CompactRIO system. You can use network-published shared variables to pass
data between the two systems. Network communication between LabVIEW systems is covered in depth in an
earlier section in this document. In this example, you are examining a battery clamp, and you want to return the
condition of the holes (if they are drilled correctly) and the current gap shown in the clamp.
157
As you can see in Figure 10.9, the results of the inspection are passed as current values to the CompactRIO system
via shared variables hosted on the CompactRIO system. You can also pass the data as commands to the
CompactRIO system.
158
Figure 10.10. Choose your execution target from the Vision Builder AI splash screen.
With this emulator, you can set up lighting and trigger options, arrange I/O to communicate to the CompactRIO
hardware, and complete many of the other actions required to configure the smart camera without having one available
for your development system. Once you have selected your execution target, click on Configure Inspection. This takes
you into the development environment, which features four main windows. Use the largest window, the Image Display
Window, to see the image you have acquired as well as any overlays you have placed on the image. Use the window to
the upper right, the State Diagram Window, to show the states of your inspection (with your current state highlighted).
The bottom right window, the Inspection Step palette, displays all the inspection steps for your application. Lastly, the
thin bar at the bottom is the Step Display Window, where you see all of the steps that are in the current state.
This example implements the same inspection as the LabVIEW example that inspected battery clamps and returned
the number of holes and the gap of the clamp back to CompactRIO via the two shared variables hosted on the
CompactRIO hardware.
Step 2. Configure the Inspection
The first step of the inspection, just like in LabVIEW, is to acquire the image. Implement this with the Acquire Image
(Smart Camera) step. Select this step and configure the emulation by clicking on the Configure Simulation Settings
button. For example, set the image to grab the images from the following path:
C:\Program Files\National Instruments\Vision Builder AI 3.6\DemoImg\Battery\BAT0000.PNG
159
This library of images should install with every copy of Vision Builder AI (with differing version numbers). After
selecting the file above, also make sure to check the box for Cycle through folder images.
You also see that with this window, you can configure exposure times, gains, and other settings for the camera.
These settings do not make any difference in the emulator, but in the real world, they go hand-in-hand with lighting
and optics choices.
From here, set up pattern matching, edge detection, object detection, code reading, or any other algorithms you need.
For example, implement a pattern match to set the overall rotation of the object, a detect objects to see if both of the
holes were in the clamp, and a caliper tool to detect the distance between the clamp prongs. This generates a few
pass/fail results that you can use to set the overall inspection status, which you can display on the overlay to the user.
Now create two new states by clicking the toggle main window view button (circled in red). Create a pass state and
a fail state. In both states, report the values back to CompactRIO but, in the fail state, also reject the part using some
digital I/O.
160
Now these results are sent back to the CompactRIO system, and the inspection waits on the next camera trigger.
As you can see, both methods (programmable and configurable) offer the user a way to acquire images, process
them, and then use the pertinent information to report results back to a CompactRIO control system or to directly
control I/O from a real-time vision system.
Motion Control
This section examines precision motion control. Motor control is the on-off control or simple velocity control of rotary
equipment such as fans and pumps. You can implement motor control with standard digital output modules to an
appropriate motor starter or with an analog output to a Variable Frequency Drive (VFD). With specialized sensors,
actuators, and fast control loops, you can perform precise position or velocity motion control, often on multiple axes. This
section discusses the more sophisticated task of performing high-precision motion control on CompactRIO hardware.
A full motion control implementation is a complex system with several nested control loopssome running at high
speedsand precise mechanical components. A reliable, high-performance motion control system consists of the
following devices:
161
1. Motion controllerThis controller is the processing element that runs software algorithms and closed control
loops to generate the motion profile commands based on the move constraints from the user-defined
application software and I/O feedback.
2. Communication moduleThis I/O module interfaces with the drive and feedback devices. It converts the
command signals from the motion controller to digital or analog values that the drive can interpret.
3. Drive/amplifierThe drive/amplifier consists of the power electronics that convert the analog or digital
command signal from the communication module into the electrical power needed to spin the motor. In many
cases, it also has a processing element that closes high-speed current control loops.
4. MotorThe motor converts the electrical energy from the drive/amplifier into mechanical energy. The motor
torque constant, kt, and the motor efficiency define the ratio between motor current and mechanical torque
output.
5. Mechanical transmissionThe transmission consists of the components connected to the motor that direct
the rotary motion of the motor to do work. This typically involves mechanical devices such as gearboxes or
pulleys and lead screws that convert the rotary motion at the motor shaft to a linear movement at the payload
with a certain transmission gear ratio. Common examples are belts, conveyors, and stages.
6. Feedback devicesThese are sensors such as encoders and limit switches that provide instantaneous
position and velocity information to the drive/amplifier and the motion controller.
162
1. Supervisory controlThis top control loop executes command sequencing and passes commands to the
trajectory generation loops. This loop performs the following:
2. Trajectory generatorThis loop receives commands from the supervisory control loop and generates path
planning based on the profile specified by the user. It provides new location setpoints to the control loop in a
deterministic fashion. As a rule of thumb, this loop should execute with a 5 ms or faster loop rate.
3. Control loopThis is a fast control loop that executes every 50 s. It uses position and velocity sensor
feedback and the setpoint from the trajectory generator to create the commands to the drive. Because this loop
runs faster than the trajectory generator, it also generates intermediate setpoints based on time with a routine
called spline interpolation. For stepper systems, the control loop is replaced with a step generation component.
163
communication interfaces to third-party drives. In addition, LabVIEW NISoftMotion enables virtual prototyping for
motion applications and machine design by connecting to the SolidWorks Premium 3D CAD design application. With
NISoftMotion for SolidWorks, you can simulate your designs created in SolidWorks using the actual motion profiles
developed with LabVIEW NISoftMotion function blocks before incurring the cost of physical prototypes.
For more information, visit ni.com/virtualprototyping.
find the correct stage for your application, you need to be familiar with some of the common terminology used when
describing stages. Some
of the keygear
items
to consider when
selecting
a stage
include
the
following:
Transmission
rationDetermines
the
linear
travel
distance
of
the
stage
per
rotary
revolution
of
the
motor.
Transmission gear
rationDetermines the linear travel distance of the stage per rotary revolution of the
AccuracyHow
closely
the
length
of
a
commanded
move
compares
to
a
standard
length.
motor.
specified in unidirectional repeatability, which is the ability to return to the same point from one direction, and
bidirectional repeatability, which specifies the ability to return from either direction.
193
Maximum loadThe maximum weight the stage is physically designed to carry, given accuracy and repeatability.
164
Stage Selection
You can choose from a variety of stages to meet your application needs. You can narrow down these stages to two
main typeslinear and rotary. Linear stages move in a straight line and are often stacked on each other to provide
travel in multiple directions. A three-axis system with an x, y, and z component is a common setup used to position
an object anywhere in a 3D space. A rotary stage is a stage that rotates about an axis (usually at the center). Linear
stages are used to position an object in space, but rotary stages are used to orient objects in space and adjust the
roll, pitch, and yaw of an object. Many applications, such as high-precision alignment, require both position and
orientation to perform accurate alignment. The resolution for a rotary stage is often measured in degrees or arc
minutes (1 degree equals 60 arc minutes). Special types of stages include the goniometer, which looks like a linear
stage that moves in an arc rather than a straight line, or a hexapod, which is a parallel mechanism that gives you
movement in six axes to controlx, y, z, roll, pitch, and yaw. With a hexapod, you can define a virtual point in space
about which the stage can rotate. While that is a benefit, the disadvantage is that hexapods are parallel and the
kinematics involved are much more complex than those for simple stacked stages.
Backlash
Another stage attribute to consider when choosing a stage for your precision motion system is backlash. Backlash is
the lag created when one gear in a system changes direction and moves a small distance before making contact
with a companion gear. It can lead to significant inaccuracies especially in systems using many gears in the drive
train. When moving on a nanometer scale, even a small amount of backlash can introduce major inaccuracy in the
system. Effective mechanical design minimizes backlash but may not be able to eliminate it completely. You can
compensate for this problem by implementing dual-loop feedback in software. The NI9516 C Series servo drive
interface module supports dual-encoder feedback and accepts feedback from two different sources for a single axis.
To understand the circumstances for which you need to use this feature, consider a stage. If you monitor the stage
position directly (as opposed to the position of the motor driving the stage), you can tell if a move you have
commanded has reached the target location. However, because the motion controller is providing input signals to
the motor and not to the stage, which is the primary source of feedback, the difference in the expected output
relative to the input can cause the system to become unstable. To make the fine adjustments necessary to help the
system stay stable, you can monitor the feedback directly from the encoder on the motor as a secondary feedback
source. Using this method, you can monitor the real position of your stage and account for the inaccuracies in the
drive train.
Motor Selection
A motor provides the stage movement. Some high-precision stages and mechanical components feature a built-in
motor to minimize backlash and increase repeatability, but most stages and components use a mechanical coupling
to connect to a standard rotary motor. To make connectivity easier, the National Electrical Manufacturers Association
(NEMA) has standardized motor dimensions. For fractional horsepower motors, the frame sizes have a two-digit
designation such as NEMA 17 or NEMA 23. For these motors, the frame size designates a particular shaft height,
shaft diameter, and mounting hole pattern. Frame designations are not based on torque and speed, so you have a
range of torque and speed combinations in one frame size.
The proper motor must be paired with the mechanical system to provide the performance required. You can choose
from the following four main motor technologies:
1. Stepper motorA stepper motor is less expensive than a servo motor of a similar size and is typically easier
to use. These devices are called stepper motors because they move in discrete steps. Controlling a stepper
motor requires a stepper drive, which receives step and direction signals from the controller. You can run
stepper motors, which are effective for low-cost applications, in an open-loop configuration (no encoder
feedback). In general, a stepper motor has high torque at low speeds and good holding torque but low torque
at high speeds and a lower maximum speed. Movement at low speeds can also be choppy, but most stepper
drives feature a microstepping capability to minimize this problem.
165
2. Brushed servo motorThis is a simple motor on which electrical contacts pass power to the armature
through a mechanical rotary switch called a commutator. These motors provide a 2-wire connection and are
controlled by varying the current to the motor, often through PWM control. The motor drive converts a control
signal, normally a 10 V analog command signal, to a current output to the motor and may require tuning.
These motors are fairly easy to control and provide good torque across their range. However, they do require
periodic brush maintenance, and, compared to brushless servo motors, they have a limited speed range and
offer less efficiency due to the mechanical limitations of the brushes.
3. Brushless servo motorThese motors use a permanent magnet rotor, three phases of driving coils, and
Hall effect sensors to determine the position of the rotor. A specialized drive converts the 10 V analog signal
from the controller into three-phase power for the motor. The drive contains intelligence to perform electronic
commutation and requires tuning. These efficient motors deliver high torque and speed and require less
maintenance. However, they are more complex to set up and tune, and the motor and drive are more expensive.
4. Piezo motorThese motors use piezoelectric material to create ultrasonic vibrations or steps and produce a
linear or rotary motion through a caterpillar-like movement. Able to create extremely precise motion, piezo
motors are commonly used in nanopositioning applications such as laser alignment. For high accuracy, they are
often integrated into a stage or actuator, but you can also use piezo rotary motors.
Speed
Maximum
Load
Travel Distance
Repeatability
Relative
Complexity
Relative Cost
Medium/Low
Medium/Low
High
Medium/Low
Low
Low
High
High
High
Medium
Medium
Low
Brushless Servo
Very High
High
High
High
High/Medium
High
Piezo
Medium
Low
Low
Very High
High
High
Stage Drive
Technology
Stepper
Brushed Servo
Because the motor and drive are so closely coupled, you should use a motor and drive combination from one vendor.
Though this is not a requirement, it makes tuning and selection easier.
The NI9512 is a single-axis stepper or position command drive interface module with incremental
encoder feedback.
The NI9514 is a single-axis servo drive interface module with incremental encoder feedback.
When run in Scan Mode, these modules must be used in any of the first four slots in a CompactRIO chassis. With
LabVIEW FPGA, you can use them in any slot.
166
NI951x modules were designed to simplify wiring by providing the flexibility to hook up all the I/O for motion control
to a single module. To further ease connectivity, the digital I/O is software configurable to connect to either sinking or
sourcing devices. The modules offer the following:
DI signals for home, limits, and general digital I/O; all software configurable as sinking or sourcing (24 V)
LEDs to provide quick debugging for encoder states, limit status, and axis faults
To further simplify wiring, NIoffers several options for connecting NI951x drive interface modules to external
stepper drives or servo amplifiers including the following:
NI9512-to-P7000 Stepper Drives Connectivity BundleConnects the NI9512 to the P70530 or P70360
stepper drives from NI.
NI951x Cable and Terminal Block BundleConnects an NI951x module with 37-pin spring or screw
terminal blocks.
D-SUB to pigtails cable and MDR to pigtails cableSimplifies custom cable creation.
Figure 10.18. Choose from several options to simplify connecting NI951x modules directly to drives.
167
instantiate background control loops to run on the controller. You use the logical channels you create when
developing motion applications using the NISoftMotion LabVIEW API.
An axis is a logical channel associated with an individual motor. Each motor you are controlling must be in an axis.
A coordinate is a grouping of one or more axes. By planning for multiple axes in a coordinate, you can create
multiaxis coordinated motion. For instance, if you have an XY stage and you want to create an oval, it is difficult
to command the two motors individually. But if you group them as an axis, the LabVIEW NISoftMotion trajectory
generator automatically develops the commanded points to each axis so the resulting motion is an oval.
A table is used to specify more complex move profiles such as contour moves and camming. You can import
the move profile from an external tab delimited text file.
An axis consists of a trajectory generator, PID control loop or stepper output, and supervisory control. You can
associate a LabVIEW NISoftMotion axis with simulated hardware or with actual hardware. Servo axes require an
encoder feedback resource. Open-loop stepper axes do not require feedback for operation.
Once you have created axes, you can generate coordinates and add axes to the coordinates. When using coordinate
resources in LabVIEW, you receive target positions and other coordinate information in a 1D array with axis
information arriving in the order that axes are added using this dialog box.
Configuring the Axes
Once you add an axis to the project, you need to configure the axis by right-clicking on it and selecting properties.
168
Figure 10.20. You can use the Axis Configuration feature to configure all of the motion I/O parameters.
To configure a stepper drive connected to the NIP7000 series stepper drive, follow these steps:
1. Right-click the axis in the LabVIEW Project Explorer window and select Properties from the shortcut menu to
open the Axis Configuration dialog box.
2. On the Axis Setup page, confirm that Loop Mode is set to Open-Loop. Axes configured in open-loop mode
produce step outputs but do not require feedback from the motor to verify position.
3. Also on the Axis Setup page, confirm that the Axis Enabled and Enable Drive on Transition to Active Mode
checkboxes contain checkmarks. These selections configure the axes to automatically activate when the Scan
Engine switches to active mode.
4. If the modules do not have physical limit and home input connections, you must disable these input signals for
proper system operation. To disable limits and home, go to the Motion I/O page and remove the checkmarks
from the Enable checkboxes in the Forward Limit, Reverse Limit, and Home sections.
5. Configure any additional I/O settings according to your system requirements.
6. Click OK to close the Axis Configuration dialog box.
7. Right-click the controller item in the LabVIEW Project Explorer window and select Deploy All from the
shortcut menu to deploy.
Note: Make sure all hardware connections are made and power is turned on before deploying the project.
Deployment switches the Scan Engine to active mode and enables your axes and drive, if connected, so that you can
start a move immediately.
Test the Motion System
To make sure your motion is configured and connected correctly, you can use the Interactive Test Panel to test and
debug your motion system. With the Interactive Test Panel, you can perform a simple straight-line move and monitor
move and I/O status information, change move constraints, obtain information about errors and faults in the system,
169
and view the position or velocity plots of the move. If you have a feedback device connected to your system, you can
also obtain feedback position and position error information.
To start the Interactive Window, right-click the axis in the LabVIEW Project Explorer window and select Interactive
Test Panel from the shortcut menu. Set the desired position, move mode, and move constraints using the tabs.
Figure 10.21. With the Interactive Test Panel, you can verify a motion configuration before writing code.
Click the Start button on the bottom of the dialog box to start the move with the configured options. Use the Status
and Plots tabs to monitor the move while it is in progress.
170
Motion function blocks are an API to the motion manager running on the CompactRIO system. They perform two actions:
1. Send a command to the motion managerThe function block sends the command to the manager when
the execute input transitions from low to high (rising edge). The default value is false so if a true constant is
wired into the block, the first iteration counts as a rising edge.
2. Poll the motion managerEvery iteration, the function block polls the manager to see if the command was
executed successfully. The results of the poll are returned through the done, busy, active, aborted, and
error out outputs.
171
The error out, done, aborted, busy, and active outputs behave according to the following guidelines:
Output exclusivity
Busy, done, error out, and aborted are mutually exclusive and set at any given time.
Only one of these outputs can be TRUE at any time on one function block. If the
execute input is TRUE, one of these outputs must be TRUE.
Output status
The done and aborted outputs are reset with the falling edge of execute (state
latches while execute is high). However, the falling edge of execute does not stop or
influence the execution of the motion manager once it has received the command.
The done output is set TRUE when the commanded action successfully completes.
The default value is FALSE. Once a move has completed, it is reset to FALSE when
the execute is false.
Every function block has a busy output that indicates that the function block
operation is not complete. Busy is set at the rising edge of execute and resets when
either done, aborted, or error out is set. It is recommended that the application
controlling the execution of this function block not be terminated for at least as long
as busy is TRUE because the software may be left in an undefined state.
Output active
The active output is set to TRUE at the moment the function block takes control of
the specified resource, all properties have been committed, and the function block
has executed.
Are triggered to pass commands to the motion manager based on a rising edge of the execute input.
Provide feedback if the motion manager successfully finishes the commanded task through a done output.
Are instanced (have a unique memory space) and reentrant, but each instance can be called from only one
location in the program.
Must be executed in a VI that is part of a LabVIEW project.
Have a double-click dialog that you can use to configure default values, automatically bind data to variables,
and configure the data source as terminal, variable, or default.
Have methods exposed on the right-click menu. For instance, the Stop Move function block can be either
decelerate, immediate, or disable drive.
Must always be run in a loop. Depending on your application requirements, you can use either a While Loop
timed using a Wait Until Next ms Multiple Function or you can use a Timed Loop.
172
You should use the function block status inputs and outputs (execute, done, and so on)not standard LabVIEW
programming methodsto determine the order of function block execution. For example, do not place function
blocks inside a Case structure unless the Case structure is controlled by the status outputs. Consider the Figure
10.24 block diagram:
Figure 10.24. Incorrect Example of Programming Motion Using Motion Function Blocks
If you are not familiar with function blocks, you likely expect this code to move Axis 1 to position 1000 and then back
to 0. However, these function blocks are not actually performing the motionthey are simply sending commands to
the motion manager when they see a rising edge on their execute inputs.
Instead this code enables the drive and axis, but no motion takes place.
The Power function sees a rising edge on the execute input (the default is false, so if you wire a true, the first
iteration executes).
When it receives a rising edge, it sends a command to the motion manager to enable the axis and drive.
This nonblocking function does not wait for the manager to finish the command before continuing the
LabVIEW code, and the done output is false on the first iteration.
All remaining blocks in the code chain do not see a rising edge on their execute inputs and do not send any
commands to the manager.
No motion takes place.
173
In this example, the drive is enabled, moves to position 1000, and moves to position 0, but it does not perform
repeated moves. This is because each function block receives a rising edge on the execute input only once.
To make the axis cycle repeatedly between 1000 and 0, you need to write code like that shown in Figure 10.26.
Figure 10.26. Correct Example of Programming Repeated Motion Using Motion Function Blocks
The loop with the Power function block sends a command to the motion manager.
It then polls the manager to check the status of the command. Once it gets confirmation that the command
was finished, it writes a true to the done bit and exits the first loop.
In the Timed Loop, the first straight-line move function block sees a true on the execute terminal and
commands the manager to move to position 1000.
The done output is false until the move has completed, and the second Straight-Line Move function block does
nothing because it has a false in the execute input.
At each iteration of the loop, the first straight-line move polls the manager to see if the move completed.
When the first move is complete, it outputs a true on the done terminal.
The second straight-line move sees a low-to-high transition on the execute bit and sends its command to
the manager.
174
When this block receives confirmation that it completed, it transitions its done terminal from false to true.
Through the shift register, this causes the first function block to see a low-to-high transition on the execute
terminal and the moves repeat.
If a stop command is ever executed, the clean-up code with the stop command stops the motion. Because the
motion manager is a separate process, without this stop command to the manager the move continues until
completion even though the LabVIEW code is no longer executing.
175
Palette
Symbol
Line
Arc
Performs a straight-line move using an axis or coordinate resource. A straight-line move connects two
points using one or more axes. The behavior of the move changes based on the Straight-Line Move Mode.
Performs a circular, spherical, or helical arc move. An arc move produces motion in a circular shape using a
radius you specify. The type of arc to perform changes based on the Arc Move Mode.
Performs a contour move using an axis or coordinate resource. A contour move is a move expressed as a
series of positions that the software uses to extrapolate a smooth curve. These positions are stored in a
table. Each point in the move is interpreted as an absolute position using the starting point of the move as a
temporary zero position. The type of contour move changes based on the Contour Mode.
Performs a reference move, such as locating a home or limit position, on an axis resource. Reference
moves are used to initialize the motion system and establish a repeatable reference position. The behavior
of the move changes based on the Reference Move Mode.
Records encoder position based on an external input, such as the state of a sensor. You can use the
captured position to execute a move relative to a captured position, or simply record the encoder position
when the capture event occurs.
Synchronizes the motor with external activities and specified encoder positions. When the specified
position is reached, a user-configurable pulse is executed. The behavior of the position compare operation
changes based on the Compare Mode.
Contour
Reference
Capture
Compare
Gearing
Camming
Read
Write
Reset
Position
Description
Configures the specified axis for gearing operations. Gearing synchronizes the movement of a slave axis
to the movement of a master device, which can be an encoder or the trajectory of another axis. The
movement of the slave axes may be at a higher or lower gear ratio than the master. For example, every turn
of the master axis may cause a slave axis to turn twice. The type of gearing operation to perform changes
based on the Gearing Mode.
Configures the specified axis for camming operations. These ratios are handled automatically by LabVIEW
NISoftMotion, allowing precise switching of the gear ratios. Camming is used in applications where the
slave axis follows a nonlinear profile from a master device. The type of camming operation changes based
on the Camming Mode.
Reads status and data information from axes, coordinates, feedback, and other resources. Use the read
methods to obtain information from different resources.
Writes data information to axes, coordinates, or feedback resources. Use the write methods to write
information to different resources.
Stop
Stops the current motion on an axis or coordinate. The behavior of the move changes based on the Stop
Mode.
Enables and disables axes and/or drives on the specified axes or coordinate resources.
Power
Clear Faults
176
177
You can place this state machine in your standard CompactRIO controller architecture with initialization and
shutdown states.
Figure 10.28. You can drop a state machine with motion commands
into the standard controller architecture.
178
CHAPTER 11
DEPLOYING AND REPLICATING SYSTEMS
Application Deployment
All LabVIEW development for real-time targets and touch panel targets is done on a Windows PC. To run the code
embedded on the targets, you need to deploy the applications. Real-time controllers and touch panels, much like a
PC, have both volatile memory (RAM) and nonvolatile memory (hard drive). When you deploy your code, you have
the option to deploy to either the volatile memory or nonvolatile memory on a target.
Deploy to Volatile Memory
If you deploy the application to the volatile memory on a target, the application does not remain on the target after
you cycle power. This is useful while you are developing your application and testing your code.
Deploy to Nonvolatile Memory
If you deploy the application to the nonvolatile memory on a target, the application remains after you cycle the power
on the target. You also can set applications stored on nonvolatile memory to start up automatically when the target
boots. This is useful when you have finished code development and validation and want to create a stand-alone
embedded system.
LabVIEW verifies that the VI and all subVIs are saved, deploys the code to the nonvolatile memory on the
CompactRIO controller, and starts embedded execution of the code.
179
After selecting Real-Time Application, you see a dialog box featuring two main categories that are most commonly
used when building a real-time application: Information and Source Files. The Destinations, Source File Settings,
Advanced, and Additional Exclusions categories are rarely used when building real-time applications.
180
The Information category contains the build specification name, executable filename, and destination directory for
both the real-time target and host PC. You can change the build specification name and local destination directory to
match your nomenclature and file organization. You normally do not need to change the target filename or target
destination directory.
The Source Files category is used to set the startup VIs and include additional VIs or support files. You need to select
the top-level VI from your Project Files and set it as a Startup VI. For most applications, a single VI is chosen to be a
Startup VI. You do not need to include lvlib or set subVIs as Startup VIs or Always Included unless they are called
dynamically in your application.
181
Figure 11.4. Source Files Category in the Real-Time Application Properties (In this example,
the cRIOEmbeddedDataLogger (Host).vi was selected to be a Startup VI.)
After all of the options have been entered on the required category tabs, you can click OK to save the build
specification or you can directly build the application by clicking the Build button. You can also right-click on a saved
build specification and select Build to build the application.
When you build the application, an executable is created and saved on the hard drive of your development machine
in the local destination directory.
Setting an executable real-time application to run on startup
After an application has been built, you can set the executable to automatically start up as soon as the controller
boots. To set an executable application to start up, you should right-click the Real-Time Application option (under
Build Specifications) and select Set as startup. When you deploy the executable to the real-time controller, the
controller is also configured to run the application automatically when you power on or reboot the real-time target.
You can select Unset as Startup to disable automatic startup.
182
183
184
A benefit of this method is that the executable includes both targets applications in one file. In addition, since the
host file is an executable, you can simply transfer it to the host using any FTP program.
The host application is required to initialize before the FPGA application is loaded. As a result, there is a delay from
device power up to the configuration of the FPGA. In addition, on power up, the state of the input and output lines of
your target is unknown since the FPGA has not yet been configured. Therefore, if the FPGA is completely
independent of the host application, its personality should be stored in the onboard FPGA flash memory.
185
Method 2: Storing the Application in Nonvolatile Flash Memory on the FPGA Target
You also can download the bitfile to flash memory on the FPGA target device using the RIO Device Setup that is
included with the NI-RIO driver as shown in Figure 11.9. Subsequently, whenever the target is rebooted, it
immediately loads the personality onto the FPGA from the flash memory independent of what the host application is
executing. To learn more about this download process, reference KnowledgeBase 47D9Q22M. In addition,
downloading the personality to the flash memory ensures that when the device is in power up, it drives all of the
input and output lines to a known state since it is loaded immediately on the FPGA.
Figure 11.9. You can download the FPGA bitfile to the FPGAs onboard flash memory
using the RIO Device Setup.
If communication does occur with the host, you must modify the host application so that the Open FPGA Reference
function does not overwrite the personality that is automatically loaded on the FPGA. To disable this download,
uncheck the Run the FPGA VI option in the Open FPGA VI Reference function configuration, as shown in Figure
11.10. In addition, since the FPGA personality is loaded immediately on boot up from the flash memory, the
connecting host does not immediately have control over the current state of the FPGA. If you need host control of
the FPGA, you should embed the personality in the host application rather than store it in flash memory.
186
Figure 11.10. You need to disable the Run the FPGA VI option in the Open FPGA VI Reference
configuration window if the FPGA bitfile is loaded from the onboard flash memory
so that the host application does not overwrite the bitfile on the FPGA.
The recommended personality deployment architecture depends on the needs of the specific application. However,
in the majority of implementations, you should embed the personality in the host application since the FPGA often is
dependent on a host application. For more information on managing FPGA deployments, see the NIDeveloper Zone
document Managing FPGA Deployments.
187
2. You can programmatically deploy the library from a LabVIEW application running on Windows using the
Application Invoke Node.
Use the Path input of the Deploy Library Invoke Node to point to the library(s) containing your shared
variables. Also specify the IP address of the real-time target using the Target IP Address input.
188
To provide scalability, this information is not hard-coded into the executable. Instead, this information is stored in a
file on the target called an alias file. An alias file is a human-readable file that lists the logical name of a target
(CompactRIO) and the IP address for the target (10.0.62.67). When the executable runs, it reads the alias file and
replaces the logical name with the IP address. If you later change the IP addresses of deployed systems, you need
to edit only the alias file to relink the two devices. For real-time and Windows XP Embedded targets, the build
specification for each system deployment automatically downloads the alias file. For Windows CE targets, you need
to configure the build specification to download the alias file.
If you are deploying systems with dynamic IP addresses using DHCP, you can use the DNS name instead of the IP address.
In the LabVIEW project, you can type the DNS name instead of the IP address in the properties page of the target.
189
Figure 11.15. For systems using DHCP, you can enter the DNS name instead of the IP address.
One good approach if you need scalability is to develop using a generic target machine (you can develop for remote
machines that do not exist) with a name indicating its purpose in the application. Then as part of the installer, you can
run an executable that either prompts the user for the IP addresses for the remote machine and My Computer or pulls
them from another source such as a database. Then the executable can modify the aliases file to reflect these changes.
190
Recommended software sets guarantee that an application has the same set of underlying drivers for every real-time
system that has the same software set. In general, there is a minimal and full software set.
System Replication
After you deploy a LabVIEW Real-Time application to a CompactRIO controller, you may want to deploy that image
to other identical real-time targets. Being able to replicate the image of a real-time target makes deploying targets
and systems easier and more efficient. Whether the user is making periodic backups of a system, deploying from a
developed system to many new ones, updating an image on a target, or giving someone else the tools to duplicate a
working system, replicating an image makes all of these applications possible. The Real-Time Application
Deployment utility makes the system replication simple and intuitive.
NIoffers a variety of tools for the replication of LabVIEW Real-Time targets. You can use the tools to replicate one
real-time target into multiple copies, circumventing the use of MAX and an FTP client in favor of a simple utility or
the ability to customize your own using LabVIEW. The imaging process includes the following steps:
1. Deploy the built application to a real-time target from the LabVIEW project.
2. Create a disk image from this controller (the image packages every file on the real-time target hard drive in a
zip file and saves it to the host machine).
3. Deploy that image to one or more targets.
191
Figure 11.17. With NIimaging tools, you can deploy images to multiple real-time targets.
With this imaging process, you can obtain an exact copy of a real-time system and easily deploy it to multiple
targets. This reduces the risk of deployment error and the need for using the LabVIEW development environment for
deployment. When using this process, you must deploy images to the same controller model used to create the
image. For example, an image that was created for a cRIO-9022 controller cannot be used on a cRIO-9024 controller.
You can choose from two methods for imaging CompactRIO systems. You can use a prebuilt imaging utility or you
can design your own custom utility using built-in functions in LabVIEW Real-Time. The next section provides an
overview of the Real-Time Application Deployment Utility in addition to several APIs for developing your own custom
utility.
192
Figure 11.18. With NIimaging tools, you can deploy images to multiple real-time targets.
The Real-Time Targets table shows all of the targets on the local subnet as well as any network targets manually
added to the list. You can use these targets for both image retrieval and image deployment. The Application Images
table shows all of the images that are stored on the local hard drive and can be deployed to a target system.
193
In addition to retrieving and deploying an image on the real-time hard drive, the utility can deploy bitfiles to FPGA
flash memory. Saving a bitfile in flash memory has some advantages to deploying the bitfile from the RT EXE. For
example, the host application is required to initialize before the FPGA application is loaded and, as a result, there is a
delay from device power up to the configuration of the FPGA. In addition, on power up, the state of the input and
output lines of your target is unknown since the FPGA has not yet been configured. Therefore, if the FPGA is
completely independent of the host application, its personality should be stored in the onboard FPGA flash memory.
Using the RTAD utility, you can now save bitfiles with an image during retrieval and then later deploy them to flash
memory when you deploy the image. Click Configure Bitfile(s) for FPGA Flash Deployment to edit your FPGA flash
deployment settings.
194
deployed to the selected targets in sequential order, one at a time. During this process, the Figure 11.20 progress
dialog is shown. This process takes several minutes per real-time target.
Click the Start button to begin the comparison process. Once the comparison begins, each file on both images is
compared for changes. Files that are found in one image and not the other are also identified. This process may take
several minutes to complete, and a progress dialog is displayed until completion. If the tool completes with no
differences found, the Figure 11.22 dialog appears.
195
However, if any differences are identified, they are listed in the Figure 11.23 table. You can then log the results to a
TSV file.
Figure 11.24. Include the USB Deploy Image VI in your deployed real-time application
to enable updates from a USB memory stick.
Once you have added this code, you can build the main application into an executable and deploy it to a CompactRIO
controller. The deployed application executable, together with all of the other files on the CompactRIO controller hard
drive, becomes the application image. For more information on this utility including downloadable files, see the
NIDeveloper Zone document Reference Design for Deploying CompactRIO Application Updates Using a USB
Memory Device.
196
RT Utilities API
The RT Utilities API also includes VIs for image retrieval and deployment.
Figure 11.26.You also can use the RT Utilities VIs in LabVIEW 2009 or later
to programmatically deploy and retrieve a system image.
197
You can download this library from the NIDeveloper Zone document
Reference Library for Reading CompactRIO System Configuration Information.
IP Protection
Intellectual property (IP) in this context refers to any unique software or application algorithm(s) that you or your
company has independently developed. This can be a specific control algorithm or a full-scale deployed application. IP
normally takes a lot of time to develop and gives companies a way to differentiate from the competition. Therefore,
protecting this software IP is important. LabVIEW development tools and CompactRIO provide you the ability to
protect and lock your IP. In general, you can implement two levels of IP protection:
Lock algorithms or code to prevent IP from being copied or modified
If you have created algorithms for a specific functionality, such as performing advanced control functions,
implementing custom filtering, and so on, you may want to distribute the algorithm as a subVI but prevent someone
from viewing or modifying that actual algorithm. This may be to achieve IP protection or to reduce a support burden
by preventing other parties from modifying and breaking your algorithms.
Lock code to specific hardware to prevent IP from being replicated
Use this method if you want to ensure that a competitor cannot replicate your system by running your code on
another CompactRIO system or want your customers to come back to you for service and support.
198
Code running on the real-time processor is compiled into an executable and cannot be decompiled back to
LabVIEW code. Likewise, code running on the FPGA has been compiled into a bitfile and cannot be decompiled back
to LabVIEW code. To aid in future debugging and maintenance, you can store the LabVIEW project on the controller
or call raw VIs from running code, but by default any code deployed to a real-time controller is protected to prevent
copying or modifying the algorithms.
The LabVIEW password mechanism is quite difficult to defeat, but no password algorithm is 100 percent secure
from attack. If you need total assurance that someone cannot gain access to your source code, you should consider
removing the block diagram.
Method 2: Removing the block diagram
To guarantee that a VI cannot be modified or opened, you can remove the block diagram completely. Much like an
executable, the code you distributed no longer contains the original editable code. Do not forget to make a backup of
your files if you use this technique because the block diagram cannot be recreated. Removing the block diagram is
an option you can select when creating a source distribution. A source distribution is a collection of files that you can
199
package and send to other developers to use in LabVIEW. You can configure settings for specified VIs to add
passwords, remove block diagrams, or apply other settings.
Complete the following steps to build a source distribution.
1. In the LabVIEW project, right-click Build Specifications and select NewSource Distribution from the
shortcut menu to display the Source Distribution Properties dialog box. Add your VI(s) to the distribution.
2. On the Source File Settings page of the Source Distribution Properties dialog box, remove the checkmark
from the Use default save settings checkbox and place a checkmark in the Remove block diagram checkbox
to ensure that LabVIEW removes the block diagram.
3. Build the source distribution to create a copy of the VI without its block diagram.
Note: If you save VIs without block diagrams, do not overwrite the original versions of the VIs. Save the VIs in
different directories or use different names.
200
You can use the following steps as guidelines to programmatically lock any application to any of the above mentioned
hardware parameters and thus prevent users from replicating application code:
1. Obtain the hardware information for the device. Refer to the following procedures for more information on
programmatically obtaining this information.
2. Compare the values obtained to a predetermined set of values that the application code is designed for using
the Equal? function from the Comparison palette.
3. Wire the results of the comparison to the selectorinputof a Case structure.
4. Place the application code in the true case and leave the false case blank.
5. Performing these steps ensures that the application is not replicated or usable on any other piece of
CompactRIO hardware.
License Key
Adding licensing to a LabVIEW Real-Time application can protect a deployed application from being copied and run
on another similar or identical set of hardware without obtaining a license from the vendor or distributor of the
application. Most modern-day applications running on desktop computers are protected by a license key that is
necessary to either install the application or run it in its normal operational mode. Many vendors use license keys to
determine if an application runs in demo mode or is fully functional. License keys may also be used to differentiate
between versions of an application or to enable/disable specific features.
You can add this behavior to a LabVIEW Real-Time application using the reference design and example code
developed by NISystems Engineering. You can download this code from the NIDeveloper Zone document
Reference Design for Adding Licensing to LabVIEW Real-Time Applications. The main modification is how you
create a unique system ID for a specific hardware target. In the case of CompactRIO, you use the controller,
backplane, and module serial numbers. For other targets, you may use the serial number or Ethernet MAC address
of a given target to create a unique system ID.
201
One example of a more complex license model is to base the license key on the serial numbers of multiple system
components but requireonly someof these components to be present when running the licensed application. This
allows the application user to replace some of the system components, in case a repair is required, without needing
to acquire a new application license key. The number of components linked to the license key that must be present
to run the application is defined by the developer as part of the license model.
Figure 11.30. Block Diagram Showing the Process of Creating the License Key
Figure 11.31 shows one possible example of generating a system ID for a 4-slotCompactRIOsystem using these
VIs. The serial numbers for all six system components are added together. While this is not a truly unique value for a
given CompactRIO system, it is unlikely that after replacing one or more system components, the sum of all the
serial numbers will be the same as when the license key was generated.
202
203
The encryption VI provides two versions of the license key. The default algorithm returns a stream of bytes that can
have any value between 0 and 255. Therefore these bytes may not represent printable characters and may not be
easily stored in a text file or passed along using other mechanisms such as email. To simplify the process of storing
and transferring the license key, the VI provides a hexadecimal version of the encrypted string made up of the ASCII
representation of the hexadecimal value of each of the byte values in the original string. This string is stored in a file
as the license key.
Store the license key on the hardware target
The reference example stores the license key in a simple INIfile on theCompactRIOcontroller hard drive.
Figure 11.33. Storing the License Key in an INIFile on the CompactRIO Controller
If the license key and file are generated away from the actual CompactRIO system, then you must copy the license
file to the CompactRIO system when you deploy the application to the controller.
Verify the license key during application startup
When the deployed application is starting up, it needs to verify the license key and, based on the result of the
verification process, adjust its behavior according to the license model. If the license key is verified correctly, the
application runs normally, but if the key is not verified, it may not run at all or run in an evaluation mode.
The reference example provides a basic verification VI that is added before the actual application.
You can choose from two different methods to verify a license key. The first and preferred method is to recreate the
license key on the target system (described in this section). The second method, which consists of decrypting the
license key, is described in the NIDeveloper Zone white paper titled Reference Design for Adding Licensing to
LabVIEW Real-Time Applications under the section titled Enabling Features based on the License Key.
204
The more basic and more secure method to verify the license key is to run the same algorithm you use to create the
license key on the target system and then compare the new license key with the license key stored in the license
file. If the two match, then the license key is verified and the application may run.
Figure 11.35. Block Diagram to Verify the License Key Stored in the File on the System
Figure 11.35 shows that this process is almost identical to the process of generating the license key. Instead of
writing the license file, however, the license file is read and compared to the newly generated license key.
This method of verifying the license key works well if you do not need any partial information from the license key
such as information about enabling or disabling individual features or the individual serial numbers of system
components. For licensing models that require more detailed information about the license key, the key itself must
be decrypted. For more information on this type of licensing, see the NIDeveloper Zone document Reference
Design for Adding Licensing to LabVIEW Real-Time Applications.
205
Figure 11.36. Connect to a touch panel through Ethernet using the NITPC Service.
You can find the IP address of the touch panel by going to the command prompt on the TPC and typing ipconfig. To
get to the command prompt, go to the Start menu and select Run In the popup window, enter cmd.
206
After selecting the Touch Panel Application, you are presented with a dialog box. The two most commonly used
categories when building a touch panel application are Information and Source Files. The other categories are rarely
changed when building touch panel applications.
The Information category contains the build specification name, executable filename, and destination directory for
both the touch panel target and host PC. You can change the build specification name and local destination directory
to match your nomenclature and file organization. You normally do not need to change the target filename or target
destination directory.
Figure 11.38. The Information Category in the Touch Panel Application Properties
207
You use the Source Files category to set the startup VIs and obtain additional VIs or support files. You need to select
the top-level VI from your Project Files and set it as a Startup VI. For most applications, a single VI is chosen to be a
Startup VI. You do not need to include lvlib or set subVIs as Startup VIs or Always Included unless they are called
dynamically in your application.
Figure 11.39. Source Files Category in the Touch Panel Application Properties
(In this example, the HMI_SV.vi was selected to be a Startup VI.)
After you have entered all of the information on the required category tabs, you can click OK to save the build
specification or you can directly build the application by clicking the Build button. You can also right-click on a saved
build specification and select Build to build the application.
When you build the application, an executable is created and saved on the hard drive of your development machine
in the local destination directory.
Building an executable from a VI for a Windows CE touch panel
The LabVIEW project provides the ability to build an executable touch panel application from a VI. To build this
application, you create a build specification under the touch panel target in the LabVIEW Project Explorer. By rightclicking on Build Specifications, you can select the option of creating a Touch Panel Application, Source Distribution,
Zip File, and so on.
208
After selecting Touch Panel Application, you see a dialog box with the three main categories that are most commonly
used when building a touch panel application for a Windows CE target: Application Information, Source Files, and
Machine Aliases. The other categories are rarely changed when building Windows CE touch panel applications.
The Application Information category contains the build specification name, executable filename, and destination
directory for both the touch panel target and host PC. You can change the build specification name and local
destination directory to match your nomenclature and file organization. You normally do not need to change the
target filename. The target destination determines if the deployed executable runs in volatile or nonvolatile memory.
On a Windows CE device
\My Documents folder is volatile memory. If you deploy the executable to this memory location, it does not
persist through power cycles.
\HardDisk is nonvolatile memory. If you want your application to remain on the Windows CE device after a
power cycle, you should set your remote path for target application to a directory on the \HardDisk such as
\HardDisk\Documents and Settings.
209
Figure 11.41. The Information Category in the Touch Panel Application Properties
Use the Source Files category to set the startup VI and obtain additional VIs or support files. You need to select the
top-level VI from your Project File. The top-level VI is the startup VI. For Windows CE touch panel applications, you can
select only a single VI to be the top-level VI. You do not need to include lvlib or subVIs as Always Included.
Figure 11.42. Source Files Category in the Touch Panel Application Properties
(In this example, the HMI_SV.vi was selected to be the top-level VI.)
210
The Machine Aliases category is used to deploy an alias file. This is required if you are using network-published
shared variables for communication to any devices. Be sure to check the Deploy alias file checkbox. The alias list
should include your network-published shared variable servers and their IP addresses (normally CompactRIO or
Windows PCs). You can find more information on alias files and application deployment using network-published
shared variables in the section titled Deploying Applications That Use Network-Published Shared Variables.
Figure 11.43. The Machine Aliases Category in the Touch Panel Application Properties
(Be sure to check the deploy aliases file checkbox if you are using network-published shared variables.)
After you have entered all of your information on the required category tabs, you can click OK to save the build
specification or you can directly build the application by clicking the Build button. You can also right-click on a saved
build specification and select Build to build the application.
When you build the application, an executable is created and saved on the hard drive of your development machine
in the local destination directory.
211
Figure 11.44. With LabVIEW, you can use the same architecture for applications ranging from CompactRIO
to high-performance PXI to board-level NISingle-Board RIO.
212
When porting code between CompactRIO targets, all I/O is directly compatible because C Series modules are
supported on all CompactRIO targets. If you need to port an application to NISingle-Board RIO, all C Series modules
are supported, but, depending on your application, you may need to adjust the software I/O interface.
NISingle-Board RIO
NISingle-Board RIO is a board-only version of CompactRIO designed for applications requiring a bare board form
factor. While it is physically a different design, NISingle-Board RIO uses the processor and FPGA, and most models
accept up to three C Series modules. NISingle-Board RIO differs from CompactRIO because it includes I/O built
directly into the board. NIoffers three families of NI-Single-Board RIO products:
Digital I/O With RIO Mezzanine Card Connector
The smallest option for NISingle-Board RIO combines the highest performance real-time processor with a Xilinx
Spartan-6 FPGA and built-in peripherals such as USB, RS232, CAN, and Ethernet. In addition to the peripherals, the
system includes 96 FPGA digital I/O lines that are accessed through the RIO Mezzanine Card (RMC) connector,
which is a high-density, high-bandwidth connector that allows for direct access to the FPGA and processor. With this
type of NISingle-Board RIO, you can create a customized daughtercard designed specifically for your application that
accesses the digital I/O lines and processor I/O including CAN and USB. This NISingle-Board RIO family currently
does not support C Series connectivity.
Digital I/O Only or Digital and Analog I/O With Direct C Series Connectivity
NIalso offers NISingle-Board RIO devices with both built-in digital and analog I/O on a single board. All I/O is
connected directly to the FPGA, providing low-level customization of timing and I/O signal processing. These devices
feature 110 3.3 V bidirectional digital I/O lines and up to 32 analog inputs, 4 analog outputs, and 32 24 V digital input
and output lines, depending on the model used. They can directly connect up to three C Series I/O and
communication modules for further I/O expansion and flexibility.
LabVIEW FPGA programming
Not all NISingle-Board RIO products currently support Scan Mode. Specifically, the NISingle-Board RIO products
with a 1 million gate FPGA (sbRIO-9601, sbRIO-9611, sbRIO-9631, and sbRIO-9641) are not supported, in addition to
the NISingle-Board RIO products with the RMC connector (sbRIO-9605 and sbRIO-9606). Instead of using Scan
Mode to read I/O, you need to write a LabVIEW program to read the I/O from the FPGA and insert it into an I/O
memory table. This section examines an effective FPGA architecture for single-point I/O communication similar to
Scan Mode and shows how to convert an application using Scan Mode.
Built-in I/O and I/O modules
Depending on your application I/O requirements, you may be able to create your entire application to use only the
NISingle-Board RIO onboard I/O, or you may need to add modules. When possible, design your application to use
the I/O modules available onboard NISingle-Board RIO. The I/O available on NISingle-Board RIO with direct C Series
connectivity and the module equivalents are listed below:
110 general purpose, 3.3 V (5 V tolerant, TTL compatible) digital I/O (no module equivalent)
32 single-ended/16 differential channels, 16-bit analog input, 250 kS/s aggregate (NI9205)
213
This NISingle-Board RIO family accepts up to three additional C Series modules. Applications that need more than
three additional I/O modules are not good candidates for NISingle-Board RIO, and you should consider CompactRIO
integrated systems as a deployment target.
FPGA size
The largest FPGA available on NISingle-Board RIO is the Spartan-6 LX45. CompactRIO targets offer versions using
both the Virtex-5 FPGAs and the Spartan-6 FPGAs as large as the LX150. To test if code fits on hardware you do not
own, you can add a target to your LabVIEW project and, as you develop your FPGA application, you can periodically
benchmark the application by compiling the FPGA code for a simulated RIO target. This gives you a good
understanding of how much of your FPGA application will fit on the Spartan-6 LX45.
214
Figure 11.45. The first step in porting an application from CompactRIO to an alternate target
is finding replacement I/O on the future target.
215
Figure 11.46. Develop a simple FPGA application to act as an FPGA scan engine.
After you have implemented a simple scan engine in the FPGA, you need to port the real-time portion of the application
to communicate with the custom FPGA scan engine rather than the scan engine I/O variables. To accomplish this,
you need to first convert all I/O variable aliases to single-process shared variables with the real-time FIFO enabled.
The main difference between the two variables is while I/O variables are automatically updated by a driver to reflect
the state of the input or output channel, single-process shared variables are not updated by a driver. You can change
the type by going to the properties page for each I/O variable alias and changing it to single-process.
Tip: If you have numerous variables to convert, you can easily convert a library of I/O variable aliases to shared
variables by exporting to a text editor and changing the properties. To make sure you get the properties correct, you
should first create one dummy single-process shared variable with the single-element real-time FIFO enabled in
the library and then export the library to a spreadsheet editor. While in the spreadsheet editor, delete the columns
exclusive to I/O variables and copy the data exclusive to the shared variables to the I/O variable rows. Then import
the modified library into your new project. The I/O variable aliases are imported as single-process shared variables.
Because LabVIEW references shared variables and I/O variable aliases by the name of the library and the name of
the variable, all instances of I/O variable aliases in your VI are automatically updated. Finally, delete the dummy
shared variable that you created before the migration process.
216
Figure 11.47. You can easily convert an I/O variable (IOV) Alias Library to shared variables by exporting the
variables to a spreadsheet, modifying the parameters, and importing them into your new target.
The final step for implementing an FPGA scan engine is adding a real-time process to read data from the FPGA and
constantly update the current value table. The FPGA I/O you are adding to the shared variables is deterministic, so
you can use a Timed Loop for implementing this process.
To read data from the FPGA scan engine, create a Timed Loop task set to the desired scan rate in your top-level RT
VI. This Timed Loop is the deterministic I/O loop, so you should set it to the highest priority. To match the control loop
speed of your previous Scan Mode application, set the period of this loop to match the period previously set for Scan
Mode. Any other task loops in your application that were previously synchronized to the Scan Mode also need to
change their timing sources to the 1 kHz clock and set to the same rate as the I/O scan loop.
The I/O scan loop pushes new data to the FPGA and then pulls updated input values. The specific write and read VIs
are also responsible for the scaling and calibration of analog and specialty digital I/O.
217
Figure 11.48. The FPGA I/O scan loop mimics the RIO Scan Interface feature by deterministically
communicating the most recent input and output values to and from the FPGA I/O
and inserting the data into a current value table.
Figure 11.49. The RT Write FPGA Scan IO VI pulls current data using a real-time FIFO single-process shared
variable, scales values with appropriate conversion for the FPGA Scan VI, and pushes values to the FPGA VI.
218
Figure 11.50. The RT Read FPGA Scan IO VI pulls all updates from the FPGA Scan IO VI, performs applicable
conversions and scaling, and publishes data to a current value table using a real-time
FIFO single-process shared variable.
After building the host interface portion of a custom FPGA I/O scan to replace Scan Mode, you are ready to test and
validate your ported application on the new target. Ensure the FPGA VI is compiled and the real-time and FPGA
targets in the project are configured correctly with a valid IP address and RIO resource name. After the FPGA VI is
compiled, connect to the real-time target and run the application.
Because the RIO architecture is common across NISingle-Board RIO, CompactRIO, and R Series FPGA I/O devices,
LabVIEW code written on each of these targets is easily portable to the others. As demonstrated in this section, with
proper planning, you can migrate applications between all targets with no code changes at all. When you use specialized
features of one platform, such as the RIO Scan Interface, the porting process is more involved, but, in that case, only
the I/O portions of the code require change for migration. In both situations, all of the LabVIEW processing and control
algorithms are completely portable and reusable across RIO hardware platforms.
2012 National Instruments. All rights reserved. CompactRIO, CVI, LabVIEW, Measurement Studio, National Instruments, NI, ni.com, the National Instruments corporate logo, and the Eagle logo
are trademarks of National Instruments. For other National Instruments trademarks see ni.com/trademarks. The mark LabWindows is used under a license from Microsoft Corporation. Windows is
a registered trademark of Microsoft Corporation in the United States and other countries. Other product and company names listed are trademarks or trade names of their respective companies.
219