From 04:00 PM CDT – 08:00 PM CDT (09:00 PM UTC – 01:00 AM UTC) Tuesday, April 16, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

OOP Design: controlling multiple (similar) devices

Hi guys,

 

We have some software that controls different kinds of "widgets." They are identicle  in function, but they are from differering vendors and have different drivers and APIs. But here's the tricky part: they may be used by themselves, or in any combination you can  think of, up to 3 at a time. 

 

Currently, we use a seperate version of our software for each widget combination, duplicating a massive amount of code-  since the only thing we do with each widget is configure it, then read its data (which it continuously takes), then close it when the program is closed. The rest of the software is the same. 

 

I'm wondering what the best approach would be to combine the code. I'm thinking LabVIEW Classes would be a good approach, but, I am new to OOP so I'd like some advice with the design. I've seen the example "Board Testing", that looks interesting and somewhat similar - there they use a different subclass for each board. Analogously I guess I would use a different subclass for each widget. But I'm not sure this is a good idea, since I can have various combinations of the widgets. My main class wire would then have to contain multiple sub-classes. 

 

Any ideas?

0 Kudos
Message 1 of 10
(2,627 Views)

Your widgets would all be "siblings" in that case so you can do things like bundle whichever combination you want into an array and run them through a dynamic dispatch method. Sounds like you might want to start off by reading up on OOP. I would suggest the book/ebook: "The Object Oriented Thought Process" by Matt Weisfield.

0 Kudos
Message 2 of 10
(2,616 Views)

Thanks, that's what I'm doing; using a Widget maser class from which I have inheriting child classes for the specific widgets. 

 

I have a question: Each widget needs a refnum to the device driver - but if, say, I have 2 widget A's, then they need to share that refnum. 

 

Right now, I am creating one class for each widget, with the refnum in the classes' private data. How can I share that refnum between classes of identicle widgets?

 

Would I just  create another class, maybe Widget Refnums, as friend class? And I could fill it using  First Call? function of each sibling class' initialization method.  That's what I'm thinking, but not sure if there's a better way. 

0 Kudos
Message 3 of 10
(2,585 Views)

Maybe a little simplified picture.

 

I have Widget A1 connected, of Widget type A. I create an instance of WidgetA class, then open a reference to its driver

 

I connect WidgetA2, also of Widget type A; I make a new instance of the WidgetA Class. But I need to use the same reference. 

 

What's the most efficient way of sharing this data? Googling around I found this on MSDN:

 

Each class instance maintains its own data. The data is isolated in such a way that if a data member changes in one instance of the class, the same data member in another instance of the class is unaffected. However, the static members of a class provide a way for all instances of the class to use the same memory location or function.


If you prefix one of your data members with the static keyword, Visual C# .NET or Visual C# 2005 creates a single location for that static data member. The data member is exposed to each instance of the class that references the storage location. If you change the value of the shared data member in one class instance, it is changed in all the other instances.


That's precisely what I need it seems. How do I implement this in LVOOP?

0 Kudos
Message 4 of 10
(2,575 Views)

I guess I could just use a global variable...but that seems inelegant.

0 Kudos
Message 5 of 10
(2,572 Views)

What about defining a method called "Initialize" in your parent class that requires your child classes to override. Each child class then calls it's own "Initialize" method for the particular hardware it is expected to control and keeps the reference in it's own private data. This assumes one child class dedicated to a particular kind of device. I wasn't sure why you would want multiple classes accessing the same device when you could build all the functionality into one object.

0 Kudos
Message 6 of 10
(2,568 Views)

@pobrepablo1 wrote:

I guess I could just use a global variable...but that seems inelegant.


No, don't do that. I would recommend that you store the reference in your private data and that the reference is set via a method or as an input to your create method. Alternatively you could use a DVR inside the child class (for this particular widget) and the first instance of this class would initialize it. Following instances would simply read the reference.

 



Mark Yedinak
Certified LabVIEW Architect
LabVIEW Champion

"Does anyone know where the love of God goes when the waves turn the minutes to hours?"
Wreck of the Edmund Fitzgerald - Gordon Lightfoot
0 Kudos
Message 7 of 10
(2,567 Views)

OK, with these comments in mind I've created an Initialize method. "Wrapper" is the name of the driver refnum.

 

I'm calling this subvi with "initialize" as the argument iff First Call? is true. I think this is the best approach? Or at least simplest for me. I've never used DVRs before (except on a TV... ;))

0 Kudos
Message 8 of 10
(2,560 Views)

@pobrepablo1 wrote:

OK, with these comments in mind I've created an Initialize method. "Wrapper" is the name of the driver refnum.

 

I'm calling this subvi with "initialize" as the argument iff First Call? is true. I think this is the best approach? Or at least simplest for me. I've never used DVRs before (except on a TV... ;))


This would not be the way that I would implement this. First of all I would have explicit methods for my operations instead of implementing like the old style action engine. Also, I would store the data in the class private data, not in unitialized shift registers. I would consider using a better name than "Wrapper". It is a poor name for your data.



Mark Yedinak
Certified LabVIEW Architect
LabVIEW Champion

"Does anyone know where the love of God goes when the waves turn the minutes to hours?"
Wreck of the Edmund Fitzgerald - Gordon Lightfoot
0 Kudos
Message 9 of 10
(2,555 Views)

I have no choice in the name "wrapper." makes no sense, I know, but that's the refnum name that the driver vendor chose, and I want to maintain consistency with their API, which we're already familiar with. 

 

Also, that data is in the private data of each class - hence the bundle action - isn't it? But I have to get it there somehow, hence the AE. This function is only called once for each class initialization. 

0 Kudos
Message 10 of 10
(2,552 Views)