LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

VISA Class cast from "Instr" to "Serial Instr"

Solved!
Go to solution

Using LabVIEW 2020, running on a cRIO 9067:  The LabVIEW app controls a HVDC power supply through an RS-232 interface.

 

Our lab has two different supply vendors for this application (TDK and Magna).  They both speak RS-232, with roughly the same configuration, i.e. 19,200 baud, 8 bits, no parity, and so on. Both vendors provide extensive and well-debugged LabVIEW libraries that can be used to operate their instruments.

 

But, the LabVIEW libraries provided by the vendors differ in one important respect: the TDK library accepts a VISA Resource Name of class "Serial Instr", whereas the Magna library accepts a resource name of class "Instr" .  Through trial and error I've learned LabVIEW will not compile a "Serial Instr" reference to an "Instr" resource, and vice versa. I have no ability, of course, of changing either library.  And, in spite of alleged industry standards, their command structure is not wire-compatible.

 

I wish to create a compatibility adapter layer between the application and the two power supply libraries that will allow the experimenters to connect either vendor's supply to the system, and the software will 'figure out" (using an IDN? command) which one it's talking to, and then route the commands to the appropriate vendor library.

 

It seems I need a "cast" operator that will convert an "Instr" VISA Resource name (initialized from s a constant, indicating what physical port on the cRIO is being used) to a "Serial Instr" resource name for use by the TDK library.  Or, an option on the VISA Open function to select the resulting class. I can't find either of these two operations. 

 

The workaround I've got so far is to maintain two parallel VISA Resource variables, one of each class, and then use the one appropriate for the individual library.  This feels like a bit of a kludge. What am I missing? 

 

 

0 Kudos
Message 1 of 12
(1,742 Views)

I would create a parent class called HVDC Power Supply and two child classes: TDK and Magna. Each of the child classes will hold the VISA resource of the corresponding class in their private data. To configure the instantiated child I would create a dynamic dispatch method with the VISA name input as a string and then using the Type Cast function the input string can be cast to the right VISA class. Parent class must have dynamic dispatch methods that will be called by the app and child classes will override and call directly VIs from the driver.

Lucian
CLA
0 Kudos
Message 2 of 12
(1,718 Views)

You cannot cast one object to become another, despite the name. An object is always just that object. If an object has a parent, it can act like that parent, but it cannot be that parent. Casting changes how LabVIEW thinks of the object.

 

For example, say you have a class hierarchy of Animal > Dog. If you have a Dog object, you can use To More Generic Type to change the wire type to Animal, but at the end of the day it's still a Dog object, LabVIEW just treats it as the parent class. If you have an Animal object, you cannot cast that to a Dog type. You must create a new Dog object and transfer the properties over to that new object.

 

To answer your question though, I think you have the hierarchy somewhat correct, as I think SerialInstr is a child of Instr. Theoretically you might be able to always use a SerialInstr class and upcast it to Instr, but it doesn't look like LV treats the Serial classes the same as other classes, and I don't know how to cast them (To More Specific/Generic Class doesn't work on VISA refs). Maybe they're not actually classes?

 

At any rate, I do know that you can generally coerce Strings to both SerialInstr and Instr classes. Perhaps you could store it as a string and have LV cast it to the correct one automatically?

 

 

0 Kudos
Message 3 of 12
(1,709 Views)
Solution
Accepted by topic author MarkBowles

What I was missing was how to programmatically create a VISA Resource Name of the proper class from a string variable. Learning from the above responses about the "coerce" operator (as opposed to type cast), I was able to create a fragment that does that:

 

MarkBowles_3-1649458020606.png

 

I think we've established that VISA Resource Names are not quite isomorphic objects. LabVIEW apparently does not allow the coerce operator to cast Instr to SerialInstr:

 

MarkBowles_5-1649458791043.png

 

Or the other way around:

 

MarkBowles_6-1649458928880.png

 

So, I have to maintain two different variables for the two classes of VISA Resource Name, but at least they can be initialized from one string.

 

Thanks for the help!

 

-- Mark

0 Kudos
Message 4 of 12
(1,695 Views)

@BertMcMahan wrote:

You cannot cast one object to become another, despite the name.


I didn't say that. Here's an example showing my idea:

LucianM_0-1649492869891.png

LucianM_1-1649492939869.png

 

Lucian
CLA
Message 5 of 12
(1,650 Views)

Hi, Lucian,

 

Brilliant minds run in concentric circles -- that's almost exactly what I came up with.  I ended up with a Power Supply class that interacts with the app, and collects and maintains the abstract state of the supply. An Adapter class provides the actual operations to read and write the supply; there's an abstract superclass Adapter, and two real subclasses for TDK and Magna; the Adapter in actual use is stored in the Power Supply object.  The actual VISA Resource session is owned by the Adapter.

 

I'm a Java coder at heart, and this is a rather Java-ish approach.

 

This sort-of-not-quite class structure in VISA is a bit of a handicap; without it, the Power Supply object could own the RS-232 port, open it once, and leave it open forever, regardless of what protocol is being sent through it. Presumably this structure is dictated by VISA, which is bigger than LabVIEW, and provides benefits of abstract communication through a variety of different channel types.

 

I'll be testing with real power supplies at the lab next week; hope I don't fry something!

 

0 Kudos
Message 6 of 12
(1,636 Views)

@LucianM wrote:

@BertMcMahan wrote:

You cannot cast one object to become another, despite the name.


I didn't say that. Here's an example showing my idea:

LucianM_0-1649492869891.png

LucianM_1-1649492939869.png

 


Sorry, I was talking to the OP. I started my reply before you posted, but you beat me to it 🙂

 

And, to the OP- you don't actually have to use the Coerce function to convert from a string. LabVIEW just handles it for you behind the scenes. As long as your internal functions know what type they need, LabVIEW handles it fine. In other words, your API's might need either an Instr or a Ser Instr type, but you can hook a string up to both. Using two internal variables is probably a little safer.

 

For example:

 

BertMcMahan_0-1649694056630.png

 

0 Kudos
Message 7 of 12
(1,578 Views)

This is a forum question, is there any way to kind of mark this thread and revisit this information in the future?

0 Kudos
Message 8 of 12
(961 Views)

You could make a bookmark in your browser.

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 9 of 12
(916 Views)

I figured it out.

Browser bookmark is definitely one option, but not ideal for me.

We can do TOPIC OPTIONS on the top, or OPTIONS on the right of the threads, a little bit small and gray.

Site-wise bookmark is available with even email subscription options, so this is what I am looking for.

Thanks anyway.

0 Kudos
Message 10 of 12
(892 Views)