Viewpoint Systems, Inc.
800 West Metro Park
Rochester, NY 14623
Phone: 585.475.9555
Fax: 585.475.9645
Viewpoint Data Management, LLC.
800 West Metro Park
Rochester, NY 14623
Phone: 585.475.9555
Fax: 585.475.9645
Viewpoint News, Winter 2008
LabVIEW is delivered with several pre-built programming constructs called Framework Templates. These templates are wonderful starting points for many standard applications. Using these frameworks saves time for expert users and assists novices by introducing new programming techniques and styles. This article shows how to access these templates and demonstrates with some actual examples.
The LabVIEW templates range from the simple, such as a VI template with error handling, to the complex, such as Producer/Consumer loops.
Note: In this article, I am using LabVIEW version 8.5, so the screen captures in the images below might show slightly different screens and images if you are using a different version.
Accessing the Frameworks
To access the templates, use the ‘File>>New…’ menu item. The image below is cropped from the LV splash screen:

This menu item goes to a screen as shown below.

This screen shot shows the selection of the ‘SubVI with Error Handling’ framework. Note the miniature image of the block diagram on the right side giving a graphic hint at the selection. After pressing the OK button, a VI appears ready to complete.
Framework Examples
The front panel of the ‘SubVI with Error Handling’ contains the input and output Error clusters and the case structure on the diagram, ready to be populated with your code. Like most VIs produced in the Framework, this VI arrives with a connector pane is a typical 12 element standard, as shown below.
![]()
As another example, the ‘Dialog Using Events’ framework presents a pre-built VI for a dialog box complete with ‘OK’, ‘Cancel’, and ‘Close Panel’ events. The front panel is:

The block diagram is:

A typical use of this template is to create a configuration dialog box. For example, a “save data” configuration setup might be created by adding controls for a file path, some text inputs for header information, and a numeric to specify the time in seconds between saves. The values in these controls are passed out of the VI to the application caller.
A portion of the Framework templates consist of Design Patterns. These are more complex templates than just discussed. The Design Pattern templates are a basis for application development. Templates are offered for State Machines and messaging paradigms, such as the Producer/Consumer model.
State Machines
Overview
A State Machine is a framework that executes code for each state of an application. Before the execution in a state is complete, the current state executes code to determine the next state, and the State Machine causes the application to transition to that state. Thus, a State Machine manages the application by moving between a set of predefined states. The sequence of these states is not fixed at development time. Instead, the states are determined at runtime by the transition code in the application.
The feature that distinguishes one State Machine implementation from another is the method used to handle state transitions. The LabVIEW frameworks offer two methods. The first handles only one transition state at a time within a state. The second queues multiple transition states, allowing one state to specify several follow-on states to reach.
Method 1 is called ‘Standard State Machine’ in the framework selection and uses an enum as an indication of state. Method 2 is called ‘Queued Message Handler’ in the framework and uses a string array as an indication of state.
The ‘Queued Message Handler’ block diagram is shown below.

As created by the Framework, this VI drops into the Default ‘No Event’ case initially, pushes the ‘Exit’ case into the array of states, and subsequently runs the ‘Exit’ state on the next iteration, causing the VI to stop iterating.
Rules for State SequencingI think this sequencing is backwards, since states pushed first should execute first (FIFO). So, I’d rather rewrite this code to extract element 0 from the start of the array while pushing new elements onto the end. However, you could also keep the code as is and push on the top in reverse order (if you want state A to run before B, our make element 0 = B and element 1 = A).
Execution Sequencing Preemption
Either way, a nice feature of using an array like this is that you can preempt state execution by pushing critical states into the array so that they are removed prior to states that have pushed earlier. This preemption is a cool feature, and a nice way to handle errors instantly, rather than waiting to complete any states already in the queue.
No Event as Default
Be careful of one other thing about this method: rely on the ‘No Event’ case also being the default so that you don’t push ‘No Event’ too frequently, possibly leaving extra ‘No Event’ states in the array that are never consumed.
Producer/Consumer Design
Have you ever tried to write an application that does something continuously (such as collecting data) but also needs to respond to events (such as a user pressing a button) that take a long time to complete? It can be frustrating to support these requirements within a single loop structure because the application has to service two competing streams (data and or events), one of which takes so long to complete that it stalls the faster stream.
Here’s more explicit example taken from a recent conversation with a new LV programmer at an NI Hands-on event. The application needed to acquire and data log data at a fairly slow rate, slow enough to allow the use to see events happen on a strip chart. While this data logging was happening, the user wanted to press a button to capture the current content of the strip chart and freeze the display to allow some analysis to occur. And, the data logging needed to continue uninterrupted.
This application is typical when multiple events need to be serviced and no events can be held off for too long. The Producer/Consumer framework handles these requirements.
The idea behind the Producer/Consumer framework is to have the producer loop push events (and associated data) into a queue for processing by the consumer loop. The queue allows consumer to take time to process the data: any additional items pushed onto the queue while processing will be available at the consumer loop next time around. See the block diagram below.

The queue created at the left side can be defined to take a string, an array, a cluster, or any other type of LV data. This data type is what you will push into the consumer loop. The ‘Queue Event’ event shows pushing the string ‘element’ which will be consumed in the Consumer loop at the bottom. Note that the ‘Dequeue element’ VI in this Consumer loop has no timeout wired and this default means the ‘Dequeue element’ will sleep until an element appears in the queue.
On average, the duration between events at the producer can be no longer than the time for the consumer to finish its task. The consumer can take longer on occasion, and the queue will start to fill up, but the consumer will then need to catch up, or the queue will overflow. Overflow can be prevented by allowing the queue to grow in size, but this can lead to sluggishness in the application as ever increasing amounts of memory are consumed by the queue. The queue created in the Producer/Consumer framework is allowed to grow without limit, so beware.
I’ve placed a strip chart on the left side of the panel and a graph on the right. As events appear in the strip chart, the user can press the grab data button which copies the strip chart history into the graph. The display on the right shows the event zoomed in a bit after using the graph palette tools.
If this grabbed data is interesting, the user can press the Save Data button and write the data to a file. Meanwhile, the data collection continues unabated.

Once the cluster is in the queue, the Consumer loop, which has been patiently awaiting an element in the queue, removes the element, and, based on the contents of the ‘Name’ string in the cluster, runs the ‘Grab’ case, which sends the data into the graph. The user now sees the data in the Graph palette and can analyze the data visually.
A similar sequence of steps applies when the user presses the ‘Save Data’ button: the source of the queue data (e.g. “Save”) is placed in the ‘Name’ element of the cluster and the consumer loop extracts this queue element, calls the ‘Save’ case to save the data into a file.
The Continuous Data Collection
Beware that the execution time of any event in the Producer consumes less time than the data acquisition buffers take to fill. If you stall the acquisition for too long, a buffer overflow occurs, and data is lost. In the VI diagram above, I’ve used 100 ms in the timeout event to service the data buffer (which I’ve assumed is often enough for this demo). Thus, if any other events complete within this duration, everything will be fine. If, for some reason, the events in the Producer loop take too long (even the timeout event), move the acquisition into a loop separate from the Producer loop. Separating these two loops give more flexibility in servicing the acquisition in a timely fashion.
Summary
The frameworks supplied with LabVIEW offer classic and powerful VI templates and software design patterns. These frameworks can save you implementation time and effort, as well as teaching about new programming models. The State Machine and Producer/Consumer models shown above have several variations not covered in this article. I encourage you to explore them at your leisure.
Download the demo VIs from this article.