psychopy.org | Reference | Downloads | Github

How to present a countdown timer with an ongoing task?


#1

Hello,

This is a follow up to my previous posting ( Design with Timer (clock) hidden from view unless called by user ).

The task I’m trying to create involves two components

  1. an ‘on-going’ task (in this case the stroop)
  2. A countdown timer running alongside ongoing task set to a time that is less than the length of the ongoing task.

The idea is that the participants are asked to indicate with a button press when the time has expired. I’m working on adding a polygon that will hide/reveal the timer, but I need to get the more basic aspects of this tasks working first.

Since my last posting (link above), I’ve managed to create an analogue clock face where just the second hand ticks backwards to 0 from a set duration (e.g., 30 seconds). This is located to the right of the on-going stroop stimuli presented at the center of the screen. The problem I’m having is that I can’t seem to get the clock’s timer to actually run while the stroop stimuli is being presented and responded to by the user. This very likely stems from a lack of understanding about how the timers work. I’ve spent a number of hours trying to figure this out independently, but can’t seem to find the answer. If someone could help me out that would be much appreciated.

I’ve posted some code below (tried to make it as pertinent as possible, but, again, I’m not certain where I’m going wrong). In the code below, the stroop task seems to run fine, and the clock is present, but the timer doesn’t work. I’ve played around a bit with the placement of the timer updates in the other modifications of this code and, when the timer does work, the stroop stimuli doesn’t show. I’m guessing I’m just missing something conceptually here.

Thank you all very much for your help and support. I’m looking forward to becoming more fluent in with psychopy.

-Scott

for thisTrial in trials:
    currentLoop = trials
    # abbreviate parameter names if possible (e.g. rgb = thisTrial.rgb)
    if thisTrial != None:
        for paramName in thisTrial.keys():
            exec(paramName + '= thisTrial.' + paramName)
    
    # ------Prepare to start Routine "trial"-------
    t = 0
    trialClock.reset()  # clock
    frameN = -1
    continueRoutine = True
    # update component parameters for each repeat
    target.setColor(color, colorSpace='rgb')
    target.setText(word)
    Response = event.BuilderKeyResponse()
    
    # keep track of which components have finished
    trialComponents = [target, Response]
    for thisComponent in trialComponents:
        if hasattr(thisComponent, 'status'):
            thisComponent.status = NOT_STARTED
    
    # -------Start Routine "trial"-------
    while continueRoutine:
        # get current time
        t = trialClock.getTime()
        frameN = frameN + 1  # number of completed frames (so 0 is the first frame)
        # update/draw components on each frame
        
        # get the PM time
        countDown = core.CountdownTimer()
        countDown.add(3)
        
        circle.draw()
        secPos = countDown.getTime() * 360 / 60  # NB floor will round down
        second.ori = secPos
        second.draw()
        win.flip()
        event.clearEvents('mouse')  # only really needed for pygame windows
        
        # *target* updates
        if t >= 0.5 and target.status == NOT_STARTED:
            # keep track of start time/frame for later
            target.tStart = t
            target.frameNStart = frameN  # exact frame index
            target.setAutoDraw(True)
        frameRemains = 0.5 + 4- win.monitorFramePeriod * 0.75  # most of one frame period left
        if target.status == STARTED and t >= frameRemains:
            target.setAutoDraw(False)
        
        # *Response* updates
        if t >= 0.5 and Response.status == NOT_STARTED:
            # keep track of start time/frame for later
            Response.tStart = t
            Response.frameNStart = frameN  # exact frame index
            Response.status = STARTED
            # keyboard checking is just starting
            win.callOnFlip(Response.clock.reset)  # t=0 on next screen flip
            event.clearEvents(eventType='keyboard')
        if Response.status == STARTED:
            theseKeys = event.getKeys(keyList=['left', 'right', 'down', 'up'])
            
            # check for quit:
            if "escape" in theseKeys:
                endExpNow = True
            if len(theseKeys) > 0:  # at least one key was pressed
                Response.keys.extend(theseKeys)  # storing all keys
                Response.rt.append(Response.clock.getTime())
                # was this 'correct'?
                if (Response.keys == str(corAns)) or (Response.keys == corAns):
                    Response.corr = 1
                else:
                    Response.corr = 0
                # a response ends the routine
                continueRoutine = False

#2

Hi Scott,

I think the issue here is that you have embedded the creation of your countdown timer within your drawing loop. Only create it once.

i.e. It looks like you are recreating it and adding 3 to it on every screen refresh, so it will never really count down.