LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

waiting for the stage: how do I have my wait and eat it too?

I am writing a driver that controls a motion-controller and translation stage. It uses the standard IVI instrument driver interface and capabilities and all of the standard function calls, and communicates with the controller via a GPIB interface. So far, so good.

 

One of the standard calls is "WaitForOPC". This allows the driver to wait for the instrument (the motion controller) to indicate that it has finished what it is doing by asserting the GPIB SRQ service-request line. Normally, then, the facility is installed as a synchronous event queue using the viEnableEvent routine:

 viEnableEvent(io, VI_EVENT_SERVICE_REQ, VI_QUEUE, VI_NULL) call.

 

If I want to wait for the motion to finish, I call the routine to move the stage. This routine then instructs the motion controller to issue an SRQ when it's finished,  calls WaitForOPC, which in turn calls the WaitForOPCHandler, which in turn calls viWaitOnEvent(....) to wait for the device to set the IRQ line, and the whole thing waits until the motion-controller is done.

 

On the other hand, if I want to do other things in my main program, then I can install an SRQ handler as a asychronous handler:

viEnableEvent(io, VI_EVENT_SERVICE_REQ, VI_HNDLR, VI_NULL)

 

In this case, the routine that starts the motion returns immediately, and the SRQ handler can set a flag to indicate that motion is complete.

 

Either one or the other works fine, but I'd like both. The problem is that I can only install a synchronous handler or an asynchronous one, but not both. In addition, if I rewrite the WaitForOPC routine so that it simply spins in place and wait for the flag to be set, the whole thing locks up, even if I use a Delay call or some such to allow the system to do other things. I'm not sure, but I suspect that this is because the WaitForOPC routine and the SRQ handler are in the same thread and the IVI mechanism is not properly utilized while the WaitForOPC routine is spinning.

 

What I need is something like the viWaitOnEvent(...) call that will allow the IVI mechanism to handle the SRQ routine properly while waiting on a semaphore or flag (actually, I'm using a Boolean attribute). However, I can find no such thing anywhere. Any suggestions would be greatly appreciated.

0 Kudos
Message 1 of 3
(3,417 Views)

People have complained that Delay () does a spinlock (busy wait).

 

You could try doing a Sleep() win32 sdk call, that will truly put the thread to sleep so that other threads can progress.  

 

I made a function that calls Sleep ( ) in intervals, and does a ProcessSystemEvents ( ) call in between sleep intervals. 

 

Or try the SyncWait call like this:

 

VOID SleepWithEvents (DOUBLE dMilliseconds, DOUBLE dInterval, INT (*ConditionFunction)(VOID)) {
   
    BOOL   Done = FALSE;
    DOUBLE dMark;
    DOUBLE dWaitStart = Timer ();                                                                                                                                                                                                                                                             
    do {
      dMark = Timer ();
      if ((dMark - dWaitStart) >= (dMilliseconds / 1000.0)) break; 
        ProcessSystemEvents ();
        SyncWait (dMark, dInterval / 1000.0);  // make sure we've consumed at least dInterval seconds
        if (ConditionFunction != NULL)  if  (ConditionFunction()) break;       
    }  while (!Done);
   
    return;
   
}  // end, SleepWithEvents   

 

I usually support both synchronous and asynchronous calls to a device driver, but, it's either a synchronous call or not ... if it's synchronous I wait for completion by loopiing and periodically polling the device (read the status byte by doing a serial poll of just that device) or by hanging a read on it (with long enough timeout on the read) after sending OPC?.   Or use a SRQ callback, have the callback set a flag, and have the driver logic wait and look for the flag and return to the caller after the flag gets set.

 

For asynchronous operation, you don't necessarily need the SRQ functionality - you can aynchronously request status with STB? or some such any time you want.

 

SRQ's are nice in the sense that the instrument / GPIB controller / driver automatically cause an asynchronous,  programmatic response as soon as the instrument signals it's ready,  and you can read the instrument data and format it or save it or whatever, while your main logic continues.  But, if your control flow depends on the instrument result (which is typical) you're going to have to be synchronous with the instrument at some point no matter what.

 

 

Menchar

0 Kudos
Message 2 of 3
(3,406 Views)
Thanks. In this case, some parts of the software need to wait for completion, but I need to keep the position displays updated while the stage is moving.
0 Kudos
Message 3 of 3
(3,385 Views)