10-08-2015 01:48 AM
Hi,
i am working on an application which requires grabbing images from a video device. To do so i've chosen to go with a 'main' VI and a 'video' VI. In the main VI a while-loop and an event structure handle user inputs. The video VI uses a (infinite) while loop to get the video data. The video VI is started with an asynchronous-call VI.
Now I need the two VIs to communicate efficiently. Example:
The main-VI sends the command 'initialize'. Then it has to wait for the video VI to finish executing the request.
Then the main-VI can send 'start grab' and the video VI starts grabbing.
To send a command in one direction i could use a queue or a notifier. But i need to wait for some processes to finish before i can go on. A C-like function call is what i have in mind.
Has anyone an idea on how to implement this?
regards
Marvin
10-08-2015 03:21 AM
Marvin,
that question is essentially the basics for the LV Advanced Architectures class.
Plenty of options:
Queue
Notifier
FGV
DVR
User Event
TCP based communication protocol
VI Server
...
Norbert
10-08-2015 01:43 PM
We do it with Queues. This is essentially a Producer/Consumer Design, but with the two parts running asynchronously in different VIs. You can Queue 20 commands all at once, but they will be execute at the (maximum) rate that the Consumer can pull a command off the Queue, execute it, and come back to dequeue the next command. The idea is that the Queue "buffers" requests, allowing to Producer to request commands at one rate and the Consumer to execute them at a different (and potentially fluctuating) rate.
Bob Schor
11-05-2015 05:52 AM
Hi,
that is exactly what i have in mind. Problem is though that i need to get a return value. Let my describe an example situation:
The main app puts the "initialize video grabber" command on the queue. The videograbber VI dequeues the command und execute the necessary code. Depending on the operation was sucessfull or not, it has to send a return value e.g. "init sucessfull" or "init not sucessfull: camera not found".
Should i use another queue to send the return values back to the caller? How can the caller match responses to the corresponding command calls?
Is there an easy way to do this. I think there has to be a simple solution, because this seems to be an every day problem, right?
11-05-2015 06:40 AM
@nollMarvin wrote:
Should i use another queue to send the return values back to the caller? How can the caller match responses to the corresponding command calls?
Is there an easy way to do this. I think there has to be a simple solution, because this seems to be an every day problem, right?
Yes, you should use another queue. There are many ways to do this, depending on your requirements.
1. You pass in the queue reference when you initially call the VI
2. You store the queue reference in an Action Engine
3. You send the queue reference with your command (as part of the queue data)
11-05-2015 07:13 AM
11-06-2015 01:10 AM - edited 11-06-2015 01:12 AM
11-06-2015 03:55 AM
@nollMarvin wrote:
To send a command in one direction i could use a queue or a notifier. But i need to wait for some processes to finish before i can go on. A C-like function call is what i have in mind.
A function-call-like feature can be achived with a temporary Queue; create a Queue, attach it to the request message, wait for the first message received on the Queue, then destroy the Queue. Queues can be created and destroyed quite quickly, and all these steps can be contained in a single reusable subVI. I use my version of such a subVI at about 3:48 in this video on YouTube. Internally, the "Query" subVI used is creating a temporary Queue to get the reply to the request.
06-03-2019 03:45 PM
Sorry to resurrect this thread, but I've been searching for half a day for a "next step" for the OP's problem. His original question was how to communicate asynchronously with a VI that has been called via Start Asynchronous Call. The proposed answers (queues, etc) are the usual suspects for async communication. But I cannot figure out (nor have I been able to find any examples of) how to communicate with a VI that has been called via Start Asynchronous Call.
So I expect the answer is "you can't" and the proposed solutions are instead-of's, i.e. use queues, etc instead of Start Asynchronous Call. If this is the case, how would I do the following:
1) Start a VI asynchronously (with inputs) based on either a timer or on user command from the GUI; there will only ever be one instance of the target VI running, I just need it to run it asynchronously with a timer VI i've written.
2) Asynchronously send commands to change its behavior (pause, resume, change parameters to sub-VIs, etc),
3) Asynchronously send a "stop" command to stop and close it.
I originally had the timer and the target VI combined in a single VI (attached - timer is on lower left, target VI is the large loop in the middle) which worked well, but I was starting to see main loop iteration times increase after 5 or 10 minutes of run time (we have to run for about 30 min). So I decided to re-architect the code so it runs for about 5 minutes at a time with breaks in between (which happens to match our use case).
06-03-2019 04:12 PM
Consider two VIs -- Main and Video. Main "runs the show", while "Video" runs as an Asynchronous VI using Start Asynchronous Call, and two-way communication between Main and Video is desired.
The simplest way to do this is to create two Queues, one from Main to Video and the other from Video to Main. I recommend that you make them "Message Queues", where the Queue Element is a Cluster (TypeDef'ed as "Message" consisting of a "State" (I use an Enum, you can also use a String) and "Data", a Variant (so you can send a "Message with arbitrary Data"). Create both of these in Main, and pass them as either separate Inputs in the Start Asynchronous Call to Video or bundled into an Array or (my preference) a Cluster.
Note that, in principle, you do not need to create Queues on Main and pass them to Video -- you could create named Queues on both Main and Video and depend on them to "link up", but since Main always runs first, I find the simplicity of a definite "creation point" and a "wired" passing of the Queue to Video preferable.
I'm getting eye-strain trying to view your "picture of code". If you want some of us (I'm thinking of myself, really) to look at your code, please attach the VI.
Bob Schor