Dear all,
I am new to DAQ and use a 6052 board. Now I am doing the transition of an existing implementation from Traditional DAQ to NI-DAQmx.
I have a problem with the triggering of the components: there is a AO which creates a square wave.
The ctr0 creates a pulse on every slope of the AO. The ctr1 creates a pulse on every second slope of the AO.
In Trad DAQ the code is this:
...
short timebase;
unsigned long interval;
short cvOut[1]={0};
double wave[2];
short scaledwave[2];
short board = 1;
u32 count1;
u32 count2;
//GPCTR-1 setup
count1= (u32) floor(20e6/(double)60 );
count2= (u32) floor(0.5*20e6/(double)60 );
GPCTR_Control (board, ND_COUNTER_1, ND_RESET);
Select_Signal (board, ND_GPCTR1_OUTPUT, ND_GPCTR1_OUTPUT, ND_LOW_TO_HIGH);
GPCTR_Set_Application (board, ND_COUNTER_1, ND_RETRIG_PULSE_GNR);
GPCTR_Change_Parameter (board, ND_COUNTER_1, ND_GATE, ND_OTHER_GPCTR_OUTPUT);
GPCTR_Change_Parameter (board, ND_COUNTER_1, ND_SOURCE, ND_INTERNAL_20_MHZ);
GPCTR_Change_Parameter (board, ND_COUNTER_1, ND_COUNT_1, count1);
GPCTR_Change_Parameter (board, ND_COUNTER_1, ND_COUNT_2, count2);
GPCTR_Control (board, ND_COUNTER_1, ND_PREPARE);
GPCTR_Control (board, ND_COUNTER_1, ND_ARM);
//GPCTR-0 setup
count1= (u32) floor((double)0/(double)60*0.1*20e6+2);
count2=64*20;
GPCTR_Control (board, ND_COUNTER_0, ND_RESET);
Select_Signal (board, ND_PFI_5, ND_OUT_UPDATE, ND_HIGH_TO_LOW);
Select_Signal (board, ND_GPCTR0_OUTPUT, ND_GPCTR0_OUTPUT, ND_LOW_TO_HIGH);
GPCTR_Set_Application (board, ND_COUNTER_0, ND_RETRIG_PULSE_GNR);
GPCTR_Change_Parameter (board, ND_COUNTER_0, ND_GATE, ND_PFI_5);
GPCTR_Change_Parameter (board, ND_COUNTER_0, ND_SOURCE, ND_INTERNAL_20_MHZ);
GPCTR_Change_Parameter (board, ND_COUNTER_0, ND_COUNT_1, count1);
GPCTR_Change_Parameter (board, ND_COUNTER_0, ND_COUNT_2, count2);
GPCTR_Control (board, ND_COUNTER_0, ND_PREPARE);
GPCTR_Control (board, ND_COUNTER_0, ND_ARM);
//wave setup
float framefrequency =60;
wave[0] = 5.0;
wave[1] = -5.0;
WFM_Group_Setup (board, 1, cvOut, 1);
WFM_Scale (board, 0, 2, 1.0, wave, scaledwave);
WFM_Load (board, 1, cvOut, scaledwave, 2, 0, 1);
WFM_Rate (framefrequency, 0, &timebase, &interval);
WFM_ClockRate (board, 1, 0, timebase, interval, 0);
// start the waveform, and all the pulse, DAQ trigger signal
WFM_Group_Control (board, 1, 1);
...
The new implementation looks like this:
TaskHandle tTaskDOut=0;
TaskHandle tTaskDCtr0=0;
TaskHandle tTaskAOut=0;
int32 iError =0;
iError = DAQmxCreateTask("",&tTaskDOut);
evalError(iError, tTaskDOut);
iError = DAQmxCreateTask("",&tTaskDCtr0);
evalError(iError, tTaskDCtr0);
iError = DAQmxCreateTask("",&tTaskAOut);
evalError(iError, tTaskAOut);
uInt32 count1;
uInt32 count2;
//GPCTR-1 setup
count1= (uInt32) floor(20e6/(double)60);
count2= (uInt32) floor(0.5*20e6/(double)60);
iError = DAQmxCreateCOPulseChanFreq(tTaskDOut, "Dev1/ctr1", "Counter1",
DAQmx_Val_Hz, DAQmx_Val_Low, 0.0, count1, 0.5 );
evalError(iError, tTaskDOut);
iError = DAQmxCfgImplicitTiming (tTaskDOut, DAQmx_Val_ContSamps, 20000000);
evalError(iError, tTaskDOut);
//GPCTR-0 setup
int pulsedelay =0;
int framefrequency =60;
count1= (uInt32) floor((double)pulsedelay/(double)framefrequency*0.1*20e6+2);
count2=framefrequency*20;
float64 dutyCycle = (float64)count1 / (float64)count2;
iError = DAQmxCreateCOPulseChanFreq(tTaskDCtr0, "Dev1/ctr0", "",
DAQmx_Val_Hz, DAQmx_Val_Low, 0.0, count1, dutyCycle );
evalError(iError, tTaskDCtr0);
iError = DAQmxCfgImplicitTiming (tTaskDCtr0, DAQmx_Val_ContSamps, 20000);
evalError(iError, tTaskDCtr0);
// Create the AO Channel
float64 data[1000];
for(int i=0;i<1000;i++)
{
if (i<500)
{
data[i]=1;
}
else
{
data[i]=-1;
}
}
iError = DAQmxCreateAOVoltageChan(tTaskAOut,"Dev1/ao0","",-10.0,10.0,DAQmx_Val_Volts,NULL);
evalError(iError, tTaskAOut);
float64 rate= (float64) 60.0 * 1000.0;
iError = DAQmxCfgSampClkTiming(tTaskAOut,"",rate,DAQmx_Val_Rising,DAQmx_Val_ContSamps,1000);
evalError(iError, tTaskAOut);
iError = DAQmxRegisterDoneEvent(tTaskAOut,0,DoneCallback,NULL);
evalError(iError, tTaskAOut);
iError = DAQmxWriteAnalogF64(tTaskAOut,1000,0,10.0,DAQmx_Val_GroupByChannel,data,NULL,NULL);
evalError(iError, tTaskAOut);
iError = DAQmxStartTask( tTaskAOut);
evalError(iError, tTaskAOut);
iError = DAQmxStartTask( tTaskDCtr0);
evalError(iError, tTaskDCtr0);
iError = DAQmxStartTask( tTaskDOut);
evalError(iError, tTaskDOut);
iError = DAQmxWaitUntilTaskDone(tTaskDOut,DAQmx_Val_WaitInfinitely);
evalError(iError, tTaskDOut);
iError = DAQmxStopTask( tTaskAOut);
evalError(iError, tTaskAOut);
iError = DAQmxStopTask( tTaskDOut);
evalError(iError, tTaskDOut);
iError = DAQmxStopTask( tTaskDCtr0);
evalError(iError, tTaskDCtr0);
The evalError checks on an error like DAQmxErrChk does.
The result is, that AO, CTR0 and CTR1 creates some stuff, but this is completely unsynchronized.
Can anyone tell me, how this can be done so that the new implementation is doing the same as the old ?
Thanks in advance.