From 04:00 PM CDT – 08:00 PM CDT (09:00 PM UTC – 01:00 AM UTC) Tuesday, April 16, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

Multifunction DAQ

cancel
Showing results for 
Search instead for 
Did you mean: 

Dynamically updating output waveform in .NET

Hello,

 

I would like to output a waveform and update its characteristics with minimum delay possible (without stopping the task).

 

So I tried to use EveryNSampleWritten event to trigger a writemultisample in an independent theread loop, but output doesn't change when I update the data with different values...Can anyone please tell me how to fix this?

 

Task configuration:

 

 

try
            {
                myTask = new Task();
                myTask.AOChannels.CreateVoltageChannel(physicalChannelComboBox.Text, "aoChannel",
                    outMin, outMax,
                    AOVoltageUnits.Volts);
                writer = new AnalogSingleChannelWriter(myTask.Stream);
                
                myTask.Timing.ConfigureSampleClock("", freq, SampleClockActiveEdge.Rising, SampleQuantityMode.ContinuousSamples, len);
                myTask.Stream.WriteRegenerationMode = WriteRegenerationMode.DoNotAllowRegeneration;           
                myTask.EveryNSamplesWrittenEventInterval = len;
                myTask.EveryNSamplesWritten += new EveryNSamplesWrittenEventHandler(NSamplesWritten_callback);                            
                myTask.Control(TaskAction.Verify);

                //Start output loop
                outData = Ramp(len, 5, 0);
                writer.WriteMultiSample(false, outData); 
                myTask.Start();

                Writer_loop_stop();
                Writer_loop_start();
              
            }
            catch (DaqException ex)
            {
                MessageBox.Show(ex.Message);
                return false;
            }
            return true;

 

Software event trigger:

private void NSamplesWritten_callback(object obj, EveryNSamplesWrittenEventArgs args)
        {
            nsampWritten.Set();
        }

 

Write loop thread:

 

private void Writer_loop()
        {
            while (!th_writer_stop)
            {
                writer.WriteMultiSample(false, outData);
                nsampWritten.WaitOne();
            }
        }

 

 

Data update:

 

        private void button_update_Click(object sender, EventArgs e)
        {
            GUI_get();            
            outData = Ramp(len, outMax, outMin);
        }

 

Thank you!

 

 

Message 1 of 4
(4,296 Views)

Update/additional info:

- I am working with Windows Forms.

- I am able to update some characteristics but not others. For instance, I can update timing frequency from a control inside the thread loop, like this:

 

 

while (true){
...
textBox_freq.BeginInvoke(new Action(() => { freq = Convert.ToInt16(textBox_freq.Text); })); myTask.Timing.ConfigureSampleClock("", freq, SampleClockActiveEdge.Rising, SampleQuantityMode.ContinuousSamples, len);
...
}

And this change happens immediatly even in the middle of the waveform (!).

 

 

I am able to update the waveform if not using a control. I tested with a random number for instance like this:

 

while (true){
...
rnd_volt = rnd.NextDouble() *5; outData = Ramp(len, rnd_volt , 0); writer.WriteMultiSample(false, outData);
...
}

 

But what I really want to do that is to change outData with a Windows Forms control doesn't work (!), like this:

 

while (true)
...
textBox_freq.BeginInvoke(new Action(() => { 
     outMax = Convert.ToInt16(textBox_max.Text);
 }));
outData = Ramp(len, outMax , 0);
writer.WriteMultiSample(false, outData);  
...
}

Or even without the BeginInvoke like this:

 

 

while (true)
...
outData = Ramp(len, Convert.ToInt16(textBox_max.Text), 0);
writer.WriteMultiSample(false, outData);  
...
}

 

 

0 Kudos
Message 2 of 4
(4,290 Views)

Hi keopz,

 

Did you take a lookt at the example ? (C:\Users\Public\Documents\National Instruments\NI-DAQ\Examples\DotNET4.0\Analog Out\Generate Voltage)

 

There are basically two ways of Analog Output with DAQmx. Regenerated AO and Non-Regenerated AO which distinct from each other by the value of the "myTask.Stream.WriteRegenerationMode" - property. 

If you choose to do non-regenerated AO (set WriteRegenerationMode to FALSE), you have to provide data fast enough to keep the Output buffer filled by calling the WriteMultiSample- method frequently.

 

Regards,

Valentin
Certified LabVIEW Architect
Certified TestStand Architect
Certified LabWindowsCVI Developer
National Instruments France

0 Kudos
Message 3 of 4
(4,175 Views)

Hello Valentin.B,

 

Thank you for your feedback. At the time of writing I was already aware of the regeneration settings. What I haven't messed with yet was the buffer size, which I guess is the key.

 

Key settings for a fast update when using:

 

myTask.Stream.WriteRegenerationMode = WriteRegenerationMode.DoNotAllowRegeneration;

 

...are these:

 

myTask.Stream.Buffer.OutputBufferSize = dataLength;
myTask.Stream.Buffer.OutputOnBoardBufferSize = 2; //2 is the minimum allowed

 

 

Although I still couldn't find a way to have an almost immediate response when writing do the DAQ because whith this it always takes the time of 1-2 buffer sizes. Any suggestion?

Could you maybe give a clear explanation of the inner working of the buffering in NIDAQ 6323?

 

Thanks,

Cheers!

 

0 Kudos
Message 4 of 4
(4,056 Views)