Jump to content

Programatically detect how an event was fired (front panel vs value signaling)


Sean Donner

Recommended Posts

We have a 3rd party application that can talk to an arbitrary LabVIEW VI (or exe) via ActiveX and can both change and read the controls on the VI (or exe).  The problem we are facing is that the ActiveX interface does not support events.  This means that if a control registered for a value-change event has its value changed over ActiveX the VI does *not* fire off the value-change event; although the control's value will indeed change.

 

Currently, our developers are working around this issue by forgoing the event structure altogher and using a polling loop instead.  My goal is to see if I can abstract away the polling loop so the developers can use the event structure and I'm *almost* there but I've hit a problem.  I've abstracted the polling loop into a "brat" VI that gets a ref to the parent and uses VI server to do the polling and if a value is found to be changed it issues a value-signaling event via the control's property node.  

 

This solution works exactly how I want it to as long as the *only* thing doing the value changing is the 3rd party application.  The problem lies in the fact that the VI's front panel is still required to be visible and operational such that a user can change the control via the front panel as you normally do.  If a user changes a control via the front panel, not only does my "brat" code detect this change and fire off a value signaling event but because it's done through the front panel the event structure fires off as well and now I get two events firing when I only want one. 

 

I don't expect there to be an elegant way to solve this, but what would be the least ugly way to do it?  Is there anyway for my "brat" code to programatically detect the last time a control ref had an event fired, *and how* (front panel vs value signaling)?

 

Thanks,

-Sean

Link to comment

The simplest way I can think of is to have the "brat" code generate the signalling event and also set a Boolean to True. The event case "Value change" can read this Boolean and always set it to False afterwards. If it's true, the event was fired by the "brat", if it's false, it was fired by the UI.

Link to comment

Suggestion: can the event structure just compare New Value to Old Value and ignore if they are the same?  That will filter all duplicates.

 

BTW, if I were doing this from scratch I would have the 3rd party app set a single (hidden) “Message†control, that would be a cluster of desired control name and control value.  The “brat†would pool for new messages and then do Value(signaling) on the named control (which it would lookup in a list created at initialization of all the available controls).

Link to comment

We have a 3rd party application that can talk to an arbitrary LabVIEW VI (or exe) via ActiveX and can both change and read the controls on the VI (or exe).  The problem we are facing is that the ActiveX interface does not support events.  This means that if a control registered for a value-change event has its value changed over ActiveX the VI does *not* fire off the value-change event; although the control's value will indeed change.

 

I don't expect there to be an elegant way to solve this, but what would be the least ugly way to do it?  Is there anyway for my "brat" code to programatically detect the last time a control ref had an event fired, *and how* (front panel vs value signaling)?

 

Thanks,

-Sean

 

I'm a bit confused here.

 

On the one hand you say this ActiveX thing doesn't cause the control to generate a value changed event  and then you say you want to detect a value changed event ("last time a control ref had an event fired").

 

How exactly does this activeX control change the value?

 

If any sort of event is fired, then you can hook that event (that will get you the user changing a control), but I'm struggling to understand what this activeX component is actually doing. Do you have an example?

Edited by ShaunR
Link to comment

I'm a bit confused here.

 

On the one hand you say this ActiveX thing doesn't cause the control to generate a value changed event  and then you say you want to detect a value changed event ("last time a control ref had an event fired").

 

How exactly does this activeX control change the value?

 

If any sort of event is fired, then you can hook that event (that will get you the user changing a control), but I'm struggling to understand what this activeX component is actually doing. Do you have an example?

 

Basically changing the value over Active X is equivalent to the VI Server method "Control Value.Set" which takes a label name and the value as a variant and then "pastes" it into the control. This does indeed not cause an event. The OP probably detects this by polling the controls for value changes and then generates a Value Change (signaling) event.

 

If the user now operates the frontpanel, there will be an event from the user interaction and another one from the brat VI detecting a value change.

 

Basically there should be a way in the event loop to detect if it is an UI value change or a property value change. But I agree that an even better approach would be to route the control from the other app through its own "hidden" interface.

Link to comment

rolfk hit the nail right on the head, what he described is exactly my problem.   I tried taking the suggestion of comparing OldVal to NewVal and not doing anything when they are equal and that does indeed stop me from getting 2x events when the value is changed from the UI but it also prevents the 3rd party app from ever firing an event because it appears that OldVal always equals NewVal.   I guess I could use that info to my advantage and set a flag when the two values are equal so that if the UI event happens 2nd I can case off of the flag.   I also moved the brat code into the timeout case of the event structure set to 10ms. 

 

I was hoping there was a way where I could completely abstract this without having to clutter up the event structure with odd control mechanisms but that possibility is looking less and less likely.  I was thinking about using an AE to contain a control<-->value hashmap but I can't seem to figure a way to eliminate the race condition.  I also tried out flushing the event queue every time my poll loop finds a change but that too is plagued by a race condition because I'm not guaranteed the UI event is on the queue by the time I try to flush it.

Link to comment

Can you have the brat VI dynamically register for the value change event on the control, and ignore the change in value that gets observed on the next poll?

 

if you notice a change in value while polling, disable the dynamically registered event (wire in a not-a-ref) before writing to the value(signaling) property, and re-enable it after.

Link to comment

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.

×
×
  • Create New...

Important Information

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