From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, 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: 

Functioning SubVI's don't update in main program

Solved!
Go to solution

Hello all,

 

I'm having some trouble with a VI I'm putting together for some lab research. I'm trying to use two SubVI's: one writes nine analog voltage outputs through a PCI 6723, the other sends M Code commands to a linear positioner through COM 4. Both work individually, but when I place them in another VI, it seems the outside loop only runs once. If I preset a track position and hit run, the track moves to that position but does not respond to further inputs. The voltage control does absolutely nothing, preset or not. The goal is that both SubVI's run in real time. That is, changing the enum for the track will automatically update the position, and moving the voltage sliders with update voltage and indicators in real time. I've tried a couple of configurations without luck. Is it perhaps because I'm trying to use both a serial port and a DAQ?

 

I've attached the main VI and SubVI's for review. Any advice is appreciated.

0 Kudos
Message 1 of 7
(3,370 Views)

Dataflow 101: A loop cannot iterate until all of the code inside has completed.  But your subVIs are not completing since their "stop" condition is set to a constant of FALSE.

 

You need to break apart your state machines and make one larger state machine that runs at the top level.  State Machine inside of another State Machine is a clear indicator of a bad design.


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 2 of 7
(3,341 Views)

@crossrulz wrote:

...  State Machine inside of another State Machine is a clear indicator of a bad design.


Could you talk to me abou that last point a bit more?

 

I have some "learnin" to do if that is true.

 

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 7
(3,335 Views)
Solution
Accepted by topic author Huwiggle

"Is it perhaps because I'm trying to use both a serial port and a DAQ?"

No, that would be a silly restriction of the language 🙂

 

There are many problems with your application (by the way, you should use a LabVIEW project for your main and subVIs), like the insane structures in the DAQmx subVI.

 

The actual bug you see is the reason of you do not understand how a shift register stores data: you use initialized shift registers for both subVIs, therefore you overwrite the stored values at every iteration. You should learn about Functional Global Variables and Action Engines, so you will understand the problem. So you need to work (also) on your subVIs, you have to change how they work. In their recent form they are not capable to do what you want...Do not have an internal state machine for the subVIs, use actions: Init, Check, Change, Close. So it is very important that your subVIs only perform one action at a time. Finally, when you stop your main While loop in your main VI, you call the two subVIs with action command "Close" to close and delete the tasks properly.

 

Here is some more reading: http://forums.ni.com/t5/LabVIEW/Community-Nugget-4-08-2007-Action-Engines/td-p/503801

 

 

Message 4 of 7
(3,331 Views)

Thanks for your help everyone, it sounds like I'm expecting my SubVI's to do too much relative to the overall sceme of things. The 1/2 credit labview course I took last semester clearly didn't offer very much education. I'll redesign the SubVI's.

0 Kudos
Message 5 of 7
(3,325 Views)

@Ben wrote:

@crossrulz wrote:

...  State Machine inside of another State Machine is a clear indicator of a bad design.


Could you talk to me abou that last point a bit more?


Disclaimer: This is a general rule based on my personal observations.

 

In the applications I have done, I find it best to keep your states "fast".  This often means repeating states.  But this needs to be done in order to 1) do timing checks and/or 2) check for user inputs (or other input states).  But if you put a loop that is a state machine inside of a state, then you are violating that "fast" principal.  Plus you are just making things more complicated and break the opportunity to reuse those states. Whatever states you had in your tiny little state machine should really be states in your larger state machine.

 

In my mind, I find it very similar to putting a large wait inside of an event case so that your GUI is bascially locked up until that very long task is complete.  In general, that is a very bad idea.


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
Message 6 of 7
(3,296 Views)

@crossrulz wrote:

@Ben wrote:

@crossrulz wrote:

...  State Machine inside of another State Machine is a clear indicator of a bad design.


Could you talk to me abou that last point a bit more?


Disclaimer: This is a general rule based on my personal observations.

 

In the applications I have done, I find it best to keep your states "fast".  This often means repeating states.  But this needs to be done in order to 1) do timing checks and/or 2) check for user inputs (or other input states).  But if you put a loop that is a state machine inside of a state, then you are violating that "fast" principal.  Plus you are just making things more complicated and break the opportunity to reuse those states. Whatever states you had in your tiny little state machine should really be states in your larger state machine.

 

In my mind, I find it very similar to putting a large wait inside of an event case so that your GUI is bascially locked up until that very long task is complete.  In general, that is a very bad idea.


Fair enough and thank you.

 

And for anther way of looking at things...

 

I DO have state machines inside of state machines when warrented. I find it simplifies complex functionality.

 

Example: Curve tracer control.

 

Will generally transition between an "Idle State" and a "Running State.

 

The "Running State" can be a state machine that starts out with an "Autoscaling State" and then enters a "Collection state".

 

The "Autoscaling State" can also be a state machine that determines the proper range for the DUT.

 

So that would be a state machine inside a state machine inside a state machine. Smiley Happy

 

My general rule of thumb is;

 

"If I can not illustrate the states and the transitions on a sinlge sheet of paper, it is too complicated." ( "The purpose of abstraction is not to be vague, but to create a new semantic level in which one can be absolutely precise" Dijkstra see here )

 

Re:"Re-using a state"

I never re-use a "state" of a state machine. If there is something done in a a state that has to be done in more than one part of the application I hear the words coming from the nether world saying "Create a subVI Ben".

 

But this is just another way to approach developing an application.

 

Thakn you for you explanation.

 

 

 

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