Introduction: Smart Phone (WiFi) Controlled Garage Door Opener With ESP8266

About: IoT - Internet of Things. Iota - small thing. Thingamajig - An object whose name can't be recalled. Iotamajig - A little unnamed internet connected gizmo!

You can control anything with your phone nowadays. And it's never been easier for DIYers to make their own home automation components. Not long ago, you had to shop online for "smart home" gizmos, but now even the home improvement stores have a pretty decent selection in stock. And they aren't cheap.

While some of these gadgets are pretty sophisticated, a LOT of them do one simple thing: switch a device on or off. That's all a garage door opener does - the wired button you likely have next to the door is a simple momentary switch.

In this Instructable, we're going to recreate that momentary switch, and with ESP module, make it web enabled. With the addition of a magnetic door sensor, we get the added benefit of knowing whether the door is open or closed. For the price of around $10, you can control and check the status of your garage door from anywhere!

Here's my disclaimer: THIS IS ONLY AS SECURE AS YOUR WIFI NETWORK. You are fully responsible for anything that happens to your garage if you use this prototype. This door opener can only be accessed by people on your home network. If you share your internet with other people, they will potentially be able to access your door.

Step 1: Gather Your Parts

To prototype it, you'll need:

To do a full build, you'll also want:

Step 2: Upload Your Code

With the FTDI upload board, load the following code to the ESP8266. You'll need to change the Router SSID/password variables, but that should be it. Before you upload the code, open the serial monitor in the Arduino IDE. Once the code uploads, it will write the module's IP address to serial - you'll want to make note of that.

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>

const char* ssid = "YourRouterSSID";
const char* password = "YourRouterPassword";

ESP8266WebServer server(80);

int switchPin = 0;
int switchStateCur;
int relayPin = 2;

int WiFiCon() {
    // Check if we have a WiFi connection, if we don't, connect.
  int xCnt = 0;

  if (WiFi.status() != WL_CONNECTED){

        Serial.println();
        Serial.println();
        Serial.print("Connecting to ");
        Serial.println(ssid);

        WiFi.mode(WIFI_STA);
        
        WiFi.begin(ssid, password);
        
        while (WiFi.status() != WL_CONNECTED  && xCnt < 50) {
          delay(500);
          Serial.print(".");
          xCnt ++;
        }

        if (WiFi.status() != WL_CONNECTED){
          Serial.println("WiFiCon=0");
          return 0; //never connected
        } else {
          Serial.println("WiFiCon=1");
          Serial.println("");
          Serial.println("WiFi connected");  
          Serial.println("IP address: ");
          Serial.println(WiFi.localIP());
          return 1; //1 is initial connection
        }

  } else {
    Serial.println("WiFiCon=2");
    return 2; //2 is already connected
  
  }
}

String htmlServe(int doorAction) {
  String htmStr;

      if (switchStateCur==1 && doorAction ==1){
        digitalWrite(relayPin, 0);
        delay(400);
        digitalWrite(relayPin, 1);
      } else if (switchStateCur==0 && doorAction ==0){
        digitalWrite(relayPin, 0);
        delay(400);
        digitalWrite(relayPin, 1);
      }

  htmStr += "<html>\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, maximum-scale=1.0,\">\n";
  htmStr += "<meta http-equiv=\"refresh\" content=\"5; URL=/sdoor\"> \n";
  htmStr += "<body>\n<center>\n<h1>\n";

      if (switchStateCur==1){
        htmStr += "Your Door is Open";
      } else {
        htmStr += "The Door is Closed";
      }
  
  htmStr +="</h1>\n<br><a href=\"/";
  
      if (switchStateCur==0){
        htmStr += "odoor";
      } else {
        htmStr += "cdoor";
      }
      
  htmStr += "\">\n<button>\n";
  
      if (switchStateCur==0){
        htmStr += "Open Door";
      } else {
        htmStr += "Close Door";
      }
  htmStr += "</button></a>\n";

  htmStr += "<br><br><br><a href=\"/sdoor\"><button>Recheck</button></a>";
  
  htmStr += "</center>\n</body>\n</html>\n";

  return htmStr;
  
}

void setup(){

  pinMode(switchPin, INPUT);
  pinMode(relayPin, OUTPUT);
  digitalWrite(relayPin, HIGH);
  Serial.begin(115200);

  WiFiCon();

   server.on("/odoor", [](){
      server.send(200, "text/html", htmlServe(0));
   });

   server.on("/cdoor", [](){
      server.send(200, "text/html", htmlServe(1));
   });

   server.on("/sdoor", [](){
      server.send(200, "text/html", htmlServe(2));
   });

  server.begin();

}

void loop(){

  switchStateCur = digitalRead(switchPin);
  
  server.handleClient();

  delay(1000);
}

Step 3: Notes on the Code

This is a BASIC garage door opener. You can get WAY fancier than what I've built here, and I encourage you to do so.

This code leverages some ESP building blocks that I have covered before. If you want more detail, or a more simplified explanation of the component code, check out these Instructables:

In this case, we amped up our web server code to include checking some variables and changing the message we display based on them (is the door open or closed), but the basic outline is still followed.

One line of HTML I added here was:

  htmStr += "<meta http-equiv=\"refresh\" content=\"5; URL=/sdoor\"> \n";

When this string loads in the user's browser (your phone), it tells it to automatically refresh the screen every 5 seconds. AND it tells it to refresh it to "/sdoor". You'll notice that the action buttons on the webform call the URLs "odoor" and "cdoor" (open and close) - we don't want to refresh to those and re-initiate the action - so we go to "sdoor" (s for status) which takes no action on it's own.

My garage door takes about ten seconds to open or close. The point of this refresh is to update the browser with the current status of the door without the user having to manually refresh the page to check. You can change the 5 seconds to whatever suits your door best.

Step 4: Build Your Prototype Board

Build out your breadboard.If you are using a breadboard power module, you can simplify this a bit, but the layout shown here is what will go into your final build.

You could also directly build this to the proto-board, though my recommendation is to breadboard it first.

Once the circuit is built plug your ESP in and fire it up. In a web browser, go to the sdoor "page" on the IP of the ESP. If the IP you got from the serial monitor was 192.168.0.153, then you need to enter this in the address bar:

http://192.168.0.153/sdoor

You should see a very simple page that tells the status of the door, and an action button to open or close it.

Hold the magnet near the reed switch, and when the browser refreshes, you should see the status change.

Hit the action button in the browser to open or close the door - you should hear a short click as the relay momentarily triggers.

If you aren't getting these results, check your wiring and your code for issues.

Step 5: Final Build Out

Transfer your circuit from the breadboard to the proto board. I prefer proto board that has the connected strips. You can use my picture as a guideline, but any way you set up is fine. If you use board with connected strips, you need to break the strips between the two rows of the 2/4 female header that the ESP will sit in. A utility knife works fine, though I use a little cut off wheel on a small rotary tool.

I also use the same cutoff wheel to slice little slits in the board for the barrel jack to sit in, since it has wide legs, not pins.

Once your soldering is done, and BEFORE you plug the ESP in, use a multi-tester to check your connections. If they check, plug power in, and test the voltage going across various point, especially making sure that the ESP is only getting 3.3 V.

Now you can plug the ESP in, and repower it to test it out like we did in the breadboard phase.

I'll also use my rotary tool to make cutouts in the project box. Hot glue the proto board and relay to the bottom. Make some marks on the enclosure for where the plug goes in and the wires need to pass through, then use the cutoff wheel to cut them out.

Step 6: Installation

To install it, you need to find a place where the door sensor can reach the door, where you have access to an outlet, AND where your ESP can get a WiFi connection.

The wired part of the sensor goes on the door frame. The magnet part goes on the door. Go ahead and laugh as you think about people setting it up the other way around.

You will need some type of low voltage DC rated two-wire wire to connect the module to the garage door opener. I used thermostat wire, because that's what I had laying around - I needed about 15 feet. On the garage door opener, you should see where the two wires from the manual button connect - you are connecting to these same terminals.

Connect the other end to our opener module's relay - one to the common pole, the other to the NO (normally open) pole.

TEST IT OUT! If everything works, staple the wiring down to pretty it up, use some double-sided tape to stick the project box to the wall, and you are DONE!

Step 7: Access From Anywhere

As it stands, our opener is only accessible from clients connected to your home router. I won't cover here the exact steps to open it up to full access from outside your network here - as that varies greatly depending on your router.

I will give you two suggestions though to help you further:

1. If you are familiar with port forwarding, it is easy to add a rule in most routers to funnel certain outside calls from the internet to specific devices. Check your router's manual on how to manage port forwarding rules.

2. We did NOT set a static IP on our ESP. Potentially, it could get a different address if it reconnects. We could add code to the ESP to have it tell the router what address it wants. Instead, I prefer to let the router manage this. Most routers allow manual setting of IP addresses for certain clients, usually in the DHCP Server settings. Again, check your router's manual for instructions.

I hope you've enjoyed this Instructable!