LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

How to architect a lot of nearly identical clusters for an event loop?

A VI architecture question here:

 

I have a DAQ system that tests 40 devices simultaneously, and in the VI I've inherited there is an individual cluster for each device, and the event loop inside the VI therefore has 40 frames for each cluster. (There are also 40 copies of local variables floating around everywhere, but that's another matter entirely) There is currently no intelligence on which control inside the cluster is clicked, which would also be desirable.

 

Currently, all 40 clusters are identical, but there may come a time when 10 or so of those clusters may get an additional control inserted, which is why an array was originally shunned.

 

My question is: what is the "correct" way to structure such a redundant number of clusters, and how can I elegantly handle value change events (i.e. the part # of cluster # 9 was changed) without having to make an absurd number of event frames or comparisons? I have some ideas myself, but none of them seem very elegant nor easy for a future developer to follow.

 

This must be a very common problem in LabVIEW, so anyone know how it "should" be solved by a CLA?

 

Thanks, Yevoc

0 Kudos
Message 1 of 10
(3,605 Views)

Hi yevoc,

 

in your original post you don't mention typedefs, so I'll assume that they aren't used. (You can check if the controls have a small black triangle on the upper left corner- from LV 2010). Typedefs help you create a "template" for a control from which you derive each control. This is extremely helpful, when you have many copies of the same controls, since you just have to change the typedef to change the content of your cluster. It even lets you control the look of the cluster from the typedef if you set it to strictly typed.

 

In your case I would suggest, creating a typedef for the original clusters and later make a copy and expand for the other clusters. And I would use Arrays, whenever possible as it makes data processing so much easier.

 

As for the events: if you use arrays, the event handling becomes a lot slimmer, too, as you can configure 1 event for all the controls within the array, then you simply compare the elements to find out which one has been pressed and pass the data on.



Remember Cunningham's Law
Message 2 of 10
(3,564 Views)

Thanks for the reply Peter.  It's definitely good to remind everyone of good programming practices like typedefs, but I still don't quite understand what the accepted programming practice for my problem is.

 

I'll try to give a concrete example.  Here I have an array of typedef'd clusters.  This is the only way I can think of getting at what value actually got changed:

 

example find value change.png

 

The problem here is that if I change something in the cluster typedef, the cluster of elements passed to the subVI has to be changed manually because it can't be tied to the cluster typedef.

 

Any thoughts on how this is intended to be done?

 

Thanks,

Yev

0 Kudos
Message 3 of 10
(3,543 Views)

Hi yevoc,

 

whenever you change a datatype (by changing a typedef) you need to check all parts of your code, which uses that datatype. In your case you need to adapt the subVI to the changed input cluster…

 

You may try to use a variant input. Then convert that variant input to a cluster of booleans. This may work as long as you don't change the number of cluster elements: then you need to go back to step one (see above)!

Best regards,
GerdW


using LV2016/2019/2021 on Win10/11+cRIO, TestStand2016/2019
0 Kudos
Message 4 of 10
(3,506 Views)

Hi Gerd,

 

I'm hoping I'm not following what you're saying.  I read that as "check your code whenever you change a typedef, and manually fix it everywhere in the code when it breaks things."

 

Please tell me I grossly misinterpreted that, because this sort of tedious programming was precisely what I was trying to avoid by making the OP.

 

Thanks,

Yev

0 Kudos
Message 5 of 10
(3,485 Views)

Hi yevoc,

 

check your code whenever you change a typedef, and manually fix it everywhere in the code when it breaks things

You interpreted correctly what I was writing!

 

When you change a datatype (like your typedef) then you are responsible for checking all code that relies on that datatype (aka typedef).

You are the programmer, you are responsible for your code!

 

Maybe some other approach to your problem is more suitable to tackle your task?

 

Idea:

- Upon startup of your program you analyze your typedef cluster and store the labels of all components as array of strings in a FGV, global, whatever.

- When comparing your clusters you get a cluster of booleans. Convert that cluster of booleans to an array of booleans.

- Now use an autoindexing FOR loop to get all labels, where the corresponding boolean is TRUE…

 

That way you can use your subVI without ever needing to change any inputs: all you need is a boolean array and a string array…

 

See this example:

check.png

- Getting the labels of the cluster elements is called only once.

- I just simulated your event case with this comparison…

- Use conditional tunnels with more recent LabVIEW versions to simplify your subVI even more…
 

Best regards,
GerdW


using LV2016/2019/2021 on Win10/11+cRIO, TestStand2016/2019
Message 6 of 10
(3,477 Views)

Wether or not the SubVI has to be changed depends mainly on the elements in the cluster. If the cluster has several of the same controls in it, you might not have to change that much. The Input should auto adapt once it is connected to the typedef.

 

I am a bit confused about what you're trying to do with the clusters, maybe share some insight on

a) What your cluster looks like and

b) What has to be done, once you changed data in it.



Remember Cunningham's Law
0 Kudos
Message 7 of 10
(3,425 Views)

Sure thing.  Here is my current mockup of the front panel that I'm working on...

 

 mockup_frontpanel.png

 

 

This is a 3D array of a typedef'd cluster.  Different values will be updated at around 1 Hz for each unit from a DAQ system.  The problem is that while this 3D cluster array will work for 80% of the DAQ slots, some of the clusters in very particular slots will need to have different/additional controls that the others don't need, and adding unused GUI controls to *every* slot (as is required in arrays) is not an option due to operator confusion.  Each unit also may not update at exactly the same frequency either, so there needs to be intelligence in terms of how data is accepted and transmitted to the user on a per unit basis.

 

Since 80% of the slots are identical and generic (and because there are so many units to deal with), it makes sense to dynamically handle user events in a single event frame.  The problem is that the slots with uniquely different controls/situations aren't in a separate drawer, they are scattered amongst the generic units (i.e. generic cluster), making it difficult to separate the clusters out on the GUI.

 

I was thinking of making a cluster that wrapped around a large number of typedef'd clusters and abandoning a large array, but I can't figure out how to handle user events in a sensical manner with that approach.

 

I am also not the only developer who will potentially touch this, but since everyone else is a beginner with LabVIEW and tends to create bugs as they go, I was hoping to provide a solution that didn't require a lot of code tracking and copy/pasting all over the place, as we do in our current VI.  We've already had some bad bugs arise because the current code of a jillion local variables & stacked sequences isn't streamlined/maintainable, so getting the most elegant approach is more than just an itch to scratch on my part.  The simpler this can be, the less time I will have to fix errors in the future.

 

Hope that clarifies my situation.

 

Tx,

Yev

0 Kudos
Message 8 of 10
(3,384 Views)

My suggestion - move the logic and display for a single element to a VI and make it reentrant. You can then open multiple copies of that VI (or another, if you have a different layout) and display them in subpanels. These VIs will then need to read/write data to something which will allow access to the data. There are many ways to do this and which one will be best suited for your case is hard to say. A couple which are easy to understand are using a DVR to hold all the data or using multiple DVRs (one for each cluster) and having something which will manage access to the DVRs by name. You can probably find discussions on similar topics here - https://decibel.ni.com/content/groups/large-labview-application-development

 

For things which are similar but not identical LVOOP might be useful, but can be tricky to understand if you're just getting into it. Ultimately, for a system which will be used by multiple people, it might be worth it for you to find a good LV consultant in your area and get them to come in, assess the details of the system and suggest an architecture which would work for you.


___________________
Try to take over the world!
Message 9 of 10
(3,347 Views)

Some might suggest an actor design, where each socket (nest?) is an actor and the UI is just a set of subpanels that get inserted.  The suggestion to use a reentrant subVI is probably a good start too.

 

BTW 3D arrays can complicate things, and I've honestly never found a time that I couldn't code around them with a more nested and organized data structure.  If these are classes then you can abstract the working with the data into functions dedicated to doing the work.

Message 10 of 10
(3,323 Views)