Project Overview
This build uses the ESP32-CAM's built-in face detection to trigger a servo-actuated door latch -- when the camera sees a face in frame, the latch releases for five seconds, then re-locks automatically. It's worth being upfront about what this is and isn't: it's face detection, not recognition, so it unlocks for any face in frame, not a specific person's. On its own, that makes it a poor fit for securing anything valuable. Paired with a PIN keypad as a second factor -- covered later in this guide -- it becomes a genuinely reasonable entry system for a workshop, a server closet, or a similar low-stakes door where "someone is standing there and they know the code" is an acceptable bar.
The live MJPEG stream stays active throughout, so you can watch the door camera from a browser at any time, and every unlock event gets logged over Serial with a timestamp for basic auditing.
How This Differs From a Real Access Control System
Commercial access control uses recognition (matching a face against a stored identity) or a hard credential like a fob, PIN, or key -- something that ties the unlock event to a specific, verifiable identity. This project uses detection, which only confirms a face is present. Anyone standing in frame triggers the same unlock a legitimate user would.
That's not a flaw in the build so much as a scope decision worth being clear-eyed about before installing it anywhere. Treat this as a convenience automation -- "the door unlocks when someone's clearly standing in front of it, so I don't fumble for a key with my hands full" -- rather than a security device, unless the keypad second-factor step later in this guide is included and actually enforced in the code.
How ESP32-CAM Face Detection Works
The Espressif camera library bundles a MTMN (MobileNet-based) face detection model that runs entirely on the ESP32's Xtensa dual-core CPU. It outputs bounding boxes for detected faces at roughly 5-8 FPS on VGA resolution. This is detection only -- not recognition -- meaning it triggers on any human face, not a specific person's face.
For a door lock use case this is still highly useful: you can combine it with a PIN pad to create a two-factor entry system (face present + correct PIN).
⚠️ Warning
The ESP32-CAM AI Thinker board does **NOT** have a USB port. You need a **FTDI USB-to-Serial adapter (3.3V)** to upload firmware. Connect FTDI GND→GND, TX→GPIO3(RX), RX→GPIO1(TX), and short GPIO0 to GND during upload to enter bootloader mode. Remove the GPIO0 jumper after uploading.
Components
10 itemsNeed these parts? Get this build sheet by email
Parts list with buy links, plus new builds as they're published. By subscribing you agree to our Privacy Policy. Unsubscribe anytime.
Wiring the Servo, LEDs, and Power
The camera pins are already committed by the AI-Thinker board's fixed pinout, which leaves a handful of GPIOs free for the lock hardware:
| Component | ESP32-CAM Pin | Notes |
|---|---|---|
| Servo signal | GPIO 13 | Needs a separate 5V supply for the servo -- don't power it off the board's 3.3V rail |
| Green LED (unlocked) | GPIO 14 | Through a 220 Ω resistor to GND |
| Red LED (locked) | GPIO 15 | Through a 220 Ω resistor to GND |
| Buzzer (optional) | GPIO 12 | Only if using audible feedback on unlock |
| Keypad rows/columns (optional) | GPIO 2, 4, 16, 17 + 2 more | Only if adding the two-factor keypad covered below |
The single most common wiring mistake on this build is powering the servo from the ESP32-CAM's onboard 3.3V regulator -- it's rated for the camera and WiFi radio, not a motor under load, and the resulting voltage sag causes random resets exactly when the door tries to unlock. Run the servo off its own 5V feed, sharing only a common ground with the ESP32-CAM.
How the Detection-to-Lock Logic Works
The flow is intentionally simple: each loop iteration grabs a frame, runs it through face_detect(), and checks whether any bounding boxes came back. A positive result calls unlockDoor(), which moves the servo to the open position, flips the status LEDs, holds for five seconds, then re-locks and resumes scanning.
That five-second hold is a deliberate design choice, not a technical limitation -- it's long enough for someone to push the door open after the face triggers the unlock, without leaving the latch open indefinitely while a face happens to linger in frame. Extending or shortening it is just a matter of adjusting the delay(5000) call in the code below.
Choosing Between a Servo Latch and a Solenoid Lock
The code above assumes an SG90 micro servo swinging a simple latch mechanism, which is the cheapest and easiest path for a first build -- but it's not the only option, and the right choice depends on the door itself:
| Servo latch (this guide) | 12V solenoid lock | |
|---|---|---|
| Cost | ~$3-5 | ~$10-15 plus a relay module |
| Holding force | Low -- fine for a light interior door or cabinet | Meaningfully higher, suited to an actual door |
| Power draw | Minimal, runs off the same 5V rail | Needs a separate 12V supply and a relay to switch it |
| Fail state | Fails locked (spring-loaded latch stays closed without signal) | Depends on solenoid type -- fail-safe or fail-secure variants exist |
| Best suited to | Cabinets, lightweight interior doors, drawers | Exterior doors, anything needing real holding force |
A solenoid swap only changes the output stage -- the servo's write(90)/write(0) calls get replaced with a relay digitalWrite(RELAY_PIN, HIGH/LOW), and everything upstream of that (the camera, detection logic, and timing) stays identical.
Adding a Keypad for Two-Factor Entry
Since face detection alone unlocks for anyone, pairing it with a 4x4 matrix keypad is the single most effective upgrade for anyone planning to use this on a door that actually matters. The logic changes from "unlock on any detected face" to "unlock only when a face is detected and a correct PIN is entered within a short window" -- both conditions have to be true, not either one alone.
In practice this means adding a Keypad library instance, a stored PIN (or hashed comparison, for anyone not comfortable with a plaintext PIN sitting in the sketch), and a short state machine: detection sets a "face present" flag with a few seconds' expiry, and the unlock call only fires if a correct PIN comes in from the keypad while that flag is still active. This also solves the "unlocks for literally anyone standing there" problem without needing to move to full face recognition -- it adds a credential requirement on top of the presence check instead.
Security Limitations and Why This Isn't a Production Lock
Worth stating plainly: this project, even with the keypad addition, is not equivalent to a commercial access control system, and shouldn't be treated as one for anything genuinely high-stakes. A few specific gaps:
- No tamper detection. Nothing here notices if the camera is covered, unplugged, or the enclosure is opened -- a determined attacker with physical access defeats it trivially.
- PIN stored in firmware. Unless deliberately hashed and compared rather than stored plaintext, anyone who can read the flash (which isn't hard with physical board access) can extract the PIN directly.
- No rate limiting on keypad entry. A brute-force PIN attempt isn't slowed down or locked out by anything in the code above -- that's a meaningful addition worth making before relying on the PIN as a real second factor.
- Single point of failure. If the ESP32-CAM crashes, loses power, or loses WiFi (for anyone gating unlock on a network call), the fallback behavior needs to be deliberately fail-secure, not accidentally fail-open.
None of this makes the project not worth building -- it makes it worth being honest about scope. This is a genuinely useful automation for a low-stakes door, and a genuinely bad substitute for a real lock on anything that actually needs to be secure.
Power and Failsafe Considerations
A door lock that depends on mains power has an obvious failure mode: a power outage leaves it either stuck locked (bad if it's a fire egress path) or stuck unlocked (bad for obvious reasons), depending entirely on which side the servo or solenoid defaults to with no signal. For the servo latch in this guide, the spring-loaded mechanism should default to locked with no power -- worth physically testing by unplugging the board and confirming the latch doesn't fall open on its own.
For anything beyond a hobby install, a small UPS or battery backup on the 5V rail keeps the system running through brief outages, and is a cheap addition relative to the cost of being locked out -- or worse, having the door fail open -- during a power blip.
Steps
- 1In Arduino IDE: File → Preferences → add esp32 board URL, then install via Boards Manager
- 2Select board: AI Thinker ESP32-CAM, set upload speed to 115200
- 3Connect FTDI: TX→GPIO3, RX→GPIO1, GND→GND, short GPIO0→GND before upload
- 4Upload sketch — remove GPIO0 jumper, press reset button on board
- 5Open Serial Monitor at 115200 baud — IP address prints after WiFi connects
- 6Open the stream URL in a browser to see the live camera feed
- 7Wave your hand in front of the camera — servo should actuate after face is detected
Troubleshooting Common Issues
Servo jitters or resets the board when triggered. Almost always a shared-power problem -- confirm the servo has its own 5V feed and only a common ground with the ESP32-CAM, not a shared 3.3V or 5V rail with the camera.
Detection works in the browser stream but the servo never fires. Check that the code path actually calls unlockDoor() on a positive detection -- it's easy to leave the stock example's detection running as display-only without wiring in the trigger, since the browser overlay and the actual servo call are two separate things.
False unlocks with no one in frame. Usually a lighting or reflection issue -- a mirror, framed photo, or high-contrast pattern in the background can occasionally trigger a false positive on the lightweight detector. Repositioning the camera or adjusting the background typically resolves it.
Latch doesn't fully release or catch. A mechanical fit issue more often than a code issue -- double-check the servo's throw angle actually clears the latch mechanism at both the 0 and 90 degree positions before assuming it's a wiring or firmware problem.
Door unlocks, then immediately re-locks before anyone can push it open. Increase the delay(5000) hold time in unlockDoor() -- five seconds is a starting point, not a fixed requirement, and a heavier door or a less rushed household may need eight to ten seconds instead.
Mounting and Enclosure Considerations
Where the camera physically sits matters more than most first-time builders expect. Mount it at roughly the height of an average adult's face, angled slightly downward rather than straight ahead -- a dead-level mount tends to catch foreheads and hairlines more than full faces as people approach at a normal walking pace, which measurably hurts detection rate right at the moment it matters most.
An enclosure is worth adding even for an indoor build, mainly to keep the servo linkage and wiring out of reach rather than for weatherproofing. A simple 3D-printed or off-the-shelf project box with a lens-sized cutout for the camera and a slot for the latch mechanism to pass through is enough -- just leave some airflow around the ESP32-S module itself, since a fully sealed box measurably raises operating temperature during continuous detection, as covered in the face detection guide linked below.
Reducing Power Draw with a PIR Pre-Trigger
Running face detection continuously keeps the ESP32-S busy scanning frames even during long stretches with nobody near the door, which is unnecessary work on a mains-powered install and genuinely wasteful on anything battery-backed. A cheap PIR motion sensor wired to a spare GPIO makes an effective gatekeeper: the main loop stays in a low-activity idle state, only starting the camera-and-detection routine once the PIR reports motion nearby.
This two-stage approach -- coarse PIR trigger, then fine-grained face detection -- mirrors how the PIR motion detection guide uses the same sensor for wake-from-sleep photo capture, and the two projects share enough wiring in common that combining them (PIR wakes the board, face detection confirms and unlocks) is a natural next build once both are working independently.
Where to Go Next
For more depth on the underlying detection model and its limitations, see the ESP32-CAM Face Detection guide. For wiring reference beyond what's covered here, the ESP32-CAM Pinout Guide covers every GPIO on the AI-Thinker board in detail.
