LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

approach to syncronise data between 2+ VIs

At first, I want to describe a simple example. 

There is a complex system which has motor and camera devices. The motor and the camera have LabVIEW libraries. User makes 2 actions:

- tune motor and camera in tune action (for example, the user uses the camera to find exact sample position)

- make measurement in main action

So the program has 2 dialogs (=VIs): main and tune. Users launches the main VI and main VI launches tune VI (Start Asynchronous Call Node). During experement user switches between main and tune VIs constantly.

 

Now a question - How motor and limit statuses, position values could be exchanged between main and tune VIs?

 

I know few ways which don't look well:

1. use global variables.

2. tune VI changes front panel control of main VI and versa vice

3. uses Shared variable, TCP/IP. VI server, Web server

4. Queue

 

Other ways?

 

Thanks, Andrey

P.s. by the way, time to time I use serial port devices which have instrument drivers. I haven't yet met a driver which takes care about syncronizarion. I assume VI with 2 loops will have an issue, like Loop 1 sends command 1 -> Loop 2 gets control, sends command 2, get  command 1 answer -> Loop 1 gets control, gets command 2 answer. Am I correct?

0 Kudos
Message 1 of 19
(4,293 Views)

Andrey,

 

The choice of method may depend on how much data is being exchanged, what the data will be used to do, how fast the exchange must take place, and whether all data must be transferred without loss or only the latest data is required.

 

For your situation it sounds like the speeds are limited buy how fast the user can operate the two VIs, which is very slow by computer standards. It also sounds like you are exchanging relatively small amounts of data (no images).

 

I would probably start by looking at queues. Use one for each direction (Main to Tune and Tune to Main). Data should only be dequeued from any given queue in exactly one place. This is why at least two queues will be required.  Queues were introduced into LabVIEW specifically for communications between parallel processes.

 

If either or both of the VIs use event structures (great caution is advised when considering more than one event structure), User Events may also be an appropriate data exchange method. The combination of using a queue from Main to Tune and a User Event from Tune to Main might be useful.

 

Lynn

0 Kudos
Message 2 of 19
(4,273 Views)

Lynn! Thank you for fast response.

 

Data volume is small - scalar or/and small size arrays. In case of big data, like image, usually there is not issue with dialog syncronizstion.

Real rate could be fast but at this case we are talking about user interface. So it is not important.

 

I have expirience with Queue to transfer data between parallel processes. Queue uses pre-defined data type so, at first, application requires to create one data type for all parameters (statuses, positions, etc. and its data types (scalar and array of float, integer, enum, string). At second, Event structure would be fired per each parameter changing which is not good in case of few cliensts. At third, any changes will require to remember and check all events.

So I would say it is chaous approach ...

 

I know how implement in WinForms framework in C# or SWING framework in Java but in LabVIEW ...

0 Kudos
Message 3 of 19
(4,200 Views)

Consider the Queued Message Handler project template. It uses strings as the basic messages with a variant datatype for any data to be transferred.  When the message is dequeued, the message string selects a case of a case structure where the variant data is decoded. By naming the messages appropriately and uniquely you cna then set the datatype in each case to required type for that value. This allows you to use the same Vis to pass messages and any type of data without requiring mutliple queues for the different datatypes.  The template can be found from the Project menu: Create Project...

 

Internally these use queues so you are still limited by the only dequeue in one place rule. Two message queues, one for each direction might be enough.

 

Lynn

0 Kudos
Message 4 of 19
(4,180 Views)

I agree that the Queued Message Handler is not a bad way to go.  I also recommend two queues, one to send, one to receive.  I, personally, find the QMH Project Template a little intimidating-- it doesn't need to be that complex.  The basic idea is that you have a Message Type consisting of two parts -- Message, which can be either a String or an Enum (people argue about which is "better"), and Data, typically a Variant, which means that each Message can have its own specific data argument (or no data at all).

 

I assume you know how the QMH works, but if not, here is a brief description.  The Caller (the originator of the Message) creates a Message Queue, with the Message Cluster as its "Type".  Whenever it wants the Callee to "do something", it sends an appropriate "Do Something" Message by enqueuing the Message along with any required data.  Meanwhile, the Callee either creates its own copy of the Message Queue, or gets passed a Queue Reference to the Caller's Queue.  It sits in a While Loop trying to Dequeue Messages.  When it gets a Message, it "Does Something" (usually by having the Message part of the Message Cluster drive a Case Statement, with one Case for every possible Message).  Note that the Callee is acting like a State Meachine, with the "States" being the incoming Messages.

 

As the Caller and Callee are running in parallel, as long as the Callee is not busy processing the previous Message, when the Caller sends a Message, you should expect the Callee to begin processing that message within a few microseconds, i.e. "near simultaneously".  Pretty good synchronization, if you ask me.

 

Bob Schor

0 Kudos
Message 5 of 19
(4,148 Views)

I need to point that my example is the simplest example with 2 dialogs, 1 device, few parameters. So discussion went to discussion of implementation 1 dual link (2 Queues).

Let look on real life from normal Computer Science point of view:

- Link dependence from dialogs - (n-1)!. For example, 10 dialogs = 9! links

- Link dependence from devices - n. For example, 10 dialogs = 10 links

- If dialog uses 1 parametert out of 100 device parameters it will get packages of 100 parameters

 

==================

I mentioned that I know how to implement such system in C# and Java GUI frameworks. C# control, for example textbox, could be binded to one of the base class of control which support the binding. In device class I use parameter variable is derived from binding class. So ...

Dialog control subscribes (binds) to parameter variable in device class. When control in any dialog would be changed -> parameter variable in device class will be changed -> controls in all dialogs which were subscribed will be updated.

 

==================

Actially, Labview control has binding through Shared variable (property -> Data Binding tab). As I know (I didn't use Shared variable) Shared variables are created on LabVIEW project level for application, computer, or network visibilty. So ...

- It means there is not way to have get of Shared variable automaticly when device VIs will attached in the LabVIEW project.

- In case of 2 or more the same devices thin system it will not work because it requires set of Shared variables per device instant.

 

=================

Any idea now?

 

0 Kudos
Message 6 of 19
(3,892 Views)

Since we are dealing with GUIs, I would use User Events.  Just register for the events and fire away.  Everybody that registers for an event will get it and can do whatever they want with it.

 

You can add some metadata into your event in order to limit how each dialog processes it.  A common event data format is a cluster that contains a string (name of the data) and a variant (that holds the data needed for the event).


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
0 Kudos
Message 7 of 19
(3,832 Views)
Is the timing of the data important? By that I mean does the receiver need to know about the change as soon as it happens, or does it simply need to have the last value when they go to use it? If timing is important, UDEs are a good solution like Tim said. If not, functional global variables would work well too.

Mike...

Certified Professional Instructor
Certified LabVIEW Architect
LabVIEW Champion

"... after all, He's not a tame lion..."

For help with grief and grieving.
0 Kudos
Message 8 of 19
(3,762 Views)

To crossruiz:

I didn't try to fire event in one VI and catch n another VI but I assume it is possible because it is the same process.

 

So if you would add next VI then you will must update all VIs! It means you try to support MxM matrix!!! Good luck 😉

0 Kudos
Message 9 of 19
(3,628 Views)

To mikeporter:

- Timing is important at GUI speed. It means if value has been changed it sould be updated that user will not notice.

- Not sure what is UDE and who is Tim ...

- global variable -> one VI per one global variable. So too many VIs and it should be slow and takes more CPU resources. It would be better to avoid from Computer Science point of view 😉

0 Kudos
Message 10 of 19
(3,620 Views)