01-09-2012 05:18 AM
Hi~ all,
Right now I am trying to generate a pusle train(squarewave) with amplitude0~3v, Freq=100Khz by the analog output(Hardware:USB 6351)
I am writing this in C/C++, but I just want to generate a pulse train with Freq.=5KHz by this API(DAQmxCfgSampClkTiming).
some parts of my codes:
for(int i=0;i<2;i++)
{
if(i%2 ==0)
data[i] = 3;
else
data[i] = 0;
}
DAQmxErrChk (DAQmxCreateTask("",&taskHandle));
DAQmxErrChk (DAQmxCreateAOVoltageChan(taskHandle,"Dev1/ao0","",-10.0,10.0, DAQmx_Val_Volts,NULL));
DAQmxErrChk (DAQmxCfgSampClkTiming(taskHandle,"",20000.0,DAQmx_Val_Rising,DAQmx_Val_ContSamps,2));
DAQmxErrChk (DAQmxRegisterDoneEvent(taskHandle,0,DoneCallback,NULL));
DAQmxErrChk (DAQmxWriteAnalogF64(taskHandle,2,0,10.0,DAQmx_Val_GroupByChannel,data,NULL,NULL));
DAQmxErrChk (DAQmxStartTask(taskHandle));
However I always get error message:
"Onboard device memory underflow. Because of system and/or bus-bandwidth limitations, the driver could not write data to the device fast enough to keep up with the device output rate.
Reduce your sample rate, or reduce the number of programs your computer is executing concurrently.
I know I should reduce the rate of DAQmxCfgSampClkTiming under 10000,
but it won't be 100kHz....
Does anyone know how to make a pulse train with Freq.=100KHz??
Please give me some idea....
01-09-2012 09:20 AM
Nesc,
I believe there are two ways to eliminate this problem.
1) Create bigger buffer. As your program is written, you have a buffer that is two samples big. Configured this way, DAQmx will not be able to transfer large blocks of data between the host buffer and your device. I would try with a buffer of at least 512 samples (ie.. declare data[512] and change your for loop conditional to i<512].
2) Configure your task to regenerate data from it's FIFO rather than streaming data from the host. This can be done by using DAQmxSetAOUseOnlyOnBrdMem. In this mode of operation, DAQmx will transfer data from the host computer to the device when you call DAQmx Write. After you start your task, your 6351 will simply loop on the data in it FIFO to create your output. Since you want to regenerate the same data repeatedly, I would recommend this approach as it will not use any bandwidth on the USB bus after the initial write.
Hope that helps,
Dan
01-10-2012 12:21 AM
Hi~ Mcdan,
First, I have to appreciate your help.
I attached my comment below after my experiment.
--------------------------------------------------------------------------------
Mcdan 已寫:
Nesc,
I believe there are two ways to eliminate this problem.
1) Create bigger buffer. As your program is written, you have a buffer that is two samples big. Configured this way, DAQmx will not be able to transfer large blocks of data between the host buffer and your device. I would try with a buffer of at least 512 samples (ie.. declare data[512] and change your for loop conditional to i<512].
Wow...it really works. But could you explain it more?
Why is the two-sampled buffer related to transferring large blocks?
By the way, I use this way and try to make duty cycle=10%
float64 data[10000];
for(j=0; j<100; j++)
{
for(i=0; i<100; i++)
{
if((100*j+i) < (100*j+10))
data[100*j+i] = 3;
else
data[100*j+i] = 0;
}
}
......
DAQmxErrChk (DAQmxCfgSampClkTiming(taskHandle,"",10000000.0,DAQmx_Val_Rising,DAQmx_Val_ContSamps,10000));
DAQmxErrChk (DAQmxWriteAnalogF64(taskHandle,10000,0,10.0,DAQmx_Val_GroupByChannel,data,NULL,NULL));
But I only could enhance it's frequency to 10kHz....
Here is the error message
"DAC conversion attempted before data to be converted was available.
Decrease the output frequency to increase the period between DAC conversions, or reduce the size of your output buffer in order to write data more often. If you are using an external clock, check your signal for the presence of noise or glitches.
Task Name: _unnamedTask<0>
Status Code: -200018" char [2048]
Does any way be able to enhance frequency to 100kHz???
2) Configure your task to regenerate data from it's FIFO rather than streaming data from the host. This can be done by using DAQmxSetAOUseOnlyOnBrdMem. In this mode of operation, DAQmx will transfer data from the host computer to the device when you call DAQmx Write. After you start your task, your 6351 will simply loop on the data in it FIFO to create your output. Since you want to regenerate the same data repeatedly, I would recommend this approach as it will not use any bandwidth on the USB bus after the initial write.
I am trying this way, but I am searching how to use it, should I add DAQmxSetWriteRegenMode?
If there is this condition(duty cycle=10%), does it support? Please give me some idea how to use it.
Appreciate sincerely...
Hope that helps,
Dan
Appreciate sincerely...
01-10-2012 08:58 AM
Nesc,
I'll try to answer your questions below:
Why is the two-sampled buffer related to transferring large blocks?
The code which is responsible for data transfer is fairly complicated, but as a general rule for multifunction DAQ devices performing continuous generation, DAQmx will attempt to transfer data blocks of min(bufferSize/2, 32768) in units of bytes. In this case 32768 is the default value for AO_USBXferReqSize attribute. Since your buffer is so small, DAQmx essentially sends data to the device in single sample chunks which is not going to be an effective use of USB bandwidth.
But I only could enhance it's frequency to 10kHz....
Here is the error message
"DAC conversion attempted before data to be converted was available.
If you look at your call to DAQmxCfgSampClkTiming, you set the rate parameter to 10 MHz. This is faster than your device supports.
I am trying this way, but I am searching how to use it, should I add DAQmxSetWriteRegenMode?
I believe that by default for continuous generation this set to DAQmx_Val_AllowRegen by default, which is what you'd need it to be to use DAQmxSetAOUseOnlyOnBrdMem. The other consideration is that all of the data written must fit in the device's FIFO. In the case of the 6351, this would be 8191 Samples / Number of Channels. So you would have to use a smaller data set than the 10,000 sample set you're attempting to use in the code posted.
Hope that helps,
Dan