我有一个实验,收集按键('x'或'n')和响应刺激显示的反应时间。如果参与者每次试用按下任一按钮,则实验运行正常。但是,如果他们反复按键盘或按住键,它会经常崩溃。 (我和孩子一起工作,即使我们不让他们这样做,这通常也会发生)。
崩溃时出现的错误是:
没有为“单元格”输入定义函数。
实验中的错误(第682行)
fprintf(dataFile,formatString,SJNB,Date,Age,block,trial,trialFaceLabel,trialLoadLabel,Target,keyStroke,tStart,keyTime,Correct,RT,FaceGen);
虽然它说'函数没有为'单元'输入'定义(与this帖子有关),但是这个函数似乎在其他所有时候都能正常工作,所以我看不出它没有被正确定义。只有当连续按下太多的按键时(例如,如果按键被按下),才会发生此错误。
即使每次试用有多个按键,我可以做些什么改变来确保实验是健壮的并且不会崩溃?任何帮助,将不胜感激。
我已经包含了以下代码。
这里有一些额外的信息,以防有用:
以下代码全部包含在实验循环中。它正在做的是:1)搜索按键2)根据按键计算响应时间3)如果响应不正确则发出蜂鸣声4)打印到文件(这是在试验结束之前)(这是错误参考)
%searching for keypress
timedout = false;
pressed = 0;
%while pressed < 1;
while ~timedout && ~pressed
[keyIsDown, keyTime, keyCode] = KbCheck;
if keyIsDown && ((keyTime-tStart) < max_stimulus_shown)
keyStroke = KbName(keyCode);
if any(strcmpi(keyStroke,leftKey)) || any(strcmpi(keyStroke,rightKey)) %|| any(strcmpi(keyStroke,exitKey))
pressed = 1;
WaitSecs(remainer-(keyTime-stimulus_shown));
break;
elseif any(strcmpi(keyStroke,exitKey))
disp('*** Experiment terminated ***');
break;
sca;
end
elseif ((keyTime-tStart) > max_stimulus_shown)
keyStroke = 'None';
timedout = true;
RT = 0;
Correct = 0;
pressed = 2; % 2 = not pressed
KbQueueStop();
end
end
%calculate response times
if pressed == 1 && (~timedout)
RT = round((keyTime-tStart)*1000); % RT in ms
if any(strcmpi(keyStroke,leftKey)) % pressed left (X)
if any(strcmpi(Target, 'X')) % target was an X
Correct = 1;
else % target was X, but pressed right (N)
Correct = 0;
end
elseif any(strcmpi(keyStroke,rightKey)) % they pressed right
if any(strcmpi(Target, 'N')) % target was an N
Correct = 1;
else % target was N, but pressed right
Correct = 0;
end
elseif any(strcmpi(keyStroke,exitKey))
disp('ESC');
break;
end
end
Screen('TextSize',Screen_wid, star_size);
DrawFormattedText(Screen_wid, '.', 'center', 'center');
WaitSecs(feedback);
Screen('Flip', Screen_wid);
%say when to beep
if Correct == 0 && ~timedout
PsychPortAudio('Start', pahandle, repetitions, startCue, waitForDeviceStart);
WaitSecs(remainer-beepLengthSecs);
elseif Correct == 0 && timedout
PsychPortAudio('Start', pahandle, repetitions, startCue, waitForDeviceStart);
Screen('TextSize',Screen_wid, text_size);
DrawFormattedText(Screen_wid, 'missed trial', 'center', 'center');
Screen('Flip', Screen_wid);
WaitSecs(beepLengthSecs+feedback);
elseif Correct == 1
WaitSecs(remainer+beepLengthSecs);
end
%WaitSecs(stimulus_shown); %stimulus shown for 0.2 seconds
Screen('Flip', Screen_wid);
dataFile = fopen(dataFileName, 'a');
fprintf(dataFile, formatString, SJNB, Date, Age, block, trial, trialFaceLabel, trialLoadLabel, Target, keyStroke, tStart, keyTime, Correct, RT, FaceGen);
fclose(dataFile);
函数KbName
通过键代码向量(key_name = KbName([21 22])
)或逻辑向量(由KbCheck返回)返回键输入的名称字符串。
如果仅提供密钥/为True,则将其作为字符串返回。但是,如果同时按下多个键,它将作为字符串的单元格数组返回。
例如,查看输出:
% for key name consistency across operating systems
KbName('UnifyKeyNames')
% one key
KbName(21)
ans =
r
% more than one key
KbName([21 22])
ans =
1×2 cell array
'r' 's'
您的问题是,当同时按下多个键时(相对于键检查循环),keyStroke
是一个包含按下的键的单元格数组。您似乎在大多数代码中正确处理单元格数组,但调用fprintf
除外,它需要单个字符串,而不是字符串的单元格数组。
如果要保存所有按键的记录,可以将字符串的单元格数组转换为单个字符串,并在元素之间使用分隔符,例如在调用fprintf
之前添加以下行:
if iscell(keyStroke)
keyStroke = strjoin(keyStroke, '_');
end
但是,请记住,您可能希望更改实验的逻辑以拒绝按下两个键的试验,或者以不同于单个键响应的方式对待它们。您当前使用“左”键优先,换句话说,如果参与者按下了左键并且目标是“X”,即使右键也被按下,试验也会被标记为正确。相反,如果参与者按下了左键并且目标是“N”,则即使也按下了右键,试验也会被标记为不正确。