# ESP32-CAM Point & Shoot — Build Guide

> A DIY digital camera with a physical shutter, SD card storage and a Wi-Fi web gallery, built on the AI-Thinker ESP32-CAM with an OV3660 sensor.

A DIY digital camera with a physical shutter, SD card storage and a Wi-Fi web gallery — built on the
AI-Thinker ESP32-CAM with the OV3660 sensor.

**OV3660 · 3 MP** · SD card · Wi-Fi gallery · Arduino IDE · ~200 Kč total cost

## 00 — Bill of materials

| Qty | Part | Note |
| --- | --- | --- |
| 1× | AI-Thinker ESP32-CAM + OV3660 + baseboard | your module |
| 1× | MicroSD card (Class 10, FAT32 formatted) | 8–32 GB recommended |
| 1× | Momentary push button (6 mm tactile switch) | shutter button |
| 1× | Li-Po battery 3.7 V, 1000–2000 mAh | or a USB power bank |
| 1× | TP4056 Li-Po charger module (with protection) | for battery charging |
| 1× | MT3608 boost converter (5 V output) | if using the Li-Po directly |
| 1× | SPDT slide switch | power on/off |
| — | Jumper wires, heat-shrink, small proto board | |

## 01 — Hardware wiring

The AI-Thinker baseboard already includes the USB-to-serial chip for programming. For the camera build,
you only need to wire the shutter button and the power circuit.

> **Important:** the ESP32-CAM uses GPIO pins for the SD card in 1-bit MMC mode. GPIO13 is free in this
> mode and is used for the shutter button. Do NOT connect anything else to GPIO4 (flash LED) or the SD
> card pins while the camera is running.

### Shutter button

| ESP32-CAM pin | Component | Notes |
| --- | --- | --- |
| GPIO13 | Button pin 1 | `INPUT_PULLUP` — button pulls to GND |
| GND | Button pin 2 | Active LOW — no resistor needed |

### Power circuit

| Module | From | To | Notes |
| --- | --- | --- | --- |
| Slide switch | Li-Po + | TP4056 BAT+ | Main power switch |
| TP4056 | BAT+ / BAT− | MT3608 IN+ / IN− | Charge protection |
| MT3608 | OUT+ | Baseboard 5 V | Boost to 5 V, adjust the trimmer |
| GND common | All GNDs | Baseboard GND | Star topology preferred |

> **Simplest power option:** if you want to skip the battery circuit for now, power the baseboard via its
> micro-USB port from a small USB power bank. This lets you test everything immediately.

### SD card

The microSD card slot is built into the ESP32-CAM module. Format your card as **FAT32** and insert it
before powering on. The firmware automatically creates a `/photos` folder.

## 02 — Firmware setup

### Arduino IDE configuration

1. Install **Arduino IDE 2.x** from arduino.cc.
2. Add the ESP32 board package URL in *File → Preferences → Additional Boards Manager URLs*:

   ```text
   https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
   ```

3. Go to *Tools → Board → Boards Manager*, search for **esp32** by Espressif and install version **2.x**.
4. Select the board: **AI Thinker ESP32-CAM**.
5. Set the partition scheme: **Huge APP (3MB No OTA/1MB SPIFFS)**.
6. Set PSRAM: **Enabled**.

### Edit the firmware

Open `esp32cam_camera.ino` and update lines 17–18 with your Wi-Fi credentials:

```cpp
const char* WIFI_SSID     = "YourNetworkName";
const char* WIFI_PASSWORD = "YourPassword";
```

### Upload / flashing

> **Before uploading:** the baseboard has an IO0 button for programming mode. Hold IO0 while pressing
> RESET (or power-cycling) to enter bootloader mode, then click Upload in the Arduino IDE.

1. Connect the baseboard to your computer via USB (it uses the onboard CH340/CP2102 chip).
2. Select the correct COM/serial port in the Arduino IDE.
3. Hold the **IO0** button on the baseboard.
4. Press **RESET** once (still holding IO0).
5. Release IO0, then click **Upload ↑** in the Arduino IDE.
6. After the upload completes, press RESET again to run.

### Verify it works

1. Open the Serial Monitor at **115200 baud**.
2. You should see: camera init OK → SD card OK → Wi-Fi IP address.
3. Open a browser and navigate to the IP address shown.
4. The web gallery UI should load immediately.

## 03 — Web gallery

The web interface is served directly from the ESP32. Connect any device on your local network to:

```text
http://<ESP32-IP-address>/
```

Available endpoints:

| URL | Method | Description |
| --- | --- | --- |
| `/` | GET | Web gallery UI |
| `/capture` | GET | Trigger a photo, returns JSON |
| `/list` | GET | JSON array of all photo filenames |
| `/photo?name=IMG_1.jpg` | GET | View a photo inline |
| `/photo?name=IMG_1.jpg&dl=1` | GET | Download a photo |

## 04 — OV3660 tuning

The OV3660 is a 3 MP sensor (better than the common OV2640). These settings in the firmware can be adjusted:

```cpp
sensor_t* s = esp_camera_sensor_get();
s->set_vflip(s, 1);        // 1 = flip vertically (OV3660 default mount)
s->set_hmirror(s, 0);      // 1 = mirror horizontally
s->set_brightness(s, 1);   // -2 to +2
s->set_saturation(s, 0);   // -2 to +2
s->set_contrast(s, 0);     // -2 to +2
s->set_whitebal(s, 1);     // auto white balance
s->set_awb_gain(s, 1);     // AWB gain
s->set_aec2(s, 1);         // auto exposure advanced
s->set_ae_level(s, 0);     // -2 to +2 exposure bias
```

### Resolution options

| Constant | Resolution | Use case |
| --- | --- | --- |
| `FRAMESIZE_UXGA` | 1600×1200 | Best quality (default) |
| `FRAMESIZE_SXGA` | 1280×1024 | Good balance |
| `FRAMESIZE_XGA` | 1024×768 | Faster capture |
| `FRAMESIZE_VGA` | 640×480 | Fastest, small files |

## 05 — Enclosure ideas

A few approaches for housing the build:

### Option A — 3D-printed body

Search Printables or Thingiverse for **"ESP32-CAM case"**. Many designs exist for the AI-Thinker module.
Add a custom top panel with a hole for the OV3660 lens, a slot for the SD card and a recessed shutter button.

### Option B — Altoids tin / project box

A 100 × 60 mm ABS project box from TME/GM Electronic fits the module and a small Li-Po. Drill a lens hole
(the OV3660 needs a ~10 mm cutout) and mount the button on top.

### Option C — Compact USB power bank

Some ultra-slim power banks (Xiaomi Slim 5000) are barely larger than the ESP32-CAM itself. Tape the module
to the back, run a short USB cable and you have instant power without any soldering.

> **Key dimensions:** AI-Thinker ESP32-CAM PCB: 40 × 27 mm. The OV3660 camera module protrudes ~15 mm above
> the PCB. The baseboard adds ~5 mm to the bottom.

## 06 — Troubleshooting

| Symptom | Likely cause | Fix |
| --- | --- | --- |
| Camera init failed 0x105 | Camera not detected | Check the ribbon cable is seated and power is adequate (≥ 500 mA) |
| SD card mount failed | Wrong format or bad card | Reformat as FAT32, try another card |
| Image upside-down | OV3660 mounting | Toggle `set_vflip(s, 0)` or `1` |
| Wi-Fi not connecting | Wrong credentials or range | Check SSID/password, move closer to the router |
| Brownout reset on capture | Insufficient current | Use a quality USB cable and a ≥ 1 A supply |
| Photo saved but 0 bytes | Frame buffer error | Add `delay(500)` before the first capture in `setup()` |
| Button fires multiple times | Bounce | Increase `DEBOUNCE_MS` to 500 |

---

The complete Arduino sketch, `esp32cam_camera.ino`, sits next to the original guide in my portfolio
repository (`blog-posts/pointandshoot-cam/esp32cam_camera.ino`). <!-- TODO(content): publish the sketch (e.g. on GitHub) and link it here. -->
