This firmware transforms your Raspberry Pi Zero W to a timelapse or RTMP streaming camera using one of the many Raspberry Pi CSI compatible cameras.
The idea is to have a stable maintenance free appliance that will not crash and burn if it looses power (for example because it is turned on and off by a timer switch)
case
subdir)OTG
(middle) Port, not the power portWhen connected to power the Pi boots the image from the SD-Card, this image is special as it is not
the usual Raspberry Pi OS or even Ubuntu. This image has been build with Buildroot and
compressed into a read-only squashfs
file system.
On boot the USB Ethernet Gadget mode is activated and an instance of dnsmasq
is providing DHCP services
on that interface. When a computer connects to it, it sees a USB network card and usually runs a DHCP client
on that interface. It will get an IP address in the Range 10.0.77.50-150
while the Pi has 10.0.77.1
.
On the Pi we have the following running services:
configfs
settings to activate Ethernet mode)dnsmasq
to provide DHCP to the connected computer (if one is connected)ntpd
to synchronize the clock over the network as the Pi has no realtime clocksshd
to be able to connect, debug and monitor the devicegetty
on the Pi's UART on the GPIO header which provides a serial console at 115200 baudwpa_supplicant
to connect to Wifi (for more info read on)planticam_web
which is the flask
based webinterface for setting up the deviceplanticam_still
which is a relatively simple python script that captures still images for timelapsesThe default username is admin
and the password is en3Eyied0mae
vfat
one)wpa_supplicant.conf
and enter your WiFi name and password instead of default
and password
.
Make sure to save with linux/unix line endings (LF only, nor CR LF which is default on Windows)planticam.conf
in your editor and see below for a description of the options (if the names are not
enough)See "The manual way" above first.
The ssh host keys of this image are embedded and will not be re-generated as the filesystem is strictly
read-only, however you can replace them as they are stored on the vfat
partition of the SD-card in
the folder ssh-keys
. It is strongly recommended to either build the complete image with buildroot
yourself
or at least change the keys if it is remotely possible the device will be accessed over the internet.
To re-generate the keys run the following commands and replace the files on the SD-card with the newly generated ones:
ssh-keygen -t rsa -f ssh_host_rsa_key -C '' -N ''
ssh-keygen -t dsa -f ssh_host_dsa_key -C '' -N ''
ssh-keygen -t ecdsa -f ssh_host_ecdsa_key -C '' -N ''
ssh-keygen -t ed25519 -f ssh_host_ed25519_key -C '' -N ''
On the boot partition you will find another SSH key, the client key, directly in the root folder.
To re-generate this one run the following command and replace the files on the card (id_ed25519
and id_ed25519.pub
):
ssh-keygen -t ed25519 -f id_ed25519 -C 'planticam' -N ''
As this is an embedded system with absolutely no external hardware attached to gather entropy from, we have to help the Pi (else every cryptographic algorithm that uses random numbers will hang on boot until enough entropy has been gathered.)
At build time the scripts generate a random seed. It is not strictly necessary to exchange that seed but if you want to be sure nobody can guess the internal state of your device you may exchange the seed if you want.
The seed is stored as a kernel-boot-parameter in cmdline.txt
in the parameter systemd.random_seed
.
To generate a base64
string to use as a seed run the following:
head -c 250 /dev/urandom |base64 -w0 -
This takes 250 bytes of random data from /dev/urandom
, base64
encodes it and prints it to the terminal.
also known as: "It does not work, what's wrong!"
There are 3 methods of accessing the device, ordered from "it mostly works" to "wtf is wrong":
planticam.local
if you have zeroconf
(also known as bonjour) running.ssh: Could not resolve hostname planticam.local: Name or service not known
either zeroconf is not working correctly or the device did not connect to Wifi, consult your router to
find the appropriate IP address to use with SSH.10.0.77.1
as root user.For console login use the root
user and the password Tu1boo4bee5i
You will not have any writable filesystem by default. You can re-mount the vfat
partition that is mounted as /boot
if you just want to correct a setting though (only vi
available on the Pi though, i
to switch to edit mode,
ESC :wq
to exit ;) ):
mount -o remount,rw /boot
Be sure to re-mount read only before disconnecting power to avoid crashed SD-cards.
To debug what went wrong, usually you can look at the following commands:
dmesg
, shows any hardware failuresjournalctl -xe
, shows any output systemd
or any of the running services generate, including
python stacktraces of any servicemkdir planticam
git clone https://github.com/dunkelstern/planticam.git
wget https://buildroot.org/downloads/buildroot-2020.11.tar.gz
tar xvzf buildroot-2020.11.tar.gz
buildroot
(without version number): ln -sf buildroot-2020.11 buildroot
cd planticam
./build-planticam.sh
output/planticam/images/sdcard.img
If you want to make changes to the planticam sources you can re-run the build process with the clean
parameter
to clean out the build packages before re-building: ./build-planticam.sh clean
, this will only clean out neccessary
files, a rebuild should be done in about a minute usually.
While building, the scripts generate SSH keys for the ssh daemon as well as a client ssh key, those will only be rebuilt
if you remove the output/planticam/images
folder, so you may experiment with new images without constantly removing
the keys from your known_hosts
or replacing the public key on your image destination server.
To put the image on an SD-card you can either use etcher or any other image writer. I prefer to do it with dd
:
dd if=output/planticam/images/sdcard.img of=/dev/sdX bs=1M oflag=sync status=progress
Replace /dev/sdX
with the appropriate device name of your SD-card, make sure you may access the device file (either
put yourself in the appropriate group for your Linux Distro or run the command as root). The oflag=sync
skips the
write cache of the SD-card so you can remove it immediately after the command finishes, the status=progress
displays
write progress, which is good as the dd
command may appear to hang while the system is copying data.
Example:
[web]
secret_key = apAkGhEL6bve1NwB/RzQSuIEafI=
username = admin
password = sha256:50000:y1c7SCo95G8FTkY8gXsmwQ==:XrTm1s1P6qDabh1pCNAVUL84eVvvLjW-OwwbnN_yJgs=
[image_settings]
resolution_x = 2592
resolution_y = 1944
rotation = 0
iso = auto
exposure_mode = auto
exposure_compensation = 0
metering_mode = average
drc = off
awb_mode = auto
awb_gain_red = 0.9
awb_gain_blue = 0.9
brightness = 50
contrast = 0
saturation = 0
sharpness = 0
denoise = 0
[timelapse]
enable = on
delay = 120
upload_mode = none
upload_server = localhost
upload_path = /data
upload_auth_user = planticam
upload_auth_password =
upload_form_field =
upload_cmd = SSHPASS= sftp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -q -i /boot/id_ed25519 {input_file} planticam@localhost:/data/{output_file}
weekday_enable = off,off,off,off,off,off,off
weekday_from = 00:00,00:00,00:00,00:00,00:00,00:00,00:00
weekday_to = 23:59,23:59,23:59,23:59,23:59,23:59,23:59
enable
: boolean value, enable the timelapse modedelay
: delay in seconds between photosupload_cmd
: (optional) command to run to upload the image somewhere, the example command uploads to a SSH server
which has the id_ed25519.pub
key in their authorized_keys
-file. Has 2 placeholders: {input_file}
the source
file and {output_file}
the output filename (usually planticam-YYYY-MM-DD_HH-MM-SS.jpg
)post_url
: (optional) URL to upload the image to, it will send a HTTP POST
-request with Content-Type: image/jpeg
and the JPEG binary as is in the bodyresolution_x
and resolution_y
: Image resolution, see
picamera documentation for explanation what the cameras
can dorotation
: (optional) Rotates the image in 90 degree incrementsiso
: (optional) ISO to use, defaults to auto
(one of auto
, 100, 200, 320, 400, 500, 640, 800)exposure_mode
: (optional) Exposure mode to use (one of off
, auto
, night
, nightpreview
, backlight
,
spotlight
, sports
, snow
, beach
, verylong
, fixedfps
, antishake
or fireworks
)exposure_compensation
: (optional) Adjusts the camera’s exposure compensation level. Each increment represents
1/6th of a stop. Range is -25 to 25, defaults to 0meter_mode
: (optional) Exposure metering mode, defaults to average
(one of average
, spot
, backlit
or
matrix
)awb_mode
: (optional) White-balance mode to use (one of off
, auto
, sunlight
, cloudy
, shade
, tungsten
,
fluorescent
, incandescent
, flash
or horizon
)brightness
: (optional) Brightness from 0-100, defaults to 50contrast
: (optional) Contrast from -100-100, defaults to 0saturation
: (optional) Saturation from -100-100, defaults to 0sharpness
: (optional) Sharpness from -100-100, defaults to 0denoise
: (optional) Denoise ration from -100-100, defaults to 0