LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Architecture and creating subvi question

Solved!
Go to solution

Hi everyone,

 

I am writing code that is supposed to do the following. Using DO/counters control a number of lasers. All this needs to do is turn on each laser for x sec, turn off for y sec until a certain total time has passed. The lasers share the same on/off sequence and total time but will be started and stopped independently from each other. I picked a QMH for this application and the code is attached, while probably full of rookie mistakes, it does what I want (have not been able to test the hardware part yet though, that is why some of the block diagram is disabled).

 

While I could add another loop for each additional laser, doing that would make the block diagram inconveniently large and I'd be duplicating a lot of code. First, is the QMH the right architecture for this application? Maybe I am making this way more complicated than necessary.

 

I have tried to create a subvi from the laser loop but when I do that it breaks the code. I have tried using references/property nodes for the front

panel controls but I have not been able to turn the loop into a functioning subvi.

 

I know it is possible to run multiple instances of a subvi or a main vi and I have seen some examples of this but I do not know enough labview to implement this. A requirement is to have one front panel that looks like the one in this vi and that the front panel remains responsive.

 

If someone could give me some advice as to how to turn the laser control loop into a functional subvi that would be helpful. Is there a way to turn this into a subvi without having to modify each subvi for each laser? I.e. have the information that tells it what laser to control as an input? I know it can be done but I am just not seeing it.

 

The attached zip file should contain all files. It is written in Labview 2017. If required I can save it for a previous version just let me know!

Thanks!

0 Kudos
Message 1 of 9
(3,503 Views)

I use LV2015 so I can't look at your code specifically, but in general this is what to do in these situations:

 

1. If you need to run one SubVI with multiple instances running in parallel, you can do so if you make it re-entrant.  This option is found on the VI properties under the "Execution" heading (default is non-reentrant, set it to either "Shared clone" or "Preallocated clone".

2. You're probably getting those references because you have indicator and/or control terminals or local variables in your loop that it's trying to update.  You'll need to remove those from the loop and then set up a messaging system of some kind (probably a queue... have all your subVIs put messages into a queue, and your main VI reads from the queue constantly to update your front panel).  Sounds like you're already using a QMH so you can probably just add a new message type that updates those front panel objects.

3. You also probably need a way to signal to each laser's VI that it's time to terminate somehow, or turn on/off, so you'll need a messaging system to send those commands to each subVI.  Either one queue per subVI or set up a series of user events that each subVI listens for.

4. If you're setting it up to run "X" amount of lasers (rather than always the same amount) you'll definitely want to use asynchronous calls to start all of your subVIs instead of having one VI icon on the diagram copy-pasted for each laser.  Even if you always run the same amount of lasers you might want to do this instead of dropping a bunch of copies of the same VI down just to avoid code re-use.

0 Kudos
Message 2 of 9
(3,480 Views)
Solution
Accepted by topic author ABSyn

Try modifying one of your slave loops such that you do not use any controls and indicators in the loop but rather act on the target controls and indicators using property nodes (Value, etc.) that use references for the target controls/indicators that are passed into the loop.

 

When the change is completed the slave loop can be turned into a sub-VI that accepts the references for the controls/indicators of one of the lasers.

 

Debug the subVI and makes sure it works as you desire.

 

Then set vi to be Re-entrant and copy another instance of that sub-VI onto you Main block diagram but now wire the reference for the controls/indicators of the next laser.

 

Provided you do not have a conflict with the DO counter tasks, that should allow you to run 2 lasers.

 

Later, Rinse, Repeat for the remaining lasers.

 

Ben

Retired Senior Automation Systems Architect with Data Science Automation LabVIEW Champion Knight of NI and Prepper LinkedIn Profile YouTube Channel
0 Kudos
Message 3 of 9
(3,477 Views)

This actually sounds like a good application for the Actor Framework.  Warning: it is heavy on the Object Oriented Programming.  But it allows for launching and communicating to an unknown number of "actors" (in your case, the QMH for each laser).  It allows for a lot of reuse.  But there is a bit of a learning curve, especially if you are not familiar with OOP.

 

As an alternative, I have used the Asynchronous Call to launch N clones of my QMH and then I can communicate with them in some fashion.  The last project I did that with, I used User Events to send everybody the same message and just included an ID to state who should actually do something with the message.  The ID could also be a value to state that everybody has to do something, such as shut down.

 

As far as sending data back to the main GUI, User Events are definitely the way to go.  You should be using an event structure already for your GUI anyways.  Might as well use that structure for getting updates.


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

This is an image of what I suggested above.

 

Control_Refs.png

 At the top of that image you see the Main VI that holds all of the controls and indicators and two red boxes highlighting two examples of passing control refs to re-entrant sub-VIs.

 

The double headed arrow show the block diagram of one of the re-entrant sub-VIs and illustrates how simple the sub-VI can look if you use sub-VIs to handle a handful of controls and references. In the case above the equipment being monitored is unique and completely un-coupled from any other functionality aside from sharing the GUI and some common buttons used to stop/stop/save.

 

Using the approach shown above, all operations related to one of the widgets being controlled are handled by the sub-VI and the Main VI does not know about or care what button was punched since the sub-VI handles all of that work.

 

But you do not have to go all of that way and just take a first step in that direction by creating the sub-VI that updates the GUI via control references and make sure you are passing the proper queue ref to the sub-VI.

 

Not trying to convince, only offering alternatives to help inspire,

 

Ben

Retired Senior Automation Systems Architect with Data Science Automation LabVIEW Champion Knight of NI and Prepper LinkedIn Profile YouTube Channel
0 Kudos
Message 5 of 9
(3,454 Views)

Ben wrote:

Not trying to convince, only offering alternatives to help inspire,


An alternative to Ben's suggestion: use subpanels.  Then everything is actually inside of the subVIs and you just load their front panel into whichever subpanel you want.  Again, you can use the Asynchronous Call for this method as well to have as many controllers as you need.


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

@crossrulz wrote:

Ben wrote:

Not trying to convince, only offering alternatives to help inspire,


An alternative to Ben's suggestion: use subpanels.  Then everything is actually inside of the subVIs and you just load their front panel into whichever subpanel you want.  Again, you can use the Asynchronous Call for this method as well to have as many controllers as you need.


Yes that will work and I considered suggesting same but that would require some extra work to make sure the proper queue refs are passed to the right instances - AND- debugging gets a little tricky.

 

But it every bit as valid as what I mentioned above.

 

"red pill or blue pill" you choose.

 

Ben

Retired Senior Automation Systems Architect with Data Science Automation LabVIEW Champion Knight of NI and Prepper LinkedIn Profile YouTube Channel
0 Kudos
Message 7 of 9
(3,438 Views)

Hi Ben,

 

First thanks to you and everyone else for responding so quickly. I think I understand what you are suggesting. All controls and indicators would be in the main vi with the subvi's having the references as inputs. I will try that. As for some of the other suggestions, Actor Framework and such, that is currently way beyond my Labview skill level. I am actually contemplating suggesting to management to hire a Labview developer. But I will give this a try first. I will update in a little bit.

 

Thanks again

Arne

0 Kudos
Message 8 of 9
(3,417 Views)

Thanks everyone. I have something that works now with a block diagram that is not ridiculously big, still some repeated code but I will have to look into the more advanced/more efficient architectures later.

Message 9 of 9
(3,354 Views)