Jump to content

Event structure and case structure in the same loop


Recommended Posts

Hi

I am writing an application to update the numeric value given user's input value and depending on the user's input value the program checks if it is greater than 10 if it is greater than 10 then the program waits for 1 second and then will have a popup message says "true".

My intention was to call the conditional check, printing true every one second if the user's input value is greater than 10; in other words, the case structure was to be called regardless of the event structure in the same loop infinitely.

But it doesn't seem to work the way I expected. Unless there is user's new input value, getting into the event structure, the program doesn't get to the case structure even though the case structure is in a loop.

Is there any way to call the case structure not dependent to the event structure but I want to use a shift register for the numerical value and also having an event structure and a case structure in parallel ? 

Thank you.

 

 

Capture_event-loop2.JPG

Capture_event-loop.JPG

test.vi

Link to post
Share on other sites

Everything in the loop must complete before it can run again. Therefore, if the case structure is in the same loop as an event structure, they have a relationship and aren't really independent.

Edited by infinitenothing
  • Like 1
Link to post
Share on other sites

A while loop will not iterate until all nodes within have completed execution.

First thing: do you have a "Timeout" event case defined?  If not, your loop is going to "hang" and only loop when your "Numeric" value changes.  The wire you have currently running to the "timeout" terminal of your event structure is not going to do anything as this defines the amount of time that the event structure "waits' for an event before proceeding via the "Timeout" event case.  You'll need to wire a separate constant for your iteration delay (i.e. Timeout value), say: 1000ms.

If you wanted these two cases to be independent, you'd have to set up a second while loop and pass data between them.  I don't know what the end product is for what you're working on, so just for simplicity's sake, I'd say to set up your timeout event case.

Note: when this is running and your timeout case is set up, there will be up to a 1000ms (1s) delay from the time you press "Stop" until the VI stops execution.  This is unless you have a "Value Change" event set up for your "Stop" button. 

Edited by Bryan
Link to post
Share on other sites

 

8 minutes ago, Bryan said:

 

First thing: do you have a "Timeout" event case defined?  If not, your loop is going to "hang" and only loop when your "Numeric" value changes.  The wire you have currently running to the "timeout" terminal of your event structure is not going to do anything as this defines the amount of time that the event structure "waits' for an event before proceeding via the "Timeout" event case.

If you wanted these two cases to be independent, you'd have to set up a second while loop and pass data between them.  I don't know what the end product is for what you're working on, so just for simplicity's sake, I'd say to set up your timeout event case.

1. I don't have a "Timeout" and yes it does hang. 

2. Yes That's exactly I want to do. Where do I create a while loop ?

The end product is to display a histogram on LabVIEW in real time. The histogram library is written with .NET and my application reads the node from .NET, which keeps changing the histogram value and I want to iteratively read the value while the user is not blocked by it. That's why I will need an event structure for the user to press buttons. 

 

 

Edited by takanoha
typo
Link to post
Share on other sites

You're probably going to have to implement a producer/consumer design pattern if you want truly parallel processes.  There are many examples of them in the LabVIEW examples.  I wasn't sure whether going into producer/consumers was going to be overkill for what you wanted, but you may want to look into going that route based on your description.

For simplicity's sake (and my lack of time), and to illustrate what I was talking about in my first paragraph using a timeout case, I've attached a VI (in LabVIEW 2016) that uses the timeout case.  The default timeout is -1, which means that the event will wait forever or until an event occurs. In my attached, it waits for 100ms.  You can have the timeout be as long or short as you want as long as it's greater than -1.  

To keep the value in your shift register, you'll have to wire your shift register value straight through your timeout case.  If you don't, it will be overwritten by a default value (normally "0"). 

This method is a quick and dirty way of allowing the event structure to complete alongside your case structure and not be dependent on it while being in the same loop and not have the while loop hanging. 

I hope this helps!

Untitled 1.vi

  • Like 1
Link to post
Share on other sites

Here's another quick and dirty example just using local variables and two separate while loops.  I don't like using sequences and local vars in practice myself, but this is just a way to show you a simple way to control parallel loops.  It's quirky, but I hope it gives you an idea.  There are much better ways to implement parallel loop control and communication, but I just wanted to provide a quick example for you.

The "Stop" button is set up to use latch functionality, which isn't compatible with having it used as a local var, so I had to create a separate indicator for "Stop All" to "hold" the value to be used by the second loop.  Please don't use this as the best example as it doesn't really show good LabVIEW programming practice, but will at least show you what's needed for parallel loops.

Again, I hope I've helped you out!

Untitled 2.vi

  • Like 1
Link to post
Share on other sites

Looking at your original code, your timeout case had an output tunnel that was unwired.  As soon as your timeout case executed once, the timeout value would go to 0 and the sift register value would get stuck there.  If you set the timeout value to zero, you program will get locked in the timeout state.  Why did you wire the shift register value to the timeout input?  Anyway, if the shift register value is zero, the case structure will not execute.  There are also a lot of bad habits in your code.  You don't need the property node in the Numeric value change event, as it just writes the same value back to the control.  If you want to pop up a dialog every second if the value is greater than 10, then use the timing feature of the event structure to check the value in the timeout case.  See below for some simpler versions, and an explanation of your error.

 

timeout.png

 

What you want to do is to use the timeout feature of the event structure to check your value every second and display a dialog if the value is greater than 10.  Although I don't really recommend this type of structure, because the modal one-button dialog can easily block the user from pressing the stop button for rates faster than 1000 ms.  In this particular case, 1000 ms is long enough for the user to press the stop button.  For faster rates, it is not recommended.  The Numeric value change event updates the shift register, and the timeout event passes the shift register value through so that it does not change until Numeric changes.  I also moved the Numeric 2 indicator outside the event structure so you can see what the shift register value is.  If you had done this you would have noticed that your value was getting set to 0 by the unwired tunnel in your timeout case.  I also added a stop button value change to stop the loop when the stop button is clicked.test.vi

timeout2.png

 

test.vi

 

Edited by smarlow
Link to post
Share on other sites

You will notice in my example above that once the value exceeds 10, it is hard if not impossible to change the value again due to the one-button modal dialog box.  You can eliminate this problem by using a two-button dialog and giving the user the opportunity to reset the value using a Value Signal property node, as shown below:

reset.png

 

Or, if you prefer, you can use the case structures and a local to reset

 

reset2.png

 

test.vi

Edited by smarlow
added example code
Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Similar Content

    • By Mode_Locked
      My code watches for an event where my Toshiba USB stick is unplugged. If the event does not occur within 30 secs, the code times out. However, in the case that there is no disconnection of the USB stick (no event generated), I can't end the program before the timeout period of 30 sec. Is there a way to end the program before the timeout period? Any help is appreciated. Thanks in advance!
      WMI_USBStorage_Event_withDeviceIDandTimeOut.vi
    • By _Mike_
      Hello!
      I am running a system with GigE camera with NI framegrabber  in continuous acquisition mode - in which I change some attributes every now and then.
      So far I have been using following scheme to assert I am getting correct image after attribute change:
      change attribute read "Last buffer number" property -> n run IMAQdx get image.vi set to "buffer' and parameter n+2 (+2 being due to the fact that i assumed attribute change arrives to camere during running exposure that will be unaffected by attribute change - hence i needed to discard "next" buffer) Unfortunately I still every now and then acquired image that obviously was aquired with previous attributes (e.g. I've dramatically increased.decreased exposure rate, while acquired image was very similar to previously acquired one). Guessing that it may have something to do with buffers I have increased "magic number" from +2 to +3. It indeed helped, but after longer usage I have discovered, that it only reduced the frequency of the error.
      Hence I needed to design more "bulletproof" solution that will satisfy my timing requirements (stoping and starting acquisition is out of question as it takes more than 100ms what is unacceptable for me)
      I would like to:
      change attribute acquire information from camera that will allow me to fetch image acquired with changed attribute For such purpose I have discovered IMAQdx events - especially "Attribute updated" and "frameDone". Unfortunately, I could not find any detailed documentation about those functions. Therefore I would like to ask you for help to determine when 'Attribute updated" is triggered. Is it when:
      driver receives the command and pushes it to camera? (pretty useless for me as I cannot relate it to any particular exposure) camera confirms getting it (then assuming it arrives during an ongoing exposure, I'll discard "next' image and expect second next to be correct camera confirms applying it (then I assume that next image should be obtained with correct settings) camera confirms it managed to acquire a frame with new parameter (pretty unlikely scenario - but the i'd expect correct image to reside in "last" buffer) Could you help me determine which case is true? Also should I be concerned about the fact that there may be a frame "in transition" between camera and IMAQdx driver which will desynchronize my efforts here?
       
    • By dhakkan
      Hello,
       
      I searched within this site and via Google for any related queries. Couldn't find any. Hence this post...
       
      Example of Situation:
      I configured an I8 Numeric with non-default limits in its 'Properties >> Data Entry' window...
      Minimum of -2 (coerced); Maximum of 2 (coerced). I set up a simple event that looks for 'Value Change' of this Numeric.
       
      Expectation:
      No matter what the 'Increment' value and 'Response to value outside limits' are set to, the 'Value Change' must NOT trigger if the numeric is already at the limit and cannot be changed further. To explain, If current value of Numeric is 2 and I try to increment it, its value must remain at 2 and no event should be triggered. Similarly, with current value of Numeric at -2, if I try to decrement it, its value must remain at -2 and no event should be triggered.
       
      What I found was that the value does remain at the limit, but an event is still triggered when the 'Increment' setting is non-zero. Is this normal behavior?
       
      Test Numeric Event Triggering.vi coded in LV2014
    • By Manudelavega
      I have been trying to understand what's going on with my tree control and I'd like to share this with the community to see if somebody has seen this behavior before. Maybe there is something obvious that I am not seeing...
       
      I attached the VI (LV2011) with instructions inside (will take you 20s to perform the experiment, I dismantled the VI to its bare minimum). Please don't comment on the overall architecture (state machine...) since I modified the VI just for the sake of posting it here and removed all advanced features.
       
      Long story short, after programmatically modifying the value of the tree, I modify its value a second time by clicking directly on one of the tree items. I then expect the NewVal value given through the left node of the value change event case to match the value of the tree terminal. Depending on the code that first modified the value programmatically, sometimes this expectation is met and sometimes it isn't. Run the code, it's easier to understand that way...
       
      Thanks for your feedback!
      Tree value issue.vi
    • By Roryriffic
      Hi all,
       
      new to Lava, so (kindly) let me know if I screwed up my post
       
      I have a multi-user web application controlled by a LV web service.  I keep track of all the users through the web service > sessions VI's.  This is pretty cool and works really great. I can give each user different levels of authentication, force them to use SSL, track where they go and when throughout the website, etc.
       
      Now what I'd like to do is keep track of when their session expires.  Obviously I can provide a "Logout" link on the client-side which ultimately calls the "Destroy Session" VI, but I can't ensure that all clients will click the link to log out (e.g. how many times do you really sign out of gmail verse just close the browser?!)
       
      What's the best way to catch the session timeout event that is specified during "Create Session" VI?  It appears as if I need a "LV Web Service Request" object to even call the Destroy Session VI, which makes matters much more difficult it seems. Is this even possible?
       
      Thanks for the help
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.