Build an ESP32 Smart Garage Door Controller with Position Sensing and Safety Interlocks
- ESP32 Dev Board (WROOM-32)
- 5V Relay Module (optically isolated, for triggering the opener's control circuit)
- Magnetic Reed Switch Sensors (2x, open and closed position)
- Time-of-Flight Distance Sensor (for mid-travel position, optional)
- 5V USB Power Supply
- Project Enclosure (small, for mounting near the opener)
- 22AWG Hookup Wire Spool Set
- Terminal Block Connectors
This site's shop ventilation and dust collection projects show ESP32 relays automating shop machines directly, but a garage door opener is one piece of equipment in most shops and homes that's worth treating with more caution than a dust gate or a fan — it's a heavy, motor-driven object that can injure someone or something if it's commanded to move without the right safety checks first. This project adds WiFi control and real position feedback to an existing garage door opener without replacing or modifying the opener itself, and treats the safety interlocks as the actual point of the build, not an afterthought bolted on at the end.
Tapping the Opener's Control Circuit, Not Rewiring It
Virtually every garage door opener built in the last few decades has a low-voltage (typically 24V DC) two-wire terminal on the motor unit meant for a wired wall button — momentarily shorting those two terminals together is exactly what pressing the wall button does. An optically isolated relay module wired across those same two terminals lets the ESP32 trigger the door the same way, without touching the opener's high-voltage side, its radio receiver, or any of its existing safety electronics (including the photo-eye beam sensors near the floor, which must stay fully intact and functional — never bypass or disconnect those). This project only ever adds a parallel momentary-contact trigger; it never replaces or overrides anything the opener manufacturer already built in.
Position Sensing: Why Two Reed Switches Beat One
SensorPlacementWhat it tells you Reed switch #1Door fully closed positionConfirms the door is actually seated closed, not just "probably closed because we told it to close a while ago" Reed switch #2Door fully open positionConfirms full open, distinguishing a fully open door from one stopped partway through a cycle Optional: time-of-flight sensorAimed at the door's travel path from a fixed pointReports approximate position while in motion, useful for catching a door that stalled partway rather than just open/closedRelying on a single sensor (or worse, no sensor at all, just tracking elapsed time since the last trigger) can't tell the difference between "closed" and "stopped halfway because something obstructed it" — exactly the failure mode you most need to know about. Two reed switches at the extremes, cheaply added with a magnet on the door's track and the switch body mounted to the fixed rail, remove that ambiguity for a few dollars of hardware.
The Safety Interlocks That Actually Matter
- Never issue a close command on a timer or an unattended automation without a camera or sensor confirmation of a clear opening. "Close the garage at 10pm every night" sounds convenient until a car's still halfway in, a kid's bike is in the doorway, or a pet is in the path — this is the single most important rule in this entire project, worth repeating here in that it's the one corner people are most tempted to cut for convenience.
- Treat the existing photo-eye safety beam as the ground truth it already is — the opener's own electronics already refuse to close if that beam is broken, and this project doesn't need to duplicate that logic, only avoid interfering with it.
- Add a software cooldown between consecutive trigger commands (a few seconds minimum) so a flaky network connection or an automation bug can't rapid-fire the relay and send conflicting open/close signals in quick succession.
- Expose door state and controls locally over MQTT rather than solely through a cloud service, so a remote open/close command only ever works when you can also see current, real position state alongside it — never issue a blind command without a confirmed current state first.
- Physical confirmation beats inferred state. If the ESP32 loses WiFi mid-cycle and can't confirm the reed switch state afterward, have it report "unknown" rather than assuming the last commanded state succeeded.
Wiring Overview
ComponentESP32 pin Relay module (trigger)GPIO23 Closed-position reed switchGPIO22 (internal pull-up, switch to GND) Open-position reed switchGPIO21 (internal pull-up, switch to GND) Optional ToF sensorI2C (GPIO21/GPIO22 shared bus, or dedicated pins if also using both reed switches)Integrating with Home Assistant
Publish door state (closed/open/moving/unknown) and accept open/close commands over MQTT using the standard Home Assistant cover entity schema, which gets you a proper garage door tile in the dashboard — current state, a single tap to trigger, and the ability to layer in automations (a notification if the door's been open more than 20 minutes, for instance) without any of that logic living on the ESP32 itself. Keep the ESP32's own firmware limited to reading sensors, driving the relay, and reporting state reliably; let Home Assistant own anything resembling a schedule or a conditional automation, where it's far easier to review, adjust, and audit than buried in embedded C++.
Testing Before Relying on It
Verify both reed switches independently (manually move the door and confirm each switch reports correctly at its extreme) before wiring in the relay trigger, and test the relay trigger itself with the door already in a safe, clear position and someone watching, not as a blind first command sent from across town. A garage door opener is one of the few home automation targets where "test thoroughly before trusting it" is not an exaggeration — the failure modes involve a heavy moving object, not just a light that doesn't turn on.
This project is a good example of where the electronics are genuinely simple — a relay and two reed switches barely qualify as a weekend project on their own — but the judgment about when and how to actually trigger that relay is where the real engineering effort belongs. Build the sensing and the interlocks first, be deliberate about ever automating a close command without a way to confirm the opening is clear, and the result is a garage door that's genuinely more convenient without becoming a hazard it wasn't before.