Measurement Studio for VC++

cancel
Showing results for 
Search instead for 
Did you mean: 

Still trying to fast-switch an analog output

I've been crawling these forums and google groups for a while now, and found some really interesting info, but I still can't get my analog output to work. What I want to do is simple : I have a 1KHz waveform output on Ao0, and want to change the amplitude of that waveform on the fly when I press an "up" or "down" button.

Here is my sourcecode :


ampl = 4.0;
for(int i=0;i<1000;i++)
data[i] = ampl*sin((double)i*2.0*PI/1000.0);

error = DAQmxCreateTask("",&taskHandle);
error = DAQmxCreateAOVoltageChan(taskHandle,"Dev1/ao0","",-5.0,5.0,DAQmx_Val_Volts,NULL);
error = DAQmxCfgSampClkTiming(taskHandle,"",1000.0,DAQmx_Val_Rising,DAQmx_Val_ContSamps,1000);

error = DAQmxSetWriteRegenMode(taskHandle, DAQmx_Val_AllowRegen);
error = DAQmxSetAOUseOnlyOnBrdMem (taskHandle, NULL, 0);
error = DAQmxWriteAnalogF64(taskHandle,1000,0,0.0,DAQmx_Val_GroupByChannel,data,&res,NULL);
error = DAQmxStartTask(taskHandle);

and this is the code for the "up" button (the "down button is identical, except for the increment on the first line) :


ampl += 1.0;
if (ampl > 5.0)
ampl = 5.0;

for(int i=0;i<1000;i++)
data[i] = ampl*sin((double)i*2.0*PI/1000.0);

int32 res;
int32 x = DAQmxWriteAnalogF64(taskHandle,1000,0,1.0,DAQmx_Val_GroupByChannel,data,&res,NULL);
if (x < 0)
{
char buf[4097];
DAQmxGetErrorString (x, buf, 4096);
AfxMessageBox(buf);
}

This code works perfectly, but has a very bizarre delay : when pressing the up or down button, it takes about 7 re-generations before the result is seen on the output pins (got a scope attached) ! So on a 1KHz sample rate, it takes about 7 seconds before my output amplitude increases or decreases

If I up the samplerate to 10KHz, it still takes 7 regenerations, but now they are done much faster ofcourse

does anyone have an idea on how to fix this ? I really really need the output to change as fast as possible (the final code will not use user-clicked buttons, but input from a TTL signal, which is then processed into a new amplitude)

many many thanks in advance!

Jeroen
0 Kudos
Message 1 of 2
(6,643 Views)
Replying to myself here, since there was little or no response. I'll summarize my findings here to help future visitors with the knowledge I gathered (or the lack thereof 🙂

after a long struggle with both on-board and off-board buffering and with regeneration, I've given up on using a DAQ card for auto-feeding custom analog output waveforms that change in mid-wave.

the solution ? Calculate the buffer as with the options above, but write it to the DAQ yourself every msec.

this method of course will ONLY work if your CPU can feed the scalar values to the DAQ fast enough. In our case, we had rather long wavelength (> 10 msec), so a once-per-msec update was almost always sufficient. If you have frequencies that surpass 1KHz, my guess is that your CPU will not be able to feed samples one-by-one. Your option might be to feed small sub-sections of the bigger wave, or live with the fact that you can not change the waveform except by stopping & restarting the output.
Message 2 of 2
(6,567 Views)