Files
picUploadApi/demo

Raspberry Pi Webcam Capture Demo

Automated picture capture and upload for Raspberry Pi 3 with a USB webcam (Logitech 1080p).

Quick Setup (5 minutes)

1. Install Required Packages

sudo apt update && sudo apt install -y fswebcam curl

2. Configure the Script

# Copy the config template
cp picupper.conf.example picupper.conf

# Edit with your settings
vi picupper.conf

Update picupper.conf with your API key and camera settings.

3. Install & Enable

# Run installer (sets up cron job)
./install.sh

That's it! Your Pi will now capture and upload one picture per minute.


Files Included

File Purpose
capture-upload.sh Main script - captures photo and uploads
picupper.conf.example Configuration template
install.sh Installer script (sets up cron)
uninstall.sh Removes cron job

Configuration Options

Edit picupper.conf:

# PicUpper server URL
API_URL="https://dev.seedheads.de/picUploadApi/upload"

# Your API key (from server admin)
API_KEY="your-api-key-here"

# Camera identifier (unique name for this Pi)
CAMERA_ID="rpi-webcam-1"

# Resolution (1920x1080 for full HD)
RESOLUTION="1920x1080"

# Video device (usually /dev/video0)
VIDEO_DEVICE="/dev/video0"

Manual Testing

# Test capture only (saves to /tmp)
./capture-upload.sh --test

# Run full capture and upload once
./capture-upload.sh

Camera Settings (Focus & Exposure)

Camera settings are stored on the PicUpper server and applied before each capture.

Set camera settings via API

# Set focus and exposure for your camera
curl -X PUT \
  -H "X-API-Key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "focus_automatic_continuous": 0,
    "focus_absolute": 30,
    "exposure_auto": 1,
    "exposure_absolute": 200,
    "brightness": 0,
    "contrast": 32
  }' \
  https://dev.seedheads.de/picUploadApi/settings/rpi-webcam-1

Get current settings

curl -H "X-API-Key: your-api-key" \
  https://dev.seedheads.de/picUploadApi/settings/rpi-webcam-1

Available settings (for Logitech C922)

Setting Range Description
focus_automatic_continuous 0-1 0=manual, 1=auto
focus_absolute 0-255 Lower=closer (manual mode)
exposure_auto 1-3 1=manual, 3=auto
exposure_absolute 3-2047 Shutter speed (manual mode)
brightness -64 to 64 Image brightness
contrast 0-64 Image contrast

Find your camera's available controls

v4l2-ctl -d /dev/video0 --list-ctrls

Note: Install v4l-utils on the Pi: sudo apt install v4l-utils


Troubleshooting

Check if webcam is detected

ls /dev/video*
v4l2-ctl --list-devices

Test capture manually

fswebcam -d /dev/video0 -r 1920x1080 --no-banner test.jpg

Check logs

# View recent capture logs
tail -f ~/picUploadApi/demo/picupper.log

Common Issues

Problem Solution
"No video device" Replug USB webcam, check dmesg
"Permission denied" Add user to video group: sudo usermod -aG video $USER
"Upload failed" Check API key and network connection

Changing Capture Frequency

Default is 1 picture per minute. To change:

# Edit cron job
crontab -e

Examples:

  • Every 5 minutes: */5 * * * * ~/picUploadApi/demo/capture-upload.sh
  • Every 30 seconds: Use systemd timer instead of cron

SD Card Preservation

Reduce SD card writes to extend its lifetime:

# Disable swap
sudo swapoff -a
# Comment out swap line in /etc/fstab
sudo vi /etc/fstab

# Disable automatic apt updates
sudo systemctl disable apt-daily.timer apt-daily-upgrade.timer

Option 2: Full Read-Only Mode

sudo raspi-config
# Navigate to: Performance Options → Overlay File System → Enable

⚠️ Before enabling read-only mode, change log location to tmpfs:

# Edit picupper.conf
LOG_FILE="/tmp/picupper.log"

Auto-Reboot (Stability)

For long-running deployments, schedule automatic reboots:

sudo crontab -e

Add (reboots at 00:00, 06:00, 12:00, 18:00):

0 */6 * * * /sbin/reboot

Hardware Requirements

  • Raspberry Pi 3 (any model)
  • USB webcam (Logitech C920/C922/C270 recommended)
  • SD card with Raspberry Pi OS
  • Network connection (WiFi or Ethernet)

Network Notes

The script retries failed uploads and logs all attempts. If your Pi loses network, captures continue and uploads resume when connectivity returns.