LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Dialogue box critique

Hi all,

 

I've been trying (in vain) to create a good dialogue box that does some bounds checking on user inputs before allowing them to be sent to the main application. Ideally, when an input is out of range, it'll blink until it gets put into range. Generally this means that bounds can only be positive (nonzero, nonnegative numbers) and that VISA resources cannot be left blank. Additionally, the difference between two of them must be bigger than or equal to 40(Range Max - Range Min >= 40). Normally, my code is pretty modular, but I think this being my first real foray into UI design has left me struggling to make things look and work nicely. I've posted the VIs thus far for critique.

 

I've described how it should work. As to how it's actually working, I've noticed that whenever I have two things that are out of range, and I fix one, the OK button is no longer blocked. I think this may have to do with how my events are set up, but can't be sure. What do you think? How can I make this better? Am I missing something fundamental in my design layout?

 

thanks,

 

ijustlovemath

Download All
0 Kudos
Message 1 of 8
(3,950 Views)

It looks very nice and tidy.

 

But like you said, it has some logic flaws.

 

I would create a VI that does all the comparisons whenever any of the controls change.  (Since it sounds like the controls are inter-related, having condition A be good, but then changing something on B may not make condition A bad.)  Have a series of comparisons you could do in a For Loop.  Output an boolean True if it passes.  At the autoindexing boundary of the For Loop, only enable the OK button if AND ARRAY Elements are all True.  Only exit the while loop if AND ARRAY Elements is true AND you've hit OK.

0 Kudos
Message 2 of 8
(3,944 Views)

So would I pass an autoindexed array of references to the For loop? I think I'd still need to create a testing VI for each condition, right? Then somehow pass an array of those in? How would I do that?

0 Kudos
Message 3 of 8
(3,938 Views)

Here are some suggestions:

  • Help the User to not enter an Out-of-Range value.  One way to do this is to set the Control Properties to coerce values between Min and Max.  A "visual" way to do this is to use a Slide control with Min and Max at the ends.  Now all of your controls are "forced" to be In Range.
  • Depending on circumstances, you might want to "force" the user to enter every value (even if it is already, by accident, correct).  That's easy -- start all of the control blinking and let any Value Change unblink them.  You can also have a boolean, initially False for each control, turn True when this happens, and enable the OK button when they are all True.
  • For more "visualization", don't Enable/Disable OK, make it Visible/Not Visible.
  • Do not use Abort VI!  I noticed that the Cancel control stayed True (because the Abort prevented it from being reset).  If you use the Error Line (which you should!), you could return Error 5001 (a User-Defined Error) on Cancel (the Cancel Event would merely set the While Stop Indicator to True, with Cancel being indicated by the Error.
  • Thanks for teaching me something -- I didn't know you could address the properties of a Cluster!
  • Avoid Local Variables!  You can reset the Control you (mis-)name Constants to its default by invoking its "Reinit to Default" Method (Methods come from Invoke Nodes, similar to Property Nodes).
  • Think about using Shift Registers that run through the While/Event loop.  You can use Bundle-by-Name to set, say, the Weight component, thereby avoiding the need for Property Value nodes.

Bob Schor

0 Kudos
Message 4 of 8
(3,927 Views)

Range Min and Range Max need to be set exactly by the user, so while I do like the idea behind the slider, I think it would just end up cluttering the dialogue while not adding much. Could you explain the "Abort VI" suggestion a little more? Also, what do you mean by using shift registers? Would that be used for just reading new values, or what?

0 Kudos
Message 5 of 8
(3,912 Views)

@ijustlovemath wrote:

Range Min and Range Max need to be set exactly by the user, so while I do like the idea behind the slider, I think it would just end up cluttering the dialogue while not adding much. Could you explain the "Abort VI" suggestion a little more? Also, what do you mean by using shift registers? Would that be used for just reading new values, or what?


So you make them "Coerced" as well, force them to be done first (by making only Min visible, using Min's value to set the Min for Max, making Max visible, then using Max and Min's value to set the other Range Control and make it Visible).  Once you have the range set, make Min and Max invisible.  By doing this, you gently lead the user by the nose through the correct steps.

 

Here is a Snippet of (some of) the rest of your question.  This picture can be "dragged" onto a blank Block Diagram and it will magically become LabVIEW code.

Simplified User Input.png

Here are points to note:

  • Following Standard NI Practice, Error In and Error Out are present.
  • The Invoke node to reset Constants to its default value comes next.
  • The (now default) Constant is brought into the While/Event loop on a shift register.
  • In a frame that you don't see, the Weight-changed Event is used in a Bundle-by-Name to change the Weight on the wire in the Shift Register, thereby storing the new value.
  • This shows what happens when Cancel is pushed.  First, we generate Error 5001, with the Error Message "User Cancelled!".  Then we exit the While loop by setting the Stop Indicator to True.  It is the User's responsibility to check if there is an Error present on the Error Line (wire the Error line to a Case Statement selector) and take appropriate action (but, please, not Abort VI).
  • The OK case is identical to this except there is no Error Cluster.

Bob Schor

0 Kudos
Message 6 of 8
(3,895 Views)

@ijustlovemath wrote:

So would I pass an autoindexed array of references to the For loop? I think I'd still need to create a testing VI for each condition, right? Then somehow pass an array of those in? How would I do that?


No.  An auto-indexed array of booleans.  A For Loop that has a case structure tied to the i terminal where each case is the test for a set of conditions.  Now you have an array knowing what conditions passed the test and which failed.  If you do AND Array Elements and have a True result, you know that all the conditions have passed.

0 Kudos
Message 7 of 8
(3,871 Views)

Hers is another place you can check for ideas.

 

http://www.notatamelion.com/2014/12/12/validating-data-input/

 

This basic idea can be easily expanded to handle arbitrarily complex validation. 

 

Mike...


Certified Professional Instructor
Certified LabVIEW Architect
LabVIEW Champion

"... after all, He's not a tame lion..."

For help with grief and grieving.
0 Kudos
Message 8 of 8
(3,858 Views)