08-14-2020 06:58 AM
I'm currently working on an application that comprises multiple VIs running in parallel but need to exchange data and I'm trying to find the best method for data sharing. The one most recommended design after perusing these forums has been to set up a publisher subscriber implementation. I've searched for a simple example to no avail. This one I found in the LAVA forum did not include the actual file. https://lavag.org/topic/13598-labview-programming-structures/
A simple example is much preferable as I'm currently not well versed in labview OOP. Any help will be appreciated. Thanks in advance.
08-14-2020 11:45 AM
You can only download from LAVA if you are logged in, I think. I could download that example.
I didn't look at it. Since that 2011 conversation there have been multiple free frameworks for "multiple VIs running in parallel but need to exchange data" that include some type of Publish-Subscribe in them. DQMH is the most popular, but there is also my "Messenger Library" among others. I would investigate those to see if one clicks with you.
08-15-2020 12:04 PM - edited 08-15-2020 12:07 PM
What you are after is a method to do 'asynchronous communication' between 'asynchronous modules'.
Fundamentally, asynchronous messaging is achieved through Queues, Notifiers, User Events or a combination of these options.
Like drjdpowell suggested, you could use the Messenger Library or DQMH. Another popular framework is the Actor Framework. These frameworks provide wrappers around the native queue, notifier and/or user event VIs. However, there is an overhead with learning any framework.
IMO, the simplest option for you would be to not use any of the frameworks above, but rather to write your own communication behaviour. It sounds like you are looking to implement a simple asynchronous comms mechanism - there's no need to overkill by adopting a framework. But you may want to adopt a framework when you are comfortable with the basics of creating your own async comms mechanisms - only then you will see the benefit of a framework 'giving you functionality for free' (i.e. without having to program it yourself) in a standard, well-understood architecture.
To get started, use the 'Obtain Queue' primitive to create a queue. Wire a string into the 'name' input, for example wire 'My Queue'. Wire the reference output of 'Obtain Queue' to an 'Enqueue Element' node. In another VI, use 'Obtain Queue' with the same string wired to its name input. This second Obtain Queue does not create a new queue - it returns a reference to the queue of same name that was already created (that's why the primitive is called 'Obtain' and not 'Create' Queue). Wire the reference of the second 'Obtain Queue' to a 'Dequeue Element' primitive. Whatever you enqueue into the queue using 'Enqueue Element' in VI A will be received in VI B by the 'Dequeue Element' function. Multiple modules can enqueue commands or messages that get dequeued by one VI. In other words, queues are perfect for one-to-one (VI A issuing commands to VI B) and many-to-one communication (VI A and VI B issuing commands to VI C).
Queues are bad at one-to-many communication. Notifiers and User Events are better for one-to-many communication (VI A issuing a command to VI B, VI C, etc.). For example, Notifiers and User Events are suitable for implementing a global 'Abort' message, where one VI can issue an 'Abort' message that all other VIs respond to. Both Notifiers and User Events are equally capable to implement one-to-many comms. I would recommend using Notifiers to get started, as they are simpler to use than User Events IMO, and very similar to using Queues. (User Events require you to use Event Handling structures, and to register/unregister for events which may become confusing at first.)
To learn about queues, open the LabVIEW Example Finder and look at 'Queue.lvproj'. Start with 'Simple Queue.vi'. In this VI, a reference wire is passed from the Obtain Queue to Enqueue and Dequeue nodes. The reference wire is another way or referencing the queue. The 'My Queue' queue name I mentioned above is another way which allows you to access the queue in different VIs.
Also, select 'Create Project' and have a look at the 'Queued Message Handler' Template and at the 'Continuous Measurement and Logging' sample project. The latter may be very similar to what you are trying to do.
Building your own comms mechanism is most conducive to learning.
An important point: You don't need to use any OOP to perform asynchronous communication. The question of asynchronous comms is independent of the question of OOP. Queues, Notifiers and User Events, which are the backbone of asynchronous comms in LabVIEW, don't need to be inside LabVIEW classes - they will work even if you don't use any OOP in your project.
When you feel confident with the basics of queues, notifiers and user events you can start learning and using a framework.
08-17-2020 08:09 AM
Thanks everyone for your replies. I'm very familiar with queues, notifiers and user events. I've been programming with them for a long time. At the moment, I'm too far advanced into the project to adopt a new framework like actor or DQMH. Matter of fact, I'm working with an inherited code so it's not like I'm starting from scratch. I guess my best option will be to look at the DQMH to see what I can learn and incorporate into the existing code.