Data Acquisition Toolbox

Continuous Acquisition Using Analog Input

This example shows how to set up a continuous data acquisition session using an analog input object. The example presents two separate cases of data acquisition using analog input:

  • Acquiring data for a defined duration.

  • Acquiring data until a certain condition is encountered in the input.

Note: This can only be run using the 32-bit version of MATLAB® and Data Acquisition Toolbox™. To learn more about using data acquisition devices on other platforms, see this example.

In this example you acquire data from the sound card on your computer. Before you begin, verify that your environment is set up so that you can record data with your sound card. For more information refer to Appendix A of the Data Acquisition Toolbox™ User's Guide.

First, find any running data acquisition objects and stop them. This stops all running data acquisition objects from interfering with this example. This code is usually not necessary outside this example unless there are multiple data acquisition objects running.

if (~isempty(daqfind))
    stop(daqfind)
end

Acquire Data for a Fixed Duration

Set the duration for Data Acquisition for 10 seconds.

duration = 10;

Create an analog input object and add a channel.

ai = analoginput('winsound');
addchannel(ai, 1);
ai
Display Summary of Analog Input (AI) Object Using 'USB Audio Device'.

  Acquisition Parameters:  8000 samples per second on each channel.
                           8000 samples per trigger on each channel.
                           1 sec. of data to be logged upon START.
                           Log data to 'Memory' on trigger.

      Trigger Parameters:  1 'Immediate' trigger(s) on START.

           Engine status:  Waiting for START.
                           0 samples acquired since starting.
                           0 samples available for GETDATA.

AI object contains channel(s):

   Index:  ChannelName:  HwChannel:  InputRange:  SensorRange:  UnitsRange:  Units:   
   1       'Mono'        1           [-1 1]       [-1 1]        [-1 1]       'Volts'  

The output line '1 sec. of data to be logged upon START', indicates that the analog input object is set up to acquire 1 second worth of data.

The analog input object us configured to acquire 1 second worth of data because the SamplesPerTrigger property is equal to the SampleRate property.

The SamplesPerTrigger property specifies the number of samples to acquire for each analog input channel for each trigger that occurs. The SampleRate property defines the number of Samples acquired per second per channel.

sampleRate = get(ai, 'SampleRate')
get(ai, 'SamplesPerTrigger')
sampleRate =

        8000


ans =

        8000

To acquire 10 seconds of data, configure SamplesPerTrigger property as the product of the duration and the SampleRate property. Use the floor function to ensure an integer value for the SamplesPerTrigger, because the SampleRate is constrained by the clock resolution on the hardware and may be forced to a float.

requiredSamples = floor(sampleRate * duration);
set(ai, 'SamplesPerTrigger', requiredSamples);

The best practice is to use the wait command before bringing the data in to MATLAB®. Set the duration of the wait command to be more than the actual duration of the acquisition. This ensures that the object has sufficient time to acquire the data even with system overhead with object setup and triggering. The recommended wait time is 110% of the duration +0.5 seconds. The wait function returns to MATLAB as soon as the acquisition completes and does not pause execution for the whole waitTime.

waitTime = duration * 1.1 + 0.5
start(ai)
tic
wait(ai, waitTime);
toc
waitTime =

   11.5000

Elapsed time is 10.508523 seconds.

The Elapsed Time shown is much smaller than the actual waitTime, indicating that the wait function returns to MATLAB as soon as the acquisition completes.

Use the getdata function to bring the data into the MATLAB workspace. By default, getdata gets the number of samples defined by the SamplesPerTrigger property.

[data, time] = getdata(ai);

Plot the data acquired in MATLAB

figure;
plot(time,data);
xlabel('Time (s)');  % Setting up the xlabel
ylabel('Signal (Volts)'); % Setting up the ylabel
title('Data Acquired using Microphone for 10 seconds'); % Setting up the title
grid on;

At the conclusion of this part, because the analog input object is no longer needed, you should:

  • Delete it with the delete function to free memory and other system resources.

  • Clear it from the Workspace.

delete(ai);
clear ai;

Continuously Acquire Data until a Particular Condition Occurs

Capture data from the microphone until a frequency in the range of 2500- 3000Hz is detected. Here, the duration of the acquisition is unknown at the start of the acquisition.

ai = analoginput('winsound');
addchannel(ai,1);

To continuously acquire data set the SamplesPerTrigger property to Inf. Use the stop command to stop the device.

set(ai,'SamplesPerTrigger',Inf);

Use the getdata command to bring the data back periodically into MATLAB. This is important when you set the SamplesPerTrigger property to Inf to avoid draining system resources. Use the daqmem command to check the system resources for the Data Acquisition Toolbox software:

daqmem(ai)
ans = 

winsound0-AI
    UsedBytes =   30.00 KB 
     MaxBytes =  891.82 MB 

The TimerFcn property of the analog input object is used to periodically monitor the data. You can assign a callback function to the TimerFcn property that will execute each time the time specified by the TimerPeriod property passes.

Set the TimerPeriod property to 0.5 seconds. Set the TimerFcn to the callback function demoai_continuous_timer_callback to get the data, update the figure and send a stop signal to the object once the condition is met.

set(ai,'TimerPeriod',0.5);

Set up the Plot for FFT of live input and start the analog input.

figure;  % Setting up the plot
P = plot(zeros(1000,1));  % Initially blank plot
T = title(['Discrete Fourier Transform Plot (fft),Number of callback function calls: ', num2str(0)]);
xlabel('Frequency (Hz)')
ylabel('|Y(f)|')
grid on;
set(ai,'TimerFcn',{@demoai_continuous_timer_callback,P,T});
start(ai);
while(strcmpi(get(ai,'Running'),'On')) % To keep the code running till the callback issues a stop
   pause(0.5);
end

The callback function, demoai_continuous_timer_callback, uses getdata to bring the data into MATLAB. The function also calls a custom demoai_continuous_fft function that returns a boolean signifying whether the particular frequency is detected. If the result is true, then the function copies the data to the UserData property of the analog object and issues a stop command to the object.

type demoai_continuous_timer_callback.m
function demoai_continuous_timer_callback(obj,event,plotHandle,titleHandle)
% This callback function executes each time the time specified by 
% TimerPeriod passes. The input parameters obj and event are passed implicitly in the callback
% function.
% * obj is the analog input object ai
% * event is a variable that stores the data contained in the EventLog
%   property
% This function calls the demoai_continuous_fft function to check whether the frequency is detected.
% If the frequency is detected then the callback issues a stop command to
% the analog input object.

persistent count;
persistent totalData;
if isempty(count)
     count =0;
end
count = count + 1;
% Get only the number of samples that are available
[data,time] =getdata(obj,obj.SamplesAvailable);
% First time through assign the data to totalData, else append it.
if isempty(totalData)
    totalData.time = time;
    totalData.data =data;
else
    totalData.time = [totalData.time;time];
    totalData.data = [totalData.data;data];
end
% Call demoai_continuous_fft to check whether the frequency is detected. If detected,
% transfer the data to UserData property of the object and stop the object
if(demoai_continuous_fft(data,plotHandle))
    set(obj,'UserData',totalData);
    stop(obj); 
end
% Update the title of the graph
set(titleHandle,'String',['Discrete Fourier Transform Plot (fft),Number of callback function calls: ', num2str(count)]);

Plot the captured data.

allData = get(ai,'UserData');
figure;
plot(allData.time,allData.data);
xlabel('Time (s)')
ylabel('Signal (Volts)')
title('Total Data captured');
grid on;

Alternatively, use the SamplesAcquiredFcn property to define a callback that executes every time the samples specified by SamplesAcquiredFcnCount property are acquired.

This completes the example. Because the analog input object is no longer needed, you should:

  • Delete it with the delete function to free memory and other system resources.

  • Clear it from the Workspace.

delete(ai);
clear all; % to remove persistent data

Print demoai_continuous_fft.m file

type demoai_continuous_fft.m
function condition = demoai_continuous_fft(data,plotHandle)
% This function calculates the FFT of the data, updates the plot and returns
% a true if it detects a frequency in the range of 2500-3000 Hz 

lengthofData =length(data);
nPower2 = 2 ^ nextpow2(lengthofData); % next closest power of 2 to the length
fs =8000; % Sample Rate
yDFT = fft(data,nPower2); % Discrete Fourier Transform of data
freqRange = (0:nPower2-1) * (fs / nPower2);  % Frequency range
gfreq = freqRange(1:floor(nPower2 / 2));  % Only plotting upto n/2 (as other half is the mirror image)
h = yDFT(1:floor(nPower2 / 2));
abs_h = abs(h);
threshold = 10;
set(plotHandle, 'ydata',abs_h,'xdata',gfreq); % Updating the plot
drawnow; % Update the plot
val = max(abs_h(gfreq > 2500 & gfreq < 3000));   % Checking for the frequency
if (val > threshold)
    condition = 1;
else
    condition = 0;
end