LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Avoiding LabVIEW 8.X File Layout

Solved!
Go to solution

I have been trying to start a new project where the file layout is EXACTLY as per the attached Project. Its built using LV2015.  And it compiles , and the EXE runs fine. 

 

This is what it will do :

Launch a Start up VI with on option to " PROCEED" . On clicking it, it launches another main VI passing the File Path through a FG. That VI just shows date and time. ( By any standards not a great APP !!) 

Once the main VI is stopped the application closes clearing the memory. 

 

The only catch here is the use of LV8.X file structure when building the EXE. If i remove the tick mark from it, the EXE does not work. 

 

I do have read all the ills of using such a flat file structure.( file name clashes etc) . But quite really do not know how to go about without using this given the file structure as i have for the VIs. ( My final application will have an  exact structure )

 

Any help appreciated. 

 

Raghunathan
LabVIEW to Automate Hydraulic Test rigs.
0 Kudos
Message 1 of 6
(3,025 Views)

There are many strange things about this code, including (a) stopping VIs using Exit (should almost never do this), (b) having a StartUp VI whose sole purpose is to start another VI, (c) stopping VIs using an Abort VI (instead of just having them stop by executing the last function), (d) using local variables to initialize LabVIEW Indicators to their default values, (e) ignoring data flow in doing Step (d), (f) having an Error Line that looks like a zig-zag snake instead of a straight horizontal line, (g) using Mouse Up for Proceed (both should be Value Change, and you should use Latch Until Read, with the Control inside its Event), etc.

 

I'm guessing you have a reason for doing this, but it is not obvious.  If you really want to run VIFilePath as your "Main", with a pop-up window that offers "Start" or "Abort" buttons (inverting the logic of your design, where the "Main" is your Startup routine that decides whether or not to run VIFilePath), the logic becomes much simpler.  Your Build has no "Always Included" elements, and your StartUp becomes VIFilePath.  It starts by calling "Startup", which returns "True" if the user presses "Start", "False" if the user presses "Abort", and simply exits when either is pressed.  VIFilePath looks at the Boolean, and if True, does whatever, with the False case being "Do Nothing".  If it's inside a While Loop, when you stop the While Loop, everything stops and the program exits.

 

This structure does not need (and should not have) the 8.x File Structure for an Executable.  It is a much simpler structure, and will certainly work.

 

Bob Schor

0 Kudos
Message 2 of 6
(2,963 Views)

@Bob_Schor wrote:

There are many strange things about this code, including (a) stopping VIs using Exit (should almost never do this), (b) having a StartUp VI whose sole purpose is to start another VI, (c) stopping VIs using an Abort VI (instead of just having them stop by executing the last function), (d) using local variables to initialize LabVIEW Indicators to their default values, (e) ignoring data flow in doing Step (d), (f) having an Error Line that looks like a zig-zag snake instead of a straight horizontal line, (g) using Mouse Up for Proceed (both should be Value Change, and you should use Latch Until Read, with the Control inside its Event), etc.

 

I'm guessing you have a reason for doing this, but it is not obvious.  If you really want to run VIFilePath as your "Main", with a pop-up window that offers "Start" or "Abort" buttons (inverting the logic of your design, where the "Main" is your Startup routine that decides whether or not to run VIFilePath), the logic becomes much simpler.  Your Build has no "Always Included" elements, and your StartUp becomes VIFilePath.  It starts by calling "Startup", which returns "True" if the user presses "Start", "False" if the user presses "Abort", and simply exits when either is pressed.  VIFilePath looks at the Boolean, and if True, does whatever, with the False case being "Do Nothing".  If it's inside a While Loop, when you stop the While Loop, everything stops and the program exits.

 

This structure does not need (and should not have) the 8.x File Structure for an Executable.  It is a much simpler structure, and will certainly work.

 

Bob Schor


The code I posted is for sure is not the deliverable. Its a sample one with the same structure as the final one and my main objective was to build it without using LV8.x file structure.

 

The StartUp vi is the LOGIN vi in the actual code and so its position cannot be altered.

Hence the StartUp and VIFilepath order cannot be changed.

 

Its all fine to look at Local variables as enemies in a data flow environment. But if care is taken to avoid a race condition they are simple to use. And exactly for this reason I could not use the Latch mode for the buttons.

 

And so with the case of Abort method - its one sure way to make sure that memory is cleaned up ? Maybe I am wrong in this assumption.

 

Finally this is sample code and for sure does not need all wires to be straight and such. I appreciate your points as they are constructive and point to good design practice.

 

Still my main issue remains - how to build this without using LV8.x. file structure. Will be happy to know.

Raghunathan
LabVIEW to Automate Hydraulic Test rigs.
0 Kudos
Message 3 of 6
(2,938 Views)
Solution
Accepted by topic author MogaRaghu

OK.  I think I have solved this for you.  I've attached my Project as a ZIP file, and I'll also walk you through the key steps.

 

First, the only VI of yours I kept was FG_Str_Status.  By the time I finished, however, I realized that I didn't need it, nor did I need the VI you called CurPathToString, which you appear to use only for starting and stopping the Main VI and the "Daughter VI" that does the actual work.

 

The next thing I did was rewrite CurPathToString (which I called Top VI Path) to do only one thing -- return the Path to the vi that is the Top VI in the Call Chain at the time of Call.  Unlike your CurPathToString, I did not return both Path and String, nor did I strip the Top VI Filename from the Path.  As it turns out, this VI is also not needed (but I kept it in to demonstrate what I think are better ways of getting the path strings to the Top Level VI and its Daughter).

 

Which brings us to the Top Level VI, here renamed Demo BS.  This has a Front Panel resembling yours, with a string, VI Path, that will show the (otherwise-unused) full path to this VI, a Proceed button (with proper Latch until Released Mechanical Action) and an Abort button (also Latch until Released).

 

The VI itself is a simple Event structure, with a TimeOut loop (set to 100 msec that "does nothing" but actually has a function that you can discover if you make the TimeOut really long), a Proceed "Change", and an Abort "Change".  Here's a Snippet through the Proceed Event, with explanation to follow.

Calling VI.png

So I noticed that one complication in your code was stopping the VIs -- you tended to use Abort VI, generally not a Good Idea.  So here is another "Bad" Idea, using a Global, "Stop All", to stop all of the loops.  Note, however, that Wiser LabVIEW Gurus than I have disabused me of the notion that Globals are dangerous ...

 

In earlier versions of LabVIEW, one used VI Server to start VIs (as you are doing).  This (as you've discovered) can lead to awkward code, and Problems Building Executables.  I don't remember when Start Asynchronous Call was introduced, but it makes running detached VIs, either in Development Mode or from Executables, a piece of cake.  Here's how it works:

  • Create a Static VI Reference (found on the Application Palette).  Right-click it, choose Browse for Path, and find the VI you want to run (here I chose DEMO Called VI).  Right-click again, and choose Strictly-Typed VI Reference (this puts the Star on the Icon).
  • Drop down a Property Node.  Wire the Static VI Reference to it (watch out, it will expand), and choose the Path Property.
  • Drop down an Open VI Reference.  Wire the VI Reference Out (top wire) from the Property Node to the Type Specifier RefNum (on top of the Function).  Wire the Path to VI Path.  Wire 0x80 (Prepare for Call and Forget) to Options.
  • Drop down Start Asynchronous Call.  Wire the VI Refnum to its input, and wire its output to Close Refnum.

When this code executes, it will start the referenced function (here DEMO Called VI) running.  However, most VIs run without showing their Front Panel, and you want to see the Front Panel when DEMO Called VI runs.  You need to change two VI Properties on this VI, which I usually do in Development mode.  Open the VI (DEMO Called VI), open its VI Properties (right-click its icon in the upper right-hand corner), choose Window Appearance, click the Customize button, "check" Show Front Panel when Called, "uncheck" Show Front Panel when Loaded, and decide if you want to Check or Uncheck Close Afterwards.

 

Now let's talk about stopping these VIs.  In the code shown above, the (not-shown) Abort Event just wires True to the Stop All Global.  Now when the next Event "fires", the Global, wired to the While Loop's Stop indicator, will stop the loop, and thereby stop this VI.  What about the Daughter?  It uses similar logic, with the Global Stop wired to its Stop Indicator.  However, you wanted the Daughter to also have a Stop Button that can Stop Everything.  This is relatively simple -- 

Called VI.png

if either the (local) Stop Button or the (global) Stop All variable are True, we stop the loop, and, for good measure, also set the Global to be True (which stops the Caller if the Daughter's button had been pushed).  I think that is the behavior that you wanted.

 

The best news comes when you build.  As you can see from the Project, I specify only the Top Level VI in the Build Source Files, with all the other VIs automatically being included (as they are referenced in the Caller).  This code runs in Development mode, and runs as a Built Application, providing the same behavior and output.  The Build does not use the LabVIEW 8.x File Layout, which is what you are trying to avoid.

 

Please test this and verify that it meets your needs and answers the question(s) you posed.  If you agree, please mark this post as the "Solution" so that other Forum users with a similar question can find the Solution easily.

 

Bob Schor

Message 4 of 6
(2,915 Views)

Dear Bob,

Thanks for your time to present a full tutorial. This is a major shift of loading VIs from the VI Server method I was aware off. Thanks.

 

Just so that I understood the concept you put across,  I worked on it to create one more level of Sub VI.  Actually all my projects are  like this only and the structure is outlined below :

1. LOGIN.VI : This is the Top level VI which first loads and takes the user credentials Once the same is done, it calls the Main.VI.  The FP of Login.VI is closed.

2. The Main.VI is the critical user interface from where he can branch off to other SUB.VIs based on need . The Main.VI has all code to handle DAQMx data acquisition and passes the collected data via Queues to the SUB.VIs. This the user can navigate to different SUB.VI based on his need. And to go from one to another SUB.VI he has to come back to Main.VI.

3. Finally the application can ONLY be closed from the Main.VI ( or the Login.VI) and for that your Global Stop is very convenient.

 

I have attached a modified version of the Project which does as above and in line with your idea. I found that I did not have to do anything extra to build the EXE and that's great.

 

The only issue as I can perceive is that in a large project when the user opens and closes many SUB.VIs ( some of my projects have about 30+ SUB.VIs) then many SUB.VIs will be in memory. Why not remove them from memory once done with ? Like in our case after the Login has happened there is no requirement for that VI to be in memory ??

 

Let me know your views.

Raghunathan
LabVIEW to Automate Hydraulic Test rigs.
Download All
0 Kudos
Message 5 of 6
(2,896 Views)

I'm glad you were able to take this "Demo" code and incorporate it into "what you really want to do".  About 5-6 years ago, I was also using VI Server to run "detached clones", but found problems when building executables.  Then I learned about Start Asynchronous Call, and never looked back!

 

There are, in fact, ways to load code into memory and then unload them when you are done (look up "Plug-in architecture").  Here's the thing, though -- memory (on a PC) is relatively cheap, compared to your Time and Effort.  I'd say that it is (probably) better to spend time on developing good algorithms and Getting The Task Accomplished than worrying about "wasting memory" (unless you "run out", which could happen, but I'm guessing won't).

 

Bob Schor

0 Kudos
Message 6 of 6
(2,885 Views)