06-09-2015 09:11 AM
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!
06-09-2015 11:34 AM
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); ... }
06-19-2015 09:23 AM - edited 06-19-2015 09:23 AM
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
07-27-2015 03:32 AM - edited 07-27-2015 03:33 AM
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!