Timelapse Pi Mk6 BrainyCam
Putting together everything I've learned from the first five Raspberry Pi timelapse cameras I made:
- Raspberry Pi 4
- 16 MP ArduCam with autofocus
Pi 4 B + 16 MP ArduCam
This camera will also be the brains of the operation:
- rsyncs all files to itself nightly
- makes videos of all cameras
- puts completed videos of all cameras on Dropbox
- serves a simple webpage showing current capture from each camera (essentially a 2 minute interval security cam)
- deletes all files picture files older than 7 days
Bonus:
- solar / battery powered?
Setup Raspberry Pi
Add SSH keys
From local MacBook, run:
ssh-copy-id username@ip-address
Test SSH to Pi
You should now be able to connect without entering a password:
ssh pi@brainycam
- install headless OS via Pi Imager
- user: pi
- pass: [mypisystem]
Edit the config:
sudo raspi-config
- enable VNC (helpful for previewing camera position when installing)
- set VNC resolution
- enable Glamor (not applicable on Pi 4b)
Install Arducam Drivers
The one drawback of the Arducam is that it doesn't run on the Pi out of the box. Gotta install the drivers manually:
Note that the autofocus wasn't supported on the latest kernel version after I ran updates. So I had to reinstall the operating system and not run upgrades. So dumb.
Connect with RealVNC
The simplest solution for connecting to the Pi in a headless setup. Both Mac / iPhone apps.
Preview camera for initial setup
Connect to Pi via RealVNC on your phone. Start the camera and open a preview window, indefinitely:
libcamera-hello -t 0
-t = time, 0 = indefinitely
Capture Still Photos On Boot
My programmer brother suggested a few simple improvements to my previous process:
- use cron to run the bash script so if something breaks it tries again upon next run, instead of failing indefinitely
- log errors with cron
So good. Here's the simpler bash script to take still photos. I named mine "run-timelapse.sh":
#!/bin/bash
date
/usr/local/bin/libcamera-still -o /home/pi/pics/ --datetime -q 90 --width 3840 --height 2884 --nopreview --autofocus
Notes:
4k resolution = 3840 x 2160. I'm using 2884 as the height so I can crop it to 4k later. 16:9 aspect ratio is quite narrow and I need to capture more height and adjust as the action moves around...
"date" simply outputs the date, which we then capture in the cron log.
cron needs the full path to libcamera-still.
Make script executable:
sudo chmod a+x FILENAME
Set script to every minute and log any errors:
sudo crontab -e
by adding this line to the end of the file:
*/1 * * * * /home/pi/run-timelapse.sh >> /home/pi/logs/timelapse.log 2>&1
Then check the directory where the pictures should be. If new images show up every minute, you're good to go. Otherwise, check the log to see what went wrong!
Grab Photos From All Cameras
rsync
Use rsync to grab all files:
#!/bin/bash
# run the script on yesterday's files...
YEAR=$(date -v -1d '+%Y')
MONTH=$(date -v -1d '+%m')
DAY=$(date -v -1d '+%d')
MK1NAKEDHQ_DIR='/Users/joelgaeddert/timelapse/Mk1-NakedHQ'
# grab all the files, and delete them off the pi
rsync --remove-source-files -azP pi@timelapsepi:pics/ $MK1NAKEDHQ_DIR
echo 'Done with Naked HQ Mk1 camera!'
MK3GREEN_DIR='/Users/joelgaeddert/timelapse/Mk3-Green'
# grab all the files, and delete them off the pi
rsync --remove-source-files -azP pi@joeltimelapse1:pics/ $MK3GREEN_DIR
echo 'Done with Green Mk3 camera!'
...
Sort Photos
#The new directory will often already exist, but if not, create it
if [ ! -d "$MK1NAKEDHQ_DIR/$YEAR-$MONTH-$DAY" ]
then
mkdir $MK1NAKEDHQ_DIR/$YEAR-$MONTH-$DAY
fi
# sort the files into the directory for the day you're working on
find $MK1NAKEDHQ_DIR -name "$MONTH$DAY*.jpg" -maxdepth 1 -exec mv {} $MK1NAKEDHQ_DIR/$YEAR-$MONTH-$DAY \;
Create Timelapse Videos
ffmpeg
Super simple mp4 creation:
# make video for the day we're working on
echo Making the timelapse of: $YEAR-$MONTH-$DAY
ffmpeg -framerate 12 -pattern_type glob -i "$MK1NAKEDHQ_DIR/$YEAR-$MONTH-$DAY/$MONTH$DAY*.jpg" $YEAR-$MONTH-$DAY.mp4
mv $YEAR-$MONTH-$DAY.mp4 $MK1NAKEDHQ_DIR
Then do it again for each camera. Or combine the steps into a simple loop...
This gets us to completed timelapse videos of each camera. Now we need a few scripts to transfer the files to Dropbox, and delete pictures older than a week to keep things clean...
Then we need to modify the scripts to run a web server to show the lastest images captured from each camera. This will mean that our rsync script will need to run more often, and the structure of our files will need to change...
Flask + ngrok