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!