Here’s a summary of the problem, hope someone can help…
Aim - to use the psychopy provided RatingScale with a Lumina LSC400 button box.
Problem - the rating scale uses keyboard input to move the scale marker up and down, but the Lumina doesn’t provide keyboard output (unlike fORP etc).
It looks like this has come up before, and the chosen solution then was to hack the ratingscale.py code (but exactly how this worked was not detailed) - and I’d rather not, if I can avoid it. So I wrote some code…
The Lumina generates events, which can be retrieved using buttonBox.get_next_response(), this returns a dict with the keywords ‘pressed’ (can be either True or False) and ‘key’ which can be 0,1,2,3,4 depending on the button pressed or if a trigger was received (=4). Each button press generates two events: similar to a button-down, button-up pair. So you can catch a specific key-press by looking for when ‘pressed’ = True and ‘key’ = chosen_key
What I wanted to happen was that when a subject pressed the right button my code would simulate a key-press, in this case the number “2” to move the rating scale to the right. I stumbled on this (http://stackoverflow.com/questions/13564851/generate-keyboard-events), and have copied the necessary into my code (not shown). Here are the relevant(?) sections:
# Initialize components for "myRatingScale"
ratingClock = core.Clock()
myRatingScale = visual.RatingScale(win,
name='rating',
marker='circle',
markerStart = 4,
size=1.0,
pos=[0.0, -0.4],
low=1, high=7,
#maxTime = 8.0,
labels=["'President Trump'", " 'Mother Theresa'"],
leftKeys = '1', rightKeys = '2',
scale='Rate trustworthiness',
singleClick=False,
showAccept=False)
At some point later we show the rating scale and start looking for responses from the Lumina (“buttonBox”).
myRatingScale.reset()
logging.data('Rating scale started')
fmriClock.reset()
myRatingScale.setAutoDraw(True)
# start rating scale, show it for 8 seconds
while fmriClock.getTime() <= 8.0:
buttonBox.poll_for_response()
if buttonBox.response_queue_size() > 0:
resp = buttonBox.get_next_response()
if resp['pressed'] and resp['key'] == 4:
logging.data('Trigger received')
trigCounter += 1
elif resp['pressed'] and resp['key'] == 0:
PressKey(0x31) # this function comes from stackoverflow link
print '%s' %('Left button')
elif resp['pressed'] and resp['key'] == 1:
PressKey(0x32) # this function comes from stackoverflow link
print '%s' %('Right button')
else:
print '%s' %('wrong button or something else')
buttonBox.clear_response_queue() # do we really need this?
if event.getKeys(['escape']):
core.quit()
win.flip()
myRatingScale.setAutoDraw(False)
The problem is that when a Lumina button is pressed, the rating scale moves ONCE in the correct direction, and the message is written to the output console (e.g. Right Button), but if I press it again nothing happens, however I see a message in the console for each and every button press. If I press the opposite direction the rating scale moves in the desired direction once more, but again only ONCE, despite the message appearing correctly.
If I use the keys “1” and “2” the ratingscale behaves exactly as expected.
What am I doing wrong? Also, the “solution” to emulate key presses is not great, as it’s Windows only - and I’d like something portable if at all possible.
Cheers, Jon