I need some help.
On machines of ours we use the 6321 PCIe-6321 multifunctional I/O device.
They have been running fine for a few years, but since about 1 year ago we ran into problems.
We assume the problems we have are related to the fact that a customer application is running on the same PC and interferes with our application.
This client performs web-access to a central server in Sweden.
It seems the problems are more severe the further away a machine is from sweden.
We have machines in sweden, holland, france and brasil. And Sweden does not report the problem but the other locations do.
So what is the the actual problem :
2020-11-23 06:13:03,86-DAQmx callback error: Attempted to read samples that are no longer available.
The requested sample was previously available, but has since been overwritten.
Increasing the buffer size, reading the data more frequently, or specifying a fixed number of samples
to read instead of reading all available samples might correct the problem.
Property: DAQmx_Read_RelativeTo Requested Value: DAQmx_Val_CurrReadPos
Property: DAQmx_Read_Offset
Requested Value: 0
Device: Dev2
Task Name: _unnamedTask<3>
Status Code: -200279
Now the source code I am using.
The appliction is not a Labview application, but a c++ application build with Embarcadero.
we also have a PCI-6518 Digital IO card in the system, so DeviceNr points to the correct board
and at startup AnOut0 and 1 are filled with the correct settings.
If the 6321 is device1 :
AnOut0 = "Dev1/ao0";
AnOut1 = "Dev1/ao1";
Initialisation of my tasks:
(DWprintf writes debug information to a seperate window. The error description above is taken from that window)
void __fastcall TAnaThread::StartRTdata(int cycletime, int NrItems)
{
DWprintf("Start RT data called");
/*********************************************/
// DAQmx Configure Code
/*********************************************/
if (AnOutputs == 0)
{
// analog output task :
DAQmxErrChk (DAQmxCreateTask("",&AnOutputs));
DAQmxErrChk (DAQmxCreateAOVoltageChan(AnOutputs, AnOut0.c_str(), "", -10.0,10.0, DAQmx_Val_Volts, ""));
DAQmxErrChk (DAQmxCreateAOVoltageChan(AnOutputs, AnOut1.c_str(), "", -10.0,10.0, DAQmx_Val_Volts, ""));
}
if (AnIns == 0)
{
// analog input task :
DAQmxErrChk (DAQmxCreateTask("",&AnIns));
if (DeviceNr == 1)
{
DAQmxErrChk (DAQmxCreateAIVoltageChan(AnIns, "Dev1/ai0:5", "", DAQmx_Val_Diff ,-10.0,10.0,DAQmx_Val_Volts,NULL));
DWprintf("Analog input task created for dev1");
}
else
{
DAQmxErrChk (DAQmxCreateAIVoltageChan(AnIns, "Dev2/ai0:5", "", DAQmx_Val_Diff ,-10.0,10.0,DAQmx_Val_Volts,NULL));
DWprintf("Analog input task created for dev2");
}
DAQmxErrChk (DAQmxCfgSampClkTiming(AnIns, "", 100, DAQmx_Val_Rising, DAQmx_Val_ContSamps, 100));
DAQmxErrChk (DAQmxRegisterEveryNSamplesEvent(AnIns, DAQmx_Val_Acquired_Into_Buffer, 10, 0, EveryNCallback, NULL));
DAQmxErrChk (DAQmxRegisterDoneEvent(AnIns, 0, DoneCallback, NULL));
}
if (Freq1 == 0)
{
// timer tasks :
DAQmxErrChk (DAQmxCreateTask("",&Freq1));
if (DeviceNr == 1)
{
DAQmxErrChk (DAQmxCreateCIFreqChan(Freq1,"Dev1/ctr0","", 0.1, 1000.000000, DAQmx_Val_Hz, DAQmx_Val_Rising, DAQmx_Val_LowFreq1Ctr, 0.001, 4, ""));
DWprintf("Freq1 task created for dev1");
}
else
{
DAQmxErrChk (DAQmxCreateCIFreqChan(Freq1,"Dev2/ctr0","", 0.1, 1000.000000, DAQmx_Val_Hz, DAQmx_Val_Rising, DAQmx_Val_LowFreq1Ctr, 0.001, 4, ""));
DWprintf("Freq1 task created for dev2");
}
DAQmxErrChk (DAQmxCfgImplicitTiming(Freq1, DAQmx_Val_ContSamps, 4000));
}
if (Freq2 == 0)
{
DAQmxErrChk (DAQmxCreateTask("",&Freq2));
if (DeviceNr == 1)
{
DAQmxErrChk (DAQmxCreateCIFreqChan(Freq2,"Dev1/ctr1","", 0.1, 1000.000000, DAQmx_Val_Hz, DAQmx_Val_Rising, DAQmx_Val_LowFreq1Ctr, 0.001, 4, ""));
DWprintf("Freq2 task created for dev1");
}
else
{
DAQmxErrChk (DAQmxCreateCIFreqChan(Freq2,"Dev2/ctr1","", 0.1, 1000.000000, DAQmx_Val_Hz, DAQmx_Val_Rising, DAQmx_Val_LowFreq1Ctr, 0.001, 4, ""));
DWprintf("Freq2 task created for dev2");
}
DAQmxErrChk (DAQmxCfgImplicitTiming(Freq2, DAQmx_Val_ContSamps, 4000));
}
/*********************************************/
// DAQmx Start Tasks
/*********************************************/
DAQmxErrChk (DAQmxStartTask(AnOutputs));
DAQmxErrChk (DAQmxStartTask(AnIns));
DAQmxErrChk (DAQmxStartTask(Freq1));
DAQmxErrChk (DAQmxStartTask(Freq2));
XmitSetpoint(0, 0.0);
XmitSetpoint(1, 0.0);
RTdataNrItems = NrItems;
RTdataTimer->Interval = 100; // cycletime;
RTdataTimer->Enabled = true;
return;
Error:
if( DAQmxFailed(error) )
{
DAQmxGetExtendedErrorInfo(errBuff,2048);
DWprintf("DAQmx Error Start RTdata: %d %s\n",tel, errBuff);
}
}
The actual error occurs in my callback routine :
int32 CVICALLBACK EveryNCallback(TaskHandle taskHandle, int32 everyNsamplesEventType, uInt32 nSamples, void *callbackData)
{
int32 error=0;
char errBuff[2048]={'\0'};
static int totalRead=0;
int32 read=0;
float64 data[2000];
int tel;
float64 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5 = 0.0;
/*********************************************/
// DAQmx Read Code
/*********************************************/
DAQmxErrChk (DAQmxReadAnalogF64(taskHandle, 10, 10.0, DAQmx_Val_GroupByChannel, data, 2000, &read, NULL));
if( read>0 )
{
tmp0 = 0.0;
tmp1 = 0.0;
tmp2 = 0.0;
tmp3 = 0.0;
tmp4 = 0.0;
tmp5 = 0.0;
for (tel = 0 ; tel < read; tel++)
{
tmp0 = tmp0 + data[tel];
tmp1 = tmp1 + data[tel + read];
tmp2 = tmp2 + data[tel + (read * 2)];
tmp3 = tmp3 + data[tel + (read * 3)];
tmp4 = tmp4 + data[tel + (read * 4)];
tmp5 = tmp5 + data[tel + (read * 5)];
}
AnIn0 = (AnIn0 * 0.7) + ((tmp0 / read) * 0.3);
AnIn1 = (AnIn1 * 0.7) + ((tmp1 / read) * 0.3);
AnIn2 = (tmp2 / read); // (AnIn2 * 0.7) + ((tmp2 / read) * 0.3);
AnIn3 = (tmp3 / read); // (AnIn3 * 0.7) + ((tmp3 / read) * 0.3);
AnIn4 = (tmp4 / read); // (AnIn4 * 0.7) + ((tmp4 / read) * 0.3);
AnIn5 = (tmp5 / read); // (AnIn5 * 0.7) + ((tmp5 / read) * 0.3);
if (LogData)
{
LogData0[LogPointer] = FreqIn0;
LogData1[LogPointer] = FreqIn1;
LogData2[LogPointer] = AnIn0; // data[tel];
LogData3[LogPointer] = AnIn1; // data[tel + read];
LogPointer++;
if (LogPointer >= NrOfSamples)
{
LogData = false;
}
}
}
Error:
if( DAQmxFailed(error) )
{
DAQmxGetExtendedErrorInfo(errBuff,2048);
/*********************************************/
// DAQmx Stop Code
/*********************************************/
DAQmxStopTask(taskHandle);
DAQmxClearTask(taskHandle);
DWprintf("DAQmx callback error: %s\n",errBuff);
}
return 0;
}
I have no control over what the other application is doing, so I am trying to find a fix in our application.
The only task that gives the error is task 2. I have not seen it for task 1, 3 and 4.
Any help/suggestion/workaround is welcome in finding a solution for keeping the tasks running (even with sometimes a buffer overflow).
If I can keep running the tasks (currently the Error section stops the task that reports the problem) and have valid data i am happy.
Thanks in advance for any help.
Rob