LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Fire "events" from object

Solved!
Go to solution

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!

0 Kudos
Message 1 of 10
(2,654 Views)

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.


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
Message 2 of 10
(2,636 Views)

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!

0 Kudos
Message 3 of 10
(2,611 Views)

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.

Matt J | National Instruments | CLA
0 Kudos
Message 4 of 10
(2,602 Views)

@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.

G# - Award winning reference based OOP for LV, for free! - Qestit VIPM GitHub

Qestit Systems
Certified-LabVIEW-Developer
0 Kudos
Message 5 of 10
(2,563 Views)

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?

0 Kudos
Message 6 of 10
(2,536 Views)
Solution
Accepted by topic author patrick.wright

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.

Matt J | National Instruments | CLA
Message 7 of 10
(2,530 Views)

Here is some code we use for passing user events around. Perhaps this will help you.



Mark Yedinak
Certified LabVIEW Architect
LabVIEW Champion

"Does anyone know where the love of God goes when the waves turn the minutes to hours?"
Wreck of the Edmund Fitzgerald - Gordon Lightfoot
Message 8 of 10
(2,525 Views)

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.

Main VIMain VIMy 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.

Popup VIPopup VIBased 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!

0 Kudos
Message 9 of 10
(2,504 Views)

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. 

0 Kudos
Message 10 of 10
(2,495 Views)