How to increase ScansAvailableFcnCount when using MATLAB to control NIDAQ

29 ビュー (過去 30 日間)
Shengjie Gao
Shengjie Gao 2020 年 9 月 7 日
コメント済み: Vincent Ferrera 2023 年 8 月 28 日
Hey guys,
I am currently trying to use MATLAB to control a NIDAQ (usb-6255) to collect data from my sensor. I want to do real-time plotting while collection the data.
I understand it is a good idea to use a callback function to do the plot like this
dq.ScansAvailableFcn = @(src,evt) plotDataAvailable(src, evt);
I just notice the default ScansAvailableFcnCount is set to a value that the plotting function above will be called 10 times a second (10Hz). My question is: Is there any way to increase the frequnency? I found it is easy to increase the ScansAvailableFcnCount so that the plotting function can be called less than 10Hz. However, when I decrease this value below 0.1*dq.Rate, it will say (here dq.Rate=300)
At the specified rate, the minimum count
allowed is 31.
Thank you very much!
  1 件のコメント
Vincent Ferrera
Vincent Ferrera 2023 年 8 月 28 日
Has this been resolved? I have the same issue with R2020b and a measurement computing device.

サインインしてコメントする。

回答 (2 件)

Noah Rubin
Noah Rubin 2021 年 3 月 3 日
Hi Anmol,
Thank you very much for your reply!
To clarify though, the only issue that is actually preventing us from sampling at a higher rate is the fact that we we have:
Fs = 3000;
dq.Rate = Fs;
nSamples = 0.02*Fs;
dq.ScansAvailableFcnCount = nSamples;
Given that Shengjie, Mauro, and Agostina all had the exact same issue as well-- a 10 Hz read limit exactly for everyone involved in this thread-- I do not believe this is an issue arising from our own use case. Unless I am misinterpreting line 1514 in my earlier screenshot, the 10 Hz limit is being set within the source code itself.
Given that we also have our setup working perfectly with the old toolbox, this convinces me further of that possibility.
If you have any other information, it would be greatly appreciated. I am happy to contact technical support if needed.
Thank you again for your time!
Noah

Anmol Dhiman
Anmol Dhiman 2020 年 9 月 13 日
Hi Shengjie,
Refer to link under Set ScansAvailableFcnCount to change the value for ScansAvailableFcnCount.
Regards,
Anmol Dhiman
  7 件のコメント
Noah Rubin
Noah Rubin 2021 年 3 月 2 日
編集済み: Noah Rubin 2021 年 3 月 2 日
Hi Anmal, thank you very much for your quick reply! We are trying to acquire data from:
4 EMG analog channels, 2 encoder analog channels, and, 1 encoder digitcal channel (PWM).
The daq (NI USB 6363 BNC) acquires data currently at a rate of 3000 Hz. We need to be able to read sensor data from the buffer every 20 ms (50 Hz). However, we are limited to reading every 100 ms (10 Hz).
Outlined below is a snippet of our code for the daq setup.
The first section does not work with matlab 2020b, but the next portion works as desired under the old toolbox in 2018b.
--
I'm also attaching a snippet of the source code for DataAcquisition.m that we may believe be causing the issue at hand (Line 1514). From our understanding, the output is of the number of scans is always reading at 0.1, so no matter how we scale our sample rate, the number of scans from the buffer allowed scales with this value. E.g. if the sample rate is 3000 Hz, it doesn't scan until 300 new samples are available. If the sample rate is 1000 Hz, it doesn't scan until 100 new samples are available. This is alluded to above by Shengjie Gao as well.
If you have any suggestions how to fix this issue in matlab 2020b that would be greatly appreciated; otherwise we will need to move forward with the older toolbox. Thank you very much for your time!
~Noah
% % % % % % % % % % % % % % % % % % % %
% Not working: Matlab 2020b with new daq toolbox:
% obtain Device ID for the DAQ
daqId = "Dev4";
% create DAQ object and set sample rate
dq = daq("ni");
Fs = 3000;
dq.Rate = Fs;
% add analog EMG channels
addinput(dq,daqId, "ai0", "Voltage");
addinput(dq,daqId,"ai1","Voltage");
addinput(dq,daqId,"ai2","Voltage");
addinput(dq,daqId,"ai3","Voltage");
% Add analog encoders
addinput(dq,daqId,"ai6", "Voltage");
addinput(dq,daqId,"ai7", "Voltage");
% Add encoder PWM Out
addinput(dq,daqId,"port0/line0", "Digital");
% # of samples after which to update (corresponds to 20 ms)
nSamples = 0.02*Fs;
% set function handle to call after nSamples
dq.ScansAvailableFcn = @(src,evt) updateState(src,evt);
dq.ScansAvailableFcnCount = nSamples;
% create global data storage arrays to be filled by updateState
global dataAll;
global timeAll;
dataAll = [];
timeAll = [];
% start data collection for 5 seconds
start(dq,"continuous");
function updateState(dq,~)
% declare global variables in function
global dataAll;
global timeAll;
% read newly available data as matrices
[data, timestamps, ~] = read(dq,dq.NumScansAvailable,"OutputFormat","Matrix");
% store newly available data
timeAll = [timeAll; timestamps];
dataAll = [dataAll; data];
%****************CALCULATE AND SEND CONTROL OUTPUT HERE********************
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Using the old Toolbox, we currently have the system working in Matlab 2018b
% Code for an identical setup that is working is shown below:
% create DAQ object and set trial duration in seconds
dq = daq.createSession('ni');
% desired device ID
daqId = 'Dev4';
% add analog EMG channels
addAnalogInputChannel(dq,'Dev4','ai0','Voltage');
addAnalogInputChannel(dq,'Dev4','ai1','Voltage');
addAnalogInputChannel(dq,'Dev4','ai2','Voltage');
addAnalogInputChannel(dq,'Dev4','ai3','Voltage');
% Wrist encoder
addAnalogInputChannel(dq,daqId,'ai6', 'Voltage');
% Hand encoder
addAnalogInputChannel(dq,daqId,'ai7', 'Voltage');
% Rotary Encoder PWM Out
addDigitalChannel(dq,daqId,'port0/line0', 'InputOnly');
% Rotary Encoder PWM Status
addDigitalChannel(dq,daqId,'port0/line1', 'InputOnly');
% set sampling rate, and set update calls to every 20 ms
Fs = 3000;
dq.Rate = Fs;
dq.NotifyWhenDataAvailableExceeds = 0.02*Fs;
global dataAll;
global timeAll;
dataAll = [];
timeAll = [];
count = 1;
dq.DurationInSeconds = 5;
% add listener to call desired function
lh = addlistener(dq,'DataAvailable',@UpdateStateNew);
% start collection in background
startBackground(dq);
function UpdateStateNew(~,event)
global dataAll;
global timeAll
dataAll = [dataAll; event.Data];
timeAll = [timeAll; event.TimeStamps];
Matlab Source Code (2020b):
Anmol Dhiman
Anmol Dhiman 2021 年 3 月 3 日
編集済み: Anmol Dhiman 2021 年 3 月 3 日
Hi Noah,
This seems to be very specific use case. This might need more follow up and discussions, hence I suggest you to contact Technical Support.

サインインしてコメントする。

Community Treasure Hunt

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

Start Hunting!

Translated by