09-17-2016 04:28 PM
I'm certain there exists a simple way to do this, but so far, I haven't been able to find it. I wish to create a state machine, where I am not certain if I will need further states down the line, and have had the issue of having to modify selectors and the such, to match new states. I have been thinking about an idea I read somewhere about storing the constant in a SubVI so it auto-upgrades in all instances, but can't seem to wrap my head around it. Concretely what I would like is:
-Creating a state machine with the n states I am certain I need right now (case architecture)
-Storing said states for the selector somewhere I can update only once, and see that reflected in the totality of the VI
-In the future, if I want to add more states, add to the "master database" just once, and not have to update old selectors
Any whitepapers or threads I may have missed guys?
Solved! Go to Solution.
09-17-2016 04:46 PM
States are usually defined by an Enum.
Just "Type Define" the Enum. As values are added, all instances will update.
(Right-Click -> Make Type Def. in later versions of LabVIEW.
Just be sure to save the new Type def.)
steve
09-17-2016 07:52 PM
The big advantage to using Enums (defined in a TypeDef) for your State is that when you change the TypeDef, it changes all the Enums. If you add a State, all of your Case structures will break as there won't be a Case for the new State (do not use a Default case). Best of all, if you open the TypeDef, you can do a "Find All Instances" of the TypeDef and find all the places the State has been used (to make sure the existing Cases and uses are still correct).
When you remove a State from the Enum, especially one in the middle of the TypeDef, you'll find "mis-assigned" Types, but the "Find All Instances" trick will help you find them.
The other way to do States is to use Strings, which (in some ways) makes adding and removing States also easy, and the order of the States doesn't matter. Finding the States is a little harder, unless you define the State String as a TypeDef (to use the "Find" trick). You also need to add a Default case, and should wire it to raise an Error or Message that it's seeing a State that doesn't (yet) have a Case.
There are arguments for both schemes (the JKI State Machine uses Strings, many LabVIEW Gurus prefer Enums ...). I've used both (tend towards Enums ...).
Bob Schor
09-18-2016 01:33 AM
Allright, that did the trick, I wasn't certain a constant enum could be defined as a typedef, but happily it is. I had built a couple state machines where I required to keep updating certain instances manually, so I decided to start with the right foot for once, instead of finishing fast, only to take way more when updating.
09-18-2016 01:55 AM
Adding on to this, you should do this even when you're not concerned with future proofing. You'll often change your mind about states if you find something that works a bit better to handle things while you're programming. Just general development is enhanced by using the typedef to avoid that problem.
Typically, I build my state machines up. I go into the application with a design in mind. I create the init and shutdown states. I add the next states in one at a time. It helps me avoid running into problem wiht debugging. Each time I add a state, I know my application was working prior. It makes it easy to know where to look when trying to find out where I introduced a bug.
09-18-2016 06:57 PM
General rule of thumb: ALL enums and clusters should be defined as type defs precisely for things like this.
Very early in my LabVIEW career, I inherited a decently sized code base with clusters everywhere. We had to add items to that cluster. I had to go through and update every single cluster control, indicator, and constant. It probably took me a full day just to add those elements to all of the clusters. Then I had to add the code to use it. Next time my NI rep came to visit, I stated my frustration and he simply said, "Why didn't you use a type def?" So right there, a type def would have saved me a full day.