LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

What are some good tips and advice for effective commenting on a VI?

I'm in the final stages of finishing my first real VI for actual use (it's been an interesting experience, honestly most of what I've learned has been from this forum so thanks!) and I'm considering how to best comment and annotate what I have to make it readable and understandable for any future developers. As I said, I'm very new at this and I don't want to ruin some developers life in a year or two by having bad code. Some specific questions:

 

Variable Names: In text based programming you'd try to keep your variable names logical and informative to make reading code easier. From what I've learned the wires can be labeled or named, and serve a similar role. How do you decide which wires are important to label, and which should be left? Are there any good general practices on how to name them (and specifically, do you just use the label thing or are there better ways)? Same questions for shift registers, etc.

 

Text Boxes: Text based code would have comments to describe the purpose of functions, the operations being done, etc. I could put text boxes around the block diagram, but is there a better way?

 

Non-visible parameters: One of the things that's been hard for me while learning LabVIEW was how many properties and parameters of objects are not defined programatically by default. For example, unless you set up something to do this specifically, an XY graph has dozens of properties defined only in the context window, some of which are important (loose scaling, stuff like that). First off, am I doing things wrong if this is the case, and second is there any way to give some sort of commenting on those properties?

 

Any other ideas: any other things you commonly see people mess up, or things that bug you when you read other people's VI's? How much should I try to make subVI's of parts of a large VI? things like that.

 

Thanks for any advice, and thanks to the forum guys in general! I don't love labVIEW but this is the most helpful software forum I've participated in.

0 Kudos
Message 1 of 11
(2,514 Views)

There are a million ways to comment your VI's, but here are a few:

 

-If a given VI's block diagram extends past one screen, it's a *great* indicator that it's doing too much. Put some of its functionality into a subVI. Keep the "single responsibility principle" in mind- each VI should be responsible for just one "thing".

-ORGANIZE YOUR DANG WIRES. No unnecessary bends. Wires travel left to right and top to bottom. If you're going backwards with a wire, you should have a really good reason to do so. The importance of neat wires cannot be overstated.

-File -> VI Properties -> Documentation: Fill out the description. This shows up in the Help window when you press Ctrl+H.

-Simple labels on shift registers is great, but if it starts to clutter the diagram up, this means you probably need to either combine your data into a cluster in a shift register or make it into a subVI.

-A single text-based label summarizing the operation of a somewhat confusing VI is great. One common technique is to enumerate the functionality in a numbered list, then place small labels in the diagram with a "1", "2", "3", etc where the aforementioned function actually happens. (See this example . Their wiring is decent but could be improved; I'm just using this as an example of numbered diagram segments. It's also used in a lot of the built-in examples in Help -> Find Examples).

-Never use the default icon for programs. Make it something meaningful, even if it's just text on a white background.

-Variable names are not really used in LabVIEW. The wire *is* the variable. Control and indicator names should be informative. Don't try to oversimplify naming; spaces, capitals, etc are great. A control labeled "Scale factor" is perfectly fine, spaces and all.

-I wouldn't worry about the non-visible parameters. If you find yourself needing to customize a specific control to your application, you can configure it like you want in the editor and save it. Typically the default values for most of those settings are fine, but if you want to programmatically edit them it's another great place for a subVI with a Control Reference as an input. That tidies up your block diagram and follows the Single Responsibility Principle.

-Post your code here for comments. Vague style guides can help but having a VI to point to can be invaluable.

Message 2 of 11
(2,507 Views)

We have a guideline in our coding standard that says comments should only be used to explain why code was written a certain way, not how it should operate. That being said, it's a guideline. We also have a guideline that says if you use the Clear Errors VI, you must place a comment that explains: 1) why you're clearing the error and (more importantly) 2) how your code can get into a state where an error is being generated in the first place.

If you find yourself wanting to put a textbox or decoration around a piece of code and put a comment on that... you should probably just make it a subVI. If it is already a subVI, you can add a description of the subVI into the VI Description. This will show when you hover over the VI with context help on. It's a great place for a description of a function, the inputs, outputs, and any errors that the subVI may generate and under which conditions it happens.

If your wires are so long, or there are so many of them running parallel where it's hard to tell which wire is which, you should maybe consider a different design where data is bundled together or private data of a class.

If you have any part of the code that is doing file path or string manipulation, it's helpful to add comments at different stages to show a sample of what the string or path will look like as it goes through the processing. You could also write unit tests for this.

Non-visible parameters: it sounds like you're doing it right. If you explicitly set a property of a contol/indicator and your application depends on that property to function correctly, you should probably document that. A comment on the block diagram near the terminal is as good a spot as any.

 

It's great that you're thinking about all of this, if you want to post a sample of a VI here I'm happy to look at what you've got for comments or where I'd like to see different kinds of documentation being used.

 

Nathan Murphy
Message 3 of 11
(2,501 Views)

These have been great comments so far, thanks! I'm posting the VI, and I think I know what the reaction to it will be. I offer this in my defense; this is the first thing I've done in LabVIEW, and it is still in active development, so things have gotten messy quickly (this version was written a few days ago, before that the block diagram was about two or three screens wide).

 

From the above comments and examples, I'm thinking the first thing to do is work on dividing things into sub VI's and cluster some of the wires. I only learned about sub VI's two days ago when I wrote the trapezoidal integrator sub VI, so I wonder if I could get some more examples of parts of the code to bundle into sub VI's. I guess an obvious one would be the whole data acquisition stage, from querying the Arduino to the string parsing. Maybe all the graphing can be put into one sub VI? Can objects (like the XY Graph) be put into a sub VI and still accessed by property nodes in the main VI or in other sub VI's?

 

I'd be lying if I said I was looking forward to the next day or two of rewriting and sub-VI-ing of this, but at least it'll look better at the end...

0 Kudos
Message 4 of 11
(2,473 Views)

In this instance, I would worry less about putting code into subVIs and more about the bigger picture application design.

 

Looking at the code, I see several things happening depending on other conditions/flags being set, and many of these things happening in parallel. 

 

I would look into well-known architectures like a state machine, or a queued message handler with multiple loops. A good candidate for one parallel loop would be where you have the Alarm playing, you could send a message to that "controller" to "start alarm" and "stop alarm". This way here, the alarm module is totally isolated and all of that code can be pulled out of your main loop. 

 

Using this logic, you can break down your application into the various "subsystem controllers" and then create a main top-level controller that orchestrates everything. This would facilitate the creation of subVIs for each of these subsystem controllers.

 

I know that this seems like a lot of work and effort, and it totally is for someone who is new to LabVIEW, and especially so for someone who isn't coming from a software design background. There are some template projects that come with LabVIEW that you can review to get an idea of what I'm talking about, but they may be a bit much to digest.

 

If you press "Create Project" from the LabVIEW welcome screen, you'll see a bunch of Templates. You can use the Queued Message Handler template to get started down the rabbit hole.

 

 

Nathan Murphy
0 Kudos
Message 5 of 11
(2,429 Views)

You might not think of wires as being documentation, but if, like others have said, your wires are neat and well-organized, it will be easy to follow them and you won't have guess where they are coming from/going to.

Bill
CLD
(Mid-Level minion.)
My support system ensures that I don't look totally incompetent.
Proud to say that I've progressed beyond knowing just enough to be dangerous. I now know enough to know that I have no clue about anything at all.
Humble author of the CLAD Nugget.
0 Kudos
Message 6 of 11
(2,417 Views)

@billko wrote:

You might not think of wires as being documentation, but if, like others have said, your wires are neat and well-organized, it will be easy to follow them and you won't have guess where they are coming from/going to.


Neat wires is the LabVIEW equivalent of neat whitespacing in text-based languages. Imagine if you got someones code that had literally no indents, or even just random indents... how hard would that be to read, even if it functioned? (not Python, of course) You'd need to fix whitespace before you could begin to work on the code.

 

That's how it is with messy wires in LabVIEW.

 

     if val>13

val = 2;

else if val>100

                       val++;

endif

Message 7 of 11
(2,360 Views)

After looking at your program I think, that as others have indicated, you're not yet ready to worry about documentation. You need to focus on what you can do to make your code more readable. Readable code becomes self-documenting. I rarely label wires. I will sometimes put a label by an uninitialized shift register if I have multiples so that I can keep track of which is which (when I'm using a state machine).

 

I agree with Nathan-M that you really should look at your architecture. I do think, though, that encapsulating areas of code that have a single function into subvis will help you to visualize an improved architecture. This encapsulation also makes the code more maintainable, and improves the self documentation (be sure that you don't use the standard icon - make it something that describes what the vi does - preferably a glyph).

0 Kudos
Message 8 of 11
(2,348 Views)

Well I suppose I'm going to revise my earlier estimate of a few days or rewriting into a few weeks.

 

In looking through the channeled message handler template, I'm finding a lot of different topics that I need to learn about before I can get this to work. One problem I'm running into is that I often will run into function blocks that I can't identify; they don't have a descriptive name and have no help option in the context window. This is probably because they are either not built in LabVIEW function blocks or (more aggravatingly to me) they are "basic enough" or don't count as function blocks, so LabVIEW just doesn't have any help link to them.

 

Is there a way to open the file location of these sort of blocks, or in some way find which function palette they're from? It would make learning about this stuff from the templates much easier.

 

For example, I opened the Channeled message handler template. Inside the Event Handling Loop, in the "do something" case, I can see a string being sent to a function block. Making the label of that visible shows me it's the "Enqueue message" VI, and double clicking opens panel for that function (so far so good). However, looking at the Enqueue message block diagram I see several elements that I don't recognize. For example, there's a "data" input. I have no clue what that is. Probably it's very basic, but I've never seen it and I have no "help" context button to go to, no idea which palette it's from. If I was going to try to make this from scratch without copy pasting, I don't know what data type this is or how to even create a constant or control of this type. How do I find info on this type of thing?

 

I know the specific examples I'm listing here are pretty basic, but I've really only learned the surface level mathematical operation part of LabVIEW and I'm mainly looking for a more efficient way to learn the rest of it.

 

Thanks for all the help in this thread by the way, it's opened my eyes to how much more efficiently and better organized I can get things (even if, to be honest, learning about this has been a bit depressing lol).

0 Kudos
Message 9 of 11
(2,322 Views)

@Tarnarmour wrote:

Well I suppose I'm going to revise my earlier estimate of a few days or rewriting into a few weeks.

 

In looking through the channeled message handler template, I'm finding a lot of different topics that I need to learn about before I can get this to work.

Trouble spot #1 - something labeled as a template is built to be used. They tend to not be super friendly to someone who doesn't know how they work. (So don't find it depressing! You'll get there eventually.)

(Btw, the examples are beginner-friendly - just not the templates. That's a design decision from NI, based on what I've read on these forums.)

 


One problem I'm running into is that I often will run into function blocks that I can't identify; they don't have a descriptive name and have no help option in the context window. This is probably because they are either not built in LabVIEW function blocks or (more aggravatingly to me) they are "basic enough" or don't count as function blocks, so LabVIEW just doesn't have any help link to them.

Trouble spot #2 - You've never used a subVI, so you don't know what they look like.

Congratulations, you found a subVI!

 

In this case, it's there as a part of a (fairly complicated) template. (Again, templates are not beginner friendly...)

 

(Assuming I understand your description correctly...)

The "Data" input is a terminal on the front panel of the subVI. Just like you would have on a Main VI's front panel, but not on the main VI.

(I don't have the same template as you - mine's showing a Set Message subVI instead of Enqueue Message - but I'll use what I found as an example for you.)

So here's a subVI:

Spoiler
Where it's used:
subVI_used.PNG


What it looks like when opened:
subVI.PNG

As you can see, we're looking at a terminal ("Data", in your case, "command" in my example).

It's on the block diagram to show how it's wired, on the Front Panel showing its default value, and on the little white box (in the corner of the front panel) to show how it gets connected when used as a subVI.

 

Basically, if you were to follow the wire into the subVI's icon, the value on the wire would be passed into the subVI, the code in the subVI would execute, and then the indicators would get passed out to the out-going wires.

If an input isn't wired, it takes the control's default value (shown on the subVI's front panel when you first open it).

 

(Using Context Help, you can also hover over the connection terminals on an Icon to see the name of the control/indicator that they're wired to)

 

I hope this makes sense (and that I'm not just wasting your time with something you already figured out, ha).

 

 

 

 

As far as additional training:

Spoiler

There's some great training here: http://sine.ni.com/myni/self-paced-training/app/main.xhtml, but it requires an SSP. It's great if your company/license provider is paying for it (I was lucky that this was the case for me), but if not, you have to use something less beautiful.

 

Another resource is this: http://www.learnni.com/getting-started

This one is free and video-based, but not as comprehensive.

 

Beyond that...

 

That's all I can manage to type properly for a Friday evening...

Good luck! Keep going for it!

-joeorbob

 

 

Message 10 of 11
(2,309 Views)