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,307 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,301 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,186 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,067 Views)