Displaying timer

1,992 views
Skip to first unread message

Camino227

unread,
Sep 12, 2013, 10:29:17 PM9/12/13
to psychop...@googlegroups.com
Hello,

I am working in builder mode and have no programming experience. I was wondering; is there a simple way to display a countdown timer on the screen in psychopy? For the experiment I am working on I am having participants write timed recall tests and I would like to display a countdown timer on the screen while they are doing these tests.

Any suggestions are much appreciated.

Thanks,

Sarah

Michael MacAskill

unread,
Sep 12, 2013, 11:53:38 PM9/12/13
to psychop...@googlegroups.com
Dear Sarah,

In the text field of a text component, put something like this:

$str(round(routineTimer.getTime(),1))

and select "set every frame" rather than the default of constant.

routineTimer is a clock that is automatically created for you at the beginning of each routine. It counts down from the time it expects the trial to last (which is the sum of the durations of the various components in the routine).

round(,1) rounds the clock value to one decimal place, and str() converts that number into a string of text.

Regards,

Michael

Camino227

unread,
Sep 13, 2013, 10:39:49 AM9/13/13
to psychop...@googlegroups.com
Thank you Michael, that worked perfectly.

Sarah

Sol Simpson

unread,
Sep 13, 2013, 5:16:08 PM9/13/13
to psychop...@googlegroups.com
Note that updating a text component may result in 'dropped frames' due to the time taken to draw() the text component the first time following a text change. The likelihood of this depends on the length of the string being displayed and how powerful your graphics card and cpu are. If using the code suggested by Michael, and showing time in seconds, then the string length will only be 3 - 5 characters I guess, which should be able to be redrawn within a frame after a text change. Definately keep any text you are changing frequently as short as possible right now/

This may not matter based on your experiment and when in it your are showing the time, but it is good to keep in mind, especially if changing the text every frame.

I have written a text area stim that draws the stim much faster than the current Text Component whenever the text changes, as it was written to support full page text draws (about 80x30 characters) within one 75 Hz frame.  However I need to turn it into much more of a standard PsychoPy Stim Component before I submit it for review and hopefully addition to PsychoPy.
 
Thanks,

Sol

Barb Lahey

unread,
Apr 9, 2015, 8:30:25 PM4/9/15
to psychop...@googlegroups.com
Dear Michael,

I believe I am trying to do something similar to what Sarah was working on here. However, I just can't seem to adjust it just so to my needs.

I have been working in builder mode and have no previous programming experience. I am attempting to display a countdown timer with minutes and seconds, presented at the same time as additional stimuli. I copied the code you have here into a text component of my routine. However, I cannot adjust it to my desired start time of 5 minutes. Would you mind explaining how I should go about this?

Also, I do not know if it is worth noting, that while I am trying to code this into a routine, I would like it to stay present for the duration of the Loop, and as the 5 minutes ends, the Loop should end.

Any help or advice would be greatly appreciated.

Regards,
Barb

Michael MacAskill

unread,
Apr 9, 2015, 9:28:18 PM4/9/15
to psychop...@googlegroups.com

> On 10/04/2015, at 11:49, Barb Lahey <barbla...@gmail.com> wrote:
>
> Also, I do not know if it is worth noting, that while I am trying to code this into a routine, I would like it to stay present for the duration of the Loop, and as the 5 minutes ends, the Loop should end.

If I have this right, you want a loop that will last for exactly 5 minutes, which encompasses multiple repetitions of a routine, each relatively brief, but regardless of which trial you are on, there is a timer which seamlessly and continuously counts down from 5 minutes?

If so (this is all untested, so expect errors):

Insert a Code component in the trial routine. In its "Begin Experiment" tab, put:

countdownStarted = False


In its "Begin Routine" tab, put:

if not countdownStarted:
countdownClock = core.CountdownTimer(300) # 300 s = 5 minutes
countdownStarted = True


In its "Each frame" tab, put:

timeRemaining = countdownClock.getTime()
if timeRemaining <= 0.0:
continueRoutine = False # end this trial immediately
nameOfYourLoop.finished = True # and terminate the loop (use its actual name)
countdownStarted = False # only necessary if you'll be using the countdown again elsewhere
else:
minutes = int(timeRemaining/60.0) # the integer number of minutes
seconds = int(timeRemaining - (minutes * 60.0))
timeText = str(minutes) + ':' + str(seconds) # create a string of characters representing the time


Then in your text component, simply put this in the text field:

$timeText

Ensure that the code component is above the text component in the Builder GUI. That way, the text component will receive the current value of timeText on each screen refresh.

Hope that helps,

Michael



Barb Lahey

unread,
Apr 10, 2015, 12:46:35 PM4/10/15
to psychop...@googlegroups.com
Dear Michael,

That was exactly what I was trying to do. I tested this out and it worked seamlessly! Very impressive.
I truly appreciate your help, especially considering what you were able to do in a day I was not able to do over a week.

Thank you so much for your time and help!

Regards,
Barb

Colby Tibbets

unread,
Jun 9, 2015, 12:05:58 PM6/9/15
to psychop...@googlegroups.com
How would I specify drawing $timeText in the coder, I can't seem to figure out how to draw the clock in my window. 
-Colby

Michael MacAskill

unread,
Jun 9, 2015, 5:57:48 PM6/9/15
to psychop...@googlegroups.com

> On 10/06/2015, at 04:05, Colby Tibbets <colby....@gmail.com> wrote:
>
> How would I specify drawing $timeText in the coder, I can't seem to figure out how to draw the clock in my window.

Before the experiment starts, you create a text stimulus along with your other stimuli. Then on every screen refresh, you just update it's text value:

yourTextStimulus.text = timeText
yourTextStimulus.draw() # if autodraw not being used.
someOtherStimulus.draw()
win.flip() # actually show the window's updated contents

Regards,

Michael


Colby Tibbets

unread,
Jun 10, 2015, 9:25:45 AM6/10/15
to psychop...@googlegroups.com
Cool, I can draw a clock, but I am having trouble with flipping the window. Do I need to have the code in a loop to view the countdown?

#5 minute rest

        if itrial== 1:
            win.flip(clearBuffer=True) #clear the screen
            #create a countdown
            countdownClock = core.CountdownTimer(300) # 300 s = 5 minutes 
            countdownStarted = True 
            timeRemaining = countdownClock.getTime() 
            if timeRemaining <= 0.0: 
                continue 
            else: 
                minutes = int(timeRemaining/60.0) # the integer number of minutes 
                seconds = int(timeRemaining - (minutes * 60.0)) 
                timeText = str(minutes) + ':' + str(seconds) # create a string of characters representing the time
            countdown.text=timeText
            countdown.draw() 
            intermezzo.draw() 
            win.flip()
            event.waitKeys(['space'])

Michael MacAskill

unread,
Jun 10, 2015, 6:12:19 PM6/10/15
to psychop...@googlegroups.com

> On 11/06/2015, at 01:25, Colby Tibbets <colby....@gmail.com> wrote:
>
> Cool, I can draw a clock, but I am having trouble with flipping the window. Do I need to have the code in a loop to view the countdown?
Yes. The screen only updates with new content when you tell it to, via win.flip()

Read through a few of the coder examples under the "Demos" menu to get a feel for how the drawing loop cycle works.

If you are updating the screen continuously, you can't use the waitKeys() function, as that waits indefinitely for a keypress, and during the pause, you can't do anything else. So instead, within your loop, use the getKeys() function on each screen redraw cycle within your loop. That just checks for any key that is pressed at that moment. i.e. it allows you to keep checking the keyboard while also updating the screen.

Regards,

Michael



>
> #5 minute rest
>
> if itrial== 1:
> win.flip(clearBuffer=True) #clear the screen
> #create a countdown
> countdownClock = core.CountdownTimer(300) # 300 s = 5 minutes
> countdownStarted = True
> timeRemaining = countdownClock.getTime()
> if timeRemaining <= 0.0:
> continue
> else:
> minutes = int(timeRemaining/60.0) # the integer number of minutes
> seconds = int(timeRemaining - (minutes * 60.0))
> timeText = str(minutes) + ':' + str(seconds) # create a string of characters representing the time
> countdown.text=timeText
> countdown.draw()
> intermezzo.draw()
> win.flip()
> event.waitKeys(['space'])

--
Michael R. MacAskill, PhD 66 Stewart St
Research Director, Christchurch 8011
New Zealand Brain Research Institute NEW ZEALAND

Senior Research Fellow, michael....@nzbri.org
Te Whare Wānanga o Otāgo, Otautahi Ph: +64 3 3786 072
University of Otago, Christchurch http://www.nzbri.org/macaskill



Reply all
Reply to author
Forward
0 new messages