Go Down

Topic: Garage-door web server (Read 4 times) previous topic - next topic

Nick Gammon

It's not fantastically exciting, but here is my garage-door notification server ...

First, a magnetically-activated reed switch on the side of the door. The magnet is clipped to the rubber edge of the door:

That is powered by a 12V power supply, which in turn activates a relay (to isolate the Arduino from whatever might be in the cable):

Inside the plastic box is a Uno, with the relay wires connected to pin 7 and ground:

The Uno has an Ethernet shield on it, which plugs into the home network. The Uno is running this sketch:

Code: [Select]

Garage door open/closed detector.

  Based on Web Server by:
created 18 Dec 2009
by David A. Mellis
modified 4 Sep 2010
by Tom Igoe

Modified by Nick Gammon
9th Feb 2011


#include <SPI.h>
#include <Ethernet.h>

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {  0x90, 0xA2, 0xDA, 0x00, 0x2D, 0xA1 };

// our address
byte ip[] = { 10, 0, 0, 240 };

// the router's gateway address:
byte gateway[] = { 10, 0, 0, 1 };

// the subnet:
byte subnet[] = { 255, 255, 255, 0 };

// which pin to connnect the relay to (held high by internal pullup)
#define relayPin 7

// Initialize the Ethernet server library
// with the IP address and port you want to use
// (port 80 is default for HTTP):
Server server(80);

void setup()
  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip, gateway, subnet);
    // initialize the relay pin as a input:
  pinMode(relayPin, INPUT);
  digitalWrite(relayPin, HIGH);   // set pullup resistor


void loop()
  // listen for incoming clients
  Client client = server.available();
  if (client) {
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
        if (c == '\n' && currentLineIsBlank) {
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");

          client.print ("Garage door is ");
          byte door = digitalRead(relayPin);
          if (door == HIGH)
            client.println ("closed.");
            client.println ("open.");
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
    // give the web browser time to receive the data
    // close the connection:

I have a "home management" web server running (not the Uno) on a Ubuntu server. This shows various useful things, like forthcoming events. Inside the server's main page it queries the other server (the Arduino one in the box) to see what the garage door status is (PHP code):

Code: [Select]
$door_status = exec('wget --timeout=5 -O -');

if ($door_status == "Garage door is closed.")
// this is normal
else if ($door_status == "Garage door is open.")
  echo "<h1><font color=red>Garage door is open!</font></h1>\n";
  // warning sound
  echo "<embed src=\"hms/garage_door.aif\" autostart=true loop=false  height=16 width=170 ></embed>";
else if ($door_status != "Garage door is open.")
  echo "<h1><font color=red>Garage door web server is down!</font></h1>\n";

And yes, I know that having one web server getting a page from another one is crazy. ;)

However since the Uno is not doing anything else, it always responds quickly. In the event that it is down for some reason the query times out in 5 seconds.

If the door is open, the web page shows this:

It also plays a sound in the hope of getting someone's attention.

It's pretty reliable.

The reason for having it in the first place is, that it is easy to operate the door with the remote control, and forget it is open, or even to accidentally open it, because the button on the remote is very sensitive.


pretty neat. what is the purpose of it? To remind you if you left the door open? you can add some logic to close it if there are no obstacles on the way (check for reflected IR over period of time and if there is no interruption, assume no movement).


Take it one step further :) I am working on a system for my iPhone where it uses the gps to determine how far from my home I am.

And when I am going away, I can set different tasks that should be executed, and different when I get home again. :)

So if I have been away and coming home, and the garage door is closed, then open it so I can get the car in, so the door is open when I reach my driveway :)
captain-slow.dk | non contagious!

Nick Gammon

These are all nice ideas, thank you. I was also thinking about an RFID tag idea, where the (house) doors would unlock if you just went near them. The GPS idea is cunning.

Probably a good security system could combine all sorts of sensor input, eg. where you are, the time of day, movement, door positions, day of the week. So for example, if movement is detected in the house on a Tuesday afternoon when you are normally out, and the iPhone GPS reports that you are in fact out, then that could be suspicious.

what is the purpose of it? To remind you if you left the door open?

Basically yes. And in fact, since you can accidentally press the button it isn't so much a reminder as information. The way the door faces, you can't easily tell from inside the house if the door is open or not.


can you use it to open :) nice!

Nick Gammon

No, I have the remote for that.


Great time to add this:
PIR to check for obstruction(above)
Hack a spare remote with a small relay and wire to arduino
Close door via web command

Now I've got to do this

Nick Gammon



Nice work on that server  :)

Can you explain me how you get data from arduino server with this code? i can't understand the code  =(
Code: [Select]
$door_status = exec('wget --timeout=5 -O -');

Nick Gammon

The wget (Web Get) function opens the web page (my server is at and downloads the contents into the variable $door_status. Inside that variable will be the string "Garage door is open." (or closed). I then test for that. The timeout is in case the web server (the Arduino) is down for some reason. The "-O -" means "output to stdout" which means to a variable in this case.

I couldn't think of an easier way of getting my internal (home) web server to interrogate another internal server. Maybe telnet would be been simpler, but hey, this has worked perfectly for months now.


Cool Project. I love seeing people make projects with more practical applications. I made a similar device, but it just acts as a timeout and will close the garage after 5 minutes. Eventually, I'll add wireless communication so I can get the status remotely like yours.


Last night I finished a similar project. It sends e-mail when the door is left open accidentally. Once I have finished a documentation so will post it here.
Arduino Uno R3, Arduino Mega 2560 R3, Ethermega (R3), and some Ethernet Shields (R3), Chronodots, TMP36 sensors, DS18B20 sensors, LCDs/TFTs, RS232C to learn and play...


Nick Gammon

Cool Project. I love seeing people make projects with more practical applications. I made a similar device, but it just acts as a timeout and will close the garage after 5 minutes. Eventually, I'll add wireless communication so I can get the status remotely like yours.

That's a good idea. Unless the cat is asleep under the door. Or you have the car boot* open and are packing it. Or you backed the car half-way out and are looking at the engine. :)

I suppose a light-beam could detect if the coast is clear, although it would have to be pretty low to detect the cat.



grt project..!!!
m working on something like this, m facing problem at 2 way switch as u did before..
my project is to control home appliances(fan, light, motor, tv, fridge etc) through controller using relays. i want to extend that to 2 way switch, means by manual n using remote(controller-8051) also.

m not getting way to check status of appliances whether is on or not by controller.
thought to use stepdown trans. but its too expensice coz i have to use separate trans for each appliances.

is there any easy method to check 230V status through realy??

or is there any relay with 230V coil? are those expensive?

Go Up