KbQueueXXX functions: which to use and where do they go in relation to the trials' loop?

Dear Psychtoolbox users,
I wrote a script to run a 2AFC task where participants must respond within a fixed deadline of 2 seconds. If participants respond earlier, then they move to the subsequent trial straight away. To collect their responses (i.e., the first key they pressed and their RT), I coded a custom function that incorporates KbQueueCheck. I am now reviewing and debugging my script but I have some doubts about the KbQueueXXX functions. I would be grateful if you could give me some feedback.

Task script

In a mixture of code and pseudocode, here is what I am doing.

KbQueueCreate(KEYBOARD, KEYS_OF_INTEREST);
KbQueueStart(KEYBOARD);

% TRIALS' LOOP STARTS
for iTrial = 1:nTrials
    KbQueueFlush(KEYBOARD);
    % show stimulus and record its onset and offset times

    respDeadline = stimulusOffset + 2;
    collectResponse(KEYBOARD, respDeadline, stimulusOnset); % <- KbQueueCheck() here!
end
% TRIALS' LOOP ENDS

KbQueueStop(KEYBOARD);
KbQueueRelease(KEYBOARD);

Custom function

Below is my custom function collectResponse() where I embedded KbQueueCheck.

function [choice, rt, choiceTime, firstPress, keyCodes, pressed] = collectResponse(deviceIndex, untilTime, targetOnset)
%% LOOK FOR KEYPRESSES
pressed = false;

while pressed == false && GetSecs <= untilTime
    [pressed, firstPress] = KbQueueCheck(deviceIndex);
end

%% PROCESS KEYPRESSES
if pressed == false                          % NO KEYS WERE PRESSED
    keyCodes = NaN;
    firstPress = NaN;
    choiceTime = NaN;
    choice = NaN;
    rt = NaN;
else                                         % ONE OR MORE KEYS WERE PRESSED
    keyCodes = find(firstPress > 0);         % all keypresses
    choiceTime = min(firstPress(keyCodes));  % ts of first keypress
    choice = find(firstPress == choiceTime); % first keypress
    if length(choice) > 1
        % handle simultaneous keypresses
        choice = -999;
    end
    rt = choiceTime - targetOnset;           % reaction time
end

end

My questions

I am not sure whether I am calling KbQueueXXX functions correctly and whether they are in the expected position.

  1. Shall I keep KbQueueCreate()/KbQueueStart() and KbQueueStop()/KbQueueRelease() respectively before and after the trials’ loop?
  2. Shall I rather just KbQueueStart(), KbQueueCheck(), and KbQueueStop() at each trial iteratively?
  3. Is it OK to KbQueueFlush() at the beginning of each trial, before the presentation of a new stimulus?
  4. Is my custom function collectResponse() fit for the purpose I described at the top of this post?

Thank you very much for your time, I look forward to knowing your thoughts.
Kind regards,
Valerio


OS: Windows 10
MATLAB: 9.10.0.1851785 (R2021a) Update 6
PTB: 3.0.18 - Flavor: beta - Corresponds to SVN Revision 13009