11-12-2018 11:51 AM
Hello,
I am new to LabVIEW and am bringing in a bunch of preconceptions from the traditional object-oriented programming world that are making it hard to wrap my head around what I would like to accomplish.
I would like to achieve the following in a LabVIEW project. I will have a stepper motor connected to LabVIEW via a USB module. I would like to be able to wrap control of this motor into a class so that I can expose methods and properties like "move to a position" or "go home" or "what position am I currently at", similar to encapsulation in a traditional programming language. I would also like to have controls on my user interface updated when changes to this motor occur. For example, I want an indicator to display the current position of the motor. This would normally make me think of implementing some sort of event fired by my motor class that gets handled (via an Event Structure) by the VI with the indicator. However, I am not sure how to "fire" my own events in LabVIEW.
I also would only want a single instance of the motor object to exist that various different VIs could connected to an listen to events from. Normally this would be achieved by a pointer passed to all the other places in the code that need access to this object. Perhaps some sort of reference in LabVIEW?
What would be the LabVIEW method of achieving this type of behavior?
Thanks in advance for any help!
Solved! Go to Solution.
11-12-2018 12:44 PM
Look up User Event and then Queued Message Handler (QMH). User Events are great for passing information to GUI loops (ie an Event Structure). And I would recommend a Queued Message Handler for managing your motor and broadcasting the status updates.
11-12-2018 03:21 PM
Thanks for the starting point, it was very helpful!
I have some questions regarding the QMH. First, would it be valid to make a single queue global so that any of my VIs can read from/write to the queue (I feel like this would sort of be like implementing my own event system)? Second, using a QMH, how would I allow multiple consumers to consume the same message? As an example, let's say I have two VIs which are GUIs. Each VI has an indicator which should display the same value which comes from a produced (in my case the motor code). One of the VIs would be a "popup" so it would not always be used, however, when it is, it needs to be able to receive these messages/events and update its indicators.
Thanks again for your help!
11-12-2018 05:12 PM
There's nothing stopping you from having a queue reference inside of some FGV or global but remember that an item can only be taken out of the queue once so it's not a good way to ensure the same message gets to multiple readers.
If you want to have multiple consumers consume the "same" message you could either have each consumer have a unique queue and have the producer write separately to each queue or use user events instead. You can have multiple readers separately register for the same event so when you generate a user event each loop which is registered to that event will get its own message.
11-13-2018 07:24 AM
@patrick.wright wrote:
Thanks for the starting point, it was very helpful!
I have some questions regarding the QMH. First, would it be valid to make a single queue global so that any of my VIs can read from/write to the queue (I feel like this would sort of be like implementing my own event system)? Second, using a QMH, how would I allow multiple consumers to consume the same message? As an example, let's say I have two VIs which are GUIs. Each VI has an indicator which should display the same value which comes from a produced (in my case the motor code). One of the VIs would be a "popup" so it would not always be used, however, when it is, it needs to be able to receive these messages/events and update its indicators.
Thanks again for your help!
Queues are Many-to-one, Events are one/many-to-many.
11-13-2018 01:31 PM
Thanks for the clarification from both of you. I think I understand the differentiation between the queue and events a little better now.
My followup question deals with actual implementation. I am going with events because of the one-to-many property and their natural integration with GUIs. I have a main window from which I would like to open a sub VI popup when a button is clicked. This popup needs to run on its own (i.e. it can be closed/reopened and does not block the main VI). I also want certain data updates on the main VI to trigger updates on the popup (if it is currently opened). To do this I am assuming I would create a new loop and event structure in the popup VI then somehow register a user event created in the main VI to this sub VI's event structure. What I cannot figure out is how to pass the user event to the popup when I open it. I would like to think that it could be passed in via the connector pane, however, as far as I know, you cannot make a popup run independently in this manner (you need to get a reference and use the Invoke node).
Any thoughts as to how to connect these two together?
11-13-2018 02:01 PM
You can asynchronously call the VI and pass it a UE reference by doing something like what this article describes.
https://zone.ni.com/reference/en-XX/help/371361H-01/lvhowto/acbr_call_and_forget/
If you need data returned from that VI you can search "call and collect" or even just pass the VI a notifier/queue or some reference which can be used to pass data back to the calling VI.
11-13-2018 02:17 PM
Here is some code we use for passing user events around. Perhaps this will help you.
11-14-2018 10:56 AM
Based upon on the information I have received and documentation I have read, I cam up with the following possible solution.
My Main VI creates a new event based upon a cluster then fires this event when the user toggles a boolean switch on the front panel of the main VI. The event consists of an "type" enum, a "name" string, and a "data" variant. In the case of the toggle switch, I named the event "Boolean" of type "User" and sent the boolean value as the data variant.
My popup VI takes a User Event reference as an input on the connector pane and uses this to register for events in its own event handling loop. When the "Boolean" event is received, it converts the variant back into a boolean and displays this value on and LED.
Based upon everyone's experience, does this seem like a good method? The only thing that really stumped me was how to get a reference to the User Event as a control on the popup VI. I ended up right clicking on the output of the Create User Event block on the main VI and clicking Create->Control. I then cut this control from the main VI and pasted it into the popup VI. Is there a better way to do this? I couldn't find a "User Event Reference" in the palette.
Thanks!
11-14-2018 12:14 PM
You won't find an event reference type - each reference is specific to the data type of that particular event, thus there is no common 'event reference' type.