psychopy.org | Reference | Downloads | Github

Touchscreen loop runs without presenting stimuli

Hi all

I’m presenting my task on a SurfacePro tablet, participants have to select one of two images. As others have reported, I had problems with the touchscreen needing to swipe rather than tap, and so have used if stimulus.contains

for stimulus in [R, L]:
    if stimulus.contains(TrialResp):
        if stimulus.image == CorrectAnswer:
             thisExp.addData('correct', 1)
             continueRoutine = False
        else:
             thisExp.addData('correct', 0)
             continueRoutine = False

to solve that problem. However that meant my stimuli were running through too fast to be presented with the same image always being selected, so I inserted a mouse reset

TrialResp.setPos(newPos=(0, 0))

routine within the loop. It now runs for a random number of trials allowing the user to click responses, before it reverts to just scrolling through at high speed and then moving onto the next part of the experiment. It’s still data logging all 11 trials so it is running them, just not showing them. I’m unclear why it works for some trials, reseting the mouse to a neutral position before each trial, and then randomly stops the mouse reset! Sometimes it does manage all 11, but there’s difference in what I did when running it.

Many thanks in advance

I’m not really sure, but (as you know) touches and mice can’t really be treated the same way. If we reset the mouse position, then the user actually has to move the mouse physically to get the pointer back to where it just was. i.e. the absolute position of the mouse on a desk is not really important, as it can be dissociated from the position of the pointer on the screen. But with touches, the finger is still physically in the same place on the screen, so I suspect that the reset in practice will almost immediately get ignored when the next touch detection cycle occurs (but I could be completely wrong about how this works in practice).

My recommendation would be that you alter the code above to not immediately end the routine on detecting a response. Instead, set a flag that touch has been detected. The test for ending the routine should then be that a touch has been detected but that currently, no touch is detected. i.e. end the routine once the finger has been lifted off the screen, rather than when it is initially detected. This will enforce a separation of events across trials.

e.g. in the “begin routine” tab:

touch_previously_detected = False

“Every frame”, something like:

touch_currently_detected = False # reset on each frame

for stimulus in [R, L]:
    if stimulus.contains(TrialResp):
        touch_currently_detected = True

        if not touch_previously_detected: # only do this once:
            touch_previously_detected = True
            if stimulus.image == CorrectAnswer:
                thisExp.addData('correct', 1)
            else:
               thisExp.addData('correct', 0)

# end the trial only if there has been a touch that has now ended 
# (i.e. the finger has been lifted from the screen):
:
if touch_previously_detected and not touch_currently_detected:
    continueRoutine = False

I haven’t worked with a touch screen, so must admit I have no idea if this will actually work. Let us know how you get on. Good luck.

Thanks for your reply! No luck with that unfortunately, it won’t move on from the first trial, something about that last segment is causing issues but I don’t know enough to figure out what.

My current workaround is to insert a filler slide with a random image, which the experimenter then moves on manually with a mouse component, making sure to click away from the 2 stimuli boxes (I only need stimulus.contains on trial slides so the kids can respond). Not ideal aesthetically but experimentally it’s not an issue.

Would be interested if anyone else has a different solution still, but it’s not vital now :slight_smile:

I’d suggest inserting some (temporary) print statements for debugging purposes, to see how the logic above may be failing. e.g. lines like these:

print('Current touch: ', touch_currently_detected)
print('Previous touch: ', touch_previously_detected)

scattered at various places in the code to check what is happening and when.