06-12-2018 04:38 PM
Hello friends,
I posted a similar question recently but after getting a better understanding of the DAQmx API I realized I could concisely re-word the question to make it more clear what I am asking.
How can I clear the data written to the DAQmx buffers without disposing and re-configuring the given task or starting it?
Example
Let's say I have some double[] array that contains 1000 points of data that form a sine wave, let's call the variable sineWaveData. And I write the sine wave data to the DAQmx buffers using WriteMultiSample(false, sineWaveData). Once this function call is complete the following things will be true...
Let's say I have some other double[] array that contains 1000 points of data that form a triangle wave, let's call the variable triangleWaveData. Now, before calling Start() on the associated task I realize that I don't want to send the sineWaveData out of the NI hardware and instead want to send the triangleWaveData instead. Without disposing of the associated task and re-configuring it or starting it, I would like to clear the sineWaveData from the buffers and write the triangleWaveData instead. How could I accomplish this?
Solved! Go to Solution.
06-13-2018 09:54 AM
I believe I understand your question correctly although I am misunderstanding why you would want to do this. Can you not simply use a decision tree prior to running the task that generates the correct data to the buffer based on user input prior to running the task?
If this needs to be done as you have stated, can you specify the NI hardware you are looking to use to output these waveforms?
06-13-2018 11:44 AM
kaschmidt,
To answer your first question. Unfortunately, it is not as simple as running a decision tree prior to running the task that writes the correct data. In the application I am developing, the user can change anywhere between 15 and 20 input parameters which alter what the waveforms look like that get sent out the analog output. On every user input change, the analog output waveforms need to get (re)generated and the hardware needs to get prepared to send the generated waveforms. Preparing the hardware includes configuring the NI task I have created that is responsible for analog output and writing the samples to the hardware. Check out some example code below, this is similar to the code that gets executed on every user input change.
public void PrepareHardware() { _task = new Task("AnalogOutputTask"); _task.AOChannels.CreateVoltageChannel(_hardwareInfo.AnalogOutputModuleName + "/ao0", "ao0", -10, 10, AOVoltageUnits.Volts); _task.AOChannels.CreateVoltageChannel(_hardwareInfo.AnalogOutputModuleName + "/ao1", "ao1", -10, 10, AOVoltageUnits.Volts); _task.Timing.ConfigureSampleClock("", _hardwareInfo.AnalogOutputSamplingRate, SampleClockActiveEdge.Rising, SampleQuantityMode.FiniteSamples, AnalogOutputSamples.GetLength(1)); _task.Triggers.StartTrigger.ConfigureDigitalEdgeTrigger("/" + _hardwareInfo.SecondDigitalIoModuleName + "/PFI0", DigitalEdgeStartTriggerEdge.Rising); _task.Control(TaskAction.Verify); _writer = new AnalogMultiChannelWriter(_task.Stream); _writer.WriteMultiSample(false, AnalogOutputSamples); }
The user can send waveforms out of the analog output with a button press on the UI, a start button so to speak. One might be wondering why I don't just write the samples to hardware when the user presses the start button. The reason for this is that writing data to the hardware incurs significant overhead and it is critical that there is as little delay as possible between the time the user presses the start button and waveforms actually start getting delivered out of the hardware.
It would be useful if I did not have to dispose of the task and reconfigure it's channels, timing, and triggering in order to clear what was written to the buffers. Configuring the task and verifying it introduces significant overhead into the execution of my program, my thought was that if I could just clear what was written to the buffers without having to mess with task, then I could improve the execution time of this code.
To answer your second question, I am using a cDaq-9174 with a NI 9263 analog output module.
06-13-2018 02:27 PM
An exception was thrown in my code today while I was trying various brainstormed ideas to solve this issue and I believe the exception message contains the answer to this question, oddly enough.
NationalInstruments.DAQmx.DaqException HResult=0x80131501 Message=Generation cannot be started because the output buffer is empty. Write data before starting a buffered generation. The following actions can empty the buffer: changing the size of the buffer, unreserving a task, setting the Regeneration Mode property, changing the Sample Mode, or configuring retriggering. Task Name: UptAnalogOutputTask Status Code: -200462 Source=NationalInstruments.DAQmx StackTrace: at nNIMSSAIL100.StatusObserverT<nNIMSSAIL100::ApiTraits<nNIMSSAIL100::DotNetApi> >.CheckWithName(StatusObserverT<nNIMSSAIL100::ApiTraits<nNIMSSAIL100::DotNetApi> >* , tCaseInsensitiveBasicString<unsigned short\,_STL::char_traits<unsigned short>\,_STL::allocator<unsigned short>\,nNIDMXS100::tLocaleConsideringWideStringComparitor\,nNIDMXS100::tLocaleConsideringWideStringCaseForcer>* pName) at nNIMSSAIL100.StatusObserverT<nNIMSSAIL100::ApiTraits<nNIMSSAIL100::DotNetApi> >.Check(StatusObserverT<nNIMSSAIL100::ApiTraits<nNIMSSAIL100::DotNetApi> >* ) at NationalInstruments.DAQmx.Task.Control(TaskAction mode) at NationalInstruments.DAQmx.Task.Start() at AnalogOutputIsolation.UptAnalogOutput.Configure() in C:\projects\MaxwellSandbox\AnalogOutputIsolation\UptAnalogOutput.cs:line 51 at AnalogOutputIsolation.Program.Main() in C:\projects\MaxwellSandbox\AnalogOutputIsolation\Program.cs:line 25
TL;DR:
The following actions can empty the buffer: changing the size of the buffer, unreserving a task, setting the Regeneration Mode property, changing the Sample Mode, or configuring retriggering.
I am hesitant to make this the accepted solution, but it seems like the best thing I have came across so far.
06-13-2018 05:11 PM
I have done some tests to verify the validity of the following excerpt from the provided exception.
The following actions can empty the buffer: changing the size of the buffer, unreserving a task, setting the Regeneration Mode property, changing the Sample Mode, or configuring retriggering.
Changing the size of the buffer
Results: Clears the buffer
Unreserving the task
Results: Clears the buffer
Set regeneration mode property
Results: Changing the regeneration mode property clears the buffer, setting the regeneration mode to itself does not clear the buffer. This should be interpreted as Change regeneration mode property.
Change sample mode
Results: Does not clear the buffer.
Configure retriggering
Results: My device does not support this, I was unable to test it.