LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Top LabVIEW Rookie Mistakes


@NZer wrote:

Fun and Games!

I'm a rookie, but I was able to pick up some of these issues with this code. Must be learning something!

 

I wonder if you could elaborate a bit on your comment about splitting the queue reference.

After all, queues must be split between producers and consumers.

Are you referring to the unnecessary split which puts "Exit" onto the queue?

Is it just bad coding which still works, or are there other subtle issues with this?

 

Thanks,

Jonathan.

 

 


The subtle issue is that the second for loop will not iterate so all the output tunnels will contain datatype default values.  Queue Ref out of that loop will be "Not a Refnum"  the third loop will error because the refnum is invalid and cannot enqueue anything to "nowhere."  The "Unnecessary branch" contains a valid refnum and the clear errors prevents the error from being reported at the end. 

 

A Shift register operates "Inline", That means both sides of the loop are looking at the same "Buffer" (Simplfied, its the same memory location.)  Had the queue ref been on a SR the same valid refnum would have left the 0 iteration loop.


"Should be" isn't "Is" -Jay
0 Kudos
Message 31 of 47
(2,703 Views)

Thanks for that! It really is subtle! We worked out that the second loop would not iterate but didn't igure out all the implications.

 

Jonathan.

0 Kudos
Message 32 of 47
(2,693 Views)

@pretech wrote:

Thanks for that! It really is subtle! We worked out that the second loop would not iterate but didn't igure out all the implications.

 

Jonathan.


Yup, you pretty much got it. It's not "bad" code per se (with the exception of the shift register missign), but definitely unconventional. I wouldn't expect to see something like this in professionally written (good) code, but it's just to see how people think in the dataflow paradigm. Not bad for a rookie 😉

0 Kudos
Message 33 of 47
(2,681 Views)

Another 'feature' which puzzled me in the past: a typecast of an integer to an enum.

I wanted to loop over all elements of an enum, for instance inputs of an ADC. In this example I created an enum with 4 elements: case 0, case1, case 2 and case 3. The for-loop iterates 4 times. To get the text part of the enum in the 'case'-structure, I typecast the internal counter 'i' to the enum datatype.

 

When running my code I got strange results, which I didn't understand.

Step by step debugging learned me that the typecast of an I32 to a simple enum (= not adapted after creation) doesn't do what I expected. The numeric part of a default enum is an U16. Casting of a I32 to an U16 results in a number, equal to the upper 16 bits of the I32. This is 0 most of the times, which results in 4 times 'case0'.

 

A warning to others: if you want to loop over all elements of an enum you should start with changing the representation to U32

Download All
0 Kudos
Message 34 of 47
(2,354 Views)

I saw a nice collection of common errors or bad programming, but I missed one feature: the (Strict) Type definition.

 

Especially when a program uses 'enums' and/or 'clusters' it is very convenient to invest some time to define the 'enum'(s) and 'cluster'(s) short after their definition. When the program evolves, I often needs to extend the numer of elements of an enum or cluster. If the type is not defined as type definition I must update all instances manually, a tedious job.

Updating the definition in the type definition and call 'Apply changes' will do the same much faster and easier.

 

Refer to the LabVIEW Help for an explanation of Type definitions and Strict Type definitions.

0 Kudos
Message 35 of 47
(2,339 Views)

@Fred.Schimmel wrote:

 

Refer to the LabVIEW Help for an explanation of Type definitions and Strict Type definitions.


I've actually one ever used a Strict Type def once in a real application.  Very rarely do I have a UI element that needs to look exactly the same in multple locations.  In this case it was a UI that showed the state of flow, pumps, and temperatures in a plumbed system.  There was a manual screen that let you interact with the UI that normally just showed the system state.  So I make the cluster of controls Strict.  I still think this confused operators because in one UI it was read only and in another they could interact so I'm not convinced the Strict Typed cluster was the right way to go.

0 Kudos
Message 36 of 47
(2,326 Views)

Another item I missed: only use the 'Unbundle' primitive in very simple code where the 'Bundle' and 'Unbundle' are close to each other and on the same Block Diagram.

 

'Unbundle' delivers the elements of a cluster in the sequence of the 'cluster order'. When the elements have different datatypes, they can be distinguised by the colors of the wires. And the code will break when the cluster order is modified, because LabVIEW is very strict in datatypes If a string is replaced by an I16 (and vise versa) the editor will complain.

 

Much worse is the situation when a cluster contains several variables of identical datatype: a change of the cluster order may result in runable code with erroneous behavior by swapping two (or more) variables of the same type.

 

To prevent these unexpected consequences one should almost always apply the 'Unbundle by Name' primitive. As the label-name is used to select the element, this primitive is not sensitive for modification of the 'cluster order'. Put this rule for good LabVIEW programming high on your list.

0 Kudos
Message 37 of 47
(2,322 Views)

Funny. I use clusters quite often and almost always as Strict Type definition.

 

Think of an Instrument Driver or a State Machine. In my programs such code is most of the time a run-once while-loop with an un-initialized shift register. The shift-register is initialized as Cluster (strict typedef) containing relevant data which can be retrieved and altered in the various actions of the concerning code. A case structure with an enumerated as selector allows the programmer to define a set of supported actions.

 

This way of programming has some similarity with OO: the data is encapsulated inside the code and the supported actions resemble  'methods'.

0 Kudos
Message 38 of 47
(2,307 Views)

@Fred.Schimmel wrote:

 

Think of an Instrument Driver or a State Machine. In my programs such code is most of the time a run-once while-loop with an un-initialized shift register. The shift-register is initialized as Cluster (strict typedef) containing relevant data which can be retrieved and altered in the various actions of the concerning code. A case structure with an enumerated as selector allows the programmer to define a set of supported actions.


Why would you choose a Strict Type def for a constant on the block diagram when it will never be seen by the user?  Why not a Type def?

0 Kudos
Message 39 of 47
(2,301 Views)

@Hooovahh wrote:
Why would you choose a Strict Type def for a constant on the block diagram when it will never be seen by the user?  Why not a Type def?

Interestingly enough, when I took my first LabVIEW course, I think I was instructed on using a Strict TypeDef.  I don't remember whether it was the instructor or what the book actually told to use.  Sometime afterwards was when I learned that the vast majority of the time that you are better off using a Regular TypeDef and save the Strict TypeDef for those rare instances when you really need to lock down the appearance of the control.

 

I'm in a cleanup mode at work, so when I come across my books from the course, I'll peek at them and see what it was they were instructing to do.

0 Kudos
Message 40 of 47
(2,268 Views)