LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

prevent double clicking action on mouse

If you post a small example of this inconsistent result, we could perhaps help to fix up the logic. Altenbach's basic idea is sound, given your description of this situation.
Jarrod S.
National Instruments
0 Kudos
Message 11 of 22
(1,781 Views)

hi Jarrod S.

Sorry about the delay getting back to you with the example. I have been pulled out from this task for a while due to other priorities. Here is the example (attached). I think having many loops have caused inconsistent result, so I'm trying to set flags to control the condition. But so far still have no success.

dphan128 

0 Kudos
Message 12 of 22
(1,765 Views)
OK, there's a lot to go through here. I think there are a number of things we should address before getting to "what happens if a user clicks a button twice on accident." When we get some of these things cleaned up, the solution to that question should fall very naturally into place.

  1. Waits in Event Loops: This is not at all necessary. Usually it's good practice to put a small wait in a while loop to make sure that it doesn't use up 100% of the CPU and starve other tasks. But here the timing of the event loop is controlled by incoming events, which are unlikely to come in often enough to make a dent in the overall CPU usage. In other words, the user can't physically click a button one million times a second. It just won't happen. So erase these waits. If you do want a specific set of code to execute every so often in an event loop, put it in the Timeout case and wire a millisecond value to the top left terminal of the event structure. You don't have any code there, so I'm assuming you don't need anything of the sort right now.
  2. Multiple Event Structures: Multiple event structures are usually discouraged in one VI. Some people argue why they might be necessary, but I've personally never heard a convincing argument that couldn't be handled better with a well-architected single event structure design. (Here are some caveats for using event structures.) You have at least three options that I see.
    1. Put your Task 1 and 2 event cases in the first event structure. There's nothing wrong with signaling one event case from another. If you signal multiple events, they'll get stored in an event queue and execute in the order they were signalled.
    2. Put the code to run the tasks in the Start event case itself. This would actually solve your original dilemma, because by default, LabVIEW locks the entire front panel until an event case completes for a given event. So when your user presses Start, the front panel actually locks until Start:Value Change finishes completing. If your task code was in that case, then your problem is solved.
    3. If you really want the separate tasks to execute in a separate loop (and there are plenty of good reasons for this), then I would highly encourage you to use a different design pattern than multiple event structures. You can still use an event-based paradigm without the use of multiple event structures. Read further about the Producer Consumer design pattern, which is available as a template in LabVIEW 7.x and on. It's extremely versatile and efficient.
  3. The top loop with the controls in it seems to serve no purpose whatsoever. It may do something in your actual application that I can't see, but here there's no reason for the top loop. The event cases for the events registered for these controls will execute regardless of whether they are being polled in the top loop. That's just wasted CPU. It's common practice to put boolean controls with Latch mechanical action inside their registered Value Change event case. The purpose here is not to help the event case execute in any way, but merely so that LabVIEW reads the boolean terminal and executes the Latch mechanical action to set the button back to false. You aren't using Latch mechanical action, you are manually setting the button back to false. It's fine if that's the way you want to do it, but there's no point then in polling the controls in the top loop.
Jarrod S.
National Instruments
0 Kudos
Message 13 of 22
(1,756 Views)
Some other things to point out regarding your sample VI.

In your Start Tasks event case, you are disabling Start Tasks, executing a Value Signaling property for Task 1 and 2, and then re-enabling Start Tasks. This is not sound logic. When you call the Value Signaling property node, this is not a syncronous process. By that I mean that you can't assume the Value Change event has been processed by the time the Value Signaling property finishes executing. So it's very bad to re-enable Start Tasks after the second Value Signaling, because you really have no idea if the tasks have actually been processed. You only know the request to execute them has been processed, and at some point in the (near) future they might get handled. The best single-loop solution is to have the Task 1 and 2 code in the Start Tasks event case as I mentioned in my previous post. If you really do want this code to execute in a separate loop, you should re-enable Start Tasks from that loop when you can be sure that the Tasks have completed execution.

Also, you are making some bad assumptions about dataflow in your example. Data doesn't flow from left to right. So just putting code to the left doesn't force it to execute before something. LabVIEW really doesn't care about the physical position of nodes, it's merely a good coding style that helps humans read the code. To control the flow of execution, you must create data dependencies. That means wiring the output from one node into the input of another node. An example that fixes the problem shown below would be to wire the error output from Start: Disabled into the Sequence frame to the right.

Message Edited by Jarrod S. on 03-05-2007 11:11 AM

Message Edited by Jarrod S. on 03-05-2007 11:13 AM

Jarrod S.
National Instruments
0 Kudos
Message 14 of 22
(1,758 Views)

Jarrod S.

Thank you for the review/feedback of my code. I knew there were lot of room for improvement there. I enjoyed reading them since they have given me ways of improving my LabVIEW programming skill significantly! And I'm sure to remember those advises for years to come!

Back to my problem, I was thinking about how to "flush my queue" when taking a look at the Consumer Design Pattern template that you have mentioned. But didn't quite figure out exactly how the code would be. I'm staying with my current seperate loop because I don't have much times to re-design the whole scheme as you have suggested. But I'll be sure to use that principle on my next program. 

dphan128

0 Kudos
Message 15 of 22
(1,742 Views)


@dphan128 wrote:

Jarrod S.

Thank you for the review/feedback of my code. I knew there were lot of room for improvement there. I enjoyed reading them since they have given me ways of improving my LabVIEW programming skill significantly! And I'm sure to remember those advises for years to come!

Back to my problem, I was thinking about how to "flush my queue" when taking a look at the Consumer Design Pattern template that you have mentioned. But didn't quite figure out exactly how the code would be. I'm staying with my current seperate loop because I don't have much times to re-design the whole scheme as you have suggested. But I'll be sure to use that principle on my next program. 

dphan128




Glad to help... Can you give an example of when you'd want to flush the queue in a producer consumer design pattern? That might help me answer the question. Generally consumer loops in a producer consumer design pattern handle data packets one at a time as they come in from the producer loop. I'm not sure when you'd want to flush the queue off the top of my head, except perhaps at shutdown to get rid of all remaining data packets. Is that what you mean?
Jarrod S.
National Instruments
0 Kudos
Message 16 of 22
(1,737 Views)

Jarrod,

Here are my thoughts:

-The "value change" event queued up if I keep pressing the start button more than once. So I was thinking on how to accept only the first value change and discard the rest.

-Or can I change it to a "mouse down" event and use the discard function.

-Or how I can use the template to do the same thing

dphan128

0 Kudos
Message 17 of 22
(1,719 Views)

I was able to fix my problem by setting "condition flags" to control the value change event. But now need to figure out how to prevent the same thing (operator clicking more than one time) when dealing the mouse's right click. (see attached).

dphan128

  

0 Kudos
Message 18 of 22
(1,709 Views)
Your code simply does not make a lot of sense.
 
Why do you need the upper loop??? (actually, one loop might be enough overall).
 
Here's a simple example. It discards right-clicks on the pane after it happens once.
 
0 Kudos
Message 19 of 22
(1,699 Views)

Altenbach,

Thank you for the modified sample code. But now the right click action doesn't do anything! I mean it doesn't start the action as it supposes to.

dphan128

0 Kudos
Message 20 of 22
(1,695 Views)