LabVIEW Idea Exchange

Community Browser
Top Authors
cancel
Showing results for 
Search instead for 
Did you mean: 
Post an idea

Hi,

it would be a great idea to choose an option to put a LV icon on the taskbar when LV is minimized (when running a program), also try to eliminate the 2 windows when open an running a "vi", with one is too enought ...

Thanks !!!

Hi,

 

it would be a great idea to choose an option to put a LV icon on the taskbar when LV is minimized (when running a program), also try to eliminate the 2 windows when open an running a "vi", with one is too enought ...

 

Thanks !!!

I'm cleaning up some code that has a lot of stuff like this (much simpler sample code shown):

Loops

The loops are (almost) the same. The normal way to clean this up would be to create a subVI like the following:

Normal

But this has problems. (1) Need to create reference on the calling diagram (2) Reading and setting values by reference (3) Doesn't handle the third loop which has an absolute value. You could deal with #3 by dynamically calling a subVI or having a case structure with an input, but that complicates the design and doesn't make it as flexible (reusable).

 

What if we expanded the idea of inline VIs introduced in 2010. Instead of the compiled code being added to the calling VI, the actual G code is added with input substitutions and then compiled. The 'Macro VI' is replaced by the code inside the VI and the gray placeholder controls/indicators are replaced by the calling VI controls and indicators. This is different from the current inline implementation in that the macro code would be reading the controls/indicators/locals during each iteration instead of just getting the values when the subVI was called. (I believe that is how things are working now, correct me if I'm wrong).

Macro1.png

To handle sections of code that might be different, we could add something like 'code fragments'. Here's an example:

Macro2.png

The orange 'code fragment' gets replaced if wired. The inputs/outputs of the code fragment would have to match.

 

I realize there are issuse if the input controls/indicators have branched wires, etc. Just throwing it out there.

My idea is to enable access logging for the Application Web Server.

 

In this way access to a web service can be analyzed which is also useful in debugging timing or performance problems of your application. To facilitate easy analysis, industry standards like the "common log format" or "combined log format" (link) should be used, then analyzer tools like AWStats can be used. The Appweb Embedded Web Server, which is the core of the Application web server, does already support logging so getting this running should be easy.

Whenever we create an executable file for example, abcd.exe from abcd.vi that can be run on a computer having the runtime engine of the corresponding labview version, it has certain default data control set at the time of creating the .exe file. I propose that there be an option to set the values default after creating the executable file.

As of now Labview Mathscript can handle only 2 indices. for example:

Mathscript can execute the following

for i = 1:10

    for j = 1:10

        B(i,j) = i+j

    end

end

but it can't do the following:

for i = 1:10

    for j = 1:10

        for k = 1:10

            B(i,j,k) = i+j+k

        end

    end

end

 

I propose that Matscript should handle more than 2 indices.

The output then would be a 'n' dimensional array, where 'n' is the number of dummy indices.

It would be great to have possibility to change/edit the code when a VI is running in "Suspend when called mode".

I mean when the VI is "paused" and waiting for you to press the "run" button, right there, possibility to edit the code for that VI and run it ones, change a little bit and run it again and again...

 

I know that this means a lot for the NI developer team to solve..Smiley Wink

But what a functionality when you are into fault finding and testing out of new developed code! ! !

 

++++++++++++

I propose a property node to tell if a control was wired when This VI was called as a subVI.

 

Wired.png

 

Sometimes it is practical to be able to distinguish if the value in a control was wired to it (data arrived via dataflow), or if the control was unwired and the value hence the control's default value. Even comparison with the known default value of the control isn't enough, as the program logic may depend on the value source.

 

Consider an FG that stores two data elements:

 

FG.png

 

You'll have to have two Set functions for this, one for Data 1 ("Set data 1"), and one for Data 2 ("Set data 2"). If you have only one Set function, you add the constraint that both data sets have to be present (wired) every time you set any of the two data sets, or else the unwired set will get overwritten in the FG with the default value of the unwired control. If the FG could decide programmatically if the value was wired to the control, or if it was merely the default value of the unwired control, it could decide whether to overwrite its stored copy or not. The data values could be the same in the two cases, but the actions very different. This is just a simple example, but I have many much more complex cases, that would get much simpler if I could tell where the control value came from. In the above example you could even dispose of the Function input alltogether, if I could tell if any data inputs were wired.

 

A polymorphic VI will remedy some of these issues, but not all, and in other cases a polymorphic VI is a drastic solution to a simple problem. It's also not an issue in a Top-level VI, as such run only once (only subVIs get called again and again, while depending on prior runs).

LabVIEW should be able to update property like background color, and so on... for the whole table instead of changing active cell one-by-one.

It's coding difficulty, and very low speed.

reference case structure.jpg

 

 

I have pondered this and not sure it is possible but it would be nice to allow using case structures to work with vi server references.  It is very tedious to test each type with a cast to more specific and the for each type and check for error (current method or itterating through the class hierarchy).

I know that subclasses pose an issue, I would like to see for the case structure to limit each case to select the highest level (ie g object) and the distince cases are error or any direct class child of the specified parent type class.

 

The Use case I see is for handling itterating through controls from an array of controls (if the control is a boolean do something different than if the reference is to a string control).

Could be very nice for scripting.

 

 

 

 

 

Maybe there is a very good technical reason why this idea is not a good one.

 

Problem: If I want to load a vi into my application the subvi's of the dynamically loaded vi can not be found.

 

My Plug-In Application (EXE) is Not Calling My Plug-Ins Correctly

 

Solution: Add a boolean input (or an options flag) to Open VI Reference which will load the vi and modify the search path so the subvis can be found.

 

I know there are several workarounds but I would like this to be easier.

If you click on the calendar button of a date & time control all updates of the user interface and all functions that happen to run in the user interface thread are halted/blocked.

This is, as far as I know, because the calendar is really an ActiveX control...We need a native control that does not show such behaviour (especially considering the fact that things like the run method is running in the user interface thread...).

 

It is quite ugly that such a fundamental control as the date & time control depends on code that will block the GUI. 

The Run Method is pretty much the only option we have in LabVIEW to scale an application dynamically by instantiating new VIs - but there is one big catch - for some reason it requires the unser interface to be idle(!).

 

Related methods like setting control values e.g. do not have this requirement so they do not pose a problem - but the main method for dynamic instantiation does - and can be blocked by something as simple as a user that opens the calendar view of a date and time control (which of course never should do this either, but that's another issue/idea).

 

Personally I use the run method to create new trend windows (you never know how many trends a user wants to see at the same time), create session handlers for remote clients etc. The times it is used to actually create user interfaces it is not a big problem that the run method is in the user interface thread, but for session handlers and other things that needs to be created in the background based on requests from the outside? A HUGE issue.

By using the VI-server reference "pane" > you will obtain a array which contains a reference for each used element. This VI-server reference can be wired in any sub-VI, to check for example the state (value) of a element. Into the respective sub-VI the array function "Array Index" can be used to check the value of the element. Everything will work fine, until you put another element into your frontpanel. At this point, LabView change the order of the reference array. Now the user wish to have a function, to edit the reference number of each element (like "Change order of elements in cluster"). The problem remains, even if the new element will be deleted.

Create a Panel Open event.

 

PanelOpenEvent.png

 

Among other things, it would provide a clean entry point for guaranteeing Control References have been created, allowing for their dynamic event registration to prevent errors such as the following:

 

PanelOpenError.png

How many times have you created a sequence structure with two milisecond timers around a section of code to see how fast it operates.  Now the VI Profiler works great if you are only looking at whole VIs, but there are lot of cases where that the VI level is not granular enough.  A great feature would be a Benchmarking Probe.  It would work similar to a Breakpoint. It would have a Benchmark Probe Manager similar to the Breakpoint Manager in which you can enable/disable/delet benchmarking probes (very useful when you need to quickly see if the benchmarking code itself is adding excessive overhead).

 

Unlike a breakpoint or a probe, it requires two icons a Start/Stop of where you want to take a measurement. I would imagine that there would be two ways to insert the benchmark probe, one method would be similar to how insert a Breakpoint (in fact you could simply use the breakpoint tool and just add a right click option to convert to a benchmark probe). Once you clicked on the Wire that you wanted to "Start" the benchmark, the mouse icon would change to a the "Stop" benchmark icon and you would choose the place to Stop the benchmark. Of course if those two points weren't "In Place" and "Sequential" with each other, LabVIEW wouldn't allow you to place it.

 

Another method could be simply highlighting the area of code you want to benchmark and then right-clicking on the hgihlighted section, you would get an additional pop-up menu item for adding a benchmark, this would automatically place the two benchmark icons.

 

The Benchmark manager would give options of viewing the Total Time, Average Time, number of Runs in miliseconds, microseconds,etc in addtion to being able to enable disable, delete benchmarks.

 

benchmark.png

Currently with LabVIEW Scripting you can very easily create an event structure and add new event cases to the event structure.    Unfortunately, for some reason, you cannot programmatically configure the event case after it's created.  I think there should be some way, via property nodes, invoke nodes etc, to accomplish this.

 

idea.png

 

PS..  I would love to be wrong about this.  If you know of how to do that, feel free to argue it in the comments and we'll get this closed as completed 😄

Idea is while loops with time out condition. That means if the maximum duration is exceeded, loop stops executing the code inside and gives a time out error. So we don't have to check the maximum iteration number or time passed inside the code and it prevents unexpected long execution timing.

Timed Out Loop.jpg

 

 

All right, due some technicalities of the LabVIEW Idea Exchange forum, I am reposting this idea with the attachment I was planning to add in part 2 attached to the first part (why is it possible to insert images in a comment but not an attachment is beyond my understanding). There will still be 3 parts to it (assuming each of them fits in the maximum allocated size per post), plus an appendix.

 

This post is intended to present a solution to a problem that I was struggling with using LV2 global variables in my applications.

I don't claim that this is a unique or elegant solution or even the first of its kind, but I'd be curious to hear comments and suggestions about it.

Since it might be a long post, I will split it into 3 parts. Part 1 will discuss the intended functionalities. Part 2 will present my current implementation. Finally, I will try to summarize all this into Part 3, opening the discussion.

So you may want to wait until that part is published before posting your comments (if any).

 

Part 1: What do I mean by Generalized (LV2) Global Variable?

 

The LV2 global variable (or functional global, FG in short) is a well known structure (see for instance the beginning of this thread). It is a subVI which can store data locally in between calls. Usually it comes with a "Write" (or "Set") action and a "Read" (or "Get") action and a few inputs (and the same number of outputs). The inputs are the variables you want to update and the outputs, their corresponding values. The advantage of this design over the standard LV global is that there is only one copy of your variables in memory. If you are only using scalars or string, etc., using LV globals might not necessarily be a big problem, but if you start storing arrays of large data structure, it could result in a significant performance penalty. Note that there are other ways to pass data from VIs to VIs (queues and notifiers). Here, I am concerned with long term storage available from many parts of an architecture (e.g. subVIs or dynamically launched Vis).

To begin with, there are two major limitations with any design based on FG (at least that I am not happy with):

1) First, as emphasized above, due to the limited connectivity of a VI's connector pane, a FG cannot store a large number of variables. You can use clusters, but that is not always very practical.

2) Second, if you try to cramp as many variables in a single FG, you will probably run into the issue that you don't necessarily want to reset all variables at once, but maybe just one or two. That calls for a more sophisticated set of actions (Write Variable 1, Write Variable 2, etc, and possibly Write All, Clear All, etc).

In practice, if you use a lot of those FG, you will encounter a third problem:

3) In which FG did I store this @$%&! variable?

Some of my applications contain many of these FGs and I figured that this had become impractical to handle when I started duplicating them, having forgotten that I was handling variable "X" in an existing FG.

The obvious solution (apart from NOT using FGs) is to have a single FG that is designed such as to handle an unlimited number of variables of ANY type that can be modified at ANY TIME from ANYWHERE.

 I first looked at the WORM (Write Once Read Many) design of tbob (you’ve got to go to the end of the thread to download the final version of the WORM VI). It is a very clever and compact solution to store different types of variables within a single variant.

Two of the limitations I saw in this design are that you need to know:

1) the NAME of the variable you want to access.

2) the TYPE of the variable that you are WRITING or READING.

Let me clarify those two points.

It seems obvious that you HAVE TO know the name of the variable you are interested in. Well, that’s maybe true when you are designing your application. But after a month or more doing other things, it is not obvious anymore whether you’ve stored the number of components as “# Components” or “Component #” in that other part of the program that…where did I save it, BTW? You get my point…

The second point is apparently taken care of by tbob’s solution of outputting the variable (as a variant) as well as its type. The problem is that this “type” provides a very limited description. For instance, what do you do with a “cluster” type?

Finally, since I want to be able to modify any variable at any time, the “Write Once” feature is not cutting it for me. This is could be easily modified, but considering the previous comments, I decided to change the architecture some more. I will describe my solution in the next part.

 

This post is intended to present a solution to a problem that I was struggling with using LV2 global variables in my applications.

I don't claim that this is a unique or elegant solution or even the first of its kind, but I'd be curious to hear comments and suggestions about it.

Since it might be a long post, I will split it into 3 parts.

Part 1 (below) will discuss the intended functionalities.

Part 2 will present my current implementation.

Finally, I will try to summarize all this into Part 3, opening the discussion.

 

So you may want to wait until that part is published before posting your comments (if any).

 

Part 1: What do I mean by Generalized Functional Global (or GFG)?

 

The LV2 global variable (or functional global, FG in short) is a well known structure (see for instance the beginning of this thread). It is a subVI which can store data locally in between calls. Usually it comes with a "Write" (or "Set") action and a "Read" (or "Get") action and a few inputs (and the same number of outputs). The inputs are the variables you want to update and the outputs, their corresponding values.

The advantage of this design over the standard LV global is that there is only one copy of your variables in memory. If you are only using scalars or string, etc., using LV globals might not necessarily be a big problem, but if you start storing arrays of large data structure, it could result in a significant performance penalty.

Note that there are other ways to pass data from VIs to VIs (queues and notifiers). Here, I am concerned with long term storage available from many parts of an architecture (e.g. subVIs or dynamically launched Vis).

To begin with, there are two major limitations with any design based on FG (at least that I am not happy with):

 

1) First, as emphasized above, due to the limited connectivity of a VI's connector pane, a FG cannot store a large number of variables. You can use clusters, but that is not always very practical.

 

2) Second, if you try to cramp as many variables in a single FG, you will probably run into the issue that you don't necessarily want to reset all variables at once, but maybe just one or two. That calls for a more sophisticated set of actions (Write Variable 1, Write Variable 2, etc, and possibly Write All, Clear All, etc).

In practice, if you use a lot of those FG, you will encounter a third problem:

 

3) In which FG did I store this @$%&! variable?

 

Some of my applications contain many of these FGs and I figured that this had become impractical to handle when I started duplicating them, having forgotten that I was handling variable "X" in an existing FG.

 

The obvious solution (apart from NOT using FGs) is to have a single FG that is designed such as to handle an unlimited number of variables of ANY type that can be modified at ANY TIME from ANYWHERE.

 

I first looked at the WORM (Write Once Read Many) design of tbob (you’ve got to go to the end of the thread to download the final version of the WORM VI). It is a very clever and compact solution to store different types of variables within a single variant.

Two of the limitations I saw in this design are that you need to know:

 

1) the NAME of the variable you want to access.

 

2) the TYPE of the variable that you are WRITING or READING.

 

Let me clarify those two points.

 

It seems obvious that you HAVE TO know the name of the variable you are interested in. Well, that’s maybe true when you are designing your application. But after a month or more doing other things, it is not obvious anymore whether you’ve stored the number of components as “# Components” or “Component #” in that other part of the program that…where did I save it, BTW? You get my point…

 

The second point is apparently taken care of by tbob’s solution of outputting the variable (as a variant) as well as its type. The problem is that this “type” provides a very limited description. For instance, what do you do with a “cluster” type?

 

Finally, since I want to be able to modify any variable at any time, the “Write Once” feature is not cutting it for me. This is could be easily modified, but considering the previous comments, I decided to change the architecture some more.

 

I will describe my solution in the next part.