Transition from Traditional NI-DAQ (Legacy) to NI-DAQmx using Microsoft Visual Basic .NET: Part Three


NOTE: This document is the third document in the series, Transition from Traditional NI-DAQ (Legacy) to NI-DAQmx Using Microsoft Visual Basic .NET. Refer to Links to Other Topics in this Series to access other documents in this series.

In previous topics in this series, you have configured the DAQ operation. This topic explains how to differentiate the run-time behaviors of the drivers by looking at how to start and stop the operations and how to read and write. The type of task initially configured determines how the I/O is performed.


Accessing Help in NI-DAQmx

This series references two main types of reference manuals that ship with NI-DAQmx.

  • NI-DAQmx Core Help--references the language agnostic manual for NI-DAQmx. The NI-DAQmx Core Help explains NI-DAQmx concepts and provides a background about the various features and capabilities of the driver. Refer to Start » Programs » National Instruments » NI-DAQ » NI-DAQmx Help to access this manual.
  • NI-DAQmx .NET Help--references the manual for the .NET DAQmx API. This reference is specific to the .NET API and provides documentation for NI-DAQmx classes, methods, and properties. There are also concept topics in this manual which are specific to using the NI-DAQmx .NET API. This help is integrated into the Visual Studio .NET documentation. In Visual Studio .NET, select Help»Contents. To view the NI-DAQmx .NET Library help, select NI Measurement Studio Help»NI Measurement Studio .NET Class Library»Reference»National Instruments.DAQmx. For tasks and concepts, select NI Measurement Studio Class .NET Library»Using the Measurement Studio .NET Class Libraries»Using the Measurement Studio NI-DAQmx .NET Library.


After configuring the task, you need to start the task to actually begin the operation. You start the configured task by using the Control method.

[VB 6.0]


With NI-DAQmx, you do not need to start the task explicitly. Calling the Read and Write methods automatically starts the task. Use the Task.Control method to alter the state of the task.

For information about the various types of timing supported by NI-DAQmx, refer to the Task State Model section in the NI-DAQmx Core Help.

Refer to the NI-DAQmx .NET Help Verifying, Committing, Starting, and Stopping NI-DAQmx Tasks Programmaticallytopic for more information about the Task State Model in the NI-DAQmx .NET API.


Traditional NI-DAQ (Legacy)
The CWDAQ controls returned data the Read method.

[VB 6.0]
Private Sub Acquire_Click()

'configure finite acquisition operation


'read a 1000 samples of data and return it in the data array
CWAI1.Read 1000, data

End Sub

To acquire data using the NI-DAQmx .NET library, use the reader and stream objects. The reader objects are not sub-objects of the Task class Refer to the Taskstopic in the for a representation of the class hierarchy.

The NI-DAQmx .NET library provides the following reader objects. Choose the appropriate type of reader based on the type of signal being read and whether the task is configured for single or multiple channels.

  • AnalogSingleChannelReader
  • AnalogMultiChannelReader
  • AnalogUnscaledReader
  • CounterReader
  • DigitalSingleChannelReader
  • DigitalMultiChannelReader

Choose the appropriate reader based on the type of task. To create a reader object, you need to use the Stream property of the task. The following example shows how to initialize the appropriate reader object for the finite analog input single channel task that you created earlier, and then read the acquired data.

'Create an analog input single channel reader and initialize it using the task Stream property
dim analogInReader as AnalogSingleChannelReader= New AnalogSingleChannelReader(aiTask.Stream))

Dim data() As Double = analogInReader.ReadMultiSample(1000)

In the previous code example, the call to ReadMultiSample is a blocking call. A blocking call means that the method call will not return until all the data is available. Using the reader in this manner is usually appropriate for quick finite acquisition operations that return a small data set with a fast sampling rate.
However, setting up the Read in this way could potentially be a problem if you need to request a large number of points and the sample rate is slow, or if the acquisition is a continuous operation. If the DAQ application has a user interface, the user interface will appear non-responsive if the Read takes too long.

The NI-DAQmx .NET API provides support for asynchronous I/O allowing us to set up operations similar to the AcquiredData event provided by the CWDAQ ActiveX controls. We will discuss Asynchronous I/O later in the Asynchronous I/O section.

Refer to the NI-DAQmx .NET Help Reading and Writing with the NI-DAQmx .NET Librarytopic for more information about reader objects.


Traditional NI- DAQ (Legacy)

Controls, such as the CWAO, CWAOOnePoint (for Analog Output), CWDO and CWPulse (for Digital Output) generate output signals using the Traditional NI-DAQ (Legacy) driver. You use the Write method to write the data to the internal driver buffer before the data can be generated at the output channels.

[VB 6.0]
CWAO1.UpdateClock.Frequency = 1000 ' Updates per second
CWAO1.Infinite = True
CWAO1.Configure 'Settings configured from property pages
CWAO1.Write data

You can use the same method for generating data on multiple channels by passing a multi-dimensional array to the method.

To write out data using the NI-DAQmx .NET API, use the writer and stream objects. The writer objects are not sub-objects of the Task class. The NI-DAQmx .NET library provides the following writer objects for use with the appropriate type of task. Use the multi-channel writer objects for writing data that is generated across multiple channels.

  • AnalogSingleChannelWriter
  • AnalogMultiChannelWriter
  • AnalogUnscaledWriter
  • CounterSingleChannelWriter
  • CounterMultiChannelWriter
  • DigitalSingleChannelWriter
  • DigitalMultiChannelWriter

The following example shows how to initialize the appropriate writer object for a one-shot analog output task configured to use a single channel.


' Configure create and configure the task, channel, and sample rate

'create single channel writer
AnalogSingleChannelWriter writer = _
new AnalogSingleChannelWriter(myTask.Stream)

'write data to buffer


'Wait 10 seconds for analog output operation to complete

'cleanup any DAQ resources

Refer to the DAQmx .NET Help Reading and Writing with the NI-DAQmx .NET Librarytopic for more information about the reader objects.

Similar to readers, the NI-DAQmx .NET API provides support for asynchronous I/O for writers.

Asynchronous I/O

This section explains how you can use the Traditional NI-DAQ (Legacy) and the NI-DAQmx .NET API to perform asynchronous I/O.

Traditional NI-DAQ (Legacy)
You use the CWDAQ controls to set up events such as the AcquireData event for performing asynchronous I/O. The data acquired is returned as one of the parameters of the AcquireData event.

[VB 6.0]

Private Sub CWAI1_AcquiredData(ScaledData As Variant, BinaryCodes As Variant)
'process acquired data here
End Sub

Private Sub Start_Click()

'set configuration parameters

'configure the settings and start the operation

End Sub


The NI-DAQmx .NET API provides support for synchronous and asynchronous I/O.
In a synchronous operation, the reader does not return until the required numbers of data points are returned.
The previous section explained how to read 1000 data points using the finite synchronous Read method. The following example demonstrates how to set up the same operation asynchronously.

Public Sub StartAI()

' Create a new task
myTask = New Task("aiTask")

' Create a channel myTask.AIChannels.CreateVoltageChannel(physicalChannelComboBox.Text, "", CType(-1, AITerminalConfiguration), -10.0, 10.0, AIVoltageUnits.Volts)

' Configure timing specs for a finite acquisition
myTask.Timing.ConfigureSampleClock("", 1000, SampleClockActiveEdge.Rising, SampleQuantityMode.FiniteSamples, 1000)

reader = New AnalogMultiChannelReader(myTask.Stream)
' begin an asynchronous analog input operation
reader.BeginReadMultiSample(1000, New AsyncCallback(AddressOf ReadCallback), Nothing)
Catch ex As DaqException
End Try
End sub
Private Sub ReadCallback(ByVal ar As IAsyncResult)

' get the data acquired from the asynchronous operation
Dim data As Double() = reader.EndReadMultiSample(ar)

' Use data here…

Catch ex As DaqException
End Try

End Sub

In the previous code snippet, the task and channel are configured in the same way as the synchronous read operation is. The only difference is the Read method that is used. BeginReadMultiSample schedules the read operation to occur in a background worker thread. You specify a function, which is ReadCallback in this example, to be called when that background worker thread completes the read operation. Once the 1000 data points are acquired, the ReadCallback method is called. This is where you can access the acquired data.
Setting up the analog input operation in this way ensures that a read operation that does not return immediately--perhaps the read operation is waiting for a trigger signal. Setting up the analog input operation in this way does not block the main UI thread and does not make the UI unresponsive.

Asynchronous I/O is the most efficient way to set up continuous AI operations. By setting up the AI operation in its own dedicated thread, you make more efficient use of system resources. Any delays in the read operation do not make the user interface unresponsive. However, realize that asynchronous I/O does not make the application faster. By making efficient use of resources, the user interface and the application do not become unresponsive.

Asynchronous I/O is similar to events, but asynchronous I/O serves a different purpose than events. The next section describes support for events in NI-DAQmx.


Traditional NI-DAQ (Legacy)
The CWDAQ controls use events to acquire data and to notify you of NI-DAQ run time warnings and errors. Acquisition controls raise the AcquiredData event to notify you when data is ready. You can then read the data by using one of the event’s arguments. For a continuous acquisition application, the AcquiredData event is raised continuously every time the specified number of samples is available. You can also use a Progress event to indicate the progress of the acquisition. Events like DAQWarning and DAQError are raised to indicate run time errors and warnings that might occur during a Traditional NI-DAQ (Legacy) operation.

NI-DAQmx events serve a different purpose. The next section explains the events supported by NI-DAQmx.

NI-DAQmx 7.4 and later supports notifications for various occurrences. Refer to the NI-DAQmx Core and the NI-DAQmx .NET documentation to ensure you have the most current list of events supported by the driver.

By default, the NI-DAQmx event handlers occur in a worker thread. You cannot access user interface controls from a worker thread, because this is not supported by the .NET framework. You can only access user interface controls from the thread that created them. For more information about how to handle such cases, refer to the Event Handler considerations in the Using NI-DAQmx Events help topic in the NI-DAQmx .NET Help.

The CWDAQ ActiveX controls use events to provide an asynchronous notification for a set of NI-DAQ events, including the AcquiredData event. The NI-DAQmx .NET API provides a similar mechanism with asynchronous I/O. With asynchronous I/O, you install callbacks to execute when a read or write operation completes. Refer to the asynchronous I/O section for more information on how to set this up.

For more information about events supported in DAQmx, refer to the NI-DAQmx Core Help topic by selecting Contents >> Key NI-DAQmx Concepts >> Timing and Triggering.