How can I read the most recent scans from a data acquisition object during continuous background recording?

32 views (last 30 days)
I’m recording voltage from microphones continuously in the background using an NI PXIe-1085 chassis and PXIe-4464 acquisition cards while changing the frequency, relative amplitude, and relative phase of voltages that are driving an array of loudspeakers. These drive voltages are also running continuously from a separate waveform generator (not part of the NI chassis).
In my code example below, I read "X" milliseconds of scans once during each frequency/amplitude/phase combination. The first read command reads the first acquired scan and each subsequent read command picks up with the scan where the previous left off, no matter how long the processing portion of the code takes. Instead, I’d like each read command to read the most recent “X” milliseconds of scans from the data acquisition object. How can I do that?
% Drive parameters
freq = 100:10:1000; % frequencies
dAmp = 0.1:0.1:1; % relative amplitudes
dPhase = 0:1:180; % relative phases
arb_volts = 0.5; % maxmum drive voltage
% Receive parameters
setting_time = 0.2; % seconds
num_cyc = 20; % number of cycles of the waveform to record
% setup arbitrary function generator and return instrument control object
arb = arbInitialize(arb_volts);
% Setup NI chassis and start acquiring data in the background
d = daq("ni");
ai0 = addinput(d, "PXI1Slot3", "ai0","Voltage");
% ai1 = addinput(...
% etc. for more channels
d.Rate = 200000;
% Start background acquisition
start(d, "continuous")
pause(0.1)
% loop over drive frequencies
for f = length(freq):-1:1
arbSetFreq(arb, freq(f))
record_duration = num_cyc / freq(f); % seconds
% loop over relative amplitudes and phases
for dA = 1:length(dAmp)
for dP = 1:length(dPhase)
arbSetAmpAndPhase(arb, arb_volts, dAmp(dA), dPhase(dP))
% measure voltages from microphones
pause(config.settling_time + record_duration)
data = read(d, seconds(record_duration));
% do some processing
% store outputs
end
% do some processing
end
% do some processing
end
% Write outputs

Answers (1)

Brahmadev
Brahmadev on 1 Apr 2024 at 11:10
As per my understanding, you would like to read only the data from the past 'X' miliseconds no matter when the 'read' function is called. The 'read' function by default continues reading the datastore from the endpoint of the previous call. Suppose the last 'X' miliseconds translate to 'Y' number of samples. If 'Y' is less than the size of 'data', why cant we take a sub-set of the data to do processing on. If 'Y' is bigger than the size of data, we can resuse the previous values by storing it in a different data buffer.
You can refer to the following modified code with the data buffer logic. Please note that the size of the data buffer should be updated according to the size of the data you are receiving.
% Your existing setup code...
desired_duration_ms = 100; % Example: X milliseconds
% Calculate buffer size based on desired duration in milliseconds
buffer_size_samples = (desired_duration_ms / 1000) * d.Rate;
% Initialize buffer
dataBuffer = [];
% Start the loop execution...
% Inside your loop, where you want to read the most recent data
arbSetAmpAndPhase(arb, arb_volts, dAmp(dA), dPhase(dP))
% Measure voltages from microphones
pause(setting_time + record_duration)
newData = read(d, seconds(record_duration), "OutputFormat", "Matrix");
% Update the buffer with new data
dataBuffer = [dataBuffer; newData];
if size(dataBuffer, 1) > buffer_size_samples
% Remove oldest data to maintain buffer size
dataBuffer(1:size(dataBuffer, 1) - buffer_size_samples, :) = [];
end
% Use dataBuffer for processing instead of newData
% Process dataBuffer..
Another approach could be calling the "flush" function before calling "pause". It removes all acquired and queued scans in the input and output buffers of the DataAcquisition interface. You can refer to the following documentation fo more information:
Hope this helps in resolving your query!

Categories

Find more on Counter and Timer Input and Output in Help Center and File Exchange

Products


Release

R2023b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!