LabVIEW Channel Wires

cancel
Showing results for 
Search instead for 
Did you mean: 

A new channel template in LV 2017: Event Messenger

[EDIT] The following was posted for LV 2016. This new channel template officially shipped with LabVIEW 2017. You only need to install the .vip if you are still using LV 2016.

 

Channels and event structures need to work better together. This is a new channel template to facilitate this.

 

This template will ship with LabVIEW 2017. I am making it available here for LabVIEW 2016 f1. You need the 2016 f1 patch for this template to work.

 

Step 1: Install the 2016 f1 patch

 

Step 2: Install the .vip attached to this post. This installs the new template.

 

Step 3: Open the shipping examples in the .zip file attached to this post.

 

Step 4: Take a look. I already have enough feedback to know this will definitely ship with LV 2017, but if you see any fine grain details that could use fixing, please let me know through comments here.

Untitled.png

[EDIT] Version 1.0.0.2 fixed a bug. "last element?" is now false in event frame when aborted, consistent with the other channel templates.

Message 1 of 19
(17,088 Views)

I don't use a current version of LV, so no channels for me, and I can't inspect the code, but a couple of questions do come to mind from looking at the image:

  1. What's the different between stop and abort? Does abort ignore the rest of the elements in the queue?
  2. What is the element valid? output?
  3. Is there a clean way of ensuring registration before generation? Is this simply built into the channel? Presumably it can't be, since the generator can't know how many listeners will exist. Would this simply be accomplished by looping the registration wire back as an input to the left loop to force data flow?

___________________
Try to take over the world!
0 Kudos
Message 2 of 19
(16,804 Views)

AQ, usual question....  What patch level do I need for Mac OS X?  Or linux?

I think the difference between Aborted and stop is that with abort, the last element is not valid and not processed.

This is very different in that the channel reader is outside the loop and only reads once to pass the User event reference.  Then each subsequent channel write is merely a user event and not channel data transmission.  The event itself passes all the data.

In this case the channel actually only transmits data once?  Am I reading the example right?

This is a somewhat confusing mixture of event and channel data transmission.

LabVIEW ChampionLabVIEW Channel Wires

0 Kudos
Message 3 of 19
(16,807 Views)

I've just "played with" the new Event Messenger Channels, and before I "complain", I want to try to answer Tst's questions (this will serve as a "check" that I "get it" -- AQ can correct us both).

  1. The difference between Stop and Abort is that AQ wired "Stop" into the "Last Element?" input, thereby potentially causing a little confusion.  I'll say more about this in my next post, "BS Comments on Event Messenger Channel".  What Last Element? does (if true) is a little unclear -- for a Stream, if it is true, it writes the Element to the Channel (assuming "Is Valid?" is True) and closes the Channel, making future attempts to write to the Channel ineffective (hence it is usually wired to the Stop terminal).  The "Last Element" flag is associated with the Element, and will thus only be True when the Last Element pops up at the Reader (hence it is also usually wired to the Stop terminal).  This means that a slow Consumer "has time" to Consume all of the Elements, even if the Writer loop has finished long ago and exited.  Abort is different -- when Abort is set True on the Writer, it is also set True on the Reader.  However, unlike the Stream with Abort Channel, the Event Messenger Channel has a "side effect" that Aborted? on the Reader also sets "Last Element?" on the Reader.  While technically it is logical that if the Channel is Aborted (and thus cannot send more data, even if the Producer loop is still running) that you have, indeed, received the "last element", these are, in fact, slightly different elements.
  2. Element Valid? is there to allow you to send the "Last Element" (or "Stop") flag without actually sending data that you'd only have to throw away.  When I use Queues to send Arrays of Data, and my Producer gets a signal to stop, I send an empty Array to the Consumer and let the Producer exit, leaving the Queue intact.  In the Consumer, I keep checking for this empty Array, a piece of "Element Valid = False" data that means "Last Element" -- when the Consumer sees "Element Valid = False" and "Last Element = True", it knows it can exit and (in the case of Queues), safely Release the Queue.
  3. I'm not sure what you are asking.  In AQ's Example 1, which has two Events, a button push and a (slow) Consumer, you can delay the Producer (I wired a 5-second Delay before I let the Producer run).  The Consumer ran just fine, registering button pushes and, after 5 seconds, registering data from the Producer.  I suppose the Event Registration in the Consumer ran first, even though there was no "data in the Pipe" (and wouldn't be for 5 seconds) -- the Producer and Consumer are really running in parallel, asynchronously, so delaying the Producer (and the filling of the Pipe) doesn't impact the Consumer (except as it has to deal with an empty pipe).

Bob Schor

0 Kudos
Message 4 of 19
(16,807 Views)

AQ,

     Here are my (extremely picky) Comments on the new Event Messenger Channel.  I basically like it, but ...

  • This is a purely aesthetic point -- the Event label "<channel value>:User Event" is ugly.  Use proper Case and capitalize things, such as "<Channel Value>:User Event".
  • Event Data Nodes are usually also Capitalized (Time, Source, NewVal) -- consider doing this for the Event Messenger Data Nodes.
  • Other Channels that have both Last Element? and Abort (notice the capitalization?) inputs and outputs keep them "separated".  While I see the logic in reasoning that if the Channel has been Aborted, no more elements will be forthcoming (and, hence, "Last Element" is logically true), it is not clear why you've made this change only for Event Messengers.  Other Channels separate these outputs (well, I only tested the Stream Channel, and I think I could set Abort without setting Last Element), so it makes sense that the "new guy" follows the same rules.
  • On the other hand, since Channels are relatively new and possibly few of us are using them (I definitely am doing so, quite enthusiastically), and since other Channels have "Abort" as a (possibly seldom-used) option, if you wanted to make Abort force Last Element to be False, allowing a single "Stop" test for a Reader loop, and make this uniform across all Channel types, now would be the time to do this!
  • Thank you for providing a way to Label multiple Event Registrations.  I'd discovered how to do this with "regular" Event Reg Refnums (label the input to Create User Event).  Now if we can only get "<channel value>" to be "prettier" ...
  • Some (all?) of the points I raised come from a context of trying to get newcomers to LabVIEW "tuned in" to some of the key concepts, such as Data Flow and being able to grasp the structure of code by looking at a well-designed Graphical Representation (a.k.a. "Style Matters!").  Introducing (asynchronous) Channels is a Blessing and a Curse -- I've held off showing it to my students and colleagues until they are ready for parallel loops running asynchronously, but I've definitely been applying it to my own work.

Bob Schor

0 Kudos
Message 5 of 19
(16,807 Views)

I've just made my first "real" Event Messenger Channel, and it works like a charm.

I've been using Channels for all of my new development work.  Several of my Projects use a Channel version of the Queued Message Handler (I call it a Channel Message Handler), with an Event Loop on top handling Front Panel button pushes and a State Machine / Channel Message Handler below.

One thing that spoiled the "clean design" was handling the Exit button.  When Exit is pushed, the Event Loop's Value Change fires, I put an Exit Message on the Messenger Channel, and tell the Event Loop to stop running.  The Message Handler sees the Exit Message, cleans up, and stops the Messenger loop.  With both loops stopped, the program exits.

But what if there's an Error?  The Messenger Loop also can process an Error Message, which outputs some text, then puts the Exit Message on the Messenger Channel so that we exit cleanly (all the ShutDown code is in the Exit state).  But how to shut down the Event Loop?  That wasn't pretty -- I did it by making the Exit button not a Latch when Released, but a Push Button, which worked, but was not (in my mind) ideal.

Enter the Event Messenger Channel.  I created an Event Messenger Writer for my State Enum (of which Exit is a member) and place that in my Exit State.  I also create a corresponding Event Messenger Reader which I position next to the Dynamic Event input terminal of my Event Loop.  I wire the Exit state to the Writer's input, snake the Channel out the Message Handler and over to the Event Loop, and then add an Event Case for the new Channel Dynamic Event.  A Nice Feature is that the Input Node is named NBState, which is the name of the TypeDef whose Enum is carried by the Channel.  Now all I have to do is detect if Exit is on the Channel, and if so, exit the Event Loop.

That's not quite 1000 words, so here's a picture:

NB Event Messenger.png

Bob Schor

0 Kudos
Message 6 of 19
(16,805 Views)

This is a reply to Sth's about the Channel Reader being outside the Event Loop, suggesting that the Channel passes Events and the Event Loop processes the data.  He then ask if the Channel only transmits data once.

I've played with the Examples, and have made an Event Messenger myself, so here's my take on things.  Yes, the Channel passes Events and the Event Loop processes the data.  However, every Write to the Channel causes data to by put into the Event Loop's Queue (where it is handled just as in a more common Queue, in the order received.

Here's how I conceptualize this.  The creation of the Channel Reader and wiring it to the Dynamic Event node both adds the <channel value>:User Event as a possible choice for the Event Structure, and also creates (behind the scenes) what used to be the User Event Queue.  Calling the Channel Writer puts things onto this Queue, where they are transferred to the User Event Queue "in the order received" (I'm not sure these take place as separate steps, but it helps me to think about it in this way).  I've done a little test routine that shows that you can have the Event Loop running before you put anything into the Event Messager Writer, just as you can have an Event Loop that process Button Pushes before you generate any User Events (in the non-Channel Dynamic Events).

Bob Schor

0 Kudos
Message 7 of 19
(16,807 Views)

Re 1: Same as other channels. "last element?" signals this is the last transmission. "abort" clears events already sent previously that haven't already been processed.

Re 2: Same as the other channels. [including LV 2015]

Re 3:

> Is there a clean way of ensuring registration before generation?

Yes.

> Is this simply built into the channel?

Yes.

> Presumably it can't be,

Upgrade and see. 🙂

0 Kudos
Message 8 of 19
(16,807 Views)

The capitalization in all of this is correct for NI style guide. We capitalize function names and lower case parameter names. We capitalize type names and lowercase field names, including event data. We capitalize UI controls. So the Stop button is wired to the last element? terminal.

>Other Channels that have both Last Element? and Abort ... inputs and outputs keep them "separated". 

I did not believe I had made any change vis-a-vis any other channel. I'll double check.

0 Kudos
Message 9 of 19
(16,807 Views)

Argh. Yes, there's a difference of behavior there. Let me check with team... since it has shipped, the preponderance of opinion will almost certainly be to make this one match the existing.

0 Kudos
Message 10 of 19
(16,803 Views)