I'm running a script (taking time-lapse photos) that I would like to execute every minute. I'm using the Raspberry Pi camera board and thus using the raspistill function, but am not using the in-built time-lapse feature in raspistill because I want to upload each image I take every time after I take it. As a result, I'm using the sleep function to ensure that there is a delay of 60 seconds between each pair of photos. (the script never takes anywhere as long as 60 seconds to execute).

Over the course of 20 minutes (i.e. 20 executions of the script) I have noticed a drift in the capture times. Rather than a photo being captured on the minute every minute, the 20th photo is captured ten seconds after the minute. Is there any reason why this might be so, and is there a better approach for me to get the images taken accurately?

In summary,

I'm taking photos using raspistill at constant intervals for a time-lapse but would like to upload the photos once they are captured. What is the best way to do this?

My code is as follows:



while [ $x -le 100 ]; do

starttime=$(date +"%s%N") # current epoch time in ns

# rest of my code goes here.

x=$(( $x + 1 ))

# this is convoluted because $(()) apparently doesn't like converting from a
# string to a floating-point, so $starttime must be an integer
sleep $(( $TIME_INTERVAL + ($starttime - $(date +"%s%N") ) / 1000000000))

  • 5
    A cronjob may be better for this job en.wikipedia.org/wiki/Cron
    – foibs
    Dec 12, 2013 at 22:05
  • thanks! I've tried that and it is definitely far more accurate. Dec 12, 2013 at 22:08
  • Should @foibs post that as an answer so that you can accept it, or is it not accurate enough?
    – syb0rg
    Dec 12, 2013 at 22:09
  • 1
    FYI, raspistill supports a timelapse option -tl <x> to take a picture every "<x>" milliseconds Dec 12, 2013 at 22:09
  • @syb0rg he should, I was about to suggest it but I think it might be under the minimum character limit. Dec 12, 2013 at 22:29

1 Answer 1


A cronjob will be more accurate for this sort of work. You can just remove all the time calculations and the loop.

Then run crontab -e to edit the crontab file and add this line to the bottom.

*/1 *  *   *   *     /path/to/you/script

This will run your executable script once per minute.

  • 2
    another benefit for the purpose is that it runs on the minute every minutes - this means that I don't need to worry about running the script again when moving the raspberry pi from point to point. thanks, @foibs! Dec 12, 2013 at 22:56
  • 2
    @VincentTjeng Thanks for accepting. To answer the other part of your question, the reason that sleep is not accurate enough is the rounding. If your code takes 0.4 seconds to execute, in the end of the loop the script will still sleep for 60 seconds. Sleep is not designed for high precision timing. It's just there to give a pause. There are high precision sleep utilities if you search, but they're not required in most cases
    – foibs
    Dec 12, 2013 at 23:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.