Acquire Continuous and Background Data Using NI Devices
This example shows how to acquire analog input data using non-blocking commands. This allows you to continue working in the MATLAB® command window during the acquisition. This is called background acquisition. Use foreground acquisition to cause MATLAB to wait for the entire acquisition to complete before you can execute your next command.
Create and Configure the DataAcquisition Object
Create a DataAcquisition object and add an input channel using the daq and addinput functions. This example uses an NI 9205 module in National Instruments™ CompactDAQ Chassis NI cDAQ-9178. This is module 1 in the chassis.
dq = daq("ni"); addinput(dq, "cDAQ1Mod1", "ai0", "Voltage");
Set the scan rate as 2000 samples per second.
dq.Rate = 2000;
Plot Live Data from Background Acquisition
During a background acquisition, the DataAcquisition object can handle acquired data in a specified way using the ScansAvailableFcn property. This example configures a callback function using the ScansAvailableFcn property to update a live plot with the acquired data.
dq.ScansAvailableFcn = @(src,evt) plotDataAvailable(src, evt);
To control how often the callback is triggered, set a value for the ScansAvailableFcnCount property. This value specifies the number of scans that must be available before the callback executes. For example, to trigger the callback 10 times per second, set the value to Rate/10.
dq.ScansAvailableFcnCount = 200;
Create a live-updating line plot by storing its handle in the UserData property of the DataAcquisition object. This allows the callback function to access and update the line plot dynamically during the background acquisition process.
figure; xlabel("Time (s)"); ylabel("Amplitude"); dq.UserData = animatedline;
Start the Background Acquisition
Use the start function to begin the background acquisition. This example performs background data acquisition for a duration of five seconds.
start(dq, "Duration", seconds(5))
Since there are no other calculations to perform during acquisition, you can use a while loop with pause to periodically check the acquisition status and display the number of scans acquired. The pause prevents the loop from becoming a tight polling loop.
while dq.Running pause(0.5) fprintf("Scans acquired = %d\n", dq.NumScansAcquired) end fprintf("Acquisition stopped after %d scans\n", dq.NumScansAcquired);
Scans acquired = 8000
Scans acquired = 9000
Scans acquired = 10000
Acquisition stopped after 10000 scans

Capture a Unique Event in Incoming Data
You can acquire data in the background continuously until a specific condition is met. This example acquires data until the signal equals or exceeds 1 V.
dq.ScansAvailableFcn = @(src,evt) stopWhenEqualsOrExceedsOneV(src, evt);
Create a live-updatable line plot by storing its handle in the UserData property of the DataAcquisition object. This allows the callback function to access and update the line plot dynamically during the background acquisition process.
figure; xlabel("Time (s)"); ylabel("Voltage"); dq.UserData = animatedline;
Start continuous background acquisition. The acquisition stops only when the listener detects a 1V event.
start(dq, "continuous");
Use a while loop with pause to periodically check the acquisition status and display the number of scans acquired. The pause prevents the loop from becoming a tight polling loop.
while dq.Running pause(0.5) fprintf("Scans acquired = %d\n", dq.NumScansAcquired) end fprintf("Acquisition terminated after %d scans\n", dq.NumScansAcquired);
Scans acquired = 4000 Continuing to acquire data Continuing to acquire data Detected voltage exceeds 1V: stopping acquisition Scans acquired = 4600 Acquisition terminated after 4600 scans

Callback Functions
This callback function updates the live plot with the data acquired in the background.
function plotDataAvailable(src, ~) [data, timestamps, ~] = read(src, src.ScansAvailableFcnCount, "OutputFormat", "Matrix"); addpoints(src.UserData, timestamps , data); end
This callback function configures the DataAcquisition object to acquire data continuously until the listener detects the 1V event and calls stop.
function stopWhenEqualsOrExceedsOneV(src, ~) [data, timestamps, ~] = read(src, src.ScansAvailableFcnCount, "OutputFormat", "Matrix"); addpoints(src.UserData, timestamps , data); if any(data >= 1.0) % stop continuous acquisitions explicitly src.stop() disp('Detected voltage exceeds 1V: stopping acquisition') else disp('Continuing to acquire data') end end