From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

How do you setup LabView to "callback" whilst blocked on a COM (ActiveX) method ?

I have a problem where I need to call a COM (ActiveX) method which blocks, waiting for a trigger. The problem is, it's edge triggered, and I have to use LabView to produce this trigger by flipping bits on and then off via port write commands, whilst blocked. A catch-22 situation.

I thought I found a way around this via the use of timed-loops, but I have since discovered that the "offset" is really only of applied the first time the timing source is started. For example, if I setup two Timed-Loops, both using the same Named-Timer-Source, I can set the first (trigger) loop with an offset of say 20ms, then setup the second timed-loop (blocking COM call) with an offset of zero, and amazingly, Labview (7.1,  7.1.1) seems to spin up another thread to handle the first (trigger) loop, whilst blocked in the COM call.

The problem, however, is that this is all contained within an other loop, and once it's successfully gone through the first time, subsequent iterations fail, because the offset is not applied again to the timed-loop(s) at the start of the next interation. That is, the timed-loop is effectively a global object, which is setup at the time of first-use, but it then continues run (in the background) from that point onwards. Whereas I was expecting that once the timed loop completed, it would be "destroyed" and "constructed" anew, each time through the outer loop.

In a procedural language, I would probably have setup a timer event just before making the blocking COM call, and handled the triggering in the (callback) event. Does anyone have any suggestions of how to do this ROBUSTLY using LabView 7.1.1 ?

0 Kudos
Message 1 of 8
(3,074 Views)

I don't have experience with timed loops, so I didn't understand your solution, but what is this COM object actually blocking? I know that DLL calls made using the CLF node will block the UI thread if they are not defined to be thread safe, but I don't think this should affect COM.

Can you upload an image of the relevant piece of code with an illustration of what actually gets blocked?


___________________
Try to take over the world!
0 Kudos
Message 2 of 8
(3,078 Views)
Thanks for responding.

The COM object blocks, waiting for me to send a trigger signal to a digital camera/shutter combination. However, I need to generate this trigger back in LabView. Because the shutter is an edge triggered device, the camera must be waiting for an image BEFORE the trigger is generated. But as I mentioned, the process of waiting for the trigger means that LabView is not executing anything else in that VI until it returns from the COM call (which is waiting for the trigger). A catch-22 situation.

Initially, we were using a level-triggered setup, and I was using only one timed-loop to generate the (~1ms) trigger pulse. But now that we are forced to use an edge-triggered setup, we have this concurrency problem.

I stumbled onto the "callback" behaviour of the timed-loop whilist Labview is otherwise blocked in a COM call. And the trick to it working, at least initially, was to have LabView execute the first timed-loop (the trigger loop), but have that loop setup with an offset. The second timed-loop (the blocking COM call) may not actually be necessary, though I found the execution order without it seemed unpredictable.

This all works fine on the first time through. But from that point on, the timed-loops continue to run, and consequently, they will not "re-apply" the 'offset' to any future iterations through the outer loop(s).

Here, I've built a something which shows the sort of problem, and how it does work the first time through the for loop:



The For loop is set to loop twice. I'm using two instances of the Windows Scripting Engine to execute two separate scripts.

The lower one creates a MessageBox whose contents adds in the iteration count into it's message. The upper one finds the Messagebox's Window, and sends an Enter Key ("~") to close the Messagebox.

The upper timed-loop is set to execute 2000ms (2 seconds) after the lower timed-loop. The first time through, it works. The second time through, the upper script fails, as it executes upper script before the lower script runs. ie It does not insert the offset again. I'll attach a Windows LabView 7.1 copy of the VI, compressed as ZIP.
0 Kudos
Message 3 of 8
(3,056 Views)

What you're describing may or may not be a bug with timed loops. I don't know since I have zero experience with them, so I don't know what t0 should be.

I would simply suggest ditching the timed loop and using any other kind of schduling mechanism. The best option is to put the upper call after the lower call, but I understand you can't do that, because the lower call needs the upper call to finish.

The other options would be using an event structure with a timeout of 2000, a wait statement wired into a sequence structure, a non-triggered notifier with a timeout, etc.

Timed loops require interacting with an external DLL to do their thing, so I don't really like them that much anyway.


___________________
Try to take over the world!
0 Kudos
Message 4 of 8
(3,051 Views)
OK, I'll try reading up on LabView events.

In the mean time, I've hacked the original timed loop sample, and have manged to get it working, by creating and deleting Timer Sources. I'm still not sure whether this will introduce a resource leak, as I've only monitored the attached sample for 1000 loops (with the offset reduced to 100 ticks). Handles was about the only thing that fluctuated, hovering around 63..66 handles - using Process Explorer with it's window moved to my second display, to reduce interference, etc.

0 Kudos
Message 5 of 8
(3,043 Views)

It seems to me you're over complicating the situations. Timed loops are for situations where you need complex timing.

In your case, the timing requirements seem fairly simple (see attached for a couple of examples).


___________________
Try to take over the world!
0 Kudos
Message 6 of 8
(3,045 Views)
I suggest a timed sequence instead of the two loops. embedded in a timed loop. Use two seperate clocks.

Ton
Free Code Capture Tool! Version 2.1.3 with comments, web-upload, back-save and snippets!
Nederlandse LabVIEW user groep www.lvug.nl
My LabVIEW Ideas

LabVIEW, programming like it should be!
0 Kudos
Message 7 of 8
(3,033 Views)
Thanks 'tst'.

I've read up and implemented a "timeout event", as suggest, and it works   Smiley Very Happy

Well, obviously I'll need to do some stress tests, etc, in the morning, as it's hard to judge via Remote Desktop, especially as it's so close to bed-time, now. But it's looking good so far.

Even better is that I'll not have to rewrite the COM object to setup and tear down asynchronous captures for each of the Red, Green and Blue frame captures... Smiley Wink


Thanks again  Smiley Very Happy
0 Kudos
Message 8 of 8
(3,023 Views)