# how to register a single key press

**URL:** <https://psychtoolbox.discourse.group/t/how-to-register-a-single-key-press/855>\
**Category:** Uncategorized\
**Created:** [June 8, 2005, 2:49pm UTC](https://psychtoolbox.discourse.group/t/how-to-register-a-single-key-press/855 "2005-06-08T14:49:31Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Allen\_Ingling](https://avatars.discourse-cdn.com/v4/letter/a/a183cd/32.png) [@Allen\_Ingling](https://psychtoolbox.discourse.group/u/Allen_Ingling)\
**Post date:** [June 8, 2005, 2:49pm UTC](https://psychtoolbox.discourse.group/t/how-to-register-a-single-key-press/855/1 "2005-06-08T14:49:31Z")

</div>

I am setting up an experiment where a sequence of stimuli is running  
and the subject presses a keyboard key to respond to events. I would  
like to know which frame of the stimulus sequence is showing when the  
key is pressed. Here is a simple demo, where a press of the right  
arrow key starts a dot travelling from left to right, and the frame  
numbers corresponding to presses of the left arrow key are stored in  
an array (bb). The program works fine except that each key press  
results in a random number of entries (between 4 and 6) in the array  
bb. For example, two presses of the left arrow key in the duration of  
travelling dot may result in:  
bb=[161 162 163 164 165 259 260 261 262 263];   
Each key press results in a series of 5 entries. I can use the first  
entry of each series as the stimulus frame corresponding to a key  
press, but I'd like to have a cleaner result. I do have a   
FlushEvents('keyDown');  
in the loop, but it does not seem to do any thing and the keyDown  
event lingers for 4 or 5 frames.   
  
I am using a 2 GHz PC running Windows 2000, MatLab 6.1 and the lastest  
PsychToolbox.  
  
Thanks!  
  
Lei   
  
% travelling dot  
white=255;  
[w,wRect]=Screen(0,'OpenWindow',white);  
srcRect=[0,0,100,100];  
dstRect=CenterRect(srcRect,wRect);  
dotRect0=CenterRect([0 0 12 12],srcRect);  
[dot offRect]=Screen(w,'OpenOffscreenWindow',white,dstRect);  
Screen(dot,'FillOval',black,dotRect0);  
  
white=255;  
black=0;  
  
d0=OffsetRect(offRect,0,0);  
  
rightKey = KbName('right');   
leftKey = KbName('left');   
escapeKey = KbName('esc');   
bb=[];  
while 1  
 [a,b,keyCode] = KbCheck;  
 if keyCode(rightKey)   
 for i=1:300  
 dotRect=OffsetRect(d0,i,0);  
 Screen(w,'WaitBlanking')  
 Screen('CopyWindow',dot,w,offRect,dotRect);  
 [a,b,keyCode] = KbCheck;  
 if keyCode(leftKey)  
 bb=[bb i];  
 end  
 FlushEvents('keyDown');  
 end  
 end  
 if keyCode(escapeKey)  
 break;  
 end  
end  
  
FlushEvents('keyDown');   
Screen('CloseAll');

---

<div class="post-metadata">

**Author:** ![daniel0906](https://avatars.discourse-cdn.com/v4/letter/d/e47774/32.png) [@daniel0906](https://psychtoolbox.discourse.group/u/daniel0906)\
**Post date:** [June 8, 2005, 11:25pm UTC](https://psychtoolbox.discourse.group/t/how-to-register-a-single-key-press/855/2 "2005-06-08T23:25:05Z")

</div>

Nice sample code. Made the issue very clear and easy to suggest help.  
 (The line "black = 0;" needed to be put before the first  
Screen('FillOval') command, but that was no big deal.)  
  
My solution for this type of issue is typically the use of state flags  
(i.e., logical variables that flip between 0 and 1 when the state of  
something changes) which get incorporated in more detailed  
if-statements and while-statements.  
  
In your case, I added the flag "leftKeyDown" which is 0 when the left  
key is not being pressed and 1 when it is being pressed. And you will  
see that I enhanced your if-statement and added an elseif-statement to  
reset the flag when the left key is no longer being pressed. Seems to  
work for me, single frame values recorded in bb for each press. Threw  
in some comments too where I made changes. I am pasting it with the  
tabs collapsed for transmission.  
  
Daniel Shima  
Vanderbilt Vision Research Center  
  
  
% travelling dot  
clear all;  
white=255;  
black = 0;  
[w,wRect]=Screen(0,'OpenWindow',white);  
srcRect=[0,0,100,100];  
dstRect=CenterRect(srcRect,wRect);  
dotRect0=CenterRect([0 0 12 12],srcRect);  
[dot offRect]=Screen(w,'OpenOffscreenWindow',white,dstRect);  
Screen(dot,'FillOval',black,dotRect0);  
  
white=255;  
black=0;  
  
d0=OffsetRect(offRect,0,0);  
  
rightKey = KbName('right');  
leftKey = KbName('left');  
escapeKey = KbName('esc');  
bb=[];  
while 1  
[a,b,keyCode] = KbCheck;  
if keyCode(rightKey)  
leftKeyDown = 0; % flag indicating state of left key.  
for i=1:300  
dotRect=OffsetRect(d0,i,0);  
Screen(w,'WaitBlanking')  
Screen('CopyWindow',dot,w,offRect,dotRect);  
[a,b,keyCode] = KbCheck;  
% Only add to bb if left key not already down.  
if (keyCode(leftKey) & leftKeyDown == 0)  
leftKeyDown = 1; % Change left key flag when down.  
bb=[bb i];  
elseif (~keyCode(leftKey) & leftKeyDown == 1)  
% Else if left key is not down but flag says it is down,  
% change flag to indicate left key not down.  
leftKeyDown = 0;  
end  
FlushEvents('keyDown');  
end  
end  
if keyCode(escapeKey)  
break;  
end  
end  
  
FlushEvents('keyDown');  
Screen('CloseAll');  
  
  

> On 6/8/05, liul15110 \<[lliu@...](mailto:lliu@...)\> wrote:  
> \> I am setting up an experiment where a sequence of stimuli is running  
> \> and the subject presses a keyboard key to respond to events. I would  
> \> like to know which frame of the stimulus sequence is showing when the  
> \> key is pressed. Here is a simple demo, where a press of the right  
> \> arrow key starts a dot travelling from left to right, and the frame  
> \> numbers corresponding to presses of the left arrow key are stored in  
> \> an array (bb). The program works fine except that each key press  
> \> results in a random number of entries (between 4 and 6) in the array  
> \> bb. For example, two presses of the left arrow key in the duration of  
> \> travelling dot may result in:  
> \> bb=[161 162 163 164 165 259 260 261 262 263];  
> \> Each key press results in a series of 5 entries. I can use the first  
> \> entry of each series as the stimulus frame corresponding to a key  
> \> press, but I'd like to have a cleaner result. I do have a  
> \> FlushEvents('keyDown');  
> \> in the loop, but it does not seem to do any thing and the keyDown  
> \> event lingers for 4 or 5 frames.  
> \>   
> \> I am using a 2 GHz PC running Windows 2000, MatLab 6.1 and the lastest  
> \> PsychToolbox.  
> \>   
> \> Thanks!  
> \>   
> \> Lei  
> \>   
> \> % travelling dot  
> \> white=255;  
> \> [w,wRect]=Screen(0,'OpenWindow',white);  
> \> srcRect=[0,0,100,100];  
> \> dstRect=CenterRect(srcRect,wRect);  
> \> dotRect0=CenterRect([0 0 12 12],srcRect);  
> \> [dot offRect]=Screen(w,'OpenOffscreenWindow',white,dstRect);  
> \> Screen(dot,'FillOval',black,dotRect0);  
> \>   
> \> white=255;  
> \> black=0;  
> \>   
> \> d0=OffsetRect(offRect,0,0);  
> \>   
> \> rightKey = KbName('right');  
> \> leftKey = KbName('left');  
> \> escapeKey = KbName('esc');  
> \> bb=[];  
> \> while 1  
> \> [a,b,keyCode] = KbCheck;  
> \> if keyCode(rightKey)  
> \> for i=1:300  
> \> dotRect=OffsetRect(d0,i,0);  
> \> Screen(w,'WaitBlanking')  
> \> Screen('CopyWindow',dot,w,offRect,dotRect);  
> \> [a,b,keyCode] = KbCheck;  
> \> if keyCode(leftKey)  
> \> bb=[bb i];  
> \> end  
> \> FlushEvents('keyDown');  
> \> end  
> \> end  
> \> if keyCode(escapeKey)  
> \> break;  
> \> end  
> \> end  
> \>   
> \> FlushEvents('keyDown');  
> \> Screen('CloseAll');
