Changing the Face of Design Patterns with LabVIEW 7 Express Event Structure
Overview
Guest columnist Michael Aivaliotis of mmWave Integrated Solutions Inc. investigates new ways of using the LabVIEW 7 Express event structure and several design patterns that have evolved and emerged since the introduction of events in LabVIEW.
Table of Contents
Introduction to Event Structure
Since the introduction of the event structure in LabVIEW 6.1, programmers have enjoyed a cleaner and more efficient way of handling user interface design and development. It now is so commonplace that it is usually the first structure put on the diagram when they need to program a user interface. It is sometimes hard to imagine life without event structure. Now, with the recent release of LabVIEW 7 Express, National Instruments has augmented the event structure by adding dynamic events. This article investigates new ways of using the event structure and several design patterns that have evolved and emerged since the introduction of events in LabVIEW.
An event structure is a structure located on the structures palette in LabVIEW placed on the diagram just like any other function. It is similar to a case structure because it contains multiple subdiagrams. Unlike a case structure, which relies on a conditional terminal, an event structure executes a specific sub diagram based on the events registered for it. When LabVIEW executes the event structure, it puts the VI, which stores the event structure, to sleep until one of the registered events happens, or fires. The event structure automatically wakes up and executes the appropriate subdiagram to handle that event. When that subdiagram completes, the event structure completes. The event structure does not automatically loop. You must place it inside a while-loop, so it can respond to the next event.
Figure 1. Event Structure Components
Event Structure Design Patterns
There are several ways to use the event structure within your application. You can determine where and how to use the event structure based on your specific application.
Usage of Basic Event Structure
The most common usage of event structures is to handle user interface events for dialog boxes and simple configuration screens. This requires the placement of an event structure within a while loop. The development of this design requires static event registration. Static registration relates to events that occur only on the front panel of the VI that contains the event structure. You configure these events at design time and cannot change the events during the execution, or runtime, of your program. You must use the edit events dialog box to configure an event structure to handle a statically registered event. Here, you can select from a list of available user interface event sources and the specific event of interest, such as Value Change or Panel Close.
You can only detect events that you statically registered when you reserved the VI that contains the event structure for execution. This happens when the VI is running or when another running VI calls the VI as a sub VI. Events that are fired prior to this state are ignored. This structure ignores events that you fire prior to this state. If the VI is not running or called by another VI then it is in the idle state. LabVIEW then unregisters all events with the event structure and events are not handled.
Some limitations of this design pattern:
1. Blocking of the front panel while an event is handled
2. Cannot share code between event cases
3. Cannot accept events from other loops or VIs
To make the user interface more responsive, you can disable front panel locking for each event case. You cannot, however, process other events while in a specific event case. Though you can generate events by unlocking the front panel, they are not handled immediately. This still makes the user interface nonresponsive. Therefore, you should use this design pattern when the event handling case needs to execute quickly, under 200 ms. Anything slower will make the screen feel as if it has locked up.
Code reuse is more difficult in this configuration because you cannot share event cases. Putting the work performed in a sub VI and reusing the sub VI in other cases can achieve some level of code sharing.
To enhance the basic event structure usage and facilitate code reuse, you can embed the event structure in a state machine. This means all work executes in another frame of the state machine. The event-handler case passes the name of the state machine frame or sequence of frames to execute. This design facilitates significant code reuse and the creation of common-state cases that you can share between events. You can use this state machine enhancement with any of the other design patterns described below. To transition between states in the state machine, you can use a multiline string. You can decode each state by extracting each line in the string. Other methods for state transitions can be an array of strings or an enumerated.
If you are building a VI that must handle user interface events and must accept events from several other locations, such as Dynamic VIs that execute in parallel, then you can use the following design pattern to accomplish this. By using only one event structure, you can combine static and dynamic events. To use dynamic events in an event structure you must right click on the frame of the event structure and select "show dynamic event terminals." In this way, you can register custom dynamic and user events with the specific event structure. Dynamic event registration is the process of registering events with the event structure during run time. LabVIEW has several functions available that you must use when doing dynamic event registration. The registration process involves:
1. Getting a reference to the object for which you want to handle events
2. Registering for events on the object by wiring the reference to the Register for Events node
3. Selecting the event type
4. Wiring the Event Registration Refnum out of the Register for Events node to the Dynamic Event Terminal of the event structure
5. Adding a case in the event structure to handle the dynamic event
6. Using the Unregister for Events function to stop handling events on the object
If you define your data type for the user event, then you will have the data for that event available to you from the event data node. Consistent with previous designs, any event handler case that is executing will block other events from being serviced. All events will eventually be serviced and none will be lost, however this means if a User Event handler case is taking too long then any user interface events will not be processed thus making the screen feel unresponsive. The event structure eventually will service all events and none will be lost. However, this means if a user event handler case is taking too long, then the event structure will not process any user interface events, making the screen feel unresponsive.
Figure 4. Handling Dynamic and Static Events with One Event Structure
Producer Consumer with Event Structure and Queues
Using two loops, an event structure, and queues, you can create a VI that is well suited for large-scale application development. This design pattern is flexible and powerful. The top loop contains the event structure in its basic form inside a for-loop. Each event handler case generates a specific message passes through a queue to the second loop. The second loop decodes the message and performs the task.
You do not need to limit the messages from the top event loop to the bottom loop. You can configure multiple queues and pass event messages to other VIs or loops. In this way, you can isolate slow tasks into separate loops of VIs, making the front panel interface very responsive. In addition, for more flexibility and to facilitate code reuse, the bottom loop also can accept queue messages from many other VIs.
Figure 5. Producer - Consumer with Event Structure and Queues
You can implement an alternative approach to the producer consumer design pattern using two loops with event structures. Using an embedded state machine inside an event structure, you can implement the bottom loop. You can register more user events with the bottom event structure by creating more user events and wiring them to the register for events node.
With dynamic event registration, an event structure can handle events for any VI in memory. Dynamic event registration gives you complete control over which events you want to generate and track. Since the process of event registration requires a reference to an object, it is not limited to user interface events of the VI that contains the event structure. Using VI server, you can open references to objects on other VIs. Using dynamic registration, you can redefine the registration of objects, including VIs or controls, while your application is running.
Dynamic event registration opens the door for a new design pattern that has a single event-structure handling and an assortment of events for many VIs and user-defined events. One major benefits of this approach is the reuse of code between VIs. Event structures within individual VIs and common events can handle unique events, and you can pass common events to a common event handler to centralize development.
The attached example shows how one common event handler processes events from several VIs. Each VI has a different set of front panel controls with a unique look and feel, or "skin." All of the VIs manipulate and receive data from the same location, making the use of a common event handler the best choice in this situation.
Figure 7. Skinner VI Example with Common Event Handler
Reader Comments | Submit a comment »
I think: Method explained in Fig. 6 can
not be alternative to method explained in
fig.5
Reason: Fig 6 doesn't explain the way to
handel events (in bottom loop) occuring
at multiple vis/ locations.
is there any way to modify fig. 6 so that it
will handel events from multiple
locations/ vis?
- vikas.kumthekar@gmail.com - Mar 24, 2009
skinner.vi
Good Document, but really really wish
skinner.vi was included as I think this is
the design pattern to go!
- Clifton, KLA-Tencor Corporation. - Apr 6, 2007
As other readers I was looking for the
skinner.vi example. Can you please
supply a link to it? Thank izhak
- izhak malkin, rafael. malkini@rafael.co.il - Jan 2, 2007
download of VI
where is skinner.vi I think it would be
really usefull.
Apart from that it's a really usefull
document
- Tom Massey, 16 and 17 Compass Point. tom.massey@esldefence.co.uk - May 23, 2006
Great, but LView queues are slow
Standard labview queues are very slow for
some reason. I had to use my own C++ (via
CIN) implementation when I need to produce/
consume more then 10000 elements per second.
- Mikhail Zakharov, Drexel University. mzu@drexel.edu - Feb 27, 2006
Where is "skinner" example?
Hi, I am trying to create a system like this
and have been looking for ideas just like
the "skinner" example at the end. Can you
please e-mail me the example file or fix the
document or add a link? Anything. Help,
I'm desperate!!!!
- Edward Balchick, Bechtel Bettis, Inc.. balchick@bettis.gov - Dec 30, 2005
Some typos I found in this article
"You can only detect events that you
statistically registered" should read "You
can only detect events that you statically
registered"
"The top loop contains the event structure
in its basic form inside a for-loop" should
read "The top loop contains the event
structure in its basic form inside a while-
loop"
- Peter Badcock, ResMed Ltd. peterba@resmed.com.au - Dec 19, 2005
it will be still better to give a nice
example to illustrate this even driven
programming...
- kallu chaitanya, BIT. kalluchaitanya@yahoo.com - Dec 8, 2005
where is the link for download the Skinner vi?
- Nov 22, 2005
consumer stops after producer stops
I strongly encourage the author to discuss
how, when using queues to pass event info
from one loop to another, it is not only
the producer loop that stops after
processing the event but also the consumer
loop will stop after it finishes responding
to the queued info -- it is waiting for
more info. Queues do not seem suitable
when it is necessary for the consumer loop
to run continuously e.g., for periodic data
logging and/or controlling a process. To
run the consumer loop continuously, either
use (1) the value property of the property
node to pass the data from producer to
consumer or use (2) a local variable to
pass the data.
- Perry Skeath, Naval Research Lab. - Feb 14, 2005
event design class
wish there was an online course on using events
in more advanced code. This would help me
understand how events really work exspecially
if some of the code includes problems
- Jan 11, 2005
This is great, though...
This is great, though I think tutorials
should not, for example, call while-loops
for-loops or say "Using an embedded event
structure inside a state machine" when they
mean "Using an embedded state machine
inside an event structure". A downloadable
VI would be cool!
- Paul Mason, Graduate student - Tufts University. paul.mason@tufts.edu - Jun 19, 2004
Excellent description
The producer consumer loop using queues was
jsut what I was looking for. Thanks1
- Frank Speers, Action Systems. franks@tfb.com - Feb 13, 2004
I could not read the text in the block
diagrams. The explanations are rather
cursory. A down load of the VI's would
greatly improve the usefulness of this doc.
- adam whiteson, bn. adam@whiteson.org - Oct 15, 2003
Downloadable example much needed
The text is really good - In general more
tutorials / examples about using the new
event structure would be good.
- Daniel Gjøde, DELTA. dg@delta.dk - Sep 29, 2003
Legal
This tutorial (this "tutorial") was developed by National Instruments ("NI"). Although technical support of this tutorial may be made available by National Instruments, the content in this tutorial may not be completely tested and verified, and NI does not guarantee its quality in any way or that NI will continue to support this content with each new revision of related products and drivers. THIS TUTORIAL IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND AND SUBJECT TO CERTAIN RESTRICTIONS AS MORE SPECIFICALLY SET FORTH IN NI.COM'S TERMS OF USE (http://ni.com/legal/termsofuse/unitedstates/us/).
