Robotics / IoT

Turret Camera

Joel Johnston 2026-04-06 Pre-stroke design

Turret Camera

Author: Joel Johnston Date: 2026-04-06 Domain: Robotics / IoT Stroke Timeline: Pre-stroke


Abstract

Pan/tilt surveillance gimbal — the first project in the parametric OpenSCAD library. SG90 micro servos, Pi Camera Module 3, Pi Zero 2W for H.264 video streaming over WiFi with browser access. $80 total build — the lightest and cheapest project in the hardware portfolio. The gimbal module designed here was refined over 4 print iterations before being generalized for the bug zapper, seeker tracker, and drone. This is where the parametric library was born.


Hardware

Gimbal and Servos

  • Servos: SG90 micro servos (2x) — 1.8kg/cm torque, 9g each, sufficient for camera weight
  • Configuration: Pan/tilt, parametric OpenSCAD gimbal module (SG90 variant — this is the origin design)
  • Control: Direct GPIO (general-purpose input/output) PWM from Pi Zero (software PWM sufficient for low-precision positioning)
  • Range: Pan ±90 degrees, tilt +45/-60 degrees

SG90 was chosen over MG996R because the camera load is under 50g. The SG90 is lighter, smaller, cheaper, and draws less current. The tradeoff (lower torque, less precise) is not relevant for camera pointing.

Camera and Compute

  • Camera: Pi Camera Module 3 (12MP, autofocus, HDR)
  • SBC: Raspberry Pi Zero 2W — sufficient for H.264 encoding and WiFi streaming; lower power than Pi 4B
  • Storage: 32GB microSD for local recording
  • Power: 5V 2A USB-C (Pi Zero draws < 1A under load)

Software

Video Streaming

picamera2 library with H.264 hardware encoding. Stream served via ustreamer (lightweight MJPEG/H.264 streamer, CPU cost < 5% on Pi Zero 2W).

Access: http://<pi-hostname>:8080/stream in any browser. No app required. No authentication in v1 (LAN-only deployment).

Pan/Tilt Control

Simple web UI served from the Pi: two sliders (pan, tilt) + directional arrows. Input sends HTTP requests to a Python server (FastAPI, running on port 8081) which translates to GPIO PWM commands.

Preset positions: home (center), left, right, up, down, stored as named presets. Keyboard shortcuts for preset recall.

Motion Detection (optional)

OpenCV frame differencing on the Pi — same approach as bug zapper and seeker tracker. On motion: start local recording, optionally send HTTP notification (webhook configurable). Resolution: 1296x972 for motion detection (lower than streaming res to reduce CPU load).


Mount Options

Three mounting options, all from the same parametric base plate:

  • Wall mount: horizontal surface, camera faces outward or angled down, screw pattern for wall anchors
  • Ceiling mount: inverted — base plate mounts to ceiling, gimbal hangs down, software remaps servo directions
  • Tripod: 1/4-20 threaded insert for standard camera tripod

All mount options are variants of the same parametric base module. Changing mount_type parameter regenerates the base for the selected mounting geometry.


Full BOM

Component Cost
Raspberry Pi Zero 2W $15
Pi Camera Module 3 $25
SG90 micro servos (2x) $6
3D-printed gimbal (PLA) $2
5V 2A USB-C power supply $10
32GB microSD $8
Mount hardware (screws, inserts) $5
USB-C cable $5
Total ~$80

Origin of the Parametric Library

The turret camera was built first. The gimbal design went through four print iterations:

  1. v1: Functional but SG90 mounting pocket was too tight. Cable routing was an afterthought — cable pinched at max tilt.
  2. v2: Widened SG90 pocket by 0.3mm. Added cable channel on tilt arm. Still a one-off design, not parametric.
  3. v3: First parametric version — servo_size parameter added. Tested with SG90 only. Cable routing improved but camera mount was camera-specific.
  4. v4: Full parametric — servo_type (SG90/MG996R), camera_mount (Module 3/HQ Camera), mount_type (wall/ceiling/tripod). This is the version added to the library.

At v4, the module was general enough to be reused. The bug zapper needed a gimbal → used the parametric module, MG996R variant. Same print without redesign, different servo class.


roboNet Future Integration

The Pi Zero 2W has enough headroom to run the roboNet mesh client in addition to the video streaming stack. As a mesh node, the turret camera would be:

  • Node type: fixed sensor
  • Capabilities: video_stream, pan_tilt_control, motion_detection
  • Task dispatch: camera can receive pointing commands via mesh (look at coordinates X, Y in scene)

Multiple turret cameras across a space, all mesh-connected, create a distributed camera network with centralized control from robonet dashboard. Each camera is just a node with video_stream capability — the dashboard aggregates all streams.