function [output] = EdulogRun(port, dur, sps, loggers) % Run specified Eduloggers for a specified duration at a specified temporal % resolution. % % "port" is the port Eduloggers are connected to, this is visible on the % Neulog API window. "dur" is the duration (s) of the clap test, it must be % at least 15s for any response to be visible. "sps" is the number of % samples the edulogger should take per second, up to a maximum of 5. % "loggers" is a one dimensional cell array, with each string specifying % the name of a different Edulogger as described in the Neulog API % literature: % https://neulog.com/wp-content/uploads/2014/06/NeuLog-API-version-7.pdf % % "output" is a structure generated by running an Edulogger experiment, % consisting of the following fields: Time: The time (s) since the start of % the experiment of each sample. (double) Concern: Whether or not each % sample took more than twice the specified sample rate to retrieve % (logical) An additional field for each kind of Edulogger used, containing % the measurements taken at each point in data.Time. Fieldnames should line % up with the names specified in "loggers". % History: % ??-??-???? Todd Parsons Written. %% Essential checks. Not sure where the folder on Linux or macOS would be? if IsWin && ~exist('C:\neulog_api', 'dir') % If the Neulog API is not installed... error('Neulog API not found, please install.') % Link user to the installation page end if ~exist('webread') error('Required webread() function unavailable. You need Matlab R2014b+ or GNU/Octave 6.0+ for this to work.'); end if ~isnumeric(port) % If the port given is not a number... error('Port number (port) must be numeric') % Deliver an error end switch isnumeric(sps) % Is the given SPS a number? case true % If so... if sps > 5 % If it is greater than 5... error('SPS exceeds max temporal resolution, please choose a value lower than 5') % Deliver an error elseif sps < 0 % If it is less than 0... error('Cannot take fewer than 0 samples per second') % Deliver an error end case false % If not... error('Samples per second (sps) must be numeric') % Deliver an error end if ~isnumeric(dur) % If the given duration is not a number... error('Duration (dur) must be a numeric value') % Deliver an error end %% Run edulogger preface = ['http://localhost:' num2str(port) '/NeuLogAPI?']; % Construct the string to preface any argument passed to the Eduloggers for n = 1:dur*sps % For each sample... tic % Start a timer while toc < 1/sps % Until the timer reaches sps^-1 for l = 1:length(loggers) % For each logger... data.(loggers{l}){n} = ... % Set the appropriate cell in data to equal... webread( ... % ...the response received from the Edulogger when you send it... [preface, 'GetSensorValue:[', loggers{l}, '],[1]'] ... % ...this command: The preface, a request for values and the logger type ); end data.Time(n) = toc; % Record the time taken data.Concern(n) = round(toc, 1) > 2/sps; % Did this sample take more than twice the desired time to retrieve? data.Event(n) = false; end end %% Transform data output=struct(); % Create a blank structure data.Time = cumsum(data.Time); % Convert time to a cumulative sum for n = 1:dur*sps % For each sample... for l = 1:length(loggers) % For each logger... output(n).(loggers{l}) = ... % Set the appropriate cell in output to equal... str2num( ... % ...as a number, not a string... data.(loggers{l}){n}( ... % ...the appropriate value from data... findnum(data.(loggers{l}){n}) ... % ...put through a function which removes anything which isn't a number )); %#ok end output(n).Time = data.Time(n); % Save timestamps to the output output(n).Concern = data.Concern(n); % Save concern matrix to the output end end function i = findnum(str) % Find values in a string which can be converted to numeric without % returning an error. % % "str" is the string in which to find numbers % % "i" is a logical matrix with the indices of numbers in the string as % true. i = find(... % Find indices at which str is equal to... str == '0' | ... % ...0 str == '1' | ... % ...1 str == '2' | ... % ...2 str == '3' | ... % ...3 str == '4' | ... % ...4 str == '5' | ... % ...5 str == '6' | ... % ...6 str == '7' | ... % ...7 str == '8' | ... % ...8 str == '9' | ... % ...9 str == '.' | ... % ...a decimal point str == '-' ... % ...a minus sign ); end