# General > IoT, IoE, and Maker Forum > Arduino Garage Door Opener

## dclamp

I have been working on several different types of Home Automation controllers using Arduino. One of them is a Garage Door controller. From my mobile phone I can open, close, or see the status of the garage door (see if its open or closed). In my garage I have an Arduino Uno with an Ethernet Shield attached to it. The garage door opener is connected to the Arduino via a SainSmart relay board. 

I discovered that the button that normally opens and closes the garage door was just a simple push button that briefly closes the circuit between the two wires running from the garage door opener. Using a Relay, I am able to simulate a button press electronically. I ran a wire pair from the connectors on the back of the garage door opener to a cabinet where the Arduino is located. I connected one wire to the common connector on the relay and the other to the normally open connector. Meaning the connection is always open until the Arduino tells the relay to close the circuit. 

Here is the Arduino (Mega Shown) with Ethernet Shield and Relay board

Here is the Web Interface from my iPhone. Garage -> Door is the button to open the garage door. 


The Relay Board has 4 relays (In picture, closest relay was broken and removed). I used digital outputs 2, 3, 5, 6 on the Arduino to control the relays. Output 0 + 1 is used for serial communication and output 4 is used for the SD card on the EthernetShield. Additionally, the relay board requires Ground and +5V. 

When I press the Garage Door button on the web interface, it sends a HTTP request to the arduino with a URL similar to http://myip:port/command. For example: http://192.168.1.204:84/flashoutput5 will quickly close and open relay 5, just enough time for the garage door to recognize it as a button press. The garage door then opens. 

Here is the code for the garage door opener with comments.

C Code:
/*
ARDUINOMATION RELAY CONTROL DEVICE
LAST UPDATED: 06/08/2014
*/
 #include <SPI.h>
#include <Ethernet.h>
 // VERSION NUMBER
float VersionNumber = 2.0;
 // DEVICE ID - MUST BE UNIQUE
char deviceID[] = "100001";
 // NETWORK SETTINGS
int port = 84;
char ipAddress[] = "192.168.1.241";
char macaddress[] = "0xDE:0xAD:0xBE:0xEF:0xFE:0xEE";
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xEE }; //physical mac address
byte ip[] = { 192, 168, 1, 241 }; // DEVICE IP ADDRESS
IPAddress controllerserver(192,168,1,204); // CONTROL SERVER IP ADDRESS
EthernetServer server(port); //CONTROL SERVER PORT
EthernetClient client;
 // CONTROL SERVER PARAMETERS
char updateurl1[] = "/projects/arduino/master_controller.php?command=checkin&deviceid=";
char updateurl2[] = "&ip=";
char updateurl3[] = "&mac=";
 // DIGITAL OUTPUTS 
String readString; 
int output1 = 2;
int output2 = 3;
int output3 = 5;
int output4 = 6;
int output5 = 7;
int output6 = 8;
int output7 = 9;
 // **************************** START CODE ****************************
 void setup(){
   pinMode(output1, OUTPUT);
  pinMode(output2, OUTPUT);
  pinMode(output3, OUTPUT);
  pinMode(output4, OUTPUT);
  pinMode(output5, OUTPUT);
  pinMode(output6, OUTPUT);
  pinMode(output7, OUTPUT);
  
  // ETHERNET CONNECTION
  Ethernet.begin(mac, ip); // , ip, gateway, subnet
  server.begin();
   //PRINT TO SERIAL 
  Serial.begin(9600); 
  Serial.println(" Device Controller Loading..."); // so I can keep track of what is loaded
  Serial.print("IP Address: ");
  Serial.print(Ethernet.localIP());
  Serial.print(":");
  Serial.println(port);
  
  // CONNECT TO CONTROL SERVER
  // Control server keeps track of all devices on the network
  if (client.connect(controllerserver, 8888)) {
    Serial.println("Connected to device server");
    
    Serial.println("Updating System");
    client.print("GET ");
    client.print(updateurl1); 
    client.print(deviceID);
    client.print(updateurl2);
    client.print(ipAddress);
    client.print(updateurl3);
    client.print(macaddress);
    client.println(" HTTP/1.0");
    client.println();
    client.stop();
    Serial.println("Server updated");
  } else {
    Serial.println("Connection to server failed.");
    
    
    client.stop();
    delay(1000);
  }
  
  // EVERYTHING IS LOADED - WAIT FOR REQUESTS
  Serial.println("Ready for requests...");
  Serial.println();
}
 void loop(){
  // Create a client connection
  EthernetClient client = server.available();
  if (client) {
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
         //read char by char HTTP request
        if (readString.length() < 100) {
           //store characters to string 
          readString += c; 
        } 
         //if HTTP request has ended
        if (c == '\n') {
           ///////////////
          Serial.println("String:");
          Serial.println(readString); //print to serial monitor for debuging 
           client.println("HTTP/1.1 200 OK"); //send new page
          client.println("Content-Type: text/html");
          client.println();
           client.println("<HTML>");
          client.println("<HEAD>");
          client.println("<TITLE>Garage Control</TITLE>");
          //client.println("<meta http-equiv="refresh" content="5">");
          client.println("</HEAD>");
          client.println("<BODY>");
           client.println("<H1>Garage Controller</H1>");
          
          
          // READ SENSOR 
          int sensor = digitalRead(8);
          
          //  PRINT STATUS OF SENSOR 
          if (sensor == HIGH) {
            client.println("Garage Open");
          } else {
            client.println("Garage Closed");
          }
          
          client.println("<br><br><a href='/?flashoutput5'>Open/Close Garage</a>");
          
          client.println("<br><br><a href='/'>Refresh</a>");
          
          //client.println(sensor);
          client.println("</BODY>");
          client.println("</HTML>");
 
          delay(1);
          //stopping client
          client.stop();
          
          ///////////////////// control arduino pin
          
          
          //******* OUTPUT 5 GARAGE *************
          //This one is Special for Garage. 
           if(readString.indexOf("flashoutput5") >0)
          {
             digitalWrite(output5, HIGH);
             delay(500);
             digitalWrite(output5, LOW);
             Serial.println("Output 5 Flashed");
          }          
          
          //******* OUTPUT 1 *************
          if(readString.indexOf("highoutput1") >0)//checks for on
          {
            
            digitalWrite(output1, HIGH);    
            Serial.println("Output1 On");
            
          }
          if(readString.indexOf("lowoutput1") >0)
          {
            
            digitalWrite(output1, LOW);
            Serial.println("Output1 Off");
          }
          
          //******* OUTPUT 2 *************
          if(readString.indexOf("highoutput2") >0)//checks for on
          {
            
            digitalWrite(output2, HIGH);    
            Serial.println("Output2 On");
            
          }
          if(readString.indexOf("lowoutput2") >0)
          {
            
            digitalWrite(output2, LOW);
            Serial.println("Output2 Off");
          }
          
          //******* OUTPUT 3 *************
          if(readString.indexOf("highoutput3") >0)//checks for on
          {
            
            digitalWrite(output3, HIGH);    
            Serial.println("Output3 On");
            
          }
          if(readString.indexOf("lowoutput3") >0)
          {
            
            digitalWrite(output3, LOW);
            Serial.println("Output3 Off");
          }
          
          //******* OUTPUT 4 *************
          if(readString.indexOf("highoutput4") >0)//checks for on
          {
            
            digitalWrite(output4, HIGH);    
            Serial.println("Output4 On");
            
          }
          if(readString.indexOf("lowoutput4") >0)
          {
            
            digitalWrite(output4, LOW);
            Serial.println("Output4 Off");
          }
          
          //******* OUTPUT 5 *************
          if(readString.indexOf("highoutput5") >0)//checks for on
          {
            
            digitalWrite(output5, HIGH);    
            Serial.println("Output5 On");
            
          }
          if(readString.indexOf("lowoutput5") >0)
          {
            
            digitalWrite(output5, LOW);
            Serial.println("Output5 Off");
          }
          
          //******* OUTPUT 6 *************
          if(readString.indexOf("highoutput6") >0)//checks for on
          {
            
            digitalWrite(output6, HIGH);    
            Serial.println("Output6 On");
            
          }
          if(readString.indexOf("lowoutput6") >0)
          {
            
            digitalWrite(output6, LOW);
            Serial.println("Output6 Off");
          }
          
          //******* OUTPUT 7 *************
          if(readString.indexOf("highoutput7") >0)//checks for on
          {
            
            digitalWrite(output7, HIGH);    
            Serial.println("Output7 On");
            
          }
          if(readString.indexOf("lowoutput7") >0)
          {
            
            digitalWrite(output7, LOW);
            Serial.println("Output7 Off");
          }
          
          Serial.println("--------------------------------------------------");
          //clearing string for next read
          readString="";
         }
      }
    }
  }
}


Here is what the serial console looks like when it is loaded. Notice that is says "Connection to server failed", thats because I do not have it connected to the network and it was not able to tell the Logic Server that its now online. 

Attachment 115163



*Edit:*
Here is part 2 of the project where I put the project in an enclosure.

----------


## dclamp

That is just a brief overview of what that code is really doing. While I do not have a fully functional home automation system, I have lots of parts that all work together with a single logic control point. I set up my arduinos to be "dumb": they only report sensors or do what the logic controller says. My Arduinos are not programmed to do any real thinking on their own. 

My logic is a PHP server with MySQL. If anyone wants a more detailed explanation of how my system works I can explain it. Its actually pretty detailed and elaborate.

----------


## dee-u

A more detailed explanation is more than welcome. :-)

----------


## Nightwalker83

Hang on! It's a Web Application how do you protect it from hacking? What I find impressive is that you managed to get .Net working on your iPhone.

----------


## dclamp

Like I said, each of the Arduino devices that I create are all "dumb" so they do not actually make any decisions. My system has the following different elements:

Arduino DevicesLogic ServerWeb Interface

My different Devices include:
Main Power Switch (Lights)Door SensorGarage Door ControllerInput Device (Button/Toggle)Alarm InputsMonitor (LCD Screen)

When I connect one of the devices to the network, it first contacts the Logic server to check in. Each device is given a unique mac address and a unique device ID. The logic server checks to see if the device is already registered with the system, if its not then its added as a new device with no logic associated. If its already registered, then its considered online.

I can then log into the Logic server and see a list of all the devices in my system that are checked in. For new devices I associate them with a room in the house and I name them. From there I can create logic for each device through the web portal depending on what type of device it is. For example, If I connect a new Button device and a Mains Power Switch, I can associate the button with the Switch. The sequence of events is as follows: Button Press -> Contacts logic server -> logic server processes what should happen -> toggles mains power switch. 

When I add new devices to the network, they are automatically added to the web interface for my phone. The one pictured above is an older version that just shows test items. 

All the devices that I have made so far are still prototypes on breadboards. I haven't been able to get around to making actual printed PCBs that are complete products. 

I got a lot of inspiration from Superhouse.TV on YouTube. He took Arduino home automation to the next level and remodeled his house around a structured wiring system with Arduino devices. He has a lot of fully developed models.

----------


## dclamp

> Hang on! It's a Web Application how do you protect it from hacking? What I find impressive is that you managed to get .Net working on your iPhone.


The Logic Server is in the private network protected by the firewall. The front end web interface is hosted on a domain outside of the home network required authentication. 

And I am not running .Net on my iPhone?

----------


## Nightwalker83

> And I am not running .Net on my iPhone?


I was thinking you needed to download files in-order for the browser to use the .Net code site but obviously I am incorrect there.

----------


## wossname

Sounds like you've put a lot of work into this.  Pretty cool stuff.  I guess you could also have done this without the internet-facing server and just connect direct to the arduino over WIFI behind your firewall.  That would provide a geographical constraint.  Unless you actually like opening your garage door from 4000 miles away of course, which might be fun.  :Smilie: 

Cool build.

----------


## dclamp

That was kind of the intent of having the sensor to see if the garage is opened or closed. Should be be away from home and notice you left the garage door open, you can close it.

----------


## dclamp

But Yeah I have put a lot of time Into it. I have worked on it piece by piece and it just keeps getting larger and more sophisticated as i continue to work on it.

----------


## wossname

I guess you could have a "dead drop" system too in case you find yourself unable to access your web front-end for some reason (some bad guy has hacked your LAN and changed the access credentials).  Have the Arduino perform a HTTP get request of a URL you have control over and simply put a predetermined phrase in the content of that web page that would never attract anyone's attention otherwise.  Despite the LAN being hacked, the Arduino would likely still have internet access.

So you could search for the words "I had sushi for dinner" in your most recent twitter messages.  The arduino sees this and treats it as a signal that it should close the door and then shutdown completely so that you can only open the garage with a physical key.  Might be a nice security feature.

Dunno really, not thought that idea through all the way but you see what I mean.

----------


## dclamp

I see where you are going with that idea... Its 0440 here in California and I am dead tired. (Graveyard sucks) I will thinking about this when I awake up and give a thoughtful reply.

----------


## dclamp

Another "fail-safe" type system would be a device that is connected to the network and if it detected that the internet connection has been comprised, it could send a signal to the other devices to go into a fail-safe manual mode and not accept any commands. This device could have a GSM chip and could query an outside source to see if I have put it int fail-soft mode.

I constantly see different home automation concepts on Kickstarter or for sale at the electronic store. I dont like how there are so many different suppliers with their own proprietary system. There needs to be an opensource, generic communication protocol for home automation devices. It would be nice to have a system that is open so I can buy devices and program the logic the way I wanted it. Maybe it already exists and I dont know about it.

----------


## wossname

http://www.openhab.org/ is the only one I've heard of, never tried it though.

----------


## dclamp

:wave:  Thanks for that link. Never heard of it before. Looking at it now

----------


## dclamp

For those subscribed to the thread... I have put this project into an enclosure and mounted it in my garage. 

http://www.vbforums.com/showthread.p...sure&p=4700199

----------

