Updated Raspberry Pi Timelapse Camera with Google Drive Upload

This is an update to my Original Raspberry Pi interval camera here
You can still use the old hardware but I'd recommend using the new scripts below

Changelog:

  • New gdrive binary
  • Camera upgraded to v2
  • Replaced fixed lens with M12 zoom lens
  • Script updates
    • Splits uploads to drive directories by day
    • Tries to fix WiFi connections when down
    • General cleanup

Hardware

You'll need a display for focusing. The larger and higher def display the easier it will be to get a sharp focus.

Setup the Pi

  • Download and install Raspbian to the SD card normally
  • Run #raspi-config
    • Expand filesystem
    • Enable camera
    • Set timezone
    • Change password
    • Finish (reboot)
  • Setup WiFi
  • Optionally setup LAN for static IP
  • Update raspbian: sudo apt-get update; sudo apt-get dist-upgrade

Enable volatile memory for photo cache

Since we'll be routinely writing and erasing 5MB photos, it's a good idea to use tmpfs in RAM. 
  • Edit /etc/fstab
  • Append: tmpfs /tmp tmpfs defaults,noatime,nosuid,size=80m 0 0
  • Reboot or remount: mount -a
Note: Adjust size if using a Pi model with limited memory. 16m should be enough.

Setup gdrive

  • Download the RPi binary of gdrive and make it executable
  • run ./gdrive about and follow the instructions to authenticate it to your account
  • Create a target folder for the photos using gdrive
    • # ./gdrive folder -t timelapse
    • gdrive will return the newly created folder details for "timelapse" including the ID which will look something like 0gtB8nmiKwJ2N3Rse9aF9zdG8
    • Save that string to a file named "parent". The script will read this file

Photo script (timelapse.sh)

This takes photos and calls the upload script below. It will also show a preview window on the HDMI or composite display at all times while not taking a photo.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
#!/bin/bash
DATESTAMP=$(date +"%Y-%m-%dT%H%M%S")

# kill any running raspistill preview windows. See below
pkill raspistill

# Take photo
echo "taking photo $DATESTAMP.jpg"
raspistill -ISO 100 -ev 5 -co 20 -sa 10 -awb auto -ifx denoise -mm matrix -drc med -th none -o /tmp/$DATESTAMP.jpg

# Show live preview window at all times while not shooting
raspistill -t 7200000 -f & 

# upload photo
/home/pi/upload.sh $DATESTAMP.jpg
if [ $? -ne 0 ]; then
  # upload failed, move out of tmp to SD
  mv /tmp/$DATESTAMP.jpg /home/pi/Pictures/$DATESTAMP.jpg
  echo "Upload failed. Storing photo in ~./Pictures"
fi

Upload script (upload.sh)

This script is called by the timelapse script with the latest photo as an argument for upload but can also be run without arguments to upload any files still left in the ~./pictures directory


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#!/bin/bash

DATE=$(date +"%Y-%m-%d")
DATESTAMP=$(date +"%Y-%m-%dT%H%M%S")
YESTERDAY=$(date -d "yesterday 13:00" +"%Y-%m-%d")
PARENT_ID=$(</home/pi/parent)
SSID="<your SSID>"

# Cleanup
if [ -f "/home/pi/$YESTERDAY" ]; then
  rm /home/pi/$YESTERDAY
fi

# Check Internet
if ! ping -q -c 1 -W 5 google.com >/dev/null; then

  # Internet connection down.
  echo "404 internet not found. Trying to fix for next run..."

  # Try to refresh connection for next time
  sudo iw dev wlan0 disconnect
  sudo iw dev wlan0 connect $SSID
  sleep 20
  sudo ifdown --force wlan0
  sudo ifup wlan0
  exit 1
fi

# Check if an instance of gdrive is already running
if pgrep -x "gdrive" >/dev/null; then
  echo "another instance of gdrive is running. skipping upload"
  exit 1
fi
  
# Check if we have the of the directory ID for today
if [ -f "/home/pi/$DATE" ]; then
  DIRECTORY_ID=$(</home/pi/$DATE)
  echo "found direcotry ID $DATE"

# No directory ID. Create new directory 
else
  echo "no daily directory found"
  DIRECTORY_ID=$(/home/pi/gdrive mkdir -p $PARENT_ID $DATE | awk {'print $2'})
  if [ -z $DIRECTORY_ID ]; then
    echo "gdrive directory creation failed"
    exit 1
  fi
  
  # Cache new directory ID as a file named by date
  echo $DIRECTORY_ID > /home/pi/$DATE
  echo "Created directory with ID $DIRECTORY_ID"
fi

# Upload current photo if a photo was passed as an argument
if [ $# -eq 1 ]; then
  TEMPFILE="/tmp/$1"
  if [ -f $TEMPFILE ]; then
    /home/pi/gdrive upload --delete -p $DIRECTORY_ID $TEMPFILE
    if [ $? -ne 0 ]; then
      echo "drive upload failed for $TEMPFILE"
      exit 1
    fi
  else
    # Photo file was passed as an argument but not found
    echo "passed photo was not found"
    exit 1
  fi
fi

# Upload any stored photos
for FILE in /home/pi/Pictures/*.jpg; do
  if [ -f $FILE ]; then
    /home/pi/gdrive upload --delete -p $DIRECTORY_ID $FILE
    if [ $? -ne 0 ]; then
      echo "drive upload failed for $FILE"
      exit 1
    fi
  fi
done

exit 0

Assembling and Focusing

The lens I linked in the hardware section is not a converter but a replacement lens so it's necessary to first remove the default fixed lens.  Pi v2 cameras now come with a white plastic tool to refocus or to remove the lens entirely. Use that tool to unscrew the lens completely. Be careful not to introduce dust on the sensor/IR filter.



Screw the custom lens mount onto the PCB and screw the lens into the mount.

To focus you'll need to connect a monitor and boot into the Raspbian Pixel UI as the live camera preview is GPU driven and does not work over SSH+X or VNC.

In order to zoom for a 1:1 preview you'll need to do some math as there doesn't seem to be a flag for this specifically.  This example assumes a 1080x1920 display and camera v2.

raspistill -p <'x,y,w,h'> allows you to set the top left corner position and size of the preview window.  w and h will always be the sensor size for 1:1, in this case 3280 × 2464. If you set x and y to 0,0 then you'll be viewing the top left corner of the image.



To center it, use the following:

x = - (3280 - <screen width>) /2
y = - (2464 - <screen height) /2

So for a 1080x1920 screen x=-680 and y=-592 and the command to hold that window open would be:

raspistill -t 7200000 -p -680,-592,3280,2464

Crontabs

Use a timelapse calculator to determine the ideal shot interval to get target video speed and duration.  If you need to shoot more than 1 photo/min you'll probably want to change the photo script to use the -tl option in raspistill.

# crontab -e
*/5 7-20 * * * /home/pi/timelapse.sh >/dev/null 2>&1

Popular posts from this blog

Simple Raspberry Pi Interval Camera with Google Drive Upload

Loose Link Pins on the Huawei Watch (hwatch) Band