LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Design question to LabVIEW events experts

Dear gurus,

 

I'm currently writing a binding for a distributed Control System (CS) offering an event service. The idea is to map the CS events onto the LabVIEW ones. 

This binding is itself a DLL (or shared library) from which LabVIEW events are fired using the PostLVUserEvent API (cintools/extcode.h). 

A CS event is associated with a uniquely identified "CS variable". Whichever is the event source (i.e. the CS variable), a CS event always carries the same data structure (which is mapped to a cluster named CSVarValue in LabVIEW). Classically, the developer must register for a particular CS variable in order to receive the associated CS events. I hope, I'm clear.

 

As far as I understand the way user events are instanciated in LabVIEW, the name of the input parameter passed to the "Reg. For User Event" Vi is used to identify the "new" LabVIEW event. In this case, systematically passing the CSVarValue cluster to "Reg. For User Event" will always "refer" to the same LabVIEW event? Right? Does it means that only one events structure can be used in my case? How can I create a user vent and associate it with its own events structure (i.e. its own event handler)? 

 

In fact, I did a test with two separated event structs (see below). I seems that they have an influence on each other (e.g. no refresh of one till the timeout of the other expires, app. slowdown, ...). 

 

So, finally, what could be the best approach/design in my case? I really would like to be able

 

Thanks for you help.

NL.

 

 

In the following example, the "T Sub.[P,C] Evt" Vi contains the "Reg. For User Event" call. The resulting event ref. num is then injected into the "T Evt. Hdlr" containing the an event structure.

 

lv-events.jpg

 

 

 

 

 

 

0 Kudos
Message 1 of 12
(3,778 Views)

Oops, there's a unterminated sentence in my previous post. I meant...

 

So, finally, what could be the best approach/design in my case? I really would like to be able to be able to use a "per event handler". Otherwise, I will have to filter the event source using the strings contained into the incoming CSVarValue - which is quite ugly. 

 

BTW, it seems that my question can be summarized the following way: how can I dynamically (i.e. programmatically) change the name of a user event? Which is finally equivalent to: how can I change the name of the data structure (cluster) used to created the user event? Reading a post in this forum there's no obvious/simple solution to this problem. Right?

 

Thanks for you help.

NL.

0 Kudos
Message 2 of 12
(3,750 Views)

It's a little hard to understand what you're asking, and your screenshot does not make it much clearer since all the important items are inside the subVIs that we can't see.

 

You can certainly register for multiple events that all share the same data structure.  You'll need a separate copy of that data structure (these can all be instances of the same type definition) for each event, and you'll need to change the label for each instance so it's unique.  Does that answer your question?  If not, can you upload your actual code and try to be a bit more clear about the problem?

 

You can also dynamically register and unregister for an existing event, although I'm not certain if that's what you're trying to do.  You can create a User Event Refnum constant and register for that event, even though the default value of a refnum the refnum is null (invalid).  Later you can feed a valid user event reference into Register for Events to register for that event instead.  The Dynamically Register for Events example included with LabVIEW demonstrates this idea, although it uses control references instead of user event references.

0 Kudos
Message 3 of 12
(3,693 Views)

nathand,

 

Thanks a lot for the detailed reply. Sorry for being so unclear.

 

1> You can certainly register for multiple events that all share the same data structure. 

2> you'll need to change the label for each instance so it's unique.

I agree. That's exactly what the LabVIEW documentation says: "user event data type is a cluster of elements or an individual element whose data type and label define the data type and name of the user event". It means that passing the same data structure with the same label to each call to "create user event" will always return the same "user event" (i.e. same user event identifier).  However, I discovered that changing the execution property of my event subscription Vi (see below) to "Reentrant + Prealloc clone" change the behaviour. I suddenly obtain to distinct user events without changing the data structure label! My LabVIEW knowledge is not good enough to explain it but that's exactly what I needed to obtain "per event handler" design I wanted. 

I guess that the magical stuff is more in "Prealloc clone" than in tha fact of chaging the execution mode to reentrant. Could someone explain me what happens behind the scene?

 

3>You can also dynamically register and unregister for an existing event...

Frankly speaking, I'm not sure to understand this paragraph (due to my poor LabVIEW programming skills). 

 

 

event-subscription.jpg

 

 

0 Kudos
Message 4 of 12
(3,676 Views)

I think it would be a lot easier to help if you attach your VIs instead of a limited screenshot.

 

Are you saying that the VI shown in the screenshot is the one that you made reentrant?  How is this VI being used?  How many events do you need to register?  When you say "per event handler" are you saying you want a different event structure to handle each event, or just that you want each event in the DLL to correspond to a unique LabVIEW user event so that you can handle each event in a different frame of the same event structure?

 

I just wrote a subVI that generates a user event (not reentrant), put two instances of it on the block diagram, and wired each user event to the same Register for Events node.  When I look at the available event cases I see two distinct events (with the same name).  So I'm not sure that it matters if the subVI is reentrant.  The problem might be the way you're passing around the user event registration refnum, not the user events.

 

The two VIs attached (LabVIEW 2011) show that the same non-reentrant subVI can generate a unique user event for each instance of the VI.  It also shows what I was saying about dynamically changing event registration.  Note that only one of the two user events responds at a time - when you click the button for one user event, then it stops listening for that event and starts listening for the other event.  I hope that helps.

 

Why are you passing the event registration refnum to the DLL?  I can't imagine what the DLL would do with that value.

Download All
0 Kudos
Message 5 of 12
(3,660 Views)

> I think it would be a lot easier to help if you attach your VIs instead of a limited screenshot.

Ok. Everything is in a big llb but I should be able to extract the required Vis. Will do that ASAP.

 

> Are you saying that the VI shown in the screenshot is the one that you made reentrant? 

Yes. I changed its execution property to "reentrant + prealloc clone...".

 

>How is this VI being used?

The Vi shown is the screenshot is just the "content" of the subscription Vi named "T. Sub P Evt" you can see in the screenshot attached to my initial post.

 

> The two VIs attached (LabVIEW 2011) ...

Thanks a lot for the example. Unfortunately, I'm still running 2010 on my Linux system and I can't open them for the moment.

Could you make them 2010 compatible please?

 

> Why are you passing the event registration refnum to the DLL?  I can't imagine what the DLL would do with that value

Just an implementation detail. This choice comes from a technical constraint due to the fact that the event registration refnum is all you get (to identify the event) in the context of "unregister for events".

 

Thanks again for all.

 

0 Kudos
Message 6 of 12
(3,634 Views)

Attached are my "event oriented" Vis (the main Vi is named TangoEventsTest).

 

Also fogot to answer some of your questions...

 

> How many events do you need to register?

The binding I'm developing is supposed to be used by anybody who wants to develop a control system client in LabVIEW. Depending on the application, he/she could register tens of control system events.

 

> When you say "per event handler" are you saying you want a different event structure to handle each event

That's the idea, one event, one handler. Ok, we could also use a single event struct for the control system events and filter the event source within this struct using tthe info (strings) coming with the data.

 

 

0 Kudos
Message 7 of 12
(3,624 Views)

nl-soleil wrote:

> The two VIs attached (LabVIEW 2011) ...

Thanks a lot for the example. Unfortunately, I'm still running 2010 on my Linux system and I can't open them for the moment.

Could you make them 2010 compatible please?


No problem, here they are in LabVIEW 2010.


nl-soleil wrote:

> Why are you passing the event registration refnum to the DLL?  I can't imagine what the DLL would do with that value

Just an implementation detail. This choice comes from a technical constraint due to the fact that the event registration refnum is all you get (to identify the event) in the context of "unregister for events".


I think it it would be better to use the event refnum as the identifier, not the event registration refnum, because the event registration refnum changes data type whenever the events for which its registered change, and that makes it problematic to pass into a subVI (if you every change the event registration, you need to recreate the control, as documented in the help).


@nl-soleil wrote:

> When you say "per event handler" are you saying you want a different event structure to handle each event

That's the idea, one event, one handler. Ok, we could also use a single event struct for the control system events and filter the event source within this struct using tthe info (strings) coming with the data.


These aren't the only two options.  One event structure can be registered for multiple events - drag down the Register for Events node to expose more inputs.  That would be better for this situation - multiple events, one event structure with separate cases for each event.  Then maybe the only issue is getting the events named properly, since if you create them in a subVI they will all have the same name (the name of the subVI event refnum output).  One way around this would be to register a bunch of "dummy" events (using event refnum constants with the correct names), then update the registration with the real events after creating them.  Another is to use the typecast trick - you can typecast a wire to exactly the same datatype, but wire a constant as the target type and set the constant's label to whatever you want.  This will rename the wire, and therefore the event as shown in the event structure.

Download All
Message 8 of 12
(3,599 Views)

Here is an approach we use. In a nutsheel we create libraies for our events. I posted our generic system library. We may also generate application and task event libraires.

 

The highlighted area shows how we register for the events.

Event Registration.PNG



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 9 of 12
(3,575 Views)

nathand,

I now have all the options and have now to choose the better approach for my case.

Your example is a good starting point to refactor my implementation.

Thanks so much for you help. I really appreciate it.

N.

 

 

0 Kudos
Message 10 of 12
(3,562 Views)