Thang Nguyen Posted December 2, 2009 Report Share Posted December 2, 2009 Hi, In my VI, I use a Gauge control with a digital display so user can either move the needle or input the value in digital display. In my VI I use an event structure to get the update value. If I use the value changed event, when I move the needle it will generate the event continously. I don't want this happen, I just want the latest value. So I tried to use the mouse up event, then it didn't generate the event if I update the digital display. I have an idea with using a seperate numeric control for digital display and have 2 event seperately. But I think this is a costly solution. Is there any simpler way to solve this? Best regards, Thang Nguyen Quote Link to comment
EricLarsen Posted December 2, 2009 Report Share Posted December 2, 2009 (edited) How about a combination of Mouse Up event and Value Change? In the Mouse up event, grab the value of the control. This accounts for the user either rotating the needle or clicking increment on the digitial control. In the Value Change event, check the status of the mouse button using mouseAcquire.vi. If the mouse button is down and the mouse positon is inside the bounds of the gauge, assume the user is twriling the dial and do nothing. It might take some tweaking to account for all the actions a user could take. Eaiser than two controls? Maybe not, but it might be worth playing around with. Edit : I already see one problem with this. I tend to enter value in controls by typing in the control and then clicking the mouse outside the control. For a square shaped control this idea would work. But because a guage is round and it's bounds are square, I think there is an area outside the round gauge that's still inside the bounds of the control. If the user clicked in that area to enter the value the bounds checking might fail. Hmm... Edited December 2, 2009 by EricLarsen Quote Link to comment
Yair Posted December 2, 2009 Report Share Posted December 2, 2009 There are a number of ways of handing continuous events. In the case of the Value Change event, the easiest thing to do is to compare the NewVal terminal to the control terminal and only perform the code if they are equal. This works because the control terminal always holds the latest value, but the NewVal terminal will cycle through all the intermediary values. If the false case of the structure has no code, the event structure will breeze through the events and will only run the code for the most recent value. Quote Link to comment
Grampa_of_Oliva_n_Eden Posted December 2, 2009 Report Share Posted December 2, 2009 (edited) Hi, In my VI, I use a Gauge control with a digital display so user can either move the needle or input the value in digital display. In my VI I use an event structure to get the update value. If I use the value changed event, when I move the needle it will generate the event continously. I don't want this happen, I just want the latest value. So I tried to use the mouse up event, then it didn't generate the event if I update the digital display. I have an idea with using a seperate numeric control for digital display and have 2 event seperately. But I think this is a costly solution. Is there any simpler way to solve this? Best regards, Thang Nguyen See here for Ton's Nuget on dynamice events. http://forums.ni.com...=242266#M242266 I can't attach an example or image but I'll try with words. USe Dynamic events to register for the value change (you will be shutting this on and off so its dynamci). In your event strture create the following events Mouse donw or Mosue enter >>> Re-register the value change against a ref contant ( this shuts down value change events while in the guage) Mouse Up or Mouse Leve >>> re-register against the guage... use property node value to read the value and write it to the value(signal) property to fire the value change event. If you put it together right it should only update the guage when you release the mouse and it will fire when you use the digital control. Have fun, Ben Edit: When I started to reply this thread had no replies. By the time I delt with questions at my desk and completed my reply, I found a pile of replies. I did not intend to duplicate the earlier suggestion. Edited December 2, 2009 by neBulus Quote Link to comment
Thang Nguyen Posted December 2, 2009 Author Report Share Posted December 2, 2009 Hi, I tried to compare the value with both the control itself or with the property node value and these always return equal. Quote Link to comment
Ton Plomp Posted December 2, 2009 Report Share Posted December 2, 2009 This is a tricky one. Ben's suggestion is OK, but has a little problem, the value will change after a mouse leave event. What you can do is add a notification and a user event. Every value change you sent the new value to the notification. In a second loop you read out the notification with this little construct inside a secondary loop (text only no LabVIEW at this PC: -Wait 25 ms -Get Notification, time-out 0 ms -Check time-out status -TimeOut == true -You had no new 'value change' events in the last 25 ms and you can trigger a user event to act on the actual value change Loop again. This makes sure that you only get a user event for that control when the value changing is dead for 25 ms, most of the time fast enough. Ton Quote Link to comment
Yair Posted December 2, 2009 Report Share Posted December 2, 2009 I tried to compare the value with both the control itself or with the property node value and these always return equal. I meant something like this: Another way of doing this, which is similar to Ton's suggestion, but doesn't require another loop, is to place the actual code in the timeout event. You then wire the value that goes into the timeout terminal through a shift register. In the continuous event frame, you pass a small number (let's say 10) into the shift register. When those events stop happening, the timeout event execute, and you push -1 (infinite timeout) into the SR. Quote Link to comment
Grampa_of_Oliva_n_Eden Posted December 2, 2009 Report Share Posted December 2, 2009 This is a tricky one. Ben's suggestion is OK, but has a little problem, the value will change after a mouse leave event. What you can do is add a notification and a user event. Every value change you sent the new value to the notification. In a second loop you read out the notification with this little construct inside a secondary loop (text only no LabVIEW at this PC: -Wait 25 ms -Get Notification, time-out 0 ms -Check time-out status -TimeOut == true -You had no new 'value change' events in the last 25 ms and you can trigger a user event to act on the actual value change Loop again. This makes sure that you only get a user event for that control when the value changing is dead for 25 ms, most of the time fast enough. Ton It only chages if I mouse down while in. (I will try to attach example). Ben Guage.vi Quote Link to comment
Thang Nguyen Posted December 2, 2009 Author Report Share Posted December 2, 2009 (edited) Thanks everybody. I quite have something here to try. Best regards, Thang Nguyen Edited December 2, 2009 by Thang Nguyen Quote Link to comment
Ton Plomp Posted December 3, 2009 Report Share Posted December 3, 2009 Mouse donw or Mosue enter >>> Re-register the value change against a ref contant ( this shuts down value change events while in the guage) Mouse Up or Mouse Leve >>> re-register against the guage... use property node value to read the value and write it to the value(signal) property to fire the value change event. I hadn't actually read your description well, your VI made things clear. Ben's suggestion is OK, but has a little problem, the value will change after a mouse leave event. Here's a video showing what I was describing (sorry for the sound): <object width="308" height="244"> <param name="movie" value="http://content.screencast.com/users/TonPlomp/folders/Jing/media/610a80a0-7b7d-4c05-9419-a06e644ebf2f/jingswfplayer.swf"></param>'>http://content.screencast.com/users/TonPlomp/folders/Jing/media/610a80a0-7b7d-4c05-9419-a06e644ebf2f/jingswfplayer.swf"></param> <param name="quality" value="high"></param> <param name="bgcolor" value="#FFFFFF"></param> <param name="flashVars" value="thumb=http://content.screencast.com/users/TonPlomp/folders/Jing/media/610a80a0-7b7d-4c05-9419-a06e644ebf2f/FirstFrame.jpg&containerwidth=308&containerheight=244&content=http://content.screencast.com/users/TonPlomp/folders/Jing/media/610a80a0-7b7d-4c05-9419-a06e644ebf2f/GaugeChange.swf"></param> <param name="allowFullScreen" value="true"></param> <param name="scale" value="showall"></param> <param name="allowScriptAccess" value="always"></param> <param name="base" value="http://content.screencast.com/users/TonPlomp/folders/Jing/media/610a80a0-7b7d-4c05-9419-a06e644ebf2f/"></param>'>http://content.screencast.com/users/TonPlomp/folders/Jing/media/610a80a0-7b7d-4c05-9419-a06e644ebf2f/"></param> <embed src="http://content.screencast.com/users/TonPlomp/folders/Jing/media/610a80a0-7b7d-4c05-9419-a06e644ebf2f/jingswfplayer.swf" quality="high" bgcolor="#FFFFFF" width="308" height="244" type="application/x-shockwave-flash" allowScriptAccess="always" flashVars="thumb=http://content.screencast.com/users/TonPlomp/folders/Jing/media/610a80a0-7b7d-4c05-9419-a06e644ebf2f/FirstFrame.jpg&containerwidth=308&containerheight=244&content=http://content.screencast.com/users/TonPlomp/folders/Jing/media/610a80a0-7b7d-4c05-9419-a06e644ebf2f/GaugeChange.swf" allowFullScreen="true" base="http://content.screencast.com/users/TonPlomp/folders/Jing/media/610a80a0-7b7d-4c05-9419-a06e644ebf2f/" scale="showall"></embed> </object> Here's a screenshot of what I was describing: Another way of doing this, which is similar to Ton's suggestion, but doesn't require another loop, is to place the actual code in the timeout event. You then wire the value that goes into the timeout terminal through a shift register. In the continuous event frame, you pass a small number (let's say 10) into the shift register. When those events stop happening, the timeout event execute, and you push -1 (infinite timeout) into the SR. I don't have enough confidence in that the user will do nothing during a specific time. Ton Quote Link to comment
Yair Posted December 3, 2009 Report Share Posted December 3, 2009 I don't have enough confidence in that the user will do nothing during a specific time. You could set the timeout to 0 , although I see what you're saying. Quote Link to comment
Shaun Hayward Posted December 3, 2009 Report Share Posted December 3, 2009 It may be "costlier" but I ended up doing the two control thing (ie a strict type def of a dial and a numeric) because I was sending out a bunch of RS232 data each time the control was changed (and at 9600 baud, I didn't want to flood any buffers). This ended up being pretty simple to implement, and the only major downside I had was having to manage two event cases per control (value change on numeric, and mouse up on dial). I know it might have been tidier to wrap this up in an X control, but that seemed like more hassle than it was worth. Shaun Quote Link to comment
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.