LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Oop with LabVIEW

Solved!
Go to solution

Dear Community,

I am trying out my first steps at going oop in my LabVIEW applications. In the underlying case I have two devices of the same manufacturer with a set of similar and different functions.I would appreciate your feedback on how to build up the architecture. I have attached a code snippet demonstrating my first steps. When working event driven in the past, the standard data type for my queues in the queued message handler would be a cluster with an enum for state transitions and a variant. Is adding a class to this cluster a good way when passing classes to dynamic dispatching vis in the consumer loop?

 

0 Kudos
Message 1 of 7
(994 Views)

It's an option. But since the devices have specialized methods, you get very little from polymorphism. Also, each message you send is probably going to relate to exactly one low level method. So, you're basically doing the work twice, in a (very) complicated way. Maintenance will become tedious.

 

The only thing you gain is the parallel execution of the devices. Something that is often overrated, but of course not always. I've seen this pattern, with feedback from the consumer to actually make the producer wait for the consumer. That is a lot easier to make with just one loop... Do you really need a parallel loop?

 

If so, I'd make a DAQ loop with the two devices in two shift registers. If you put them in a container (array, map), you immediately have to start casting to specific, which sounds like no fun at all.

 

I'd send (much) higher level commands from the GUI loop. Not: method 1 for device 1, message 4 for device 2, but "start measurement", "stop measurement". That way, both loops stays generic, focusing on their stuff, the DAQ loop on devices, the GUI on the GUI.

 

This looks a lot like the HAL trap. HAL's are hard, you should only start doing HALs when you're experienced enough to know better 😋.

 

Of course, I know very little about your project.

0 Kudos
Message 2 of 7
(961 Views)

Thank you for your attentive answer wiebe@CARYA

A short description of what i want to do:

I have a GUI in which the user can set the configuration values for the devices used. As mentioned earlier I use two measurement devices from the same manufacturer. The user can then check for hardware changes, start/stop measurement or create a report.

 


 

The only thing you gain is the parallel execution of the devices. Something that is often overrated, but of course not always. I've seen this pattern, with feedback from the consumer to actually make the producer wait for the consumer. That is a lot easier to make with just one loop... Do you really need a parallel loop?

 


My intention is to send higher level command from the GUI loop to the state machine loop. Commands of the likes of "start measurement". I need the second loop (the lower loop) because starting a measurement will call many states in the lower loop (Sending different device commands, Setting program status, Changing properties of controls on the User interface). 
It is possible that using classes here might be overkill. The reason i am using classes is that I want to start encapsulating my code better than in the past. Besides that I think that in this case  it is helpful to use dynamic dispatching when carrying out commands both devices understand (open, close, set value, measure).

 

What I have not figured out yet is what the best way is to tell my lower loop which class it should be using..The snippet i attached earlier was my initial idea on how this could be done. If anyone has a better idea please feel free to inform me.

 

0 Kudos
Message 3 of 7
(948 Views)
Solution
Accepted by topic author labviewette

@labviewette wrote:

What I have not figured out yet is what the best way is to tell my lower loop which class it should be using..The snippet i attached earlier was my initial idea on how this could be done. If anyone has a better idea please feel free to inform me.


Either let the GUI loop send it with a "set device" event\queue, and then keep the class there (the GUI loop doesn't need it) or send an enum (or index or ID string) and let the DAQ loop do anything.

 

Nothing wrong with sending a class as a variant parameter, but I thought you planned on sending the device class with every command. That will become problematic, because the object can't change it's private data, unless it's send back to the GUI loop. As the GUI loop keeps running, you'll get a big mess (race condition on steroids).

 


@labviewette wrote:

It is possible that using classes here might be overkill. The reason i am using classes is that I want to start encapsulating my code better than in the past. 


The most basic class is just a library that keeps it's private stuff private.

 

As you have 2 devices sharing methods (private and public) and probably settings as well, a parent with 2 childs won't be overkill. It will be a very decent solution. 

 


@labviewette wrote:

Besides that I think that in this case  it is helpful to use dynamic dispatching when carrying out commands both devices understand (open, close, set value, measure).


DD (Polymorphism) might not shine here. The two devices extend the parent with methods. To call these extensions, you need to either cast to the specific child or give the parent all methods that don't get implemented in one of the children. That's just the situation you're in, not a great use case for polymorphism.

 

But this is all talk about how to prevent a mess. Without oo, you'll get a mess for sure 😉 (cases here, there and everywhere).

 

A way out could be to make a generic device driver class with low level methods. Then make a higher level parent with all the higher level commands (like start measurement). Two children then implement these high level methods, using the generic driver. Of course you can make a generic driver hierarchy and a high level command hierarchy. That might be overkill, or it could make perfect sense, depending on a lot of details. I'm not completely sold on this idea, but fact is you have 2 devices that only share a part of the functionality.

Message 4 of 7
(920 Views)

I'd simplify it by having the class in a shift register in the consumer loop instead of sending it as a parameter (together with other needed data as a cluster). That way the consumer can easily change values as needed and the UI loop only sends commands.

G# - Award winning reference based OOP for LV, for free! - Qestit VIPM GitHub

Qestit Systems
Certified-LabVIEW-Developer
0 Kudos
Message 5 of 7
(902 Views)

But let's say that the consumer loop has a state called "config" that both classes child1 and child2 (i.e. device a and device b) can use. How can a UI event trigger that state for the right class? The UI would need to send some sort of info about what class should be used to the consumer loop. Is that a neater way of doing things than sending the class as a parameter from the UI loop?

Pardon me for writing text rather than attaching code that clarifies what I mean.

0 Kudos
Message 6 of 7
(892 Views)

All architectures have their ups and downs. 🙂

If you mean you have 2 child classes you don't have to think about it as classes handle that themselves (which implementation to use).

If you mean you have 2 instances of some or several classes active at once, then you need to address them anyway, so why not with a simple integer (or enum if you want easier to read code) to say which one? The natural continuation is of course to have all instances as an array of the base class.

G# - Award winning reference based OOP for LV, for free! - Qestit VIPM GitHub

Qestit Systems
Certified-LabVIEW-Developer
0 Kudos
Message 7 of 7
(885 Views)