LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Sub vi not peforming like the same code does either when the sub vi front panel is visible, or the code is brought to the top.

I have seen this before, but usually with larger programs. A sub vi works, but not as expected. In one case I brought all the sub vi code to the top level, and it worked. There was data logging in that example. It my current example, I am just moving a rotary stage, and querying the encoder to see where it is. I get unexpected behavior when the sub vi front panel is invisible, but it works fine when I make it visible. The unexpected behavior is always with the initial move. I take the angle to move to, and decide if it is relative or absolute. If relative, I add it to the existing encode position, multiply it by the steps per degree, and send it with an absolute command. After that I check my position, and correct the angle until the rotary stage is where I want it. That part works fine, but the initial angle, whether it is absolute or relative has a huge overshoot, until I made the front panel visible. This is LabVIEW 2018.

0 Kudos
Message 1 of 20
(1,119 Views)

1. You did not include the subVI.

2. I suspect a race condition due to your abuse of Local Variables.  Learn to use proper data flow instead of use Local Variables.

3. You might also learn to use a proper State Machine.  It will greatly help your current situation.


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 20
(1,090 Views)

Thank you. I haven't actually used a state machine, but I will learn. I had not realized that my use of locals was excessive. I appreciate your feedback. I am including the encoder sub vi, which works fine. The vi I included before is actually the sub vi that gives a problem. I did forget the encoder sub vi. Could you be more specific in what a race condition is of local variables. I am reading the State Machine link you sent, but am not sure how it will help. I will take your feedback seriously. Thank you!

0 Kudos
Message 3 of 20
(1,079 Views)

You really need to review the basic LabVIEW tutorials and completely strike the Stacked Frame structure from your mind and never use it. It is a very bad code construct. State machines are a much more controlled programming pattern for controlling the execution of your application. Stacked Frame Structures are extremely inflexible conde constructs that make anything other than the most basic piece of code too rigid and complex. Remember, once you enter a stacked frame structure you MUST execute every single frame. Passing data between frames is a nightmare as well as trying to implement any type of error or exception handling. There is a very good reason they were removed from the palatte years ago. When programming in LabVIEW you need to use data flow for controlling program execution at the most basic level. Your data should be passed and accessed  using wires, not by using local variables.

 

A race condition is when two items are accessing the same data at the same time. Because of the inherent parallel nature of LabVIEW this can happen very easily. The problem is when you need to know the state of the data when you access it. For instance, if one part of your code is writing an update to the data item and one is reading, the one reading may want to make sure it is always reading the most up to date version of the data. However, if you are using local variables to both read and write the data and the code can run in parallel there is no way for you to guarantee the write comes before the read. In some cases this may not be a major issue but in other cases it can have devastating effects on the code.



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 4 of 20
(1,069 Views)

Thank you. That was extremely helpful. Most of the hundreds of programs I have written are enormous, and require 700 or more database variables to define a test, more to calculate and store data, and to control hardware. Since timing is never an issue, I got used to stacked sequence frame structures because they reduced the screen size of the huge vi's I have created, and control what happens in sequence at any given time. I read up on racing, but nothing I do is in parallel, all sequential. I will use what you have taught me, and at least for this sub vi, and it's sub vi, I will rewrite them using wires to pass data. Below is a typical example of the size of many of my vi's.

 

Global read variables                                9

Local write variables                                 1105

Local read variables                                  2985

VI size                                                       4,839,403 bytes

Controls                                                    181

Indicators                                                  595

Depth of nesting structures                       29

Number of diagrams                                 5783 diagrams

Node count                                               16,976 nodes

 

They work exactly as expected, and have really helped. Obviously they could be improved on. I remember an old Benjamin Franklin quote when writing a letter to the king of England. "If I had more time I would have written a shorter letter."

 

Thank you for everything you told me.

0 Kudos
Message 5 of 20
(1,062 Views)

I'm sure your programs work fine for you now, but a tip going forward- you need to drastically reduce the size of your programs. I write some reasonably complex stuff (for a solo dev) and a "very large" VI is less than 100 kB. Often it's even that big because I accidentally saved a big block of array data in there via a "save as default values" misclick.

 

A very reasonable and attainable goal is to have all VI's on a single "screen" of real estate. If you need more space than that... make it a subVI. If you absolutely need to have more room, expand in one axis only (i.e., so you can view the whole thing by scrolling a single scrollbar).

 

You don't indicate how you use globals, but I'd recommend using zero of them. They're acceptable for "write once read many" usage for things like config loaded at the beginning of the program, or language conversions, but I still don't ever use them.

 

You also need to drastically reduce your local variable usage. A reasonable, attainable goal is zero for 99% of your VI's. Every once in a while you wind up needing one, but using that many locals indicates you're not "thinking dataflow". Your wire is the variable, not the terminals.

 

I know you think you don't have time now, but trust me: a 5 MB VI file with three thousand local read variables is not something you'll want to stick with in the long term. It's far, far, far simpler and faster to break things down into manageable, testable chunks.

Message 6 of 20
(1,055 Views)

@BertMcMahan wrote:

I'm sure your programs work fine for you now, but a tip going forward- you need to drastically reduce the size of your programs. I write some reasonably complex stuff (for a solo dev) and a "very large" VI is less than 100 kB. Often it's even that big because I accidentally saved a big block of array data in there via a "save as default values" misclick.


Digging through my last project...It looks like a very large majority of my VIs are less than 25kB.  A few more are up to 50kB, including a GUI heavy VI.  I see one at 77kB (not sure why, perhaps from the VIMs it calls).  But the main VI is 248kB.  Yes, it is a large state machine to do a full test sequence.

 

@BertMcMahan wrote:

You don't indicate how you use globals, but I'd recommend using zero of them. They're acceptable for "write once read many" usage for things like config loaded at the beginning of the program, or language conversions, but I still don't ever use them.


As the one who made a defense of Global Variables at NI Week 2016, I will state that I rarely use them.

 


@BertMcMahan wrote:

You also need to drastically reduce your local variable usage. A reasonable, attainable goal is zero for 99% of your VI's. Every once in a while you wind up needing one, but using that many locals indicates you're not "thinking dataflow". Your wire is the variable, not the terminals.


The only real places I find that I need Local Variables are for GUIs, and that is usually because an indicator needs updated in more than one event case.

 

But what really scared me with those statistics is the depth of nested structures (29!).  That just screams "STATE MACHINE" and/or "SUBVIs".


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 7 of 20
(1,044 Views)

I have read everything and sincerely accepted that I can do better. Getting rid of the locals is difficult. One of the first things that is done is I download about 700 variables from an SQL database. They tell the system which tests are performed, what their specs are, what angles to move the rotary stage, what temperature to go to, which calculations to perform. There are some 26 different defined tests, which are turned on or off with boolean variables. It seems so much easier to download them all at once, and use them throughout the program when they are needed. I will work on small sections at a time, and start reducing everything. I do have an upper code size limit, and have shrunk the programs numerous times so I can add more code. Over time I will continue to shrink these huge vi's. I was given some very good information today, and I will do my best to use what I have learned. I have a long way to go.

0 Kudos
Message 8 of 20
(1,037 Views)

I work on some very large and complex systems and I use 0 global variables and possibly a handful of local variables. The local variables are generally only used in code dedicated to UI operations since writing to a local variable is much more efficient than using a property node.

 

The systems I work on consist of 100s of classes, close to 200 PPLs supporting a plug-in architecture and utilizing a DB backend which manages data for product testing. A single product has a little over 200,000 tests. Basically what I am trying to say is that none of that code has extremely large VIs. In fact, most are extremely simple. There isn't a single stacked frame structure in the code. There are very few frame structures. They are only used to force dataflow where none exists. A well designed system should be very pleasant to look at. Not only will it work well but it will be well organized, easily understood, be very module and support a great deal of re-use.

 

Here is a basic sample of what our typical VI looks like.

Sample VI.png

 

 

I should add that I looked at our VIs and most are less than 30 KB. Larger UI state machines are about 150 KB. It should be noted that we separate are compiled code from the source. Not sure how much that would increase the size if it was included.



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 20
(1,032 Views)

I am including a large program, just so you can see what mine look like. I won't include the sub vi's but this is what I have been doing. I accept that I can, and will use what I have learned to do better.

Download All
0 Kudos
Message 10 of 20
(1,024 Views)