Close GUI menu after discrete time period or user keystroke

I'm making an n-back test using MATLAB 7.10.0, and I need to acquire either or both keystrokes 'A' and 'S' from the user within 2.5s. If 2.5s passes without any keystrokes pressed, then the program will set the response to 0.
Simple algorithm: 1) Ask user for data 2) Start timer, t = 0s 3) Acquire keystrokes from the user and store ASCII equivalent as answer. 4) End timer, t = 2.5s 5) If no keystrokes, then answer = 0.
I've looked online and through the Product Documentation, but nothing is coming up -- although I'm sure it's possible.
Thanks in advance.
EDIT: In the same vein, rather than keystrokes as the input, I'd actually like to use the menu function, with three buttons: 'A', 'S', and 'A+S'. But the problem is closing the menu after a discrete time period.
WHAT I REALLY NEED TO KNOW: 1) Time the input period 2) Acquire specific keystroke 3) Close the menu using code -- 'close' fn doesn't work with menu.

Answers (2)

EDITED
% Create timer object that stops after 2.5 seconds
f = 'h = findobj(0,''Name'',''GETKEY''); if h; uiresume(h); end';
t = timer('StartDelay',2.5,'TasksToExecute',1,'TimerFcn',f);
% Accepted keys are 'A'or 'a' for rist position and 'S' or 's' for second position
keys = false(1,2);
vec = {'A' 'S'};
% Start timer
start(t)
% Run till timer executes
while strcmp(get(t,'Running'),'on')
% Acquire keystroke
key = getkey;
% Check if already pressed
keys = keys | strcmpi(key,vec);
% If both pressed before the timer stops exit the loop
if all(keys)
break
end
end
disp(keys)
Link to getkey. You may want to make it invisible.

14 Comments

Thank you for the help. That is very good. Is it possible to close the menu function with code provided that someone hasn't clicked the GUI button?
Actually, could you explain what you're doing here?
keys = keys | ismembc([65 83 97 115], key);
It yields an error message when executed.
Also, getkey prevents the loop from closing until a key is pressed even though the timer has stopped. Any ideas on how to fix this problem?
ismembc() is an internal routine used by ismember(); some people prefer to code ismembc() because it is faster, whereas unless there is strong reason I prefer to code ismember() for clarity.
I think Oleg has miscoded the call: getkey() is going to be a single value, but ismembc() is going to return a logical array as long as its first argument, 4, which is not going to work when or'd (|) against the array false(1,2) used to initialize keys.
Yeah, I just noticed when writing that it could be case insensitive and modified inappropriately. Now it should be fine for the dimension mismatch. Haven't looked yet into getkey issue.
Oleg, did you perhaps want strcmpi(key, {'a', 's'}) instead of 'a' and 'b' ?
@Walter: Thanks, corrected.
@Robert: now my edited script takes care of closing getkey (no modification needed).
Oleg, your updated code is nearly perfect: strcmpi(key,vec) should be strcmpi(char(key),vec). If you make that change, it works like a charm.
When I run the above code in the Command Window it executes perfectly. But when I try executing it from an .m file script, I get the error:
??? Error using ==> subsindex
Function 'subsindex' is not defined for values of class
'timer'.
When I try executing it as a function keys = timedKey, I get the error:
??? Error while evaluating TimerFcn for timer 'timer-62'
Undefined function or variable 't'.
??? Error using ==> delete
Invalid handle object.
Error in ==> getkey at 73
delete(fh) ;
Error in ==> timedKeys at 21
key = getkey;
Let me clarify... I'm trying to write this code to a function, which -- in the main script -- will be looped for i = 1:n. But for some reason Matlab doesn't recognize 't' although it is defined. This causes the program to be caught in the loop until a key is pressed. Normally I'd figure it out on my own, but I'm not familiar with the timer function, and what I've tried has been unsuccessful.
I'll try to test it within a function foo and come back to you.
Thank you, friend. That works great!
If yout hink my answer solved your problem please accept it.

Sign in to comment.

I solved the problem by making a function getkey2, which combines Oleg's suggestion, my code, and the getkey function. Here it is if anyone is interested.
function ch = getkey2(m)
if nargin == 1,
if strcmp(lower(m),'non-ascii'),
callstr = ['set(gcbf,''Userdata'',get(gcbf,''Currentkey'')) ; uiresume '] ;
else
error('Argument should be the string ''non-ascii''') ;
end
else
callstr = ['set(gcbf,''Userdata'',double(get(gcbf,''Currentcharacter''))) ; uiresume '] ;
end
% Set up the figure
% May be the position property should be individually tweaked to avoid visibility
fh = figure('keypressfcn',callstr, ...
'windowstyle','modal',...
'position',[0 0 1 1],...
'Name','GETKEY', ...
'userdata','timeout') ;
try
% Create timer object that stops after 2.5 seconds
t = timer('StartDelay',0.5,'TasksToExecute',1,'TimerFcn','stop(t)');
% Accepted keys are 'ASas' ASCII values [65 83 97 115]
keys = zeros(1,2);
% Start timer
start(t)
% Run till timer executes
vec = [65 83];
while strcmp(get(t,'Running'),'on')
ch = get(fh,'Userdata') ;
end
if isempty(ch),
ch = NaN ;
end
catch
% Something went wrong, return and empty matrix.
ch = [] ;
end
delete(fh) ;

6 Comments

Actually this doesn't work yet... Any other ideas?
What do you do with vec() ?
You get values and assign them in to ch, but as long as the timer is running, you risk overwriting ch with the next value read.
Recheck my script, I have modified it to close getkey if nothing happens in x seconds and fixed the other error.
It is case insensitive, wether you press 'A' or 'a'. But you can use strcmp instead of strcmpi to make it case sensitive.
vec() was a lazy residual part of earlier code. At some point, getkey2 worked, but now it's not. I'll look at Oleg's code soon, as I'm sure that's the most concise option.
Fixing one last thing, if you have typed both A and S it exits the loop and when the timer stops later it calls uiresume but at that point no getkey figure exists thus it creates and empty one.
Ok now it should work properly.

Sign in to comment.

Categories

Find more on Loops and Conditional Statements in Help Center and File Exchange

Products

Asked:

on 22 Aug 2011

Community Treasure Hunt

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

Start Hunting!