# Party Cam: Instant Thermal Camera & Digital Gallery A DIY point-and-shoot that prints dithered lo-fi photos on thermal receipt paper and simultaneously uploads captures to a local Rust web server. --- ## Hardware BOM | Part | Notes | | :--- | :--- | | ESP32-CAM (AI-Thinker) | Camera + WiFi module | | Thermal Printer | TTL serial, 5V–9V | | 2× 18650 Li-Ion | In series = 7.4V; powers printer directly + 5V buck converter for ESP32 | | Tactile button | Shutter trigger | | FTDI adapter or Arduino Uno | For flashing only | --- ## Wiring | ESP32-CAM Pin | Component | Function | | :--- | :--- | :--- | | **5V** | PSU 5V | Power in | | **GND** | PSU GND | Common ground | | **GPIO 12** | Button | Shutter (other leg → GND) | | **GPIO 14** (U1T) | Printer RX | Data to printer | | **GPIO 15** (U1R) | Printer TX | Data from printer | | **GPIO 4** | Flash LED | Optional built-in flash | All pin assignments are in `include/config.h`. Change them there if your wiring differs. --- ## Server Setup Run the server on any machine on the same local network as the camera. It receives uploads and hosts the gallery. ### Option A: Docker Compose (recommended) ```bash cd server docker compose up -d ``` Images are saved to `server/party_images/` on the host. To change the gallery password, edit `GALLERY_PASSWORD` in `compose.yml`. ### Option B: Cargo (dev) ```bash cd server cargo run --release ``` Requires a `.env` file in the `server/` directory: ```ini SERVER_HOST=0.0.0.0 SERVER_PORT=3000 GALLERY_PASSWORD=partytime UPLOAD_DIR=./uploads ``` `GALLERY_PASSWORD` is required — the server panics at startup without it. --- ## Firmware Setup ### 1. Configure Check `platformio.ini` and make sure `board` matches your actual hardware. The default is `4d_systems_esp32s3_gen4_r8n16` — change it to `ai_thinker_esp32-cam` if using a standard ESP32-CAM. Camera pin definitions in `include/config.h` are pre-set for AI-Thinker. ### 2. Flash (Arduino Uno as bridge) Wire the Uno as a passthrough: - Arduino RESET → Arduino GND (bypasses the Uno chip) - Arduino Pin 0 (RX) → ESP32 U0R - Arduino Pin 1 (TX) → ESP32 U0T - **ESP32 IO0 → ESP32 GND** (enables download mode) Click **Upload** in PlatformIO, then press RST on the ESP32 when "Connecting…" appears. ### 3. Boot Disconnect IO0 from GND, press RST. The camera boots. --- ## First Boot Configuration 1. Power on. Camera broadcasts WiFi AP: **`PartyCam-Setup`**. 2. Connect your phone — a captive portal opens automatically (or go to `192.168.4.1`). 3. Select the venue WiFi and enter the password. 4. Set the **Upload URL** to `http://:3000/upload`. 5. Adjust contrast/heat to taste. **Save & Reboot.** The portal times out after 3 minutes. If it closes before you save, the camera boots in offline mode (printing still works, upload disabled). --- ## Settings Page After first boot the settings page is always reachable at: ``` http://partycam.local ``` (or the camera's IP address on port 80). Use it to adjust contrast, brightness, flip/mirror, heat density, and the upload URL. --- ## Gallery ``` http://:3000/gallery ``` Open from any device on the same network. The browser will prompt for the gallery password. New photos appear automatically — the page polls every 5 seconds. --- ## Customisation | What | Where | | :--- | :--- | | Pin assignments | `include/config.h` | | Printer baud rate | `include/config.h` → `BAUD_RATE` | | Default camera settings | `include/settings_service.h` → `AppSettings` struct defaults | | Gallery password | `compose.yml` or `.env` | | Capture resolution | `src/camera_service.cpp` → `config.frame_size` (update `IMAGE_WIDTH`/`IMAGE_HEIGHT` in `server/src/main.rs` to match) |