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:
/*
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);
server.begin();
// 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.println();
client.print ("Garage door is ");
byte door = digitalRead(relayPin);
if (door == HIGH)
client.println ("closed.");
else
client.println ("open.");
break;
}
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
delay(1);
// close the connection:
client.stop();
}
}
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):
$door_status = exec('wget 10.0.0.240 --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.