04-14-2014 05:01 PM
Hi,
I am trying to implement continuous analogue waveform generation in a LabWindows/CVI programme.
My application should not be allowed to regenerate samples. While my implementation in LabVIEW similar to the example in Voltage (non-regeneration) - Continuous Output.vi works without problems, I run into issues in LabWindows, namely I either don't generate all the samples I need or I get a buffer underrun:
DAQmxCreateTask("stimAna", &stimOutATH); DAQmxCreateAOVoltageChan (stimOutATH, "SpikeDAQCard/ao0", "", ANAO_MIN_VOLT, ANAO_MAX_VOLT, DAQmx_Val_Volts, NULL)); DAQmxCfgOutputBuffer (stimOutATH, (uint32_t) myWave.SamplingRate/5); DAQmxCfgSampClkTiming (stimOutATH, NULL, myWave.SamplingRate, DAQmx_Val_Rising , DAQmx_Val_ContSamps ,(uInt64) myWave.SamplingRate/10)); DAQmxSetWriteAttribute (stimOutATH, DAQmx_Write_RegenMode, DAQmx_Val_DoNotAllowRegen); DAQmxSetWriteAttribute (stimOutATH, DAQmx_Write_RelativeTo, DAQmx_Val_CurrWritePos); while (data_left_to_write) { DAQmxWriteAnalogF64 (stimOutATH, chunk_size, false, -1, DAQmx_Val_GroupByChannel, y, &sWritten, NULL); if (first_run) { DAQmxErrChk (DAQmxStartTask(stimOutATH); } } // set data and output to safe values y[0] = 0; DAQmxWriteAnalogF64 (stimOutATH, chunk_size, false, 10, DAQmx_Val_GroupByChannel, y, &sWritten, NULL); // *1 DAQmxWaitUntilTaskDone(stimOutATH, -1); // *2 DAQmxStopTask (stimOutATH);
If I don't wait for the task to be done (*1), I don't generate all the samples of my waveform, specifically, if the waveform to generate is short, only few samples will be generated before reaching DAQmxStopTask (*2). On the other hand, if I do wait until the task is done using (*1), then stopping the task (or indeed any other operation on it) will trigger error -200290 (buffer underrun).
How should I best handle this situation? And why does the LabVIEW example write all samples before stopping the task?
04-15-2014 02:47 PM
Hey jonasz,
I'm including a document that I believe will answer your question. Take a look at this articleand there is also an example linked to it that you may want to take a look at:
http://digital.ni.com/public.nsf/allkb/A806A0349FBF30CD8625795A007376F3?OpenDocument
Also, LabVIEW writes all samples before stopping the task because you're using a DAQmxWaitUntilTaskDone function. It will empty the buffer before moving to the Stop Task function. Take a look at the link below for further explanation.
http://zone.ni.com/reference/en-XX/help/370471W-01/daqmxcfunc/daqmxwaituntiltaskdone/
04-15-2014 04:27 PM - edited 04-15-2014 04:28 PM
Hi Taylor,
Thanks for your answer. I have seen the explanation for how to deal with error -200290. However, this does not address my problem.
My problem is that I cannot use the DAQmxWaitUntilTaskDone function, because using it will throw error -200290 next time I refer to the task (e.g. to stop it).
Another approach to take was to try to query how many items are still left in the write buffer. I used this function:
DAQmxGetWriteAttribute (task, DAQmx_Write_SpaceAvail, &space);
However, space does not seem to increase after the task was started and remains at 0 no matter how much time passes.
Is there another way to tell how many items are still in the buffer (I know the difference between on-board and PC buffer; PC buffer would be enough)?
Thanks,
Jonas
04-16-2014 05:34 PM
Hey jonasz,
Take a look at the document that I'm including. Hopefully this will give you a good direction to head in. Regarding your other question about another way to tell how many items are still in the buffer, there isn't a function that allows you see what's left inside the buffer.