07-13-2010 12:06 PM
I am currently using a CVI routine to do acquisition and generation. I am using a 9172 chassis and 9205 module for voltage acquisition and 9264 module for voltage generation.
I seem to run into an error during the startup of my task in the StartDAQ routine. The enclosed message is in the attached document. The message is cryptic and I am not sure what I have done wrong. I would some appreciate help in decoding the message and correcting the program.
The document contains the error code when I run the code.
The routine creating the tasks.
1. int StartDAQ (void)
{
daqrunning=0;
if (CreateDAQTask16diff(&taskHandle)) {StopDAQ (1);return 1;}
if (DAQmxStartTask(taskHandle)) {StopDAQ (1);return 1;}
if (CreateMAVS_DAQ_Taskout(&taskHandle_Out)) {StopDAQ (1);return 1;}
if (DAQmxStartTask(taskHandle_Out)) {StopDAQ (1);return 1;}
daqrunning=1;
return 0;
}
2. int32 CreateMAVS_DAQ_Taskout(TaskHandle *taskOut1)
{
int32 DAQmxError = DAQmxSuccess;
TaskHandle taskOut;
DAQmxErrChk(DAQmxCreateTask("", &taskOut));
for (ich=0;ich<CHANS_Osc;ich++) {
DAQmxErrChk(DAQmxCreateAOVoltageChan(taskOut, chanel_Out[ich],
"", -10, 10,
DAQmx_Val_Volts, ""));
}
DAQmxErrChk(DAQmxCfgSampClkTiming(taskOut, "",
rate_Out, DAQmx_Val_Rising,
DAQmx_Val_ContSamps, sampsPerChanOut));
// DAQmxErrChk(DAQmxSetWriteAttribute(taskOut, DAQmx_Write_RegenMode, DAQmx_Val_AllowRegen));
*taskOut1 = taskOut;
Error:
return DAQmxError;
}
3.
//------------------------------------------------------
static int CVICALLBACK Thread_AD (void *functionData)
{
int i,j;
//double fr;
int sys_hh,sys_mm,sys_ss;
int32 daqsts,daqoutsts;
div_t divres;
for (j=0;j<CHANS_Osc;j++) {
for (i=last;i<BDIM;i++) data_Out[chan_Out[j]*ADIM+(i-last)]=1.0;
}
SetCtrlAttribute (phsplash, SPLASH_MSGDAQ, ATTR_VISIBLE, 1);
StartDAQ ();
HidePanel (phsplash);
SetCtrlAttribute (phsplash, SPLASH_TXT2, ATTR_VISIBLE, 0);
SetCtrlAttribute (phsplash, SPLASH_MSGDAQ, ATTR_VISIBLE, 0);
InstallCtrlCallback (phsplash, SPLASH_P1, HideSplashScreen, 0);
InstallCtrlCallback (phsplash, SPLASH_P2, HideSplashScreen, 0);
InstallCtrlCallback (phsplash, SPLASH_TXT1, HideSplashScreen, 0);
InstallCtrlCallback (phsplash, SPLASH_TXT2, HideSplashScreen, 0);
InstallCtrlCallback (phsplash, SPLASH_TXT3, HideSplashScreen, 0);
InstallCtrlCallback (phsplash, SPLASH_TXT4, HideSplashScreen, 0);
InstallCtrlCallback (phsplash, SPLASH_TXT5, HideSplashScreen, 0);
InstallCtrlCallback (phsplash, SPLASH_TXT6, HideSplashScreen, 0);
DisplayPanel (ph); //SetPanelAttribute (ph, ATTR_WINDOW_ZOOM, VAL_MAXIMIZE);
DisplayPanel (phtree);
GetSystemTime (&sys_hh, &sys_mm, &sys_ss);
divres = div (sys_mm, 10); //reminder after dividing by 10
sek = datetime_to_sec (0, 0, 0, 0, divres.rem, sys_ss);
if (sek<0) sek=0;
if (sek>599) sek=0;
while (!gExiting) {
if (daqrunning) {
daqsts=DAQmxReadAnalogF64(taskHandle,sampsPerChan,4.0,DAQmx_Val_GroupByChannel,data,sampsPerChan*numChannels,&numRead,NULL);
if (daqsts<0) StopDAQ (2);
if (daq_out_data) {
for (j=0;j<CHANS_Osc;j++) {
for (i=last;i<BDIM;i++) data_Out[chan_Out[j]*ADIM+(i-last)]=stroke[j][i]/sens_Out[chan_Out[j]];
}
daqoutsts = DAQmxWriteAnalogF64 (taskHandle_Out, sampsPerChanOut, 0, 4.0, DAQmx_Val_GroupByChannel, data_Out,
&numWrite, 0);
if (daqoutsts<0) StopDAQ (2);
daq_out_data = 0;
}
if (startup) startup--;
else {
// retrieve data from DAQ buffer
// for (j=0;j<CHANS;j++) for (i=0;i<ADIM;i++) rw[j][i]=data[i+chan[j]*ADIM]/sens[chan[j]]; // retrieve data from DAQ buffer
// !!! new !!!! retrieve data from daq buffer and undersample from 2048 to 1024 !!!
for (j=0;j<CHANS;j++) for (i=0;i<ADIM;i++) rw[j][i]=data[2*i+chan[j]*2048]/sens[chan[j]]; // retrieve data from DAQ buffer & undersample
for (j=0;j<CHANS_Osc;j++) {
memcpy (&big[j][0],&big[j][ADIM],bigsize);
memcpy (&big[j][last],&rw[j],rw1size);
// put here low pass antialiasing filter prior to undersampling
//iir ??? later...
for (i=0;i<ADIM/4;i++) rw2[i]=rw[j][4*i]; // undersampling by 4 (new Fs is 256 Hz), used only for better FFT resolution
memcpy (&bfft[j][0],&bfft[j][ADIM/4],btmsize); // move data left
memcpy (&bfft[j][last2],&rw2,rw2size); // paste new undersampled data to last position
}
// !!! new !!!! retrieve data from daq buffer and undersample from 2048 to 1024 !!!
for (j=CHANS_Osc;j<CHANS;j++) for (i=0;i<ADIM;i++) rw_Osc[j-CHANS_Osc][i]=rw[j][i]; // retrieve data from DAQ buffer & undersample
for (j=0;j<CHANS_Osc;j++) {
memcpy (&big_Osc[j][0],&big_Osc[j][ADIM],bigsize);
memcpy (&big_Osc[j][last],&rw_Osc[j],rw1size);
}
newdata=1;
}
// raw data file logging
GetSystemTime (&sys_hh, &sys_mm, &sys_ss);
//sprintf (timebuff,"%02i:%02i:%02i",sys_hh,sys_mm,sys_ss);
sprintf (ftrend[sek].timebuff,"%02i:%02i:%02i",sys_hh,sys_mm,sys_ss);
SetCtrlVal (ph, P_TIME, ftrend[sek].timebuff);
CalculatePstroke2 ();
FillTrendData ();
sek++;
if (sek==600) {sek=0;save10min=1;}
for (j=0;j<CHANS;j++) for (i=0;i<ADIM;i++) fdat[j][i+dtcount]=rw[j][i];
dtcount+=ADIM;
if (dtcount==FDIM) dtcount=0;
if (save10min) {
if (dtcount==0) for (j=0;j<CHANS;j++) memcpy (&fdatout[j],&fdat[j],FDIM*sizeof(float));
else {
for (j=0;j<CHANS;j++) {
memcpy (&fdatout[j][0],&fdat[j][dtcount],(FDIM-dtcount)*sizeof(float));
memcpy (&fdatout[j][FDIM-dtcount],&fdat[j][0],dtcount*sizeof(float));
}
}
save10min=0;
savedata=1;
}
led=!led;
}
ProcessSystemEvents ();
}
StopDAQ (0);
return 0;
}
//------------------------------------------------------
07-14-2010 05:37 PM
Howdy d_tinman!
The error code that you are receiving means that you are starting your DAQmx generation task before you've written any data to the output buffer. This will not work because the device cannot begin outputting anything until it has been told what to output. You will need to load the buffer with samples using the DAQmxWrite function before you call DAQmxStartTask.
Regards,
07-14-2010 06:18 PM
Appreciate your reply. After looking through various examples, I separated the generation into a different thread and did what you suggested and it started generating data. However, this brings me to the next question. Do I need to introduce a delay in the acquisition and generation thread so that they do not stomp on each other's buffer. When I ran the program, no red flag was raised. However, during an actual run except for the first channel the rest of the voltage acquisition channels now read bad and I am not sure if this is a result of improper management of the threads. Basically, my reads are turning out bad values except for the first channel.
07-15-2010 05:45 PM
There is a separate buffer space and timing engine for analog input and analog output tasks. You can have both types of task running without having to worry about the buffers interfering with each other.
Regards,