A few months ago, someone tried the door handle on my workshop shed at 2am. Nothing got stolen, but it rattled me enough that I finally built the security camera I'd been putting off for a year. I didn't buy some overpriced subscription-based camera brand — I built one myself with an ESP32-CAM module, a PIR motion sensor, and about $12 in parts. It's been sitting above my shed door ever since, and honestly, it works better than I expected for something this cheap.
If you've been wanting a low-cost, no-subscription camera for a shed, garage, front porch, or workshop, this guide will get you there.
Why the ESP32-CAM Specifically?
There are a lot of ways to build a DIY camera, but the ESP32-CAM keeps winning for a few practical reasons: it's incredibly cheap, it has Wi-Fi built in so you don't need extra networking hardware, and it comes with a small 2MP camera sensor that's more than good enough for monitoring a door or driveway — you're not trying to read license plates from 50 meters away here.
The trade-off is that it's not plug-and-play like a commercial camera. You'll need to flash some firmware and do a bit of wiring. It's not hard, but it's also not "open the box and it just works." If you're fine with that trade-off, keep reading.
What You'll Need
- 1x ESP32-CAM module (with the OV2640 camera)
- 1x FTDI programmer (or any USB-to-serial adapter) — the ESP32-CAM doesn't have a built-in USB port, so you need this to upload code
- 1x PIR motion sensor (HC-SR501 is the common cheap option)
- Jumper wires
- A 5V power source (a phone charger and micro USB cable works fine)
- Optional: a small weatherproof enclosure if you're mounting it outdoors
Step 1: Wiring the FTDI Programmer
This part trips people up more than anything else in the whole project, so pay attention here.
- ESP32-CAM 5V → FTDI VCC (5V, not 3.3V — this is a common mistake)
- ESP32-CAM GND → FTDI GND
- ESP32-CAM U0R (RX) → FTDI TX
- ESP32-CAM U0T (TX) → FTDI RX
- ESP32-CAM IO0 → GND (only during upload — this puts the board into flashing mode)
That last step is the one everyone forgets. If you don't connect IO0 to GND before uploading, the code upload will fail every single time and you'll be left wondering what's wrong with your board. Nothing is wrong with your board — you just skipped this step.
Step 2: Uploading the Firmware
In the Arduino IDE, select AI Thinker ESP32-CAM as your board, then open the built-in example: File > Examples > ESP32 > Camera > CameraWebServer. Enter your Wi-Fi SSID and password in the code, and make sure the camera model is uncommented correctly for the AI Thinker board (it's usually the top option, but double-check).
Upload the code. Once it finishes, disconnect the IO0-to-GND wire, press the reset button on the board, and open the Serial Monitor. You should see an IP address printed out — that's the address you'll type into your browser to view the live camera feed.
Step 3: Adding Motion Detection with a PIR Sensor
The camera on its own is nice, but constantly streaming video you're not watching isn't practical. This is where the PIR sensor comes in — it only wakes the camera up and triggers a photo or recording when it actually detects movement.
Wiring the PIR sensor:
- VCC → 5V
- GND → GND
- OUT → GPIO 13 (or any free GPIO pin on the board)
In your code, you'll want to check the PIR pin state in a loop, and when it goes HIGH (motion detected), trigger esp_camera_fb_get() to capture a frame and save it, either to the onboard SD card slot or send it over Wi-Fi to a server or messaging service.
A simplified version of the trigger logic looks like this:
#define PIR_PIN 13
void setup() {
pinMode(PIR_PIN, INPUT);
}
void loop() {
if (digitalRead(PIR_PIN) == HIGH) {
captureAndSavePhoto();
delay(10000); // avoid spamming multiple captures for the same event
}
}The 10-second delay after each capture matters more than you'd think. Without it, one person walking past will trigger a dozen near-identical photos in a row, and you'll end up ignoring the alerts entirely — which defeats the whole purpose.
Step 4: Viewing It Remotely
If you only need this on your home network, you're basically done — just open the IP address on your phone whenever you want to check the feed. If you want to check it from outside your home network, you have a couple of options: set up port forwarding on your router (works, but exposes your camera to the internet if not secured properly), or use a service like Home Assistant with remote access already configured, which is the safer route for most people.
I run mine through Home Assistant, mostly because I already had it set up for other sensors, and it means I don't have to think about port forwarding at all.
Common Problems (And How I Actually Fixed Them)
The upload keeps failing with a timeout error. Nine times out of ten, this is the IO0-to-GND wire either not connected or not making good contact. Double-check it, and try pressing the reset button right as the upload starts.
The camera image is really dark or grainy. The OV2640 sensor struggles in low light. If you're mounting this outdoors at night, you'll want an infrared LED board or a version of the ESP32-CAM with built-in IR LEDs.
The board keeps resetting randomly. This is almost always a power issue. The camera module draws more current than people expect, and a weak USB port or a cheap cable can cause brownouts. Use a solid 5V/1A (or higher) power supply.
PIR sensor triggers constantly, even with no one around. Give it a couple of minutes to warm up after powering on — PIR sensors are notoriously twitchy for the first 30-60 seconds. If it's still overly sensitive after that, adjust the sensitivity potentiometer on the sensor board itself.
Final Thoughts
This isn't going to replace a proper commercial security system if you need something bulletproof. But for a shed, a side gate, a garage, or just peace of mind about who's walking up to your porch, it's genuinely solid — and there's something satisfying about knowing exactly how your security camera works instead of trusting a black box with a monthly subscription fee.
If you build one, mount it somewhere covered from direct rain even if the enclosure claims to be weatherproof. Mine's been running for months, but I'm not pushing my luck with a Moroccan summer downpour testing that seal.


