Commercial smart doorbells do one thing well and charge a subscription for the privilege: they tell you someone's at the door and show you who. This project builds the same core experience -- press the button, get a phone notification with a photo attached, in under two seconds -- on an ESP32-CAM, with no subscription, no cloud storage fee, and full control over where the photos actually end up. It's not trying to replicate every feature of a commercial unit (no two-way audio here, no professional monitoring), but for the actual "someone's at my door and I want to see who before I answer" use case, it covers the whole job.
Hardware Needed
Components
6 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 Button
Unlike a lot of ESP32-CAM projects fighting over pins already claimed by the camera or SD card interface, a single doorbell button has an easy time of it -- any free GPIO with internal pull-up support works:
| Component | ESP32-CAM Pin | Notes |
|---|---|---|
| Button (one leg) | GPIO 3 | Free on this board with no camera or SD conflict |
| Button (other leg) | GND | Completes the circuit when pressed |
| Buzzer + (optional) | GPIO 12 | Only if adding an audible chime at the door |
Using INPUT_PULLUP means no external resistor is needed -- the internal pull-up holds the pin HIGH until the button press connects it to GND, pulling it LOW. That's the same pattern used in the Photo Capture & microSD Storage guide, and it's the standard, reliable way to wire a simple momentary button on this board.
The Code
This builds on the Telegram alert pattern from the ESP32-CAM Face Detection Security Camera project, but triggers on a button press instead of a face detection event -- a more deliberate, lower-false-positive-rate signal than motion or detection alone, since a doorbell button only fires when someone specifically chose to press it.
The exact Telegram photo-sending call varies slightly between library versions -- sendPhotoByBinary is one common signature, though some versions of UniversalTelegramBot expect a slightly different callback structure. Worth checking your installed library version's examples if the exact call above doesn't compile cleanly; the underlying pattern (capture, then send both a text alert and the binary photo) stays the same regardless.
Debounce Time Longer Than a Motion Sensor
The debounce window here is deliberately longer than the 300ms used for a general-purpose button in the photo capture guide -- 500ms. A doorbell button gets pressed by people who aren't thinking about debounce logic at all, sometimes pressed twice in quick succession out of impatience or uncertainty whether the first press registered. A slightly longer debounce window absorbs that "did it work? let me press again" double-tap as one single doorbell ring instead of two separate Telegram photos and alerts a few hundred milliseconds apart.
Adding a Local Chime
A phone notification is the primary alert, but it's not instant if the phone is in another room on silent, or if whoever's home doesn't have the Telegram app open. A small piezo buzzer wired to a spare GPIO gives an immediate audible chime at the door itself, independent of anyone's phone:
A piezo buzzer through tone() produces a thin, unmistakably "electronic doorbell" sound rather than anything resembling a traditional chime -- perfectly functional as an alert, just worth setting expectations that it won't sound like a Nest or Ring chime out of the box. For something closer to a traditional doorbell tone, a small speaker driven through a simple amplifier and a short recorded chime clip is possible but a meaningfully bigger project than this guide covers.
Powering the Doorbell
Most homes with an existing wired doorbell already have a transformer nearby, typically stepping mains voltage down to 16-24V AC for the traditional mechanical or electronic chime. That's not directly usable for the ESP32-CAM without a proper AC-to-5V-DC converter in between -- don't wire the board directly to that transformer output, since it's both the wrong voltage and the wrong current type (AC, not DC) for the board's 5V input.
A dedicated 5V DC wall adapter, run alongside or instead of the existing doorbell wiring and terminating at the ESP32-CAM specifically, is the straightforward path here. If reusing the existing doorbell transformer is genuinely important -- avoiding a second visible power cable, for instance -- a buck converter rated for the transformer's AC output, converting down to a clean 5V DC, is the correct component, not a plain resistor-based voltage divider, which doesn't handle AC-to-DC conversion at all.
Either approach lands at the same final requirement: a clean, stable 5V DC feed to the board, delivered continuously rather than in brief bursts. The camera and WiFi radio together draw enough current during an active capture-and-send cycle that a marginal or improvised power path -- an old phone charger rated for less than the board actually needs, for instance -- shows up as intermittent resets or failed Telegram sends right when the doorbell is actually being used, which is the worst possible moment for a reliability issue to surface.
⚠️ Warning
Never wire the ESP32-CAM's 5V pin directly to a doorbell transformer's AC output. It's the wrong voltage and the wrong current type, and will damage the board immediately. A proper AC-to-DC buck converter is required in between if reusing existing doorbell wiring.
Weatherproofing the Button and Enclosure
The button itself needs to be genuinely weatherproof, not just the enclosure around the board -- it's the one component that has to remain physically exposed and pressable from outside. Doorbell-specific buttons are built for exactly this, with a sealed switch mechanism rated for outdoor exposure; a generic panel-mount button not rated for weather resistance will corrode or stick within a season of exposure to rain.
The camera lens, similarly to the PIR camera project, benefits from a slightly recessed mounting position rather than flush with the enclosure's outer surface -- this reduces direct rain contact on the lens and keeps water from beading directly across the field of view during a capture.
Reducing False Alerts from Wind, Rain, or Package Deliveries
A button-triggered doorbell is inherently more resistant to false triggers than a motion-based one -- nothing fires unless someone physically presses it, which rules out wind, passing cars, or animals entirely. The remaining false-trigger sources are narrower and mostly mechanical:
| Cause | Symptom | Fix |
|---|---|---|
| Button stuck in a partially-pressed position | Repeated or continuous triggers with no one present | Check for debris or corrosion in the switch mechanism; replace if a sealed button has failed |
| Loose wiring vibrating in wind against a bare contact | Occasional trigger during storms with no visitor | Secure wiring firmly, ideally within the enclosure rather than exposed |
| Water pooling across exposed contacts on a non-fully-sealed button | Triggers during or after heavy rain | Confirm the button is genuinely rated for outdoor/wet exposure, not just splash-resistant |
| A delivery person deliberately pressing it and leaving before you can respond | Not a false trigger, but a common source of "why didn't I see anyone" confusion | The photo attached to the alert resolves this -- check it before assuming the system missed something |
That last row is worth calling out specifically: a genuine press followed by the visitor leaving quickly (a package drop-off, for instance) isn't a system malfunction -- it's exactly what the photo attachment is for, confirming who was there even after they've gone.
Battery Backup for Power Continuity
Unlike a plain camera project where a brief power blip just means a missed frame, a doorbell that's down during a power outage is down at exactly the wrong moment -- someone's at the door with no way to know it. A small UPS-style battery backup on the 5V rail, the same pattern covered in the Face Detection Door Lock project, keeps the doorbell functional through brief outages without needing a full whole-home battery backup solution.
This matters less for a board relying entirely on the existing doorbell transformer, since mains power loss affects that the same way it affects a traditional wired doorbell -- but it's a cheap, worthwhile addition for anyone running the board off a dedicated adapter where a battery buffer is a simple inline addition.
Testing the Full Flow Before Mounting Permanently
A doorbell that fails silently is worse than one that never worked at all, since it creates false confidence -- worth deliberately testing the entire chain end to end before it's mounted somewhere hard to reach:
Steps
- 1Press the button while connected to Serial Monitor and confirm the debounced press is detected and logged
- 2Confirm the Telegram text alert arrives, then separately confirm the photo attachment arrives and actually opens correctly
- 3Press the button twice in quick succession deliberately and confirm only one alert fires, not two
- 4If a local buzzer is wired in, confirm it's audible from a normal distance, not just right next to the board
- 5Disconnect and reconnect power to simulate a brief outage, and confirm the board reconnects to WiFi and resumes working without manual intervention
- 6Mount temporarily first, test for a full day of normal use, and confirm no false triggers or missed presses before final permanent mounting
Common Mistakes
Wiring the board directly to an existing doorbell transformer's AC output. This is a fast way to damage the board -- a proper AC-to-DC converter is required in between, not a direct connection.
Using a non-weatherproof button for an outdoor installation. A generic momentary switch not rated for outdoor exposure corrodes or sticks within a season; a doorbell-specific sealed button is worth the extra cost.
Setting debounce too short for how people actually press doorbell buttons. A 300ms window tuned for a general-purpose trigger is often too short here -- 500ms accounts for the double-press people tend to do out of habit or uncertainty.
Relying on the phone notification alone with no local chime. A phone on silent in another room means the notification arrives, unread, well after whoever's at the door has given up and left.
Mounting the camera lens flush with the enclosure surface outdoors. Rain beading directly across the lens distorts or obscures captures until it evaporates or is wiped clear -- a slightly recessed lens position avoids most of this.
Troubleshooting
| Symptom | Likely Cause | Fix |
|---|---|---|
| Button press does nothing | Debounce logic not reached, or wiring issue | Verify with Serial.println() that digitalRead() actually changes on press; recheck GND connection |
| Notification arrives with no photo attached | Telegram library's photo-sending call failed silently | Check Serial output for errors; verify the exact method signature matches your installed library version |
| Double notifications on a single press | Debounce window too short | Increase DEBOUNCE_MS closer to 500-800ms |
| Board resets when button is pressed | Electrical noise or a poor ground connection at the button | Check for a solid, dedicated ground wire to the button rather than a shared or loose connection |
| Buzzer makes no sound | Wrong pin, or tone() not supported on the chosen GPIO | Confirm BUZZER_PIN is a GPIO that supports PWM/tone output |
Frequently Asked Questions
Can this integrate with a smart home system instead of, or alongside, Telegram? Yes -- the same button-press trigger can call a Home Assistant webhook or MQTT publish instead of, or in addition to, the Telegram alert, letting it appear as a proper doorbell entity in an existing smart home dashboard rather than only as a chat notification.
Will this work if the house doesn't have existing doorbell wiring? Yes -- a dedicated 5V adapter run to the mounting location works independently of any existing wiring; the transformer-reuse approach above is purely an option for avoiding a second visible cable, not a requirement.
How is this different from the Telegram Camera Bot project? The Telegram Camera Bot is pull-based -- you request a photo whenever you want one. This doorbell is push-based -- it sends a photo automatically the moment someone presses the button, with no request needed on your end.
Can I add two-way audio like a commercial doorbell? Not with this hardware alone -- the ESP32-CAM has no microphone or speaker beyond the simple buzzer covered here. Real two-way audio would need additional audio hardware (an I2S microphone and amplifier) and is a substantially larger project than this guide covers.
What happens if WiFi is down when someone presses the button? The photo capture and local buzzer chime still work independently of WiFi, but the Telegram alert can't send until connectivity is restored -- worth deciding whether to buffer and retry the send, or simply accept a missed remote notification during an outage, depending on how critical remote alerting is for your specific use case.
Can the same board handle both doorbell duty and general security monitoring? It can, but doing both well on one board asks a lot of a single-core-equivalent workload -- a dedicated board for the doorbell specifically, kept simple and reliable, tends to work better in practice than one board juggling multiple triggers and alert types.
Where to Go Next
For a version that identifies who's at the door rather than just alerting that someone is, see the ESP32-CAM Face Detection Door Lock project, which pairs detection with an actuated lock. For the underlying Telegram integration pattern used here, the ESP32-CAM Telegram Camera Bot covers that in more depth.
