Pi Camera: Take Timelapse Photos


ANY RAspBERRY pi wiTH A 40-piN GpiO Connector Raspbian Pixel, official Pi camera, 1x push button, 1x breadboard, 1x MCP3008 ADC, 9x male-to-male jumper wires, 8x female-to- male jumper wires, 2x 10k potentiometers

TIME LAPSE PHOTOGRAPHY can create fascinating footage of certain phenomena, such as plants growing and flowering, that you wouldn’t get to see in such detail in everyday life. Using the Raspberry Pi camera for timelapse is a simple project, but ensuring that the subject of your photography is lit correctly can be a little tricky. In this project, we shall create a timelapse controller that has analog controllers for the brightness and contrast of the images to be captured. The files saved will also have a timestamp, to ensure that they’re captured correctly and can be reviewed in chronological order. -LES POUNDER

1 circuit city

To build the circuit for this project, we need to place an MCP3008 analog-to-digital converter onto the breadboard. Pay special attention to a dip in one end of the chip, which identifies the top of the chip. Pin 1, which is the first analog input, is located in the top- left of the chip if we look at the chip with the dip at the top.

>> Connect the MCP3008 to your Raspberry Pi as per the diagram shown below [image A]. The potentiometers are connected to 3V and GND rails, and their output is fed into the first two pins of the MCP3008. Our push button is connected to the GPIO and to the GND rail.

>> Next, insert the official Raspberry Pi camera into the camera port [image B], which is located either between the Ethernet and HDMI port of the model B series, or on the end of the Pi Zero board — note that this requires a special adapter. The ribbon cable should be carefully inserted with the blue tab that’s facing the Ethernet port, and remember to lift the plastic guard on the port before inserting, then close the guard to lock the camera in place. Applying a small blob of modeling clay prevents the camera from making contact with the GPIO pins, which could damage the camera. Now connect your keyboard, mouse, and so on, and power up your Raspberry Pi to the desktop.


The official Raspberry Pi camera and our MCP3008 both need their interfaces configuring. To do this, go to the Raspberry Pi Configuration tool, which is located in the “Preferences” menu. In the “Interfaces” tab, enable the Camera and SPI interface. Save your configuration, and the application now asks you to reboot. Do so, and return to the Raspbian desktop.

7Review earns Amazon affiliate commissions from qualifying purchases. You can support the site directly via Paypal donations ☕. Thank you!

>> To test the camera, open the Terminal, and enter this command to take a photo, which will be output as image.jpg: $ raspistill -o image.jpg

>> If this doesn’t work, repeat the configuration, power down the Pi, and check that your cable is inserted correctly.

>> Now to write some code. Go to the “Programming” menu and click “Python 3.” When the application opens, click “File > New” to create a new blank file. Immediately save the file (“File > Save”) as timelapse-controller.py before carrying on. We start the code by importing the libraries that we will be using. These are “picamera,” used to control the camera; “GPIO Zero” for our analog- to-digital converter and the push button; the “sleep” function is imported from the “time” library; and we’ll need “datetime” to create a timestamp later. from picamera import PiCamera from gpio zero import MCP3008, Button from time import sleep from datetime import datetime

>> Now we need to set up the channel connections to the MCP3008, tell the GPIO where our push button is connected, and create an object from the “picamera” library that makes it easier to work with:

pot1 = MCP3008(channel=0) pot2 = MCP3008(channel=1) button = Button(17) camera = PiCamera()

>> To capture our images, we create a function that can be called later in our code. The function, called “capture,” starts with a “for” loop that iterates for a user-controlled

number of times. The “for” loop creates a timestamp- the time and date at that moment—then uses that value as a filename to capture an image. The loop then sleeps for another user-controlled duration before repeating:

def capture(): for i in range(timer):

timestamp = datetime.now().isoformat() camera.capture(‘/home/pi/%s.jpg’ % timestamp) sleep(delay)

>> In order to see what the camera sees, we create a preview window. In this case, this window has a fixed resolution of 640×480, and is placed in the top-left of the screen (0,0). But, typically, the preview is full-screen.

camera.start_preview(fullscreen=False, window = (0, 0, 640, 480))


Using a “try, except, finally” construction to handle any errors and the user exiting the code, we create two variables: “timer” and “delay.” The “timer” variable stores the amount of time in minutes that the timelapse should run for. The “delay” variable is used to store the delay in seconds between shots. Both variables capture user input from the keyboard, and convert it to an integer: try:

timer = int(input(”How long in minutes should the timelapse run for?”))

delay = int(input(”How long is the delay, in seconds, between shots?”))

>> Inside a “while True” loop, we now take the value of the potentiometer, typically between 0.0 and 1.0, and multiply it by 100 to give us a value to control the brightness and contrast of the image. Turning the potentiometers changes the value, and prints the new value to the shell:

while True:

brightness = round(pot1.value * 100) print(”Brightness”,brightness) contrast = round(pot2.value * 100) print(”Contrast”,contrast)

>> Use the “brightness” and “contrast” variables to update the preview window, showing the change in configuration. We then create the “settings” variable that contains both values:

camera.brightness = brightness

camera.contrast = contrast

settings = “Brightness: “+str(brightness)+”

Contrast: “+str(contrast)

>> These settings are then printed to the Python shell, before being annotated to the preview window, typically at the top-center of the image. There’s a sleep step of 0.1 seconds before the process is repeated:


camera.annotate_text = settings sleep(0.1)

>> Now our button is ready to start the timelapse sequence. When the button is held for two seconds, it calls the “capture” function (created earlier). This then captures a time lapse using the “timer” and “delay” variables that the user specifies.

button.when_held = capture

>> We now come to the final part of the project. Here we have the “except” part of the construction. This handles the user exiting the application by pressing Ctrl-C, a keyboard interrupt. It stops the preview, then moves on to the “finally” part, where we print that the application has exited to the Python shell: except KeyboardInterrupt:

camera.stop_preview() finally:


>> Save the code, then click “Run > Run Module” to start. The preview window opens, and you can tweak the brightness and contrast using the potentiometers, set the timer and delay, then, when ready, press and hold the button to start the sequence. Now all you need to do is find a suitable subject to photograph over time.


We recently had to create a timelapse video using images, and the first obstacle we faced was converting the timestamps into an ascending numerical order of images. Luckily, and thanks to a little Bash magic, we found a one-line shell script that managed to convert the timestamp images into numbers. We did this with a copy of all the images, to ensure that we had backups.

$ ls | cat -n | while read n f; do mv “$f” “$n.jpg”; done

So, why did we capture the images with a timestamp? Well, this project can be used in scientific experiments, so capturing the time and date of each image means that we can review when a change took place, say watching cress or sunflowers grow.

To create the video we used avconv. This can be used with the Raspberry Pi. To install it, open the Terminal and type:

$ sudo apt-get install libav-tools

We used it with a Core i5 laptop, because it’s much quicker in terms of performance. Now run the command in the same directory as the images we’ve just renamed. This will set the frame rate to 10 fps, it will start from number 1 in the sequence of images, it sets the bitrate to 1,000k, and saves the file to test.mp4:

avconv -r 10 -start_number 1 -i %d.jpg -b:v 1000k test.mp4

Now open the video using omxplayer, and enjoy the fruits of your labor. omxplayer test.mp4

7Review earns Amazon affiliate commissions from qualifying purchases. You can support the site directly via Paypal donations ☕. Thank you!
We will be happy to hear your thoughts

Leave a reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.