Hey there, I’ve been having trouble reading responses from a Cedrus Lumina LSC-400B. I’ve managed to successfully read the correct responses using the standard Pyxid code, but the readings happen inconsistently.
My experiment consists in presenting Yes/No questions to the user, and proceeding to the next question once the user answers it. Sometimes I can read the button press correctly, but sometimes it takes up to 20 seconds of random pressings in order to identify a response, and other times it just gets stuck on the loop. I’m aware of an old issue where Cedrus crashes due to button smashing, so we’re trying to avoid that.
I’m using the following code to read responses (only managed to get it to work with that else loop):
# Read response from cedrus_box
if dev.is_response_device():
paradigm.clock.reset()
dev.reset_rt_timer()
dev.clear_response_queue()
while True:
dev.poll_for_response()
if dev.response_queue_size() > 0:
response = dev.get_next_response()
if response['pressed']:
if response['key'] != 4:
resp_time = paradigm.clock.getTime()
print('Block %d - Sentence %d | Response: %d - Answer Time: %.3f'%(file_index,each,response['key'],resp_time))
break
else:
core.wait(0.01)
continue
I included if response['key'] != 4: because the MRI is constantly spamming a trigger (which I’m told is normal behaviour). I’m thinking maybe this spam is filling the queue and thus it just returns the button responses on lucky strikes, but I couldn’t find mentions on this being an issue.
I’m using Psychopy 1.90.2 with Pyxid 1.0, on Windows 7.
Many MRIs will send a trigger at the start of each volume. So if your TR is 3.0 s, say, this shouldn’t be causing too many issues for you in terms of the rate they are sent, but I suspect at the moment, the code won’t deal properly with even a single extra value in the response queue.
I’m not familiar with the pyxid API, but I guess the issue here is with your looping structure. At the moment, you end with a continue statement: this will take you back to the start of the next iteration of your while loop. As mentioned, I don’t know the API, but I’m guessing that when dev.poll_for_response() is called again, the queue size will be reset to zero, even if you hadn’t completed cycling through the queue before. So I would guess that you need two loops, something like this:
while True:
dev.poll_for_response()
# work through however many values are in the queue:
while dev.response_queue_size() > 0:
response = dev.get_next_response()
if response['pressed']:
if response['key'] != 4:
resp_time = paradigm.clock.getTime()
print('Block %d - Sentence %d | Response: %d - Answer Time: %.3f'%(file_index,each,response['key'],resp_time))
break # otherwise a second response would overwrite the RT
core.wait(0.01) # needed to give breathing space to other processes
I can’t test this here, but it would be useful if you can post your actual solution here: I see our example, which presumably comes from the pyxid documentation, seems to have the same structure as your code above, and might need amendment.
I was wondering if you managed to resolve this issue as I’m having exactly the same problem at the moment! Our scanner also constantly spams a ‘response’, which sometimes overrides the real participant response, and I’m trying to figure out how to get around this. If you could maybe share what you did to fix it, that would be greatly appreciated!
We did manage to solve it, but it required a switch from Windows to Ubuntu. As stated somewhere in the documentation, the above script has been tested only on Linux. The same script worked perfectly on Ubuntu, the only issue being installing the Cedrus driver on it, and in my case altering some Pyxid source script for reading the correct com port. It seems Pyxid was updated on github a few months back, so you might not need to do that.
Anyway, if you need further details, I’ll be glad to help.