Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Supported by

Dual Task / BCE simultaneous keyboard response collection

Beautiful, helpful people!

I am working on a dual task backward crosstalk effect (BCE) experiment. The basic setup is simple, and I think this works well enough via the block loop table.

I present a fixation dot, to the left of the fixation dot appears a number, and after a given SOA (one of three possible SOAs), a second number appears to the left of the fixation dot.

The participant's task is to decide for both numbers whether they're odd or even.

They react to the first number with their left hand: press the y key for even numbers, and the x key for odd numbers (German keyboard layout).

They then react to the second number with their right hand: press the n key for even, the m key for odd numbers.

So far, so simple. Troublesome is the response collection. The response collection for Task 1 (the left number) has to start as soon as the first number is presented, and has to go on when the second numer (Task 2) is added. I have to be able to collect two responses to two tasks at the same time and I have no idea where to start with this. The only idea I have so far is that it could have something to do with coroutines, but otherwise, I'm at a blank.

I have Task 1 on a sketchpad, for the duration of [soa], then paint a second sketchpad with Task 1 and Task 2 on it. But when I put the keyboard_response between the two sketchpads, Task 2 won't appear until the keyboard response time window is over, which is much too late.

Plus, it has to be ensured that subjects respond to Task 1 first. If they press a key with their right hand first, and then with their left hand, the trial has to be marked as incorrect.

Any input is greatly appreciated. Thank you so much for your time.

Love, Vincent


  • edited April 2019

    I started toying with the (extremely handy, thank you for implementing!) coroutine tool, and this is what I've come up with so far, which doesn't look too shabby, I think.

    However, I have more questions :)

    • how do I make it so, that the coutine is ended after BOTH responses are given? If participants answer to T2 first, it'll be ended right now (which in theory is fine, as it's gonna be a wrong trial anyway, but it can be irritating if you're trying to answer both tasks and get cut off)
    • I need a number of different feedback screens, how do I implement that they are called according to their proper preconditions?
    • 1) correct: shown if both responses T1 and T2 were correct AND in the correct order
    • 2) wrong order: shown if T2 was answered before T1
    • 3) incorrect: shown if either T1 or T2 or both were answered wrong
    • 4) too slow: shown if after 2500 ms after showing T1 either T1 or T2 or both weren't answered

    And how do I make it so that in the logfile only trials are marked correct where both T1 and T2 were answered correctly and in the right order?

  • Ever so slowly, I'm getting somewhere. At least it starts now, and I can get a "correct" feedback. All other feedbacks are "wrong" though, plus the thing crashes after the first trial with this:

    Unexpected error
    item-stack: experiment[run].practice_loop[run].block_sequence[run].block_loop[run].trial_sequence[run]
    exception type: TypeError
    exception message: unsupported operand type(s) for +: 'int' and 'str'

    My trial_sequence looks like this by now, with my dilettante attempt at implementing the four feedbacks.

    If anyone fancies having a look at the thing, I would be a) forever grateful and b) I have attached it.

    Big love and good night



  • I'm just keeping this thread updated, for two reasons. A) when someone looks into this, I want them to know where I stand so they don't comment on stuff I already figured out, and B) I thought it might be educational for people struggling with the same stuff.

    Please let me know if this is unwelcome spamming :)

    I found some of the errors in my trial_sequence feedback run if statements, it now looks like this:

    Naturally, I ran into new problems. In wrong order trials, I now get both feedbacks "Wrong" and "Wrong order", and I never get a "too slow" message, even when I don't answer at all, I get both "Wrong" and "Wrong order" feedback, one after the other.

    I also figured out I had an error in my loop table with the correct answers which I fixed, but what's really weirding me out is that I now never get the correct screen anymore.

    Here's an updated version of the experiment.

  • Hi Vincent,

    Sorry for not getting back to you earlier. How is it going? Could you solve your issue(s)?


  • Hey Eduard,

    sorry for my now very belated response, I opted to receive an e-mail when someone answered, but that got lost, thanks for getting back to me.

    There wasn't much progress since my last post, I'm starting to look into it again right now. I fiddled around with the run_if conditions some more, and some things are working better, others are worse.

    I'm pretty sure that can't be right and I'm making it way too complicated. Any input is still appreciated :)

  • edited May 2019

    My latest idea (which isn't working as of now, but in case someone wants to gon in that direction) is to have a set of inline scripts setting variables to 1 which then call the feedback appropriate for the current trial.

    My trial sequence now looks like this

    I initalize variables in the beginning of the trial as follows (the initialize_variables inline_script):

    var.T1_button_pressed = 0
    var.T2_button_pressed = 0
    var.T1_correct = 0
    var.T2_correct = 0
    var.RT_T2_plus_SOA = 0
    var.feedback_wrong_order = 0
    var.feedback_wrong = 0
    var.feedback_too_slow = 0
    var.feedback_correct = 0

    And then I try to use the check_responses_and_set_feedback inline to determine which feedback is appropriate

    #set all variables needed for feedback check to their appropriate values
    if var.response_response_T1 != "None":
    	var.T1_button_pressed = 1
    if var.response_response_T1 == var.cor_resp_T1:
    	var.T1_correct = 1
    if var.response_response_T2 != "None":
    	var.T2_button_pressed = 1
    if var.response_response_T2 == var.cor_resp_T2:
    	var.T2_correct = 1
    var.RT_T2_plus_SOA = var.response_time_response_T2 + var.soa
    #prepare feedback variables used in trial sequence to check which feedback to run
    if var.T1_button_pressed == 0 or var.T2_button_pressed == 0:
    	var.feedback_too_slow = 1
    elif var.RT_T2_plus_SOA < var.response_time_response_T1:
    	var.feedback_wrong_order = 1
    elif var.T1_correct == 0 or var.T2_correct == 0:
    	var.feedback_wrong = 1
    elif var.T1_correct == 1 and var.T2_correct == 1:
    	var.feedback_correct = 1

    My idea is, that i then only have to put in the variables like feedback_too_slow in the trial sequence and the correct feedback is selected. I felt kinda smart when I came up with this... sadly, it isn't working at all 😅

    I also attached the latest version. It's running, the feedback I'm getting is only all kinds of messed up.

  • Alright. Phew. My problem is a completely different one than I thought. The response items are not logging anything, which is why they're always set to "None", which is why I only get the "too slow" feedback. Argh. I've been asking the wrong questions for days, it appears :(

  • Hey Vincent,

    In this case, the easiest to find the problem is printing out the response variables that change on every trial, ie. var.response, var.correct, var.response_time. If they are not defined, that try to find out whether the response variables have a different name.

    (and yet again sorry, for the delay...)

  • Hey Eduard,

    thanks for the input, I think I identified one troublemaker: the "flush pending key presses" box in the response loggers, as they are to run simultaneously. The whole feedback situation still doesn't look too promising, though, and I don't know why, but sometimes it registers both key presses, and sometimes only one :(

    Will look into it further tomorrow.

  • This thing is now half working, but it's completely unsystematic, when it feedbacks that an error was made (and which). Seems that the responses are logged only half the time, and I can't find the reasoning behind it. Could someone please, please look into this? Getting desperate...

  • edited June 2019

    It looks like the keypresses only register sometimes, sometimes it just throws "None", even though keys were pressed. Or rather, it takes some time after stimulus presentation, until the response item registers keypresses (if I press a response key multiple times before the timeout, it gets registered eventually).

  • Hi VIncent,

    I have never spend enough time to really get coroutines. I hope you don't mind if I rewrite your code without them?

    It is now all within an inline_script. The logic that is applied is similar to a co-routine, just not using generator functions, but quickly iterating while loops.

    Hope this is useful to you!


  • Wow. I'll look right into it. That sounds amazing, thank you 😘

  • edited July 2019

    Alright, I tweaked a bit here and there, and now it's running beautifully, with all the different feedback options working. @eduard , thank you so, so much for your time.

    As a little curtesy, I wanna give back to the community two working experiments. One is the basic Backwards Crosstalk Effect dual task paradigm described above (with a brief delay, two numbers are presented, and subjects have to make a parity judgment for each). I added a lot of comments, so I hope the code is very accessible now.

    I also modified it with an alerting signal. In the second version, in half the trials a tone appears either on the left or the right speaker / headphone, 100 ms before the task 1 stimulus. In the other half, no tone is presented.

    Maybe someone can make use of these tasks. I would like to edit my original post saying something along the lines of "working experiments" or at least "solved", but it appears that I can't edit it (maybe because it's too old?).

Sign In or Register to comment.