LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Variant Quick Lookup Dictionary in HAL to hide Obj Ref in Teststand?

Solved!
Go to solution

Hi All,

 

I need some help to see if I am going down the right path or if this implementation is a terrible idea.

 

First of all, I am implementing a HAL using LVOOP with a hierarchy of Grandparent, Parent, Child = "Instrument" > "Instr. Type" > "Specific Instrument".  An example would be "Instrument" > "DMM" > "NI4070" or "Instrument" > "SCOPE" > "Keysight 1234".

 

I am using a variant as a lookup table/dictionary and I am looking to store the key as a some kind of string serial number (DMM0, DMM1, SCOPE0, etc) and the val as the lvclass path to the parent class.  To invoke one of the instrument specific methods, I have a wrapper that calls the dictionary, then a factory pattern dispatcher then the parent class method.

 

Harding the device specific lvclass path for trialHarding the device specific lvclass path for trialtest wrapper to dispatchtest wrapper to dispatch

This way, all I need to do in Teststand is to pass it a string serial number of DMM0, or SCOPE0 and it will dynamically dispatch and I won't have to keep track of the object references in Teststand.

I have done a quick test of this in LV and in TS and both yielded the result I expected, however, like I mentioned at the start, I am not sure if this is the correct way to get what I want.

I already see something that bothers me with the wrappers is the constant call to the dictionary and the dispatcher across every wrapper.  For this, I have thought about making the dictionary key val pair serial number to parent lvclass, but I will need to make a dictionary for every parent class instead having just one dictionary for all different classes.

 

Any help would be greatly appreciated.

 

Best Regards,

Mike

 

 

0 Kudos
Message 1 of 7
(3,122 Views)
Solution
Accepted by topic author Mwcmwc11

I was with you up to the launching of an actor with each call.  Your dictionary should just output the class and then you let the Dynamic Dispatch do the work from there.  Personally, I have a library for each type of instrument.  For instance, my power supply library has direct library calls to handle things like "Enable Output", "Set Voltage", "Read Current", etc.  Each of those VIs does the object lookup, act on the object to accomplish the goal, and then update the object in the dictionary (if necessary).  So TestStand just calls those library functions and none of the OOP or HAL stuff comes out.  I just have trouble finding enough common ground among my instruments to warrant a "instrument" class to rule them all.


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 7
(3,101 Views)

Hi crossrulz,

 

Good to know at least the overall idea doesn't seem out there.  My current project layout seems similar to yours as I have a library for each type of instrument as well.  My grandparent of "Instrument" only have 3 methods, Init, Reset, Close.  Honestly, I was on the edge regarding this since there doesn't seem to be enough common grounds as you mentioned, but ultimately I went with implementation because it seemed more orderly when I looked at it.

 

I do have a follow up question.  For a dictionary that is outputting class, are you using a different dictionary per parent type of instrument or are you keeping everything in one dictionary? 

 

Thanks a bunch!

Mike

0 Kudos
Message 3 of 7
(3,081 Views)

@Mwcmwc11 wrote:

For a dictionary that is outputting class, are you using a different dictionary per parent type of instrument or are you keeping everything in one dictionary?


My dictionaries are private scoped VIs in the respective instrument libraries.  So 1 per instrument.  Though, with the "Instrument" parent class, you could add the dictionary there.  Seems like you would want an "Instrument" library to handle that though.


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
0 Kudos
Message 4 of 7
(3,071 Views)

@crossrulz wrote:
Though, with the "Instrument" parent class, you could add the dictionary there.  Seems like you would want an "Instrument" library to handle that though.

So I tried this and it works, but wondering if there is a more elegant way of doing what I am doing now...  I ended having to call a "To More Specific Class" function to down cast my "Instrument" dictionary.  My current dictionary is as follows:

InitInitGetGetSetSet

This is straight forward with the 3 inherited methods: "Initialize", "Reset", and "Close" but for "Instrument Type" specific methods it would cause me to down cast in every wrapper.  Is there a way to avoid this or this is what I am stuck with? 

DMM_SetRange Test WrapperDMM_SetRange Test Wrapper

0 Kudos
Message 5 of 7
(3,060 Views)

@Mwcmwc11 wrote:

This is straight forward with the 3 inherited methods: "Initialize", "Reset", and "Close" but for "Instrument Type" specific methods it would cause me to down cast in every wrapper.  Is there a way to avoid this or this is what I am stuck with?


Here is your trade-off:

1. Have a central dictionary and have to use To More Specific Class in all of your wrapppers

OR

2. Have a different dictionary for each instrument, also causing you to have to duplicate Initialize, Reset, and Close methods

OR

3. Way overload your Instrument class with every single possible method any instrument could possibly use so that "Set Voltage" is in the instrument class

 

I chose #2.  This is where traits would come in handy.


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 6 of 7
(3,056 Views)

Hi cross,

 

May I know how you are calling these lookup dictionaries?  I have 4 public access wrappers: Init, Set, Get, Get all for all my instrument dictionaries.

 

I was experimenting with them in phases.  I originally had a top level VI that was initializing all the dictionaries and setting my instrument classes into them.  This was done by reading an ini file and see what was configured in the system then my top level VI was calling the dictionary initialization using a case structure.

 

Now, I am trying to move away from using the case statement and started to use call by reference to dynamically load up the dictionary.  However, I run into the issue that when I tried to access the dictionary later, they are all empty.  I suspect that they are not being kept in memory, so when I reference them later, there are no valid data (key or class values) kept inside.

 

Dyn_loader.pngDyn_Get.png

I am actually using one of your snippets as a path finder to help load and it works very well so I don't think it is a pathing problem.

0 Kudos
Message 7 of 7
(2,976 Views)