Hi everyone,
In a few words, I'm working on a application whose aim is to generate audio samples on the four AO channels.
I first load audio files (in raw format) in memory, then I mixed them in one data array.
After settings the right properties to my generationTask (clock at 52000Hz, ...), I use DAQmxWriteBinary16 to generate samples.
When I'm starting my task I get an "Onboard Memory Underflow" Error (code -200016).
I'm working under linux RHEL4, using the NiDAQmx C API.
My computer got a Pentium D processor (Dual Core) at 2.8Ghz with 1Go RAM.
My NI card is an PCI 6259 (Accordings to the specification, it can output 1.25MS/s when using the 4Channels)
I first developped this application under my computer (linux), the code works well but was not tested with high
frequency and multiple AO Channel (just one channel). This code was ported on windows (with the useful informations found on
this forum to compile using devc++, thanks a lot!!), it runs well since weeks (generating at 52000Hz, on 4 AO
Channels) on an equivalent comuter (P4 3.0Ghz, 1Go RAM).
Last week I come back on my linux computer to add more functionalities. Testing a bit more my application, I
detected the problem with high frequency.
I first test with a clean system of RHEL4 (no result), then I suspected an hardware problem and I test with another
PCI6259 cards (no more results). After that I suspected the incompatibility of niDAQmx 8 under RHEL4. This problem
is well known on this forum but I didn't believe it was the reason of my crash, because an other part of my
application is to acquire at the same high frequency on twelve channels simultaneously (at current time it seems to
work correctly). Nevertheless I try under RHEL3 (supported by niDAQmx8), on the same computer; no
more results, it still crash !
So I suspect a coding error. Here is a part of my code :
/*********************************************/
// Load and combine files in one array
/*********************************************/
mixedSamples = (int16 *) malloc (samplesNb*channelNb * sizeof(int16));
if (mixedSamples == NULL) {
printf("Erreur durant l'allocation du tableau d'échantillons\n");
}
printf(" Chargement des samples en mémoire ... \n");
for (i=0; i<samplesNb*channelNb; i=i+channelNb){
for (j=0; j<channelNb; j++){
totalRead = totalRead + fread ((mixedSamples + i + j), sizeof(int16), 1,samplesFile[j].fdescRawData);
}
}
printf(" %ld samples présents dans %d fichiers; %ld chargé \n", samplesNb, channelNb, totalRead);
if (totalRead != samplesNb*channelNb){
printf ("Erreur au cours de la phase de chargement : totalRead != samplesNb*channelNb \n");
exit(-1);
}
/*********************************************/
// Generate the right label for output
/*********************************************/
switch (channelNb)
{
case 1: outputLabel = strdup("Dev1/ao0");
break;
case 2: outputLabel = strdup("Dev1/ao0, Dev1/ao1");
break;
case 3: outputLabel = strdup("Dev1/ao0, Dev1/ao1, Dev1/ao2");
break;
case 4: outputLabel = strdup("Dev1/ao0, Dev1/ao1, Dev1/ao2, Dev1/ao3");
break;
default : printf(" Error - Cas impossible \n");
break;
}
/*********************************************/
// DAQmx Configure Code
/*********************************************/
DAQmxErrChk (DAQmxCreateTask("",&taskHandle));
DAQmxErrChk (DAQmxCreateAOVoltageChan(taskHandle, outputLabel,"",-10.0,10.0,DAQmx_Val_Volts,NULL));
DAQmxErrChk (DAQmxCfgSampClkTiming(taskHandle,NULL,sampling_rate,DAQmx_Val_Rising,DAQmx_Val_ContSamps,samplesNb));
DAQmxErrChk (DAQmxRegisterDoneEvent(taskHandle,0,DoneCallback,NULL));
/*********************************************/
// DAQmx Write Code
/*********************************************/
DAQmxErrChk (DAQmxWriteBinaryI16(taskHandle,samplesNb,0,10.0,DAQmx_Val_GroupByScanNumber,mixedSamples,NULL,NULL));
/*********************************************/
// DAQmx Start Code
/*********************************************/
DAQmxErrChk (DAQmxStartTask(taskHandle));
printf("Génération des échantillons en continue. Appuyez sur Entrée pour arrêter\n");
getchar();
Error:
if( DAQmxFailed(error) )
DAQmxGetExtendedErrorInfo(errBuff,2048);
if( taskHandle!=0 ) {
/*********************************************/
// DAQmx Stop Code
/*********************************************/
DAQmxStopTask(taskHandle);
DAQmxClearTask(taskHandle);
}
if ( mixedSamples != NULL) {
free (mixedSamples);
}
if ( samplesFile != NULL) {
free (samplesFile);
}
if( DAQmxFailed(error) )
printf("Erreur DAQmx : %s\n",errBuff);
printf("Fin du programme, appuyez sur Entrée pour quitter\n");
getchar();
return 0;
}As you can see, this code is very similar to the examples supplied with niDAQmx.
Has someone an explication, some code corrections to give me ?
Thanks in advance,