LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Best way to code multiple choice numeric inputs / bit flags

Solved!
Go to solution

Hello.

I need some suggestions.

 

We have several API libraries (for controlling our hardware) written in C and distributed as DLLs.  For many of them we have a library of LabVIEW VIs wrapping them (using the Call library function node).

 


We have several functions in which the input (in the original C library) is an unsigned integer which is meant to be several flags (each one bit value) ORed together.

 

I have seen more than one way this interface has been transferred to the wrapper VIs.

1.  Numeric input.  User has to understand and use it exactly as the C programmer would

2.  Attempt to make it nicer -- an input which is an array, that appears on the front panel as a multiple choice list box kind of input (Internally in the block diagram this is used to create the correct input to the C function)

 

I think there were others, but that is what I remember right now.  When I first saw option number 2 (looking at the front panel) I thought it was much nicer; more intuitive and clear (user could select from named choices, not numbers, not strange hex values, etc.).  However when I put it on a block diagram and tried to wire it, I had to supply an array of numbers; I had no idea what the values were supposed to be.  So for a UI option 2 seems much better, but for an API I think it is actually worse.

 

What would you like to see, if you were the programmer integrating my functions into your application?

 

Thank you.

Batya

0 Kudos
Message 1 of 21
(3,793 Views)

I think the array of rings is a good choice.  You can just use OR Array Elements to combine the flags.

 

If you do go with the numeric input, set the radix to Binary (and show the radix).  This way you can see exactly which bits (flags) were set.


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
Message 2 of 21
(3,788 Views)
Solution
Accepted by topic author BPerlman

Since each value is a single bit, I would suggest that the wrapper have booleans on the connector pane and then convert it internally to the correct bitfield. Another option is to use a cluster of booleans, but that can be a less friendly to the user of the API. I would suggest doing that only if you have more than a few options.


___________________
Try to take over the world!
Message 3 of 21
(3,779 Views)

You could use an array of booleans (using free labels to "label" each element of the array, then simply use boolean array to number to convert it to a number.  Just make sure that the array has as many elements as you need to represent the number  integer type (even if you need to hide some of them).  The drawback is that you can't actually label the elements so making it into a typedef would have little meaning.

Bill
CLD
(Mid-Level minion.)
My support system ensures that I don't look totally incompetent.
Proud to say that I've progressed beyond knowing just enough to be dangerous. I now know enough to know that I have no clue about anything at all.
Humble author of the CLAD Nugget.
Message 4 of 21
(3,759 Views)

Wow.  Thanks everyone for the input.  I have some questions (of course 😉  )

 

crossrulz:  You said, "I think the array of rings is a good choice.  You can just use OR Array Elements to combine the flags."

I am not sure what the array of rings is.  Is it a new suggestion or something I described?  The thing I described seeing seems to be an array of integers.  I attached screenshots of the front panel of the VI, and also of how it looks if I put it in a block diagram and create a constant wired to that terminal.  Is this what you meant?  Or was my description unclear and you were describing something else that it sounded like I meant?  If so, what?

 

tst: You wrote:


Since each value is a single bit, I would suggest that the wrapper have booleans on the connector pane and then convert it internally to the correct bitfield. Another option is to use a cluster of booleans, but that can be a less friendly to the user of the API. I would suggest doing that only if you have more than a few options.

I didn't think of that idea! Anyway, how many would you call more than "a few" options?

Also, in another function with a similar problems, the VI starts multiple channels (say, five or ten).  In the "C" function we give him the option of "OR"ing together bits which represent the channels, but we also give him a predefined named value which means all the channels, to make it easier to use.  How would I do that if the wrapper has booleans on the connector pane?  Something like the following inputs:

channel 0

channel 1

channel 2

channel 3

channel 4

all channels

And you'd not wire 0-4 and yes wire "all channels" if you wanted them all?  Or is it simply not worth adding this option in this configuration?

 

billko:  I don't understand how this would help the user of the API.  It is pretty rare that anyone (other than me, in initial testing or something) uses the thing via the front panel.  At the moment, the front panel is fine.  It is when the VI is added to a block diagram and I try to wire it that it looks confusing.  How would I have the user of the VI in a block diagram see these free labels?  I'd think he'd just see an array of booleans and have no idea what to do with it.

 

Again, thanks to all!

 

Batya

 

Download All
0 Kudos
Message 5 of 21
(3,735 Views)

@BPerlman wrote:
Anyway, how many would you call more than "a few" options?

I would say around 4-6, which is what you can decently fit on a connector pane before it gets too crowded, and it looks like you pass that limit, so I would suggest going with the cluster. Make it a typedef and then let the user bundle the elements by name.

 

For the all options thing, you could add a special boolean in the cluster (or on the connector pane of the wrapper) which you look at and if it's T, you set all the others to T. Another option is to have the cluster as an output of a subVI (so that you can have a clean and safe way to bundle it by name) and then that subVI output two clusters - one with all F and one with all T. If the user wants all T, they simple take the second output and wire it in directly.

 

Whether or not it's correct to give such an option in the API is up to you. Generally, it is usually recommended that APIs not have this sort of specialized knowledge so that they're kept clean, but if this is something which is used commonly, then it's valid to make it part of the API (or at least have a helper function which makes it easy to do).


___________________
Try to take over the world!
Message 6 of 21
(3,728 Views)

Or would it be better to wrap my function in two wrappers -- Start selected channels (with an input for each channel) and start all channels?

Or does that sound like overkill?

 

As for the connector pane getting too crowded, it seems it would only be crowded if all the inputs were wired.  If I default them all to false, the user could wire only the ones he wants to select, correct?  Then it seems more could comfortabley fit on the connector pane (this is what I did when wrapping a different function that had a lot of inputs, but only a couple were really used at a time and the rest just passed a zero -- so I defaulted to zero and wired only the ones I wanted to use).

 

Does that sound reasonable?

 

Thanks.

Batya

0 Kudos
Message 7 of 21
(3,721 Views)

@BPerlman wrote:

Or would it be better to wrap my function in two wrappers -- Start selected channels (with an input for each channel) and start all channels?

Or does that sound like overkill?


It sounds reasonable. Basically, it's the helper function I referred to (and it can simply wrap the standard call and set all the values to T).

 

As for the connector pane, I was referring to the number of elements on the CP, not to how many you actually wire. Technically, you can go all the way up to 28, but I get uncomfortable considerably sooner. If you have a group of values which go together (like an option set), I find that having them as a single input is cleaner, particularly if you want to add more in the future. That said, it's a style issue and therefore it's down to personal preference.


___________________
Try to take over the world!
Message 8 of 21
(3,704 Views)

BPerlman wrote:

I am not sure what the array of rings is.  Is it a new suggestion or something I described?  The thing I described seeing seems to be an array of integers.  I attached screenshots of the front panel of the VI, and also of how it looks if I put it in a block diagram and create a constant wired to that terminal.  Is this what you meant?  Or was my description unclear and you were describing something else that it sounded like I meant?  If so, what?


Rings are integers.  This way you can have descriptions go along with your integers.  I just figured out that the OR Array Elements doesn't work with integers, but you can use FOR loop to do the job easily enough.


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
Message 9 of 21
(3,692 Views)

@BPerlman wrote:

<snip>And you'd not wire 0-4 and yes wire "all channels" if you wanted them all?  Or is it simply not worth adding this option in this configuration?

 

billko:  I don't understand how this would help the user of the API.  It is pretty rare that anyone (other than me, in initial testing or something) uses the thing via the front panel.  At the moment, the front panel is fine.  It is when the VI is added to a block diagram and I try to wire it that it looks confusing.  How would I have the user of the VI in a block diagram see these free labels?  I'd think he'd just see an array of booleans and have no idea what to do with it.

 

Again, thanks to all!

 

Batya

 </snip>


I'm sorry, I completely misunderstood your intent!  😞

Bill
CLD
(Mid-Level minion.)
My support system ensures that I don't look totally incompetent.
Proud to say that I've progressed beyond knowing just enough to be dangerous. I now know enough to know that I have no clue about anything at all.
Humble author of the CLAD Nugget.
Message 10 of 21
(3,679 Views)