Labview: creating subVIs makes the Block Diagram expand - labview

I wrote a rather complicated piece of code in Labview (with many loops and other sequences). Therefore I want to create many subVIs to make my code more clear.
When I have a loop in the code I want to have in a subVI, the icon of the newly created subVI appears far away form my original piece of code, causing my Block Diagram to expand.
Why does it happen and how can I avoid it?
The piece of code I want to turn into a subVI:
The same fragment of my Block Diagram after I created the subVI:
And here is my newly created subVI - approximately 1 m to the right at 1 m down in comparison with the first piece of code:

Thanks for adding images -- that is quite an inflation of the block diagram.
I don't know why LabVIEW is behaving that way, but my guess is that the control and indicator references are contributing.
As for ways to prevent it from happening, aside from refactoring the code (which is likely necessary anyway), you can try turning off automatic wire routing: Tools » Options » Block Diagram » Uncheck 'Enable automatic wire routing'.
Avoid creating subVIs that contain terminals in a structure
However, to move the block diagram's complexity into a sub VI will require some refactoring because you want to include a while loop that changes behavior based on front panel input (like the stop abs 2 boolean button). Otherwise, whatever value stop abs 2 has when the new sub VI executes will not change while it's running.
The LabVIEW Help reiterates this point: "Because the terminal remains on the original block diagram and the terminal is wired to the new subVI, the subVI does not update the value of the terminal on every iteration of the loop inside the subVI."
Here is an illustration.
Communicating with running subVIs
To send input and receive output from a sub VI while it is executing requires some data synchronization like queues or notifiers. Typical design patterns for this include:
Producer/Consumer on the targeted and simple side, to
Queued Message Handler in the middle, to
Actor Framework on the general and complex side.

Related

Include a large amount of SubVIs in a main VI

I have a large amount (about 50) of SubVIs including beyond some usage specific code a small number of GUI elements (mostly about 2: input and output).
My goal is to reuse those VIs without creating a huge mess in a new ('main') VI and collect all GUI elements on a GUI common pane a user shall finally interact with.
I tried to use the Open VI Function, 'VI Reference' and 'Run SubVi' like in the examples to create references for subpanels, but the subpanel ui is only shown when the program is run and the amount of additional blocks is mostly bigger than the code in the respective SubVI.
The SubVIs should be loaded only once to construct the main User Interface.
In addition: In this tutorial they create a subVI and recreate GUI elements that are already defined in the subVI.
I assume this behaves like passing arguments as in a text based programming languages like the snippet:
def main_vi(x, y, z): # inputs x, y, z
s = sub_vi(x, y, z)
return s # output s
Is this necessary, or can the subvi's GUI controls directly be reused from outside?
Is it possible to use the subVIs inside of an "main" VI that includes everything and maps everything to a common UI using tabs?
Or is it better to copy everything to the main VI, i.e. no code reuse at all?
Thanks in advance!
Depending on the functionality you are going for, yo may want o look into XControls. This would allow you to encapsulate your functionality into a reusable control that could be used on a main panel without making the main panel very messy.
Large UI's can be a pain (pun with pane not intended), especially if there are a lot of controls and indicators. There are some useful ways to break UIs into modular components. XControls are one of those but I don't recommend them due to their unpredictable behaviors. Instead look into working with Sub Panels. There is a great toolkit for this from a company called Moore Good Ideas (or MGI). More info can be found on their website here.
There is also a better alternative to XControls, called QControls. More info on them can be found here.
In general, though, you might want to look into a more modular framework. More info on Frameworks can be found here.

Labview Program changes behavior after looking at (not changing) the Block Diagram

My Labview Program works like a charm, until I look at the Block Diagram. No changes are made. I do not Save. Just Ctrl+E and then Ctrl+R.
Now it does not work properly. Only a Restart of Labview fixes the problem.
My Program controls two Scanner arrays for Laser Cutting simultaneously. To force parallel working, I use the Error handler and loops that wait for a signal from the Scanner. But suddenly some loops run more often than they should.
What does majorly happen in Labview when I open the Block diagram that messes with my code?
Edit:
Its hard to tell what is happening without violating my non-disclosure agreement.
I'm controlling two independent mirror-Arrays for Laser Cutting. While one is running one Cutting-Job, the other is supposed to run the other Jobs. Just very fast. When the first is finished they meet at the same position and run the same geometry at the same slow speed. The jobs are provided as *.XML and stored as .net Objects. The device only runs the most recent job and overwrites it when getting a new one.
I can check if a job is still running. While this is true I run a while loop for the other jobs. Now this loop runs a few times too often and even ignores WAIT-blocks to a degree. Also it skips the part where it reads the XML job file, changes the speed part back to fast again and saves it. It only runs one time fast.
#Joe: No it does not. It only runs once well. afterwards it does not.
Youtube links
The way it is supposed to move
The wrong way
There is exactly one thing I can think of that changes solely by opening the block diagram.
When the block diagram opens, any commented-out or unreachable-code-compiler-eliminated sections of code will load their subVIs. If one of those commented out sections of code were somehow interfere with your running code, you might have an issue.
There are only two ways I know of for that to interfere... both of them are fairly improbable.
a) You have some sort of "check for all VIs in memory" or "check for all types in memory" that you're using as a plug-in system. When the commented-out sections load, that would change the VIs in memory. Such systems are not uncommon when parsing XML, so maybe.
b) You are using Run VI method for some dynamically invoked VI to execute as a top-level VI, but by loading the diagram, it discovers that it is a subVI of your current program. A VI cannot simultaneously be top-level and a subVI, so the call to Run VI returns an error.
That's it. I can't think of anything else. Both ideas seem unlikely, but given your claim and a lack of a block diagram, I figured I'd post it as a hypothesis.
In the improbable case someone has a similar problem. The problem was a xml file that was read during run time. Sometimes multiple instances tried to access it and this produced the error.
Quick point to check: are Debug and "retain data in wires" disabled? While it may not change the computations, but it may certainly change the timing of very tight loops, and that was one of the unexpected program behaviors, OP was referring to.

Create subvi from output of loop

Labview is very frusturating to me having used C/Java before.
I have a simple problem I dont know how to solve.
My program does some operations in a loop and updates an indicator inside the loop. I would like to make this loop (and the inputs it requires) into a VI but I have no idea how to make the indicator an output of the VI.
I would like to be able to reuse this VI, connect an indicator to it, and have it automatically update without creating any loops outside of the VI.
In C I would be able to do this by either returning a pointer or passing by reference to a function.
Use a queue to move data between loops in block diagrams.
The producer/consumer pattern uses a queue to move the data between two loops on the same diagram, but a queue is global to a VI hierarchy and by naming it when you create it, a second VI can obtain a reference to it by using the same name.
NB: queues are 1:1 and lossless; if you need 1:N data transmission, use a notifier (which is newest-value lossy) instead.
In LabVIEW while loops have simple condition. The value can go outside the loop only when we will meet the condition. There is a condition terminal in the right down corner of the loop.
At general:
1) When true flag will be set there (stop if true) then the value will be passed outside the loop.
2) When the false flag will be set there (continue if true), then the value will be passed outside the loop.
3) You can always use error wires with condition terminal inside the loop, when error will be raised, then loop will stop.
In your case:
Always try to use the smallest amount of while loops as it is possible due to optimalization reason.
1) You can use while loop in your main VI, while all SubVIs will be in this loop and all values (indicators) will be updated.
2) You can try using while loops inside subVIs, but then you have to provide mechanisms that will transport values outside the loop such as queues or local variables
You can make a reference for a labview indicator as well, but you would need to make it a global variable or pass in the reference from the calling vi.
As for your frustrations, you should know that you can pretty much do anything in Labview that you can do in C.
A) The image below shows how to do this.
B) This style of programming works in small applications, but as an application grows larger, I would encourage you to explore an actual architecture for producing data in one hierarchy and consuming it in another (as alluded to by other answers to this question). In particular, do File >> Create Project and choose the Producer/Consumer template to explore a good starting point for such architectures. There are more sophisticated ones, but that makes an excellent beginning.

LabVIEW: missing block diagram

I have a two broken VIs with front panels that open fine, but I can't edit or run them, or open theis block diagrams.
One of these was made as a replacement for the first when it started to have this problem. I need to at least find out how to avoid this problem in future, so I don't lose work on bigger VIs.
I'm not sure if it makes any difference, but I very recently upgraded to LabVIEW 2013.
Thank you in advance.
This is the error I get when I try to run them:
"
VI has a bad connection to or cannot find a subVI or external routine.
This VI has a bad connection to or cannot find a subVI or external routine but
it has no block diagram to show or fix the error. You must find or correct the
subVI or external routine. Check for more information in the Explain dialog box
in Get Info.
"
Before reverting to a previous version (using dropbox) I got a different error with one of them:
"
LabVIEW: Generic error.
An error occurred loading VI 'sweep harmonics first test.vi', LabVIEW load
error code 6: Could not load the block diagram.
"
One situation how this happened.
Sometime LabVIEW crashes, and it restart. After restart, LabVIEW will ask you to recover the autosaved code.
I personally always discard those autosaved code. If you do choose to recover autosaved code, there is a chance the recovered code is corrupted. Once you save corrupted code to disk, you are probably going to lose the ability to open/save the block diagram ever again.
Having a version control system is usually a way to avoid minimize the damage when LabVIEW crashes. At worst, you loose maybe an hour worth of work.
If you can't open Block Diagram of your VI, first check the suggestion by #Rodrigo - it is most likely just a "compiled" VI, which has Block Diagram removed.
If you think there is Block Diagram inside and it is just corruped - you may contact NI support. And if you want to look deeper by yourself, extract the VI to XML using pyLabview, and look into the XML - there you can modify every single part of the VI. For example, you may start removing parts until it starts working.
I wouldn't go into manual VI editing unless you have at least a dozen of affected files though. For a single file, it will be faster to re-create it in LabVIEW instead of trying to understand the internals. If many files are affected - may be worth finding the issue in one, as other files probably have the same glitch, so you can make a script which extracts, modifies and re-creates VIs automatically.
From the sound of it, I believe what happens is that you are trying to run the VI's created as "DATA" for an executable, instead of the actual source VI's.
When you build an executable LabVIEW creates a copy of all the Top Level VI's dependencies into the support (DATA) folder which should be in the same directory as your executable.
Try opening the VI's that are marked as not having a block diagram and navigate to File>>VI Properties to check the path from which the VI is being loaded. If it's not the original VI, you can just replace it.

How to find or create the iteration number box in a For loop

I have a large, somewhat messy For loop in which I can not find the iteration number box. Is there any way of searching for this component or simply creating a second iteration number box?
You can't create a second iterator terminal, but you can use scripting to move the iterator to a typical location (bottom left) with this VI Snippet.
Be sure the file is open before running the script.
This is a bit of a gamble, but you can try the Clean Up Diagram tool and see if that helps. If it doesn't it should still expose the iteration icon, and you can find out what wires it is connected to. Hit Ctrl-Z to undo the clean-up, and double click on the wire indicated previously and it should expose everywhere the wire routes to. Hopefully you can track it down then.
A messy diagram means that sub-vis or an architecture re-design is badly needed.
Depending on what version of labview you are using, you can use Block Diagram Cleanup tool, as mentioned by Austin. But you can also highlight a section of code and clean that up individually. This 'selective cleanup' feature was introduced in 2012.
Regardless, you can't search for an iteration counter. Use your eyeballs...how bad could this for loop be? Hint hint: I want to see it :-)