LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Managing USER EVENTS in large projects

Hallo, this is a long question with possibly short answer that is already existing somewhere, but I didn't find:

 

I inherited a BIG LabView-2015-project. My precedessor organized the whole project synchronization with USER-EVENTS.

It is a complete Spaghetti-code-nightmare, but it works.

I feel I didn't understand something basic about user events.

My LabView-Life worked PERFECT using Named-Queues for synchroniting MY big projects so far.
But now I have to deal with theses USER-EVENTs...

 

If you look for examples on user-events you'll find a lot in the net. But all are small examples.
I kind-of understand the basic scheme... but how do you deal with 100s of user events all with different datatype?
I mean you cannot NAME them and the down-the-way locally in some sub-sub-sub-VI generate a reference on it ?

 

I tried to put my dilemma in the attached VI/picture.
There I compare the Named-Queue Synchronization with the user-Event Synchronization.

I don't want to trigger a discussion on what is better to use.

For this one project I have to live with USER-EVENTS.

Has anyone a link or post on how to ORGANIZE the user events.
I mean, should you really save all the references and event-wires in a GLOBAL-VI ?
And then acess the references from the same global VI from within all sub-VIs?

That sound odd.

 

Hm... I feel this is a very stupid question.... OK...
But why is it stupid? NI must have had a usage scheme in mind that is different from using references in globals.

Thanks a lot, Sebastian

Download All
0 Kudos
Message 1 of 12
(200 Views)

I have a little trouble understanding precisely what your question is.

 

Do you understand how user events work?

 

I don't think so because the comparison you show in your image is incomplete.

0 Kudos
Message 2 of 12
(172 Views)

Events are One to Many, Queues are Many to One.

If you want to signal/broadcast something to many listeners, you need Events. If you want many to use e.g. a single resource like a com-port, then you better use Queues.

Neither are really a good option to synchronise stuff since you can't know when they're executed. You can however use an event to send out a Notifier or Semaphore if you want to do that.

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

Qestit Systems
Certified-LabVIEW-Developer
0 Kudos
Message 3 of 12
(153 Views)

Named queues are just global variables in disguise. That is probably one reason why User Events are not addressable by name. Global variables are also very much not modular.

 

You can emulate the queue behaviour by sticking every Create User Event in an FGV and create the event on first use. Then you will at least know all the places where the reference is used.

If you then make the FGV private to the module and give the module a public API (which can access the FGV) it will make your life easier.

 

If you want to learn how to use User Events in modular applications, take a lot at the DQMH framework. It does what I wrote and a lot more.

0 Kudos
Message 4 of 12
(150 Views)

@Yamaeda wrote:

Events are One to Many, Queues are Many to One.

If you want to signal/broadcast something to many listeners, you need Events. If you want many to use e.g. a single resource like a com-port, then you better use Queues.

Neither are really a good option to synchronise stuff since you can't know when they're executed. You can however use an event to send out a Notifier or Semaphore if you want to do that.


Slight expansion:

Events can be many to many, one to many, many to one or one to one depending on how the registration is handled.

0 Kudos
Message 5 of 12
(137 Views)

@Intaris wrote:


Slight expansion:

Events can be many to many, one to many, many to one or one to one depending on how the registration is handled.


Yes. Many is any number from 0 to lots, in this case you don't need to have any listeners/consumers of an event at all. With many to one it's basically a queue with the option of expanding the reactors of the event.

However, the point is that having many users/reactors to a queue is quite messy, so from a basic/introductory perspective, the many-to-one and one-to-many is a good analogy. 🙂 

 

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

Qestit Systems
Certified-LabVIEW-Developer
0 Kudos
Message 6 of 12
(124 Views)

OK, I am not an expert on USER EVENTS, since my life worked fine without them until now.

Hm... so what basic thing is missing in my image? Maybe that is part of the problem...

Yes.. of course ... the "destroy Event", yes. but that makes it even messier....
I attached a picture of the bigger (messy) project.

I mean, the project works.
I just ask, what is a way to clean it up.

If I had something like "obtain reference of user event" VI....

0 Kudos
Message 7 of 12
(97 Views)

There is an addition aspect to User Events which you seem to be missing.

Each event, and a subsequent "Event Registration Refnum" is it's own queue.

Bundling them together via multiple events is more like bundling together lots of different queues to handle one at a time. Execution order is maintained across all of these queues due to a timestamp being added to each and every event fired.

 

So there are two sides to user events. On one side, the User Event itself is the "sender" of events. Creating a user event, firing it and destroying it actually does nothing because nobody has registered for it. The User Event is not a queue, it's more like a "sender API". Without having someone registered for it in the background, there is no queue. The queue gets created for each consumer who registers for it. As such, the "Destroy event registration refnum" is actually akin to destroying a queue.

 

There's an old video from Jack Dunaway which goes through it really well (and which taught me a lot of the topics I'm trying to explain here.)

 

https://www.youtube.com/watch?v=1uyCfLiqB6I

Message 8 of 12
(87 Views)

If I had something like "obtain reference of user event" VI....

use FGVs

 

snip.png

 

You can bundle multiple event refnums into a cluster and wire them togehter it to a Register for Event node.

You can also bundle multiple Register for Event refnums into a cluster and wire that to a Dynamic Event Terminal.

Wiring the Event Registration Refnum wire to multiple Dynamic Event Terminals is similar to dequeuing from the same Queue Refnum at multiple places.

 

Here is the repository to the video above: https://github.com/donyaco/LabVIEW-User-Events-Tips-Tricks-and-Sundry

 

0 Kudos
Message 9 of 12
(77 Views)

@Seb77 wrote:

I just ask, what is a way to clean it up.

If I had something like "obtain reference of user event" VI....


Don't blame user events for long wires on your block diagram.

 

Have a look at

https://www.notatamelion.com/2014/10/23/making-udes-easy/  (with template code in SVN repository)

https://www.notatamelion.com/2016/04/12/implementing-dynamic-user-defined-events/ 

 

There you see an example how to put an user defined event (UDE) in a library having 3 public VIs, which form the API for the UDE.

UDE Library.PNG

One VI for registering the event at every event structure which is listening to the event.

One VI for generating the event.

One VI for destroying the event.

 

When using the library the long wires on your block diagram are gone, as in your overview of your named queues.

Message 10 of 12
(68 Views)