Measurement Studio for .NET Languages

cancel
Showing results for 
Search instead for 
Did you mean: 

How can I clear the data written to the DAQmx buffers without disposing and re-configuring the given task or starting it?

Solved!
Go to solution

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...

  • the on-board hardware buffer will be allocated to hold N samples and filled with the first N samples from sineWaveData
  • the pc (ram) buffer will be allocated to hold M samples and populated with the last M-N samples from sineWaveData
  • the associated task will not be started

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?

0 Kudos
Message 1 of 5
(3,673 Views)

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?

0 Kudos
Message 2 of 5
(3,643 Views)

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.

0 Kudos
Message 3 of 5
(3,637 Views)

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.

0 Kudos
Message 4 of 5
(3,633 Views)
Solution
Accepted by topic author b!tmaster

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.

Message 5 of 5
(3,628 Views)