05-15-2018 04:28 PM - edited 05-15-2018 04:31 PM
Hey all,
I have recently become very skeptical of the way I am using managing the lifetime and state of a DAQmx Task object. The Task object under discussion is responsible for doing finite analog output. The application allows the user to set a variety of parameters that influence what the waveform being output looks like. Every time the user changes a parameter, the system regenerates what it will send out of analog output channel zero. Once this regeneration is complete, the AnalogOutput class below will receive a message that contains the generated samples. Every time that the AnalogOutput class receives an updated sequence of samples to output, it re-configures the hardware via the Configure() method.
public class AnalogOutput : IAnalogOutput, IHandle<SamplesAvailableEvent> { private Task _task;
private AnalogSingleChannelWriter _writer;
private double[] _deliverySamples;
private readonly IDeviceLocator _deviceLocator;
private readonly IEventAggregator _eventAggregator;
private int _numberOfSamplesToOutput;
public AnalogOutput(IEventAggregator eventAggregator, IDeviceLocator deviceLocator)
{
_eventAggregator = eventAggregator;
_deviceLocator = deviceLocator;
_numberOfSamplesToOutput = 2;
_eventAggregator.Subscribe(this);
Configure();
}
public void Configure()
{
if (_task != null)
{
_task.Dispose();
_task = null;
}
_task = new Task("AnalogOutputTask");
_task.AOChannels.CreateVoltageChannel(_deviceLocator.DeviceName + "/ao0", "ao0", -10, 10, AOVoltageUnits.Volts);
_task.Timing.ConfigureSampleClock("", SamplingInfo.OutputSampleRate, SampleClockActiveEdge.Rising, SampleQuantityMode.FiniteSamples, _numberOfSamplesToOutput);
_task.Done += (sender, args) =>
{
_eventAggregator.PublishOnUIThread(new DeliveryCompleteEvent());
};
_task.Control(TaskAction.Verify);
_writer = new AnalogSingleChannelWriter(_task.Stream);
}
public void Start()
{
_writer.WriteMultiSample(false, _deliverySamples);
_task.Start();
}
public void Stop()
{
if (_task == null)
{
return;
}
_task.Stop();
_task.Control(TaskAction.Unreserve);
}
public void Handle(SamplesAvailableEvent message)
{
_numberOfSamplesToOutput = message.Samples.Count + 1;
_deliverySamples = new double[_numberOfSamplesToOutput];;
message.Samples.ToArray().CopyTo(_deliverySamples, 0);
// Update finite sample clock since it is possible that the number of samples
// to output has changed.
Configure();
} }
The statement below may be unclear to some folks, it is from Caliburn.Micro the MVVM framework my app is using. This statement publishes a message of type DeliveryCompleteEvent. Once this is published, the Handle(DeliveryCompleteEvent message) method will be executed. This method is shown a little below.
_eventAggregator.PublishOnUIThread(new DeliveryCompleteEvent());
To help give a more complete picture of what is happening in the application, more code is provided below. These functions are found within my applications view model and interact with the AnalogOutput class pictured above.
public void Deliver()
{
_analogOutput.Start();
}
public void Handle(DeliveryCompleteEvent message) { _analogOutput.Stop(); _analogOutput.Configure(); }
With that being said I am left with the following questions...
Any comments on the code above or answers to these questions are welcome, thanks!
05-17-2018
01:25 PM
- last edited on
06-12-2025
12:25 AM
by
Content Cleaner
Hello,
For the first inquiry of disposing a task: when we code in LabVIEW it's more efficient and faster to keep the same task and then just update the information is a while loop of sorts, similar can be said with Visual Studio or LabWindows/CVI. It isn't technically necessary, but it's just best practice to do so.
For the second inquiry, I would suggest looking at Text Based NI-DAQmx Data Acquisition Examples to see if it is something that you personally need to clean up.
Parul M.
Applications Engineer
National Instruments
05-17-2018 04:40 PM
Thanks for the information Parul. I will look into improving my code by updating the existing task instead of destroying it and creating a new one. I will check out the provided link as well.