Jump to content

Dynamic Selection of Control/Typedef


ejensen

Recommended Posts

I'm developing a system to test several boards by switching relays and taking readings with PXI DMMs. I'm hoping to make it as easy as possible to add new boards. Currently, I have a subVI containing the tests for each DUT. The VI for DUT 1 is DUT 1.vi, etc. The VI that runs is determined by the value of the DUT enum. If DUT 1 is selected, DUT 1.vi is run. Initially, I used a case statement with a case for each DUT, but I don't want to have to add cases to several subVIs to add a board. I solved the problem with a Call by Reference Node.

post-13866-1232997441.png?width=400

I am trying to find a way to accomplish the same thing with a typedef. Currently, I have a case statement with a case for each board. The other cases are the same as pictured below, but have the appropriate Results and States for each DUT.

post-13866-1232996766.png?width=400

I would like the typedefs to be determined by the value of the DUT enum without having to use a case statement (as with the VI above). The typedefs are just used as constants and are manually set for each DUT. Is it possible to determine which typedef will be used based on the DUT enum input?

Link to comment

I was afraid that was the answer I would get. I tried to use LVOOP, but had a hard time getting the hierarchy figured out up front. I started the entire process over after several failed attempts at LVOOP. I'm afraid I need to avoid it until I can get some proper training. I don't come from a programming background and I still haven't wrapped my head around OOP. Any other ways to accomplish this?

Link to comment

QUOTE (ejensen @ Jan 26 2009, 02:39 PM)

I was afraid that was the answer I would get. I tried to use LVOOP, but had a hard time getting the hierarchy figured out up front. I started the entire process over after several failed attempts at LVOOP. I'm afraid I need to avoid it until I can get some proper training. I don't come from a programming background and I still haven't wrapped my head around OOP. Any other ways to accomplish this?

I think it was Shane that posted a Nugget on Function Overloading but I could not find a link.

Define a cluster with an enum to determine the type of widget and add a variant to hold the data.

Use the enum to drive a case structure and inside the case cast the variant to the proper type for that enum.

Sorry I could not find the link,

Ben

PS LVOOP would have been my first suggestion as well.

Link to comment

QUOTE (ejensen @ Jan 26 2009, 02:51 PM)

That thread morphed into a "why you should buy Test Stand.

You above posted code sorta does a lot of what LVOOP does in the sense you are calling the right VI for your widget. The dynamic dispatch does this (chooisng the right flavor of VI) automatically.

If you are having trouble understanding LVOOP I would like to suggest you start asking "dumb questions"* and let people give you the nudges you need.

Ben

* By dumb Q I mean Q's where you may feel dumb, not that they are really dumb Q's

Link to comment

You say you're having trouble coming up with the inheritance hierarchy... here's an easy way that might not be optimal but would get you started:

Pretend you're writing the enum-wired-to-Case-Structure that you talked about initially, with one of your DUT VIs in each frame. We're going to use that as a starting point for the class hierarchy...

  1. Create or open a project.
  2. On "My Computer", pop up and select "New >> Class" and name the class "ParentDUT.lvclass". This creates the class and its private data control. Ignore the private data control -- we're going to leave it empty.
  3. Pop up on ParentDUT.lvclass and select "New >> VI From Dynamic Dispatch Template". Edit this VI so that it has the connector pane of your DUT VIs, but leave that "class in" control alone -- it is going to be the placeholder for the typedefs that you were talking about in your original post. Leave the block diagram untouched. Save this VI as "DUT.vi"
  4. Now, for each frame of that case structure that you were building, create a new class and name that new class one element of the enum. So if the enum has strings "DUTA" "DUTB" and "DUTC", you're going to end up with three classes named "DUTA.lvclass", "DUTB.lvclass" and "DUTC.lvclass".
  5. Save the class -- save every one of these classes to a separate subdirectory. Common practice is to name the directory the same as the class without the .lvclass file extension.
  6. Pop up on the "Whatever.lvclass" and select Properties
  7. Go to the Inheritance entry. Click on the "Change Inheritance" button. Change the inheritance so that "ParentDUT.vi" is its parent. Hit OK to close the Properties dialog.
  8. Double click on the private data control for "Whatever.lvclass". You'll get a control VI with an empty cluster on it. Fill that cluster in with all the stuff you would've put in the typedef. When done, save and close the control VI.
  9. Pop up on "Whatever.lvclass" and select "New >> VI for Override..." When the dialog appears, select DUT.vi.
  10. A new VI is created. Fill this VI in with whatever functionality you want for this type. You can unbundle that class wire to get at all the data that you packed into the private data control. Save the new VI -- LabVIEW will start you off in a directory and assume a VI file name. Just accept both the default name and location --- that will put each DUT.vi next to the class that owns it.
  11. When finished, do File>>Save All.

Alright... there's your inheritance hierarchy. Now we need to invoke it...

  1. Create a new "Run my tests.vi". In all the following, when I say "the VI", I'm talking about that one.
  2. In the example code that you posted, you used the DUT enum to pick out a VI to load from your support\boards directory. We're going to do the same idea but altered just a bit. Given the value of an enum, build up a path to the class -- remember that each one is in a directory that is the enum string and is a file that is the enum string plus the file extension.
  3. On your diagram, drop the "Get LVClass Default Value.vi", found in the same palette as the bundle and unbundle nodes. Wire the path up to the input.
  4. Drag from your project to the block diagram the "ParentDUT.lvclass". You now have a block diagram constant of the parent class.
  5. Drop a "To More Specific" primitive on the block diagram (also in the same palette as bundle/unbundle).
  6. Wire the constant to the middle terminal of "To More Specific". Wire the output of "Get LVClass Default Value.vi" to the left input of "To More Specific".
  7. Drop DUT.vi as a subVI (just drag any of the DUT.vis from the project tree to the block diagram -- it doesn't matter which one you drag).
  8. Wire the output of the To More Specific prim to the input of the DUT.vi.
  9. Wire up any other inputs to the subVI that you want.
  10. Run your VI.

There you go. Dynamic dispatch magic over a VI hierarchy, generated, almost by rote recipie, from an enum and a set of typedefs.

Good luck!

Link to comment

QUOTE (Aristos Queue @ Jan 26 2009, 03:35 PM)

You say you're having trouble coming up with the inheritance hierarchy... here's an easy way that might not be optimal but would get you started:

...

There you go. Dynamic dispatch magic over a VI hierarchy, generated, almost by rote recipie, from an enum and a set of typedefs.

Good luck!

Notes to go with Aristos' posting.

Don't mess with the icon connector layouts required etc. until your light bulb turns on (ie you are starting to get it)

Same thing with public vs privates.

Both of those things can get complicated and are not required to get a handle on LVOOP.

Ben

Link to comment

Thanks for the additional responses. I think I found the nugget neBulus referred to in his first post (nugget). It was informative, but I didn't get around to implementing it yet. I have decided to give LVOOP another shot first, and I am using Aristos' post as a starting point. I have made my classes and will get started on the wiring tomorrow. On a previous attempt at LVOOP, I ended up with essentially the same hierarchy, but was unable to get much further. I know more now than I did then. We'll see how it works out. I appreciate all the advice.

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.