Raspberry Pi Zero W as a headless time-lapse camera

March 13, 2017

tl;dr: There are many ways to capture time-lapse videos. But this one is cheap, completely wireless, and mine. If you want to skip the post and go straight for the glory, grab a copy of my Time-lapse app for the Raspberry Pi.

Time-lapses transform subtle, slow processes into something beautiful, and often make us think about things in new ways. For example, have you ever thought about just how heavy a wet snow is? The trees in your yard might know a thing or two about that! Check out a time-lapse I recorded this morning some mighty oak tree branches, as they relaxed upward as if in relief from the wet snow falling off:

Quality time-lapse photography used to require expensive equipment special knowledge, so it remained the domain of the specialist. Fast forward to 2017, and we have a $10 computer and a $30 camera that can create a wireless time-lapse device that can produce footage in any modern resolution—even up to 4K! Sure there are many cameras with built in intervalometers and lenses you can use to make more creative images... but would you be willing to leave your expensive equipment in places or situations where you risk damaging them? $50 of equipment, maybe... $1000+, no way! (At least, not for fun and exploration.)

The Raspberry Pi has freed me to think in new directions for computing (for example, check out my Raspberry Pi Dramble project), and it's also allowing me to expand my photography horizons. And if you want to tinker as well, all you need is this little guy:

The Raspberry Pi Zero W.

For this year's Pi Day (3.14), I decided to grab a Raspberry Pi Zero W from Micro Center, write up a small app, and record time-lapses. And I've decided to open source all my work, and share this blog post so you, too, can enjoy watching life in fast-forward!

Requirements

There are some programs you can download that are more automated, but (a) they usually require the use of a keyboard and monitor (which we don't want to use), and (b) they usually consume more power (meaning less battery life) and are less customizable than I desire.

Parts needed

USB battery power supply (I use the AUKEY 30,000 mAh power supply, but any rated at 10,000 mAh or more will go for days)

(Optional) camera case (I like the one Adafruit sells, but any will do—helpful in rigging the camera, since it needs to be still!)

Another computer to use to set things up and view the results

A WiFi network (this allows the rig to be fully portable and remote-controllable)

Setting things up

I'll assume you're using a Mac for the setup process, but you can do the same thing on Windows if you use Ubuntu Bash or some other command line emulator that allows SSH access... and if you use Linux, you're golden—just pop open a Terminal window and follow along!

In this guide, we'll set up the Raspberry Pi headless—you don't need an extra monitor, keyboard, and mouse to plug into the Pi (nor do you need all the extra adapter cables to get it all hooked up!)

Put Raspbian on the microSD card

Mount the microSD card (I use a microSD to SD adapter, then plug that into my USB SD card reader) on your Mac.

Initialize SSH and WiFi configuration.

Create a wpa_supplicant.conf file to tell the Pi to connect to your WiFi network on boot. Create a new file with that title in the boot volume, with the contents below:

network={
ssid="YOUR_SSID"
psk="YOUR_PASSWORD"
key_mgmt=WPA-PSK
}

Eject the microSD card, and stick it in the Raspberry Pi.

At this point, the Pi is fresh and new, and will boot up and connect to your WiFi network, allowing you to administer it via SSH.

Connect to the Pi

Assuming your WiFi network uses DHCP to assign IP addresses to devices (this is almost universally true), you need to figure out the IP address your Pi acquired when it booted. Use one of the following two options:

(Note: Check your computer's local network IP address—if it's something like 192.168.0.x, then you need to use 192.168.0.1/24 instead of 10.0.1.1/24.)

Either of these options will scan the network for a bit, then output a list of Host addresses and MAC/Hardware addresses. nmap additionally prints human-readable manufacturer labels, so it's even easier to identify devices labeled with (Raspberry Pi Foundation) on your network!

Once you have found the Pi's IP address, log into it: ssh pi@[IP-ADDRESS-HERE] (the default password is raspberry). Since this is the first time the Pi is being used, it needs to be configured:

sudo raspi-config

Set a new password (first option in the list).

Set a hostname (e.g. pi-zero-timelapse).

Go to 'Interfacing Options', then 'Camera', then choose 'Yes' to enable the camera interface.

Aren't the graphics amazing?

Create your own Time Lapse script

Now that the Pi is set up, and you're connected to it, you need to install a few libraries so you can call them in your Python time-lapse script:

sudo apt-get install -y python-picamera python-yaml imagemagick

Then create a script named timelapse.py (nano timelapse.py to open it in the nano text editor), with the contents:

from picamera import PiCamera

camera = PiCamera()camera.capture('image.jpg')

This is basically how the guide in Raspberry Pi's official documentation works (Time-lapse animations with a Raspberry Pi). But at this point, we want to go a bit deeper, and have a more flexible way to control the timelapse—the length, the exposure settings, color temperature, etc.

To that end, I've built a little Python app (really, it's a glorified script... but nowadays everyone calls anything resembling software an 'App', so I might as well, too) that you can download from GitHub to have greater control over your time-lapses!

Going deeper

With the pi-timelapse app, you can build timelapses like the one at the top of this post pretty easily. Some of the features I've built so far include:

Easy configuration via a config.yml file

Resolution control

Intervalometer control (number of images and interval between images)

Ability to generate an animated gif or an mp4 video after capture is complete (experimental)

After the number of frames you configured have been captured, there will be a folder named series-[date-and-time] in the directory with the pi-timelapse project. That directory contains all the images that were captured, numbered in a sequence like image00001.jpg, image00002.jpg, etc. And if you configured a gif or video to be created, then you'll see a .gif and/or .m4v video in the pi-timelapse project directory too.

You can use ls to display the contents of the directory, and cd [folder] to go into a folder, or cd .. to go back one directory.

More Examples

Here's a video I shot at 1 frame every 15 seconds of cirrus clouds in the sky in front of my house:

And a shot of an earlier snow melting (as it was falling!) in my backyard:

And here's a gif I captured of myself, showing one of the risks of working at an adjustable-height standing desk:

I haven't had time to build any more elaborate time-lapses, mostly because they often take hours (or days!), depending on what I'm trying to capture, and I've still been honing the software in the short term.

Comments

Ive made a few timelapse with my pi. I didn't have the time to mess with a hardware switch so I spoofed my pi to set the time to midnight anytime it booted without wifi and I coded it to take pictures for 8 hours and then had a cronjob to turn the pi off after 8 hours. (Bit of a write-up for reference: https://github.com/HerbFargus/Raspberry-Pi-Scripts/wiki/Timelapse#schedu...)

Very nice project, I like it!
I suggest you to use python >= 3.5 and take advantage of async. I'm developing a similar project, but I want to use telegram to take photos, timelapse, videos or set options! All your photos or similar will be on your telegram cloud.

Couple things - first, works great on a pi zero-w with the original camera. Nice. Second, your code doesn't like interval=1 because you sleep interval-2 in the code. I didn't know you coded up the wayback machine :-)

It would be nice to be able to specify an output directory for the finished product(s) and whether to copy them there or not. FWIW, I usually just stash this stuff in a nginx docroot subdirectory and serve'em up via the web. Everybody loves a timelapse !

This is great for fiddling with the camera resolution, but just running 'motion' will get the job done nicely and do timelapse very efficiently on even the oldest Pi. I've been running it doing timelapse movies for a few years now on an old model-B with a USB webcam. Gonna port all this stuff over to the zero-w and my new ZeroView mounting thing from pihut (way cool - would be great for a birdbox cam)

Please excuse the basic nature of this question - I would appreciate any help that you can offer. I have only cloned repositories on github a few times, and I am clearly missing a step here that is holding me back.

Running through a series of troubleshooting my confusion (much of it self-inflicted by having 8 different windows open to diagnose what I haven't done to Raspbian) - I realized I hadn't run the install for "git" yet (sudo apt-get install git). For me, that seemed to open this up.

Hey Jeff thank you for the script, been experimmenting with it and having fun.

My scripting skillz are somewhat lacking and I have two question I hope you can answer.
How do it change the resolution of the pictures made, tried different formats but either I get an error or the default resolution.
What will the resolution of the mp4 video if i choose to use the option?

With the video option, the resolution you set will be the resolution of the final video. If you want to capture one resolution then scale the video at a different resolution, you'd have to manually run the command to scale the video using avconf later.

I went a step further and wrote a unit file and added it to systemd startup. Now it starts capturing images as soon as I turn it on. I use a short bash script to start it in the root of a running web server on the pi zero. So I can browse to it and see all the captured images.

That's awesome! I actually needed that earlier today, since I was going to a remote location to do a project with no Internet/network, and didn't have time to set up the Pi manually via direct WiFi...

Do you think you'd be able to share the unit file either as a pull request or some other way, and I could include it with the project? It would add the main missing feature ("set it and forget it") that's currently missing from this setup.

Hi Jeff,
Can't get scp to work. I get this error: ssh: connect to host 192.168.0.102 port 22: Connection refused
lost connection
From this: scp image.jpg donde@192.168.0.102:/home/donde/Public
image.jpg is in /home/pi of the Pi Zero
donde@192.168.0.102 is referring to the Mint box I'm on now.
I notice my older Netgear router has Device Names sometimes mixed together on same line. Don't think this matters.
So, why doesn't this single image get moved from the Pi Zero to the Mint box?
Thanks, Don

More info
First of all, can either machine be the Remote or the Local? If the file to be moved resides in a machine, this is the Local? And the other machine is the Remote? I think this can be confusing in looking at the examples in Google.
As the file move starts, I see at the far right ETA. Then after a number of seconds, I see STALLED and then the move hangs. Do a Ctrl C.
I look where it's supposed to be and see correct file name, but no bytes.
From which machine should I send the move command? Should I use the host name or the IP address? I have been looking at SCP in Google. It seems this command has lots of problems with others too. As I remember, a move did complete, but to the same machine! Please excuse my babbling.

Any more you are adding to this time lapse project? I did see about you improving focus of pi camera. Have to read it. I have the same little case for camera and Pi Zero. I can't believe why they didn't put a slit to remove the micro SD card!
Want to read about your other projects. You are quite diverse!
Take care, Don

I'm lucky to be in the path of totality, so I'm working on my setup and practicing the full progression—working on a blog post and YouTube video explaining the things I'll do, with some links to equipment I'm renting and/or buying to help make it fun, safe, and most importantly, memorable!

FYI
A new problem. For scp tests I was using small files around 1 K. Well, anything much over this, scp would stall and I would never receive any bytes. Got the file name OK. Nosing around Stack Overflows using phrase scp stalls over 1 KB, I found this as a fix.
sudo ip link set eth0 mtu 1024. Now I can receive the 250 K jpg example file with no problem. For days, all I would see was STALL along with other problems. How frustrating this science is!

Jeff,
great project and great stuff on your blogg.
I came across this site while searching for Zeri W power consumption.

I'm looking for a real time birds view cam with low latency for persons with limited sight/impaired who can view the cam stream on an android phone/tablet. They love to see the birds and squirrels in front of their eyes instead of using a glass.

But currently the cams are powered by a power line and I t want to replace it with a solar powered power bank .
Therefore I need a glimpse ofbzero w's power consumption while streaming camera ... and you have the cam , the zero w and the foundation cam.
Maybe you have an idea what streaming means in power consumption, what size of panel and powerbank I need for 14 hours live transmission
Thx ...

Jeff, thanks for making your time-lapse code public, it sure saved me a lot of time! Your write-up is very clear too.
One thing that is confusing me - it seems that the call to create the movie is happening as soon as the series of photographs STARTS, not after it ENDS. I'm not experienced in python, so I don't know enough to say how this is possible.
I've watched the directory where the photos are slowly being created, and as soon as it starts, there's already a time-lapse.mp4 file there. Its file size is very small. I've stripped out the avconv call and done it manually later on the directory full of photos, and it clearly processes them all and creates a proper mp4 file.
What do you think?