Viewpoint News, November 2011
Part
2: Architecture Design for the LabVIEW CLD and Other Apps
Last month’s issue of this newsletter
reviewed some tips for improving your outcome on the CLD. Since most
of those tips were useful for many LabVIEW applications, the next few
issues of this newsletter will cover the development of a basic “CLD-style”
application, the architecture of which can be used for many types of
applications.
This month’s issue will outline the
goals of this basic app and continue to include some source code snippets
for your own use.The goal is to improve LabVIEW coding methods for the
CLD and your own applications. Want to improve your LabVIEW skills,
then read on.
Application Requirements
The application to be developed has
some fairly straightforward requirements. These requirements are generic
enough that the application applies to many situations. In fact, these
requirements are a sanitized version of an actual application we developed
for one of our biggest clients.
Here are the requirements, in no particular
order:
- Acquire data from a couple
devices (plug-in card, serial, whatever). For this application, assume
two devices, one that has a maximum sample rate of 100 samples per second
per channel and another that acquires at most 10 samples per second
per channel. Each device can acquire multiple channels.
- The data streams from the
multiple devices are combined such that,at each overall system time
increment (called a “heartbeat” and defined below), a collection
of numbers is logged to a data file along with a time and date stamp.
Specifically, at each “heartbeat”, the data file is appended by
the set of values (a vector) listed as [date, time, x0, x1, …,xN],
where, for example, xN is the Nth data value.
- Include the following information
on a configuration tab:
- Filename for the datalogging
file.
- The “heartbeat” time
increment (in seconds) at which to retrieve and log data.
- File for calibrating channels
specified by name.
- A ‘Start’ and a ‘Stop’
button for starting the application. Gray out the buttons when appropriate:
‘Stop’ is gray until ‘Start’ is pressed which then grays ‘Start’
until ‘Stop’ is pressed.
- Status information about
the data acquisition progress.
- Maintain a configuration
file with the information selectable on the application configuration
tab and the following items as well:
- A list of data value names
and associated indices in the data vector [x0, …,xN].
- Configuration information
for each device from which data is acquired. Include the channel configurations
and associate each channel with one of the data value indices in the
data vector.
- The application reads the
most recent configuration file upon start-up.
- The application writes updated
configuration info into the configuration file if any value changes
on the UI.
- Include a tab with 4 strip
charts with the name of the channel to be displayed next to each strip
chart. The channel can be changed on the UI.
- When the name is changed,
the new values are pushed to the display without clearing the graph
history.
- The tab includes a ‘Clear’
button that resets the history of all the strip charts.
- This tab is greyed out until
the Start button is pressed and the application is successfully started
(i.e. , no errors on acquisition or initial other start up actions).
- The system heartbeat is
managed by software timing but this heartbeat interval should not restrict
any data collection process to perform at this interval. For example,
some devices may produce data at higher rates (such as a DAQ device)
for use in data processing (FFT, noise reduction by averaging, and so
on). Or, some devices may be slower than the heartbeat interval (such
as a slow serial device). Or, some devices may produce data at the heartbeat
interval (such as a DMM that produces a single reading fast enough to
keep up with the heartbeat). In all these cases, the data streams need
to have the most recently available data value ready to be displayed
in the chart and logged to the file at the rate of the heartbeat.
Basic App Architecture
Design
If this were the CLD, you would now
stop and cogitate on these requirements for the period of time you decided
(prior to starting the exam!) to apply to design efforts. For any other
non-CLD application, you need to do the same, without the time constraint.
Design
Outline
This application has a couple features.
Here are the highlights with design suggestions:
- The heartbeat interval cannot
be stalled (i.e., blocked) so the system must be responsive to user
interactions without causing the data acquisition or file logging to
be halted.
- A producer/consumer loop
with an event structure can listen to user input while “sleeping”
when not needed.
- Data can be acquired from
several devices at disparate rates and must be merged into a single
vector for output to the file.
- Each device has its own
acquisition loop.
- Each device pushes data
into a data manager which holds the last value from each channel
- A data manager can access
(write and read) a data value by name.
- The names and their associated
indices into the data vector are managed in a configuration file, so
this manager needs to be initialized with those names and associated
indices.
- A configuration manager
to access (write and read) information from a configuration file.
- A logged-data file manager
to create and write information to the data log file.
Developing this application will need
the following tools:
- A few timer managers (such
as the one whose code was presented in the previous newsletter).
- Some file access managers.
- Some device acquisition
managers.
- Some state machines to coordinate
the device actions.
- A producer/consumer loop
to handle the UI and other events, such as might be spawned at the heartbeat
interval.
Action Engines
(a.k.a. Functional Globals)
Many of the design elements are managers
of some sort of data. The best method to develop these managers is to
use Object Oriented (OO) techniques.
Many LabVIEW programmers don’t yet
know how to use the indigenous LabVIEW objects. Yet, OO principles have
been applied within LabVIEW for years before LVOOP appeared. The Action
Engine (AE) design pattern uses such OO goals. Many call the AE pattern
by the name Functional Global (FG) since it grew out of the original
way to create globals in LabVIEW.
The idea of an AE (i.e., FG)
is that the object’s data is held in while-loop shift registers and
the object’s methods are handled via a case statement inside the while
loop. Here’s an entry on NI’s web site about Functional Globals: https://decibel.ni.com/content/docs/DOC-2143. The only major differences between anAEs
and an object in a true OO language are 1) inheritance and 2) automated
create and destroy capabilities. In the latter, you can’t automatically
create a new object of some class by laying down the AE onto a block
diagram. Instead, you need to copy the VI and then call this a new instance.
Or you need to create your AE to take an index which allows multiple
instances to be handled in the same VI as referenced by the value of
the index.
Embrace AEs. They will save you development
headaches and debug time since all associated functions and data are
in one place.
Source code for
example AEs
The Timer VI given out last month (found
in the October Newsletter).
Here’s another example that will
be useful for the application we are developing. This one will manage
the data vector. Click here for an Action Engine timer and test case VI example.
Summary
The requirements for the “CLD”
application cover a wide range of typical applications, including some
applications presented in past CLD exams. Next month,
the app development will continue with more development of the Action
Engines.