02-23-2017 06:27 PM
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?
02-24-2017 04:20 PM
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)?