psychopy.org | Reference | Downloads | Github

Keyboard polling

Hi community,

I have just collected data from a flanker task. Responses were given on the keyboard. Below is the critical part of my code (stimulus display and RT recording):

> timer_RT =core.Clock()
> Routine = True
> event.clearEvents(eventType='keyboard')
> win.flip() # display stimulus
> timer_RT.reset()#reset clock
> while Routine:
>     key_press = event.getKeys(keyList=["f", "j"])
>     if len(key_press) > 0:
>         if (key_press[0]=="f") or (key_press[0]=="j"):
>             RT = timer_RT.getTime()
>             Routine = False
>             win.flip()#response given, remove stimulus

Note that I am continuously polling the keyboard to increase RT precision, similar to what the event.waitKeys() function does. Some time ago, Michael advised me to incorporate a time.sleep (0.001) to let CPU breath, but our OS is windows 10 , and the minimum possible time.sleep is ~13ms (and this latency is not constant, see manual of the time library). So I removed it, check the CPU workload, which was only 57%.
My data look clean, but RTs appear a little slow. The keyboard is already a polling device, and I am wondering if my code is really correct. This stuff is driving me crazy. Could you (i) shed light on this issue and (ii) indicate the amount of distortion (if any) in my data?

Many thanks!

The polling happens after each win.flip() so there will be between 0 and 16.67 ms delay (on a 60 Hz monitor) on the recorded keyboard responses compared to when the pressed key actually made contact with the electronics beneath it. This is caused by the code “waiting” at win.flip() until the next frame before the loop returns to event.getKeys() and timer_RT.getTime() which are executed almost immediately after each other (probably a few microseconds apart).

For future reference, you could use iohub if you want to check for keyboard responses while win.flip() or other presentation processes are running.

Hi @jonas, in this case, the polling is continuous: the win.flip() occurs only after a keypress has been detected (presumably there should be some other code there to exit the loop as well).

Agree that ioHub may be the best way to go, for asynchronous time-stamped keypress detection.

But if the loop only ever runs for a few hundred milliseconds at a time while waiting for a response, perhaps the lack of sleep periods isn’t so much of a problem? I don’t know, but it would be a hope-and-pray situation.