Multifunction DAQ

cancel
Showing results for 
Search instead for 
Did you mean: 

如何用DAQmx C API函数方式实现Ad采集后再由DA输出

我想再VC6的开发环境下利用DAQmx C API函数写一个测试程序,对NI-USB6211进行测试。
测试的流程是这样的用AD采集数据然后将采集的数据再由DA发送出去。我自己尝试着写了一个程序,
但发现输出的数据会被输出缓冲区再生的数据覆盖一些后,才能输出采集进来的数据。请问如何解决。
不知道有没有这样的例程可供参考。
0 Kudos
Message 1 of 6
(7,982 Views)
你试试这个程序,只有AO的生成,没有同步。
 
C:\Program Files\National Instruments\NI-DAQ\Examples\DAQmx ANSI C\Analog Out\Generate Voltage\Cont Gen Volt Wfm-Int Clk
0 Kudos
Message 2 of 6
(7,963 Views)
这个例程我已经试过了,它只是产生一次定长的正弦波送给DO输出,然后利用Buffer的再生功能反复的发送正弦波。
我希望实现的功能是不利用Buffer的再生功能,而是由AI采集的数据去更新AO的Buffer。
现在的问题是更新的速度赶不上AO的速度,Buffer再生的数据会覆盖一部分应用程序更新的数据,这样输出的波形是不连续的。
有没有这方面的例程可供参考。谢谢!!!
0 Kudos
Message 3 of 6
(7,961 Views)
你可以使用int32 __CFUNC DAQmxSetWriteRegenMode(TaskHandle taskHandle, int32 data)函数设置一下就好了。 这里的data 就是regeneration mode
 

Regeneration Mode

Data Type: int32
Description: Specifies whether to allow NI-DAQmx to generate the same data multiple times.

If you enable regeneration and write new data to the buffer, NI-DAQmx can generate a combination of old and new data, a phenomenon called glitching.



Valid values

DAQmx_Val_AllowRegen 10097 Allow NI-DAQmx to regenerate samples that the device previously generated. When you choose this value, the write marker returns to the beginning of the buffer after the device generates all samples currently in the buffer.
DAQmx_Val_DoNotAllowRegen 10158 Do not allow NI-DAQmx to regenerate samples the device previously generated. When you choose this value, NI-DAQmx waits for you to write more samples to the buffer or until the timeout expires.

 

这个函数你放在timing的设置之前应该就好了

0 Kudos
Message 4 of 6
(7,955 Views)
hunag:
 
感谢你的回复!
我试过你说的办法,但是还是不行,程序运行时产生了一个错误,错误代码是 -200018;
 
我的程序的主要流程是这样的:
再窗口线程中按开始按钮后执行以下代码:
 DAQmxErrChk (DAQmxCreateTask("",&AITaskHandle));
 DAQmxErrChk (DAQmxCreateAIVoltageChan(AITaskHandle,"Dev1/ai0","",DAQmx_Val_RSE,-10.0,10.0,DAQmx_Val_Volts,NULL));
 DAQmxErrChk (DAQmxCfgSampClkTiming(AITaskHandle,"",28400.0,DAQmx_Val_Rising,DAQmx_Val_ContSamps,2840));
 DAQmxErrChk (DAQmxSetBufInputBufSize(AITaskHandle,284000));
 DAQmxErrChk (GetTerminalNameWithDevPrefix(AITaskHandle,"ai/SampleClock",trigName));
 
 DAQmxErrChk (DAQmxCreateTask("",&AOTaskHandle));
 DAQmxErrChk (DAQmxCreateAOVoltageChan(AOTaskHandle,"Dev1/ao0","",-10.0,10.0,DAQmx_Val_Volts,NULL));
 DAQmxErrChk (DAQmxSetWriteRegenMode(AOTaskHandle,DAQmx_Val_DoNotAllowRegen ));
 DAQmxErrChk (DAQmxCfgSampClkTiming(AOTaskHandle,trigName,28400.0,DAQmx_Val_Rising,DAQmx_Val_ContSamps,2840));
 DAQmxErrChk (DAQmxWriteAnalogF64(AOTaskHandle,2840,0,10.0,DAQmx_Val_GroupByChannel,data,NULL,NULL));
 
DAQmxErrChk (GetTerminalNameWithDevPrefix(AITaskHandle,"ai/StartTrigger",trigName));
 DAQmxErrChk (DAQmxCfgDigEdgeStartTrig(AOTaskHandle,trigName,DAQmx_Val_Rising));
 
 AfxBeginThread(ThreadFun,(LPVOID)&AOTaskHandle);
 Sleep(10);
 m_eventHandle = OpenEvent(EVENT_ALL_ACCESS,FALSE,"DAEvent");
 
 DAQmxErrChk (DAQmxRegisterEveryNSamplesEvent(AITaskHandle,DAQmx_Val_Acquired_Into_Buffer,2840,0,EveryNCallback,(void*)&m_eventHandle));

 DAQmxErrChk (DAQmxRegisterDoneEvent(AITaskHandle,0,DoneCallback,NULL));
 DAQmxErrChk (DAQmxRegisterDoneEvent(AOTaskHandle,0,DoneCallback,NULL));

 /*********************************************/
 // DAQmx Start Code
 /*********************************************/
 DAQmxErrChk (DAQmxStartTask(AOTaskHandle));
 DAQmxErrChk (DAQmxStartTask(AITaskHandle));
这些代码完成创建一个AO任务,一个AI任务,注册EveryNSamplesEvent Callback函数,并开始一个工作线程。
 
在EveryNCallback函数中触发工作线程等待的事件,代码如下:
int32 CVICALLBACK EveryNCallback(TaskHandle taskHandle, int32 everyNsamplesEventType, uInt32 nSamples, void *callbackData)
{
 int32       error=0;
 char        errBuff[2048]={'\0'};
 int32  read = 0;
 int i = 0;
 count++;
 HANDLE* pEvent = (HANDLE*)callbackData;
 /*********************************************/
 // DAQmx Read Code
 /*********************************************/
 DAQmxErrChk (DAQmxReadAnalogF64(AITaskHandle,2840,10.0,DAQmx_Val_GroupByChannel,dpCurr,2840,&read,NULL));
 if(iFlag)
 {
  for(;i<2480;i++) {
    data[i]= dpCurr[i]/2;
  } 
  dpCurr = dpADBufA;
  SetEvent(*pEvent);
 }
 else
 {
  for(;i<2480;i++) {
   data[i] = dpCurr[i]/2;
  } 
  dpCurr = dpADBufB;
  SetEvent(*pEvent);
 }
 iFlag ^=1;

 /*********************************************/
 // DAQmx Write Code
 /*********************************************/
// DAQmxErrChk (DAQmxWriteAnalogF64(AOTaskHandle,2840,0,10.0,DAQmx_Val_GroupByChannel,data,NULL,NULL));
 Error:
 if( DAQmxFailed(error) )
  DAQmxGetExtendedErrorInfo(errBuff,2048);
 if( DAQmxFailed(error) )
  AfxMessageBox(errBuff);
 return 0;
}
 
工作线程启动一个循环,等待在EveryNCallback函数中触发的事件,然后向AO写数据。代码如下:
UINT ThreadFun(LPVOID pParam)
{
 int32       error=0;
 char        errBuff[2048]={'\0'};
 TaskHandle* pTaskHandle = (TaskHandle*)pParam; 
 HANDLE eventHandle = CreateEvent(NULL,FALSE,FALSE,"DAEvent");
 
 while (1) {
  WaitForSingleObject(eventHandle,INFINITE);
  DAQmxErrChk (DAQmxWriteAnalogF64(*pTaskHandle,2840,0,10.0,DAQmx_Val_GroupByChannel,data,NULL,NULL));
 }

Error:
 if( DAQmxFailed(error) )
  DAQmxGetExtendedErrorInfo(errBuff,2048);
 if( DAQmxFailed(error) )
  AfxMessageBox(errBuff);
 return 0;
}
我把VC++ 6.0下的代码放在附件中
0 Kudos
Message 5 of 6
(7,947 Views)
你可以试着提高你的buffer size和每次写的sample数目来试一下
0 Kudos
Message 6 of 6
(7,943 Views)