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.

Counter/Timer

cancel
Showing results for 
Search instead for 
Did you mean: 

AsyncCallback with CounterReader deadlocks daqmx tasks

 

I have a scanning microscope system that reads in frames using a NI 6321 board.  Everything is working, but I would like to read out a quadrature encoder synchronously with frames.  I also have this mostly working, but I have some strange deadlocks that I suspect are due to my inexperience with DAQMX and .NET programming. 

 

My current acquisition thread:

 


while (gettingFrames)
{
    do
    {
        status = getFrameReadyStatus();
        Sleep(1);
        
    }while(status == STATUS_BUSY && !previewThreadStop);
        
    CopyFrame(framebufpointer);
}

 

I added a new function readQuadDecoderPostion() right after CopyFrame that reads the current position of a quad decoder hooked up to the microscope.  If I do this in the same thread using ReadMultiSampleDouble to read out the last few positions, everything works, but my maximum frame rate is limited because of the variable delay for ReadMultiSampleDouble.  Makes sense.

 

So now I am trying to do this using async IO.  I've added the following:

 

 

void readDecoderPostionAsync()
{
    System::String ^ path = "C://path//to//save//data"
    
    //feed the callback and path to the the CounterReader class
    counterReader->BeginReadMultiSampleDouble(numberOfSamples, ascX, path);
}

void CounterSaveCallback(System::IAsyncResult ^ar)
{
    array<double>^ counterXData = counterXInReader->EndReadMultiSampleDouble(ar);
    
    //write out samples (few KB of data)
    ...
    
    //setup the read for the next frame when it triggers
    counterReader->BeginReadMultiSampleDouble(numberOfSamples, ascX, (System::String^) ar->AsyncState);
}

void setupAsyncCounter()
{
    //setup the counter to trigger when the frame is ready
    myXCounterTask->Timing->ConfigureSampleClock("/Dev1/PFI0", hz, SampleClockActiveEdge::Rising, SampleQuantityMode::ContinuousSamples, numberOfSamples);    

    //setup couter readers that will return the positions of each frame
    counterReader = gcnew CounterReader(myCounterTask->Stream);

    //setup a callback to handle data saving
    ascX = gcnew System::AsyncCallback(this, CounterSaveCallback);
    myXCounterTask->SynchronizeCallbacks =false;    //doesn't seem to do anything?
}

 

What I think should happen is that each counter read will be handled using a thread in a .NET thread pool, leaving my main worker thread free to handle display updates without lag.  Each counter read callback will then setup the read for the next frame. 

 

What actually happens is that I get through about 5-6 frames and then my scanners completely deadlock and stop triggering for new frames, and then eventually the daqmx task handling the frame scanning times out.  My theory is that somehow doing this asynchronously disturbs the NI board in a way that doing it in a single thread does not, but I can't see how that happens.  My understanding is that the daqmx software is all thread safe, and I've tried to follow the guidelines here: 

 

http://zone.ni.com/reference/en-XX/help/370473H-01/mstudiowebhelp/html/eventscallbacksthreadsafety/

 

What am I missing?

 

0 Kudos
Message 1 of 2
(2,832 Views)

You’re write about DAQmx being thread safe.

http://digital.ni.com/public.nsf/allkb/4AABFC713B77FE0886256EBA00766454

 

Do you get any sort of error when the trigger stops (screen shot)?

0 Kudos
Message 2 of 2
(2,788 Views)