The main software architecture consists of four primary processes as shown in Figure 1.
Figure 1 - Main Software Architecture
These processes perform the following tasks:
The messaging system between the different processes is based on the Asynchronous Message Communication (AMC) reference library.
There are two types of data that are passed between processes: commands and data. All of the commands are sent via AMC. Time domain data is sent over a lossless mechanism (queue) and a lossy mechanism (notifier). The design decision was made to guarantee delivery of data to the logging process while potentially sacrificing delivery to the display modules. If the PC has enough resources, both the queues and notifiers will perform in a lossless way. If the PC cannot handle what is being asked of it, the queue will buffer the data while the notifier will drop data. This data flow is shown below in Figure 2.
If you have another process which requires lossless data transfer, you can use another queue to transfer data to it. This could be for signal processing or a data display for example.
Figure 2 - Data flow between processes
The source code is organized into multiple Project Library (.lvlib) files. The top-level Project Library is named Data Acquisition Reference Design.lvlib (highlighted in yellow in Figure 3). This library contains the main application, system configuration VIs, buttons, and each of the specific modules. Each module is also a Project Library (highlighted in green in Figure 3). The use of the Project Libraries provides a good mechanism for protecting the namespace of the VIs, defining the scope of the VIs (public, private, etc.), and organizing the VIs. For more information on Project Libraries, refer to the Sharing Code With the LabVIEW Project Library guide.
The Project Library also provides a very convenient method for creating a new version of the code to modify by using the “Save As…” feature to the save a copy of the Project Library to a new working directory.
Figure 3 - Project view of Data Acquisition Reference Design
This reference design has four code modules for each of the major functional pieces of the application. These modules are Configuration, Data Acquisition, Logging, and Display.
The Configuration module’s purpose is to provide a way for the user to configure the system interactively. This could be through a front panel, loading saved configurations from file, or a configuration currently in memory. The decision of the specific implementation is up to the user and developer. Configuration is a very important piece of any application since there is typically lots of user interaction and it must strike a fine balance between features and usability.
There can be a wide range of implementations for configuration from very simple to very complex. A good place to start is with the Queued Message Handler Template from AMC.
The Data Acquisition module acquires data from the configured data source. This would typically be a hardware data acquisition device, but could also be data from a file or even simulated data. This module must be able to acquire data in a lossless fashion and send it to other processes for logging to disk, signal processing, or display.
Depending on the application requirements, signal processing can also be added to the Data Acquisition module or could be an entirely new module\process of its own.
The data acquisition process in the main application is a queue driven state machine (see Figure 4). A VI is used to receive messages generated by the user (such as pushing the Start button) and to progress the state machine appropriately. The state machine has four main states: Idle, Start, Acquire, and Stop.
Figure 4 - Data acquisition process in main application
The Data Logging module saves time domain data to disk. The data is received from the data acquisition process via a queue. The queue is a buffered mechanism which guarantees that the data path is lossless, but if the data logging process cannot write data to disk fast enough, the buffer in the queue will continue to grow and use memory. Thought should be given on how to handle this situation such as some combination of limiting the queue size, monitoring the queue backlog, automatically stopping the acquisition and notifying the user.
The data logging process is also a queue driven state machine (see Figure 5). A VI is to receive messages generated by the user and dictate the next state for the state machine. The state machine consists of four states: Idle, Open File, Write to File and Close File.
Figure 5 - Data logging process in main application
The display windows provide a way to get immediate feedback from the data as it is being acquired. The display windows are launched through VI Server in the Main Message Processor as reentrant VIs so that multiple windows of the same type kind can be viewed at the same time. The display VIs must be placed in a specific directory relative to the main application. The directory is <main>\Modules\Display.
The display windows are built from a VI template (see Figure 6). The Display Template.vit is based on the Queued State Machine template in AMC. Every time new data is received from the notifier, the Process Data state is executed. This is where any display code should be place such as channel selection or signal processing (FFT, RMS, etc). If it is important to the display, the data can be checked for continuity so the user is informed if the display is not continuous. This is particularly important to know in cases where signal processing like averaging or filtering is used across multiple data blocks.
Figure 6 - Display window template block diagram
Follow these recommended steps to add a new display window.
Figure 7 - AMC command to launch FFT Display.vi
Creating an application which is functionally powerful and intuitive at the same time can be very challenging. A lot of this challenge is in the design and implementation of the user interface (UI). Below is a list of different techniques for implementing the user interface in LabVIEW used in this application.
Figure 8 - Toolbar of the main application
Figure 9 - Splitter bar for front panel resizing
Figure 10 - Hidden tabs
Figure 11 - Channel Monitor XControl
For more examples of UI techniques in LabVIEW, join the UI Interest Group on NI.com’s Community area.
For a more advanced architecture for running multiple sections of code running in parallel and sending data between them, please review this guide on Using a Queued Message Handler in LabVIEW.