How to Display Data in a Control in LabVIEW - labview

I have a numeric control( not Indicator) and a for loop(limit 5)
I need to display the [current loop Index+ value in the numeric control] in the Numeric control. I'm new to LabVIEW. Is there any idea to do this?

To write a value to a control, you need to create a local variable from it (right-click on the control's terminal on the block diagram and choose Create > Local Variable). To have it update each iteration of your For loop, put the local variable terminal inside the For loop and wire whatever you want displayed to that terminal. I'm not sure if this is going to be a good user interface design, but it's the answer to your question.
You can also use local variables to write to indicators from more than one place in your block diagram, and to read from indicators or controls. You can have more than one local variable terminal for any given control or indicator. Each local variable terminal is either for reading or writing - right-click on the local variable and choose Change to Read or Change to Write.
You should be careful about using local variables to pass data around, because program flow will no longer be controlled by data flow as it is when you pass data along a wire, and this could give you unpredictable behaviour (race conditions). Writing in one place and reading in multiple places is OK if the readers only need to know the current value at the time they execute, and so is writing to an indicator from multiple places where the indicator is only being used to display information to the user.

Is there any specific reason you need to update a control that often?
If it needs to be updated that regular it might be better to alter it into an indicator.
If you update a control that often the user will have the feeling he's not in 'control'.

As mentioned aleady you can use local variables and proerty nodes to set the value of your control or indicator. If you are trying to persist data there is a much better way.
Google "functional global" or "labview 2 style global". The basic pattern is to use a while loop hard coded to stop after one iteration. Add an unitialized shift register. Add a case structure inside the loop. Use a control (boolean, enum, or string) to select on the case structure. Drop a control/indicator pair of the same datatype on your VI. Wire the indicator to the outter-output of the right shifter on the outside of the loop. Place the control INSIDE the loop in the "set" (usually true, non-default) case and wire it out of the case into the input of the right shifter. Go to the other empty case(s) and wire the inner-output of the left shifter through the cases to the terminal that connects to the inner-input.
Becuase you did not wire the outter-input of the left shifter it is an "unitialized shift register". It will persist data from the last call to the VI. This is like declaring a variable on the heap in a c function and having the last assigned value available to you at the next function call.
The three main benefits are preservation of data flow, thread saftey, and performance. You get data flow by adding error IO to your VI. Thread saftey is ensured becasue the VI's execution is guaranteed to be atomic. Perfomance is improved becasue LV data wants to live on a wire. Every time you write data to a control's proerty node the LV runtime writes that data to the UI thread. I think there is a similar threading based performance hit for locals too but I'm not sure.
Per the first comment...
Copied here from the link for your benefit (yes you Mr Reader).
Problem:
I am considering using local or global variables; in what thread do variables execute?
Solution:
A common misunderstanding is that local and global variable operations execute in the UI thread, or require a thread swap to the UI thread - this is not true. The following describes the behavior of local and global variable write and read operations:
Write:
When you write to a local or global variable, LabVIEW does not switch to the user interface thread immediately. LabVIEW instead writes the value to the transfer buffer, which is a protected area of memory. The user interface updates at the next scheduled update time. It is possible to update a variable multiple times before a single thread switch or user interface update occurs. This is possible because variables operate solely in the execution thread.
Read:
When you read from a local or global variable, the operation will occur in the thread which the VI executes, thus, you can be sure it does not occur in the UI thread by setting the execution system in the VI properties to standard. There is a thread protection mechanism to make sure that no writer of the global is changing the data while you are reading it, but this is done via a mutex, and not by going to the UI thread. However, if the global variable panel is opened, then a message is posted to redraw the global control, and the redraw will happen in the UI thread.
nekomatic is correct. The thread swap does not occur when you write to locals.

I agree with Ton. If you are changing the value of a control programatically, then you should consider whether it should be an indicator, or maybe have a pseudo-indicator of the control.
It would be a good idea to post an isolated version of your code so we can understand what exactly is going on.

If you wanted to maintain dataflow to control the program flow, you could instead use a property node of the control and set the "Value" property.
To create the property node, right click on the control's terminal on the block diagram, and select Create » Property Node » Value. Now you can adhere to dataflow programming by using error wires to control the flow of the program.
Again, to re-emphasize Ton's point - If you are going to change the value of a control frequently, it might be worth changing it into an indicator instead.

Related

LabVIEW: How to share a .NET object created from LabVIEW

I have a class called Camera in the .NET library and once I instantiate the object I want to create a reference of it so that this instance can be used from other VIs. How do I make a reference or how do I make it global ?
Thanks,
There are a couple ways to approach your question.
Possible answer 1: You're looking to let multiple parallel subVIs use the object at the same time. The .NET wire is already a reference wire. Forking that wire does not copy the object. Just wire it into the other VIs, however many there are, and let them all use the reference.
Possible answer 2: You're trying to obtain the existing reference in another VI without passing the reference on a wire through a subVI conpane or Call By Reference node. In this case, you would pass the .NET object refnum the same way you would pass any other bit of data in LabVIEW when avoiding wires. In general, the rule is "avoid passing data outside of dataflow." Seriously... try to pass the refnum through a conpane... if this program is going to have any significant lifetime, you'll be happier when you can take that approach. BUT... when such outside-of-dataflow passing is necessary, there are many tools -- queues, notifiers, global VIs, data value references, functional globals. Which of those tools is the right one depends greatly on what you're actually trying to achieve. The simplest is to create a global VI, but that introduces a lot of polling checks as the second VI has to keep polling the global to see if the first VI has stored the value yet or not. A notifier refnum is probably the most flexible option that I can point you toward... create a named notifier of your .NET refnum type. Both first and second VI can obtain the notifier by name. The second VI then blocks on Wait For Notificiation waiting for the first VI to write the refnum into the notifier. See http://zone.ni.com/reference/en-XX/help/371361L-01/glang/create_notifier/ for more information on notifiers. Or Google the other terms that I listed if that seems insufficient for your needs.

VB.NET Pass label reference to thread in class

hopefully you can either validate my assumption or point me in the right direction.
I'm working on a small GUI to monitor a variable DC power supply. The equipment communicates via a COM port. To do this I have created a Class to handle communicating with the PSU. I would like to implement a method in which the calling form (class) can pass 2 Label references to my PSU class which it can periodically update with voltage and current.
I have already worked out how to update a Label's text from outside the main thread (with Invoke), and I have worked out how to start a second thread running a method with no parameters. From my reading, I can only pass a single parameter to a parameterized thread start.
My current approach is to create a Collection and have the items be those two labels which I mean to pass. The method to create and start the thread accepts (what I think are) pointers to the two labels with the following:
Public Sub monitor(ByRef vLbl As Label, ByRef aLbl As Label)
Inside that sub (after some error checks and other tasks) I create a new Collection and add the two label references:
Dim coll As Collection = New Collection()
coll.Add(vLbl)
coll.Add(aLbl)
Which I then pass coll in the thread.Start call.
In the sub actually running on the other thread, I start it by breaking out the two labels:
Dim _vLbl As Label = coll(0)
Dim _aLbl As Label = coll(1)
Is this a sound approach to the problem? I realize that I could simplify some of this by eliminating the class approach and taking more of a procedural one, but I'm trying to develop my PSU class reference to be used by some other software tools as a library eventually. Please forgive if I have messed up the terminology, I haven't been doing this for long and am trying to teach myself how all of this works.
Thanks in advance.
Edit: Grammar Fail
For what it's worth, this isn't how I'd do it, as it violates separation of concerns. The code that knows how to read the PSU shouldn't need to know what a label is or how to update it. In the future, you might want to use something other than a label, or may wish to store the numbers in a database as you go, or you might want to use a globalized approach to formatting the number (for example). If you were ever to make those changes, you shouldn't have to touch the PSU code.
Instead, I would create an object, say, PSUMonitor, which does the monitoring. The PSUMonitor would raise an event with a custom EventArgs capable of carrying the data you wish to track.
Then, your UI form would subscribe to those events, read the numbers, and then format the information to put them on a label, two labels, a graph, a table, aor whatever else you want.

Get value of control refnum in one step in SubVI

I'm trying to de-spaghetti a big UI by creating SubVIs that handle only the controls that are relevant, via control refnums.
Now, when extracting the code from the main VI and re-wiring into the subVIs, things get clutter-y.
To read/write these refnums, I have to do a two-step process. First add a terminal to get the control refnum value and then another to get the value of the control.
Wiring the refnums everywhere is not really an option as that will create more spaghetti if there are more than two of them. (usually 4-10)
Is there a better way?
UPDATE
Guys, this is a low-level question about the picture above, not really a queston about large scale architecture / design patterns. I'm using QMH, classes, et.al. where appropriate.
I just feel there should be a way to get the typed value from a typed control ref in one step. It feels kind of common.
In the caller VI, where the controls/indicators actually live, create all your references, then bundle them into clusters of relevant pieces. Pass the clusters into your subVIs, giving a given subVI only the cluster it needs. This both keeps your conpane cleaned up and and makes it clear the interface that each subVI is talking to. Instead of a cluster, you may want to create a LV class to further encapsulate and define the sub-UI operations, but that's generally only on larger projects where some components of the UI will be reused in other UIs.
I'm not sure there is a low-touch way to de-spaghetti a UI with lots of controls and indicators.
My suggestion is to rework the top-level VI into a queued message handler, which would allow you to decouple the user interaction from the application's response. In other words, rather than moving both the controls and the code that handles their changes to subVIs (as you're currently doing), this would keep the controls where they are (so you don't need to use ref nums and property nodes) and only move the code to subVIs.
This design pattern is built-in to recent versions of LabVIEW: navigate to File » Create Project to make LabVIEW generate a project you can evaluate. For more information about understanding how to extend and customize it, see this NI slide deck: Decisions Behind the Design of the
Queued Message Handler Template.
In general, it is not the best practice to read/write value using refnum in perspective of performance. It requires a thread swap to the UI thread each time (which is a heavy process), whereas the FP Terminal is privileged to be able to update the panel without switching execution threads and without mutex friction.
Using references to access value
Requires to update the front panel item every single time they are called.
They are a pass by reference function as opposed to a pass by value function. This means they are essentially pointers to specific memory locations. The pointers must be de-referenced, and then the value in memory updated. The process of de-referencing the variables causes them to be slower than Controls/Indicators, or Local Variables.
Property Nodes cause the front panel of a SubVI to remain in memory, which increases memory use. If the front panel of a SubVI is not displayed, remove property nodes to decrease memory use.
If after this you want to use this method you can use VI scripting to speed up the process: http://sine.ni.com/nips/cds/view/p/lang/en/nid/209110

LabVIEW: Programmatically setting FPGA I/O variables (templates?)

Question
Is there a way to programmatically set what FPGA variables I am reading from or writing to so that I can generalize my main simulation loop for every object that I want to run? The simulation loops for each object are identical except for which FPGA variables they read and write. Details follow.
Background
I have a code that uses LabVIEW OOP to define a bunch of things that I want to simulate. Each thing then has an update method that runs inside of a Timed Loop on an RT controller, takes a cluster of inputs, and returns a cluster of outputs. Some of these inputs come from an FPGA, and some of the outputs are passed back to the FPGA for some processing before being sent out to hardware.
My problem is that I have a separate simulation VI for every thing in my code, since different values are read from and returned to the FPGA for each thing. This is a pain for maintainability and seems to cry out for a better method. The problem is illustrated below. The important parts are the FPGA input and output nodes (change for every thing), and the input and output clusters for the update method (always the same).
Is there some way to define a generic main simulation VI and then programmatically (maybe with properties stored in my things) tell it which specific inputs and outputs to use from the FPGA?
If so then I think the obvious next step would be to make the main simulation loop a public method for my objects and just call that method for each object that I need to simulate.
Thanks!
The short answer is no. Unfortunately once you get down to the hardware level with LabVIEW FPGA things begin to get very static and rely on hard-coded IO access. This is typically handled exactly how you have presented your current approach. However, you may be able encapsulate the IO access with a bit of trickery here.
Consider this, define the IO nodes on your diagram as interfaces and abstract them away with a function (or VI or method, whichever term you prefer). You can implement this with either a dynamic VI call or an object oriented approach.
You know the data types defined by your interface are well known because you are pushing and pulling them from clusters that do not change.
By abstracting away the hardware IO with a method call you can then maintain a library of function calls that represent unique hardware access for every "thing" in your system. This will encapsulate changes to the hardware IO access within a piece of code dedicated to that job.
Using dynamic VI calls is ugly but you can use the properties of your "things" to dictate the path to the exact function you need to call for that thing's IO.
An object oriented approach might have you create a small class hierarchy with a root object that represents generic IO access (probably doing nothing) with children overriding a core method call for reading or writing. This call would take your FPGA reference in and spit out the variables every hardware call will return (or vice versa for a read). Under the hood it is taking care of deciding exactly which IO on the FPGA to access. Example below:
Keep in mind that this is nowhere near functional, I just wanted you to see what the diagram might look like. The approach will help you further generalize your main loop and allow you to embed it within a public call as you had suggested.
This looks like an [object mapping] problem which LabVIEW doesn't have great support for, but it can be done.
My code maps one cluster to another assuming the control types are the same using a 2 column array as a "lookup."

Need advice regarding VB.Net multithreading options

Good day all,
I'm having a hell of a time figuring out which multithreading approach to utilize in my current work project. Since I've never written a multithreaded app in my life, this is all confusing and very overwhelming. Without further ado, here's my background story:
I've been assigned to take over work on a control application for a piece of test equipment in my companies R&D lab. The program has to be able to send and receive serial communications with three different devices semi-concurrently. The original program was written in VB 6 (no multithreading) and I did plan on just modding it to work with the newer products that need to be tested until it posed a safety hazard when the UI locked up due to excessive serial communications during a test. This resulted in part of the tester hardware blowing up, so I decided to try rewriting the app in VB.Net as I'm more comfortable with it to begin with and because I thought multithreading might help solve this problem.
My plan was to send commands to the other pieces of equipment from the main app thread and spin the receiving ends off into their own threads so that the main thread wouldn't lock up when timing is critical. However, I've yet to come to terms with my options. To add to my problems, I need to display the received communications in separate rich text boxes as they're received while the data from one particular device needs to be parsed by the main program, but only the text that results from the most current test (I need the text box to contain all received data though).
So far, I've investigated delegates, handling the threads myself, and just began looking into BackgroundWorkers. I tried to use delegates earlier today, but couldn't figure out a way to update the text boxes. Would I need to use a call back function to do this since I can't do it in the body of the delegate function itself? The problem I see with handling threads myself is figuring out how to pass data back and forth between the thread and the rest of the program. BackgroundWorkers, as I said, I just started investigating so I'm not sure what to think about them yet.
I should also note that the plan was for the spawned threads to run continuously until somehow triggered to stop. Is this possible with any of the above options? Are there other options I haven't discovered yet?
Sorry for the length and the fact that I seem to ramble disjointed bits of info, but I'm on a tight deadline and stressed out to the point I can't think straight! Any advice/info/links is more than appreciated. I just need help weighing the options so I can pick a direction and move forward. Thanks to everybody who took the time to read this mess!
OK, serial ports, inter-thread comms, display stuff in GUI components like RichTextBox, need to parse incoming data quickly to decode the protocol and fire into a state-machine.
Are all three serial ports going to fire into the same 'processControl' state-machine?
If so, then you should probably do this by assembling event/data objects and queueing them to the state-machine run by one thread,(see BlockingCollection). This is like hugely safer and easier to understand/debug than locking up the state-engine with a mutex.
Define a 'comms' class to hold data and carry it around the system. It should have a 'command' enum so that threads that get one can do the right thing by switching on the enum. An 'Event' member that can be set to whatever is used by the state-engine. A 'bool loadChar(char inChar)' that can have char-by-char data thrown into it and will return 'true' only if a complete, validated protocol-unit has been assembled, checked and parsed into data mambers. A 'string textify()' method that dumps info about the contained data in text form. A general 'status' string to hold text stuff. An 'errorMess' string and Exception member.
You probably get the idea - this comms class can transport anything around the system. It's encapsulated so that a thread can use it's data and methods without reference to any other instance of comms - it does not need any locking. It can be queued to work threads on a Blocking Collection and BeginInvoked to the GUI thread for displaying stuff.
In the serialPort objects, create a comms at startup and load a member with the serialPort instance. and, when the DataReceived event fires, get the data from the args a char at a time and fire into the comms.loadChar(). If the loadChar call returns true, queue the comms instance to the state-machine input BlockingCollection and then immediately create another comms and start loading up the new one with data. Just keep doing that forever - loading up comms instances with chars until they have a validated protocol unit and queueing them to the state-machine. It may be that each serial port has its own protocol - OK, so you may need three comms descendants that override the loadChar to correctly decode their own protocol.
In the state-machine thread, just take() comms objects from the input and do the state-engine thing, using the current state and the Event from the comms object. If the SM action routine decides to display something, BeginInvoke the comms to the GUI thread with the command set to 'displaySomeStuff'. When the GUI thread gets the comms, it can case-switch on the command to decide what to display/whatever.
Anyway, that's how I build all my process-control type apps. Data flows around the system in 'comms' object instances, no comms object is ever operated on by more than one thead at a time. It's all done by message-passing on either BlockingCollection, (or similar), queues or BeginInvoke() if going to the GUI thread.
The only locks are in the queues and so are encapsulated. There are no explicit locks at all. This means there can be no explicit deadlocks at all. I do get headaches, but I don't get lockups.
Oh - don't go near 'Thread.Join()'.