From 04:00 PM CDT – 08:00 PM CDT (09:00 PM UTC – 01:00 AM UTC) Tuesday, April 16, 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: 

Micro-Nuggets !!! ~~~~ Post 'em if you got 'em


@altenbach wrote:

Can you elaborate on your diagram comment for the need of two FOR loops. Since your are indexing over the same array, shouldn't the iterations always match?


Argh! Smiley Mad Thanks Altenbach. That was a modified older file. It "works" so I didn't think twice after I ran it then decided to post it. There were a few things missing in the old one as well.

 

Let's try again....

 

Preview New.png 

 

 

 

.

Richard






Message 61 of 361
(9,916 Views)

Here's a more complete list which was generated using a private method. It looks like there are ~280 classes in total and about 140 of those are BD classes. The BD classes seem to occupy the upper bit of an I16.

 

Classes.png


___________________
Try to take over the world!
0 Kudos
Message 62 of 361
(9,884 Views)

What I was trying to provide was a way to view the ClassID, the ClassName, and a picture of the item in question. Below is a representation of what I was trying to achieve by placing the items directly on the BD.

 

There are some surprises in there....  Is it intuitive that "GenClassTagRefConstant" is the ClassName for for the System Host?

 

Why is an Expression node just "Node"?

 

Decimate 1D Array = "Bundler"

 

Array To Cluster = "ArrayToCluster" but...Cluster To Array = ""Function" Smiley Mad

 

BD List with Pics.png

 

Richard






0 Kudos
Message 63 of 361
(9,846 Views)

Nice.  You're probably better off using Traverse for GObjects though, which will recurse into any structures.

 

 

 

Also, there are some Class IDs which can have multiple Class Names - for example, all the Express Nodes and XNodes have the same ID but different names (at the moment, your list of Names and IDs might not be the same length, or match up properly).

Message 64 of 361
(9,809 Views)

I see the question of stopping multiple loops posted a lot. Here is the most recent example - stop button do not work.

 

This micro nugget has the following goals:

 

  1. Demonstrate the usage of libraries and access scope
  2. Demonstrate the usage of Functional Global wrapper VIs
  3. Demonstrate usage of these concepts to create a simple API to shut down multiple loops

The assumption of this micro nugget is that the behavior of an uninitialized shift register is understood. I will not attempt to outdo Ben on his Community Nugget. If a novice LabVIEW user is getting to the point to where he or she needs multiple loops, this is a good time to learn about the concepts presented.

 

There are a lot of methods to signal loop shutdown and this is probably not the best. But it is probably the most simple acceptable way. It uses a Boolean Functional Global Variable. It also demonstrates how I like to privately scope FGVs in a library with public wrappers for the API.

 

Privately scoped items can only be used by other items in the library. In this example the FGV is only available to the wrapper functions which are Publicly scoped. You can modify the private items any way you want. After testing the public API you can redeploy the library and your applications that use it will work. If the applications directly use the FGV they would break if you modify it or remove it.

 

To change access scope you right click on a library item and select Access Scope. There are three - Public, Private and Community. Community scope will not be discussed here.

 

In a real application I would probably use a shutdown message with a notifier or queue instead. But I wanted to demonstrate this particular technique. I also want you to understand that since the FGV is private it could be removed and replaced with a notifier or other technique without breaking the applications which use the library. You can modify the inner workings of the API but the inputs and outputs stay the same.

 

I always call any privately scoped FGV or Action Engine "core.vi". The actions for this one are:

 

  • Initialize - sets the global stop to false
  • stop - sets the global stop to true
  • check - returns the global stop value

I always set the command enum to input required. Here is the Global Stop core.vi

 

Global Stop.lvlib_Core_BD.png

 

I created three wrapper VIs - one for each action. I do this for several reasons.

 

  • I do not like the command constant to be publicly exposed
  • It is easy to accidentally modify the constant when moving it if you use the autotool
  • I do not want to see the command constant. i would rather have an icon indicate the function
  • I do not want the constant taking up valuable space on the block diagram. I am a real neat freak when it comes to the block diagram!
  • I like to have only the inputs and outputs of the function that are needed for that function. A complex action engine can have several terminals while the individual functions only need one or two.
  • And most importantly I want to be able to change how the functionality is implemented and know that I only have to test the wrapper VIs. I could change this to use a notifier instead of a FGV sometime in the future. My applications will be none the wiser.

Here are the three wrappers.

 

Initialize

 

Global Stop.lvlib_Initialize_BD.png

 

Stop

 

Global Stop.lvlib_Stop_BD.png

 

Check

 

Global Stop.lvlib_Check_BD.png

 

I have a test VI to demonstrate the use of this library.

 

Test Global Stop_BD.png

 

Attached is a project containing the Test Global Stop VI and the Global Stop library along with the two SubVIs in LabVIEW 8.2 format.

 

=====================
LabVIEW 2012


Message 65 of 361
(9,748 Views)

I really like this approach Steve - wrapping the FGV's. Moreover, there's no errors to handle, such as when using Notifier or Queue errors to stop loops, like I do did. Smiley Happy

 

Richard






0 Kudos
Message 66 of 361
(9,695 Views)
Ah yes, the error trick. I did that until I realized that is like stopping a machine by throwing a wrench in it.

One benefit that I forgot to mention is documentation is a lot easier. You can document the individual functions in the wrappers instead of trying to fit it all in the FGV.
=====================
LabVIEW 2012


Message 67 of 361
(9,697 Views)

A really simple one, that I'd probably have known if I'd read the manual...

Adding two numeric clusters (e.g. position of a control) sums the corresponding elements, no need to separate them out and rebundle:

cluster.png

 

I'll pay credit to Darin.K for this - used in his angry bird game (which I've only just looked into after downloading an eval version of 2010... hmm, I'm cleary behind the times in more ways that one as it sounds like 2011 is here!)

Message 68 of 361
(9,642 Views)

I discovered recently that when working with a cluster on the front panel, if you group multiple elements they will stay together when the cluster is autosized.  This means if you have, say, a cluster of 6 numeric values and you want it arranged in rows of 3, you can autosize the cluster for horizontal alignment, select 3 elements at a time and group them together, then autosize the cluster for vertical alignment.

 

step 1.PNG

 

step 2.PNG

 

step 3.PNG

Message 69 of 361
(9,601 Views)

Re: Steve's Micro-Nugget

 

I really like this micro-Nugget and would like to add another benefit to the list.

 

When we develop our Action Engine we may not the only user of the AE and are faced with the chalenge of try to ensure our AEs are being used correctly to;

 

1) reduce frustration for the users of our AEs

 

2) make it clear when they have been used inappropriately

 

3) and avoid those cries from the Bull-pen that would start with phrases like "Ben, your AE did ...!"

 

By creating wrappers for our AE we (the developer and most knowlegable re: the AE's inner working) can ensure the AEs are being used correctly.

 

Example:

 

 

As shown above my GUI Controller Core is initialized inside a wrapper. Since the GUI Controller may not be used until latter in the code, a failure to properly define the control references COULD result in an error far down the road.

 

Knowing this I include logic in the "Init" action  wrapper to check to ensure the refs are defined before I proceed.

 

This little bit of "extra" has saved me time on multiple occasions when I added anothe control and forgot to why the ref.

 

Thank you very much for reading and...

 

THANK YOU STEVE for the Micro-Nugget!

 

Ben

Retired Senior Automation Systems Architect with Data Science Automation LabVIEW Champion Knight of NI and Prepper LinkedIn Profile YouTube Channel
Message 70 of 361
(9,538 Views)