06-27-2008 05:27 PM
06-27-2008 10:45 PM
Update:
I rewrote the code for this timer and callback using NI-DAQmx C library. Now the jitter problem is completely gone (great!), but the CPU issue is even worse. The following code utilizes 100% CPU even with the 10Hz counter!!!! Am I missing something here? I tried all the options for interrupt based processing instead of busy polling to no avail. This is just unacceptable. These days one can't even deliver an app that is permanently running at 100% cpu without raising some eyebrows...
I must be missing something...
Please help,
Philip
static int StaticTriggerCallback(TaskHandle taskHandle, int32 signalID, void *callbackData)
{
return 0;
}
int TTCameras::StartTimer(void)
{
int error=0;
CTTEyes::Log("Starting Spin Trigger", false, 1);
spintotalTriggerPulsesCallbacks = 0;
spinROITimeStart = 1;
spinROITimeEnd = 0;
threadHandles[0] = threadHandles[1] = threadHandles[2] = threadHandles[3] = 0;
// Configure DAQmx ct3 as our spin camera trigger. 1000Hz
DAQmxErrChk (DAQmxCreateTask("", &taskHandle));
DAQmxErrChk (DAQmxCreateCOPulseChanFreq(taskHandle, "/Dev1/ctr3", "CameraSpinTrigger", DAQmx_Val_Hz, DAQmx_Val_Low, 0.0, 10.0, 0.5));
// /Dev1/PFI1 rising edge will enable this trigger so that it will start at the same time as /Dev1/ctr0
// DAQmxErrChk (DAQmxCfgDigEdgeStartTrig(taskHandle,"/Dev1/PFI1", DAQmx_Val_Rising));
// continuous samples
DAQmxErrChk (DAQmxCfgImplicitTiming(taskHandle, DAQmx_Val_ContSamps, 1000));
DAQmxErrChk (DAQmxSetReadWaitMode(taskHandle, DAQmx_Val_WaitForInterrupt));
DAQmxErrChk (DAQmxSetRealTimeWaitForNextSampClkWaitMode(taskHandle, DAQmx_Val_WaitForInterrupt));
// register callback which will occur each time counter reaches zero and toggles output trigger signal.
DAQmxErrChk (DAQmxRegisterSignalEvent(taskHandle, DAQmx_Val_CounterOutputEvent, 0, (DAQmxSignalEventCallbackPtr)StaticTriggerCallback, NULL));
DAQmxErrChk (DAQmxTaskControl(taskHandle, DAQmx_Val_Task_Commit));
double freqSpin;
DAQmxErrChk (DAQmxGetCOPulseFreq(taskHandle, "CameraSpinTrigger", &freqSpin));
TTCameras::periodSpin = 1.0 / freqSpin;
DAQmxErrChk (DAQmxStartTask(taskHandle));
Error:
if (DAQmxFailed(error))
{
char str[1000];
int l = sprintf_s(str, 1000, "Error: StartTimer(), DAQmxFailed=.");
DAQmxGetExtendedErrorInfo(&str[l], 1000 - l);
CTTEyes::Log(str, true, 10);
StopTimer();
}
return 0;
}
06-30-2008 01:35 PM
06-30-2008 11:22 PM
Thanks for the response PBear.
I removed those 2 lines of code and NIDaq still takes up 100% CPU, so your suggestion does not work. The only reason I put them there in the first place is in order to try to get NIDaq to use interrupt based processing rather than busy polling.
My application requires that I generate TTL level trigger pulses and at the rising edge of each trigger pulse, I also need to execute some very short C code. This code should run within .5ms of the trigger edge. This should be no problem for a modern CPU. This is why I am using DAQmx_Val_CounterOutputEvent. However, I cannot have NIDaq implement this using busy polling. It is simply not acceptable to be running at 100% CPU for several reasons. The documentation and your support site talk about interrupt based processing, and the hardware is obviously capable of it.
So, the 2 questions I have are:
1. What do I have to do in order to have NIDaq use interrupt based processing instead of busy polling (for the DAQmx_Val_CounterOutputEvent callbacks in my application)?
2. In addition to (1), can I make it so that my callback only gets called on the rising edge of the trigger signal instead of both the rising and falling edges?
Thanks in advance
Philip
07-07-2008 03:21 PM - edited 07-07-2008 03:21 PM
07-07-2008 10:18 PM
07-07-2008 10:19 PM
Also sorry for the duplicate posts. I thought since I am now doing this using c++ I should post to the appropriate forum. Anyway, I am happy to pursue this issue with you in this forum 🙂
Philip
07-08-2008 12:48 PM
07-09-2008 10:22 AM
Hi Chris.
This is very strange but now my application no longer has this problem either. I did change some other third party software, so that must somehow have done it. However, removing DAQmxRegisterSignalEvent previouly got rid of the 100% CPU even though the callback did nothing, so it was definitely enabling the callback that caused 100% CPU. Very strange.
Anyway, now it consumes reasonable amounts of CPU so I'll leave it at that. The only thing for me to test now is the accuracy and jitter with which the callback gets called. I can't test this right now but will post results as soon as I do.
BTW, you said that using interrupts would not help my situation (in terms of CPU usage). Can you tell me what mechanism NIDaq is using to call this callback? The output frequency of this counter will have to be around 1000Hz, meaning that the callback will be called at 2000Hz. Since it is no longer using 100%, doesn't this mean that this must be done via interrupt based processing? Busy polling would incur a lot of CPU usage no? And sleep mode would not be possible due to the high frequency, no?
Thanks for your help
Philip Gruebele
07-10-2008 06:32 PM