LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Struggling with Event Structures

Solved!
Go to solution

I'm pretty new to LabVIEW and I'm having some real difficulty with event structures. In the example I've attached, I have a very simple VI where the user inputs an array. There are three buttons, one to close the VI, one to clear the array, and one to graph the array (I know I could just use a case structure in the while loop to do the graphing, I'm trying to learn how to use event structures). 

 

When I run this VI, it 1) doesn't graph, 2) won't close until after all three buttons have been pressed. I have no clue what's going on, when I run it in debug mode and step through something weird is going on and I can't figure out where the VI is getting stuck on. I'm not sure if it's because of the condition (on button push) and maybe that condition is being hit before the VI runs on accident, or what. I'm honestly really confused here.

0 Kudos
Message 1 of 8
(4,804 Views)

LabVIEW is a little different from languages like C, Basic, and Matlab -- it uses the Principle of Data Flow which gives it some unusual properties.  If you are learning LabVIEW on your own, without access to a book, a course (like NI's Core 1 and Core 2), or a decent Mentor, it will be a little more difficult, particularly for some concepts like the Event Structure, which is (almost) always combined with a surrounding While Loop to make an Event Loop.

 

The purpose of an Event Structure is to respond to an Event, when it happens, without you having to write a lot of code ("Did it happen yet?  Did it happen yet? Did it happen yet? ...")

 

Going back to the Principle of Data Flow, a "naked" Event Structure can only respond once when an Event occurs.  A common way that an Event Loop is used is to have a While Loop surrounding a single Event Structure and to put every Event that you want to acknowledge (the most common of which are Changes to Controls on the Front Panel, i.e. "Did you push the Stop button?" or "Did you enter the Number of Data Points?") in a separate Event Case (the Event Structure has some aspects like a Case Statement and can handle multiple Events).  When the chosen Event "fires", code in the Event Structure decide what to do about it.

 

Often this takes place "somewhere else", in another loop running in parallel with the Event Structure.  You can learn about this by learning a little more LabVIEW.  Besides the Training listed on the first page of this Forum, you can also go on the Web and ask about "LabVIEW Event Structure tutorial" and find more information.

 

It is a very rare thing to find an Event Structure without a surrounding While Loop.  It is also very rare to find more than one Event Structure in a well-written LabVIEW VI.

 

Bob Schor

0 Kudos
Message 2 of 8
(4,764 Views)
Solution
Accepted by Tarnarmour

I can tell you're pretty new to LabVIEW.

 

First, about 99.9% of the time you will need to put the event structure inside a While loop.

Second, about 90% of the time you want to only have one event structure per VI.  

 

I'm guessing that you don't know a few things:

  • Event structures can have more than one frame, just like case structures
  • Event structures (and all structures, actually) follow the rules of dataflow
  • The most basic rule of dataflow, "A block diagram node executes when it receives all required inputs", applies to structures, even though they might not seem like a "node".
  • The way event structures work may appear simple but is rather complex "under the hood"

Basically the way an event structure works is as follows:

  1. First, an event "registration" occurs.  If it's something like "mouse down" or "value change", it occurs the moment your VI starts running.  This registration occurs for every event that is listed at the top of an event frame.  (There are ways to register for thing after it start running, but that's way too complex to hand to a beginner)
  2. Next, the dataflow has to get to the event structure.  This means that every wire leading to it comes from a node that has finished running, and that any structures that it is inside of are currently active.
  3. Then, the event structure now checks its "registration" to see if any events happened on the list that it cares about since the last time it was run.  If any of them have run, it takes the first one that occurred, and finds the frame with it, and starts that frame running.
  4. If none of them have occurred yet, it waits for one of them to occur.  This could take forever if no events occur.  There is an event case created by default when you create an event structure, and if you wire a value to the hourglass terminal at the top left of the event structure, the event structure will wait that many milliseconds and then fire the event structure on the "timeout" frame if no other event happens before it.
  5. Eventually one of the frames inside the event will have run.  This frame continues to run until all of the nodes inside of it have completed.
  6. Finally, the event structure exits, and any wires leaving the event structures now contain data and allow anything connected to them to run and any structure it was inside to finish.

 

So, all of that boils down to this for your specific VI:

  • Put a single event structure in your while loop.
  • In that event structure, add one frame for every button press you want to do something on, plus a timeout case
  • Put every button in the event frame that triggers it
  • In the timeout case, put anything you want to run on a regular basis
  • Use shift registers (best) or local variables (bad, but easier to figure out) to pass data between the event frames

 

Message 3 of 8
(4,763 Views)

Thanks for the quick and very well written response! This all makes a lot more sense.

 

The only question I have now is if the event structure needs a timeout case, does that mean we have to wait at least 1ms for an event structure that hasn't had an activation? It seems like there could be cases where this is pretty slow (though admittedly I can't think of one off the top of my head).

0 Kudos
Message 4 of 8
(4,748 Views)
Solution
Accepted by Tarnarmour

The timeout case isn't required, and you can wire a 0 to the timeout.

 

Couple things to note

1. If you don't have a timeout case the event structure will wait to execute till a event occurs. This will stop the data flow and "block" till an event occurs.

2. If you wire a 0 to the timeout be aware that this is akin to running a while loop without a wait function.

Download All
Message 5 of 8
(4,737 Views)

Kyle's message is very well written.

 


@adekruif wrote:

The timeout case isn't required, and you can wire a 0 to the timeout.

 

Couple things to note

1. If you don't have a timeout case the event structure will wait to execute till a event occurs. This will stop the data flow and "block" till an event occurs.

2. If you wire a 0 to the timeout be aware that this is akin to running a while loop without a wait function.


I would add one more commend to adekruif's message.  If you wire a value of -1 to the hourglass terminal, that is the same as an infinite timeout.  It will never timeout.  Why would you want a timeout case and have a -1 wired to the hourglass?  While the vast majority of the time you'll see a constant wired to the timeout terminal, it can be programmatically determined.  Perhaps you don't want to timeout when the VI first starts, but after some other event happens, you want to enable the timeout case.  You can use a shift register to store the timeout value and wire that to the timeout terminal so you can programmatically change what the timeout wait should be.

0 Kudos
Message 6 of 8
(4,717 Views)

You already got some detailed advice. One good way to understand dataflow is to run your VI in highlight execution mode. It will be slow, but you can follow what it does.

 

Properly programmed, you need one toplevel loop containing a single event structure. None of you methods and property nodes are needed. It is very rare to use "mouse down" events on latch action buttons. A better choice is "value changed" (mouse down is tricky because it can be used to trigger something if the item is an indicator or even disabled. much more dangerous!)

 

You don't need an event for the graph, just update the graph whenever the array changes.

 

Never delete the labels of controls (stop). You can hide it on the front panel if you don't want to see it there, but it should always show on the diagram.

 

The only thing you want to clear (do you?) is the array. latch action booleans (all your buttons) reset automatically.

 

Here's a very simple rewrite. See if it makes sense to you.

 

altenbach_0-1601309318929.png

 

0 Kudos
Message 7 of 8
(4,577 Views)

What a great explanation. I came from traditional programming to labview and this helped me a lot. Thanks.

0 Kudos
Message 8 of 8
(2,415 Views)