Wednesday, March 25, 2009

There Are No Strict Type Definition Constants

Type definitions (aka typedefs) are very useful. However, they also have some unexpected behaviors that can cause you a lot of trouble.

As a usability advocate, it pains me every time I have to explain this one, but here it is: There are no strict typedef constants in LabVIEW.

I am not going to try to defend this as "good" behavior. But it's not a bug when constants linked to strict typedef files only update on type changes.

Basics of Custom Controls

LabVIEW has three kinds of custom controls (.ctl files).
  1. Unlinked custom control. A "regular" custom control uses a definition (.ctl) file but the instances are not linked to the definition file. Thus, when you edit the .ctl file, instances that were created from it in the past do not update.
  2. Linked by type (aka typedef or type definition). Whenever the definition (.ctl file) changes type, all instances need to update. If the instance is set to auto-updating, it will update itself on load. [Note, however, that it will not auto-update while the definition file is open in the control editor.] If not set to auto-updating, you must right click on each instance to update it.
  3. Linked by all attributes (aka strict typedef). Similar to a typedef, except that any time the definition changes, all instances must update. This is achieved by time stamp comparison between the definition and instances. The intent is to have all instances cosmetically identical to the definition. Since most cosmetic attributes are invalid on the block diagram, there is no such thing as a strict typedef constant. Constants linked to strict typedef definitions act like typedef constants.

Confusion Over When Typedefs Update

If you have a ring, its type is its numeric representation, e.g. unsigned word.

If you have an enum (which can look identical on the front panel), its type contains its item names.

Thus, when you add items to a typedef ring definition file, the instances don't update (because the type didn't change). When you add items to a typedef enum definition file, the instances do update. However, if you make a strict typedef ring, then control instances will update when you add items. But since there's no strict typedefs on the diagram, constants that are linked to a strict typedef ring will not update when you add items. This behavior is confusing, but it is working as designed.

Forcing Updates

Even though typedefs only update when types change, instances get cosmetic changes from the definition whenever they update. So one trick to "push" changes to typedef instances is to change the data type, apply changes, and then change the data type back. [edit, March 26 - Note that the typedef instances need to be in memory when you use this trick].

Unreliability of Data

Another potential problem with typedefs is that you shouldn't rely on them keeping their data values when they update. LabVIEW will attempt to preserve data. For example, if you have a typedef numeric constant and change its representation, LabVIEW will convert the value. However, there are many cases where LabVIEW will not preserve the values correctly, especially with clusters, so it's a good policy not to rely on the values being preserved. (Or to visit all the typedef instances when you make changes, in order to verify their values).

Why Use Typedefs?

I would be remiss if I didn't make a case for using typedefs despite the potential problems that I've covered here. Typedefs let you change the type of all the instances with a single edit. This is very useful, for example, when you have a set of VIs operating on a cluster and you later realize you need to add or remove items to it. Without using a typedef, you have a lot of broken wires until you visit every VI that passes the cluster in or out of its connector pane. And strict typedefs are extremely valuable for maintaining consistent user interfaces - you can make controls on any number of VIs have the same appearance.

One final note - if you're using LabVIEW 8.2 or later, and you want to use a typedef so that you can encapsulate data for passing between VIs, then you should consider using a LVClass instead. You may still choose to use a typedef, but it's good to evaluate, because LVClasses serve the role well and give you a lot of other benefits as well.

[Please ignore this edit. I'm trying to see if updating an older post makes it show up on my blog mirror on NI Communities, without causing ill effects.]

Tuesday, March 03, 2009

VI Makeover Edition - Part 1

For a long time, I've been meaning to do a series of posts I call the "VI Makeover Edition" where we take a VI front panel from "drab" to "fab!" :-)

I helped "spiffy up" a VI for an NI Week keynote demo last year. It is a graphic equalizer powered by LabVIEW MathScript. You can watch the demo video on

The goal was simply to make the VI look better on the big screen, and make it easier to see the operation of the controls from the back of the room.

The original VI looked something like this:

And the final VI looked something like this:

Some of the tips and tricks I plan to cover include:
  • VI panel wallpaper
  • Background images and locking
  • Customizing the parts of a slider control
  • Adding decorations to controls
  • Using transparent color
  • Gradients and graphics
  • Grouping and alignment
If you want me to cover these in a particular order or have questions in advance that I should cover, please let me know!