Weekend project: Putting my doorbell online

Running your webserver from home gives lots of opportunities to connect the real world to the internet.  I’ve previously connected a webcam with motion detection so I can see people entering and leaving the driveway and, more recently, connected a wireless weather station to give regular Elderslie weather updates.

I decided my next project would be to put my front doorbell online.  As well as being a relatively simple, fun project, it also makes some sense: coupled with the webcam it can be used to give me a decent idea of who’s there when the doorbell goes and I’m out.   It also means I can hear the doorbell when I’m at the bottom of the garden, thanks to SMS or IM alerts on my iPhone.

Here’s the project in it’s rough state, before it gets packaged up into a project case.

If you’re interested in setting up a similar project, read on…

The first step is to come up with a method to get signals into the PC from the real world.  For that, I’m using an Arduino Duemilanove that I bought from SK Pang.  The Arduino has a few tricks that make it ideal for a project like this: It can provide 5v or 3.3v power to small devices; It had take both digital and analogue inputs; It has a programming language that can be used to convert noisy analogue signals into clean data (such as a text string written to a COM port).

Next step was to decide on a method to get the doorbell signal to the Arduino.   I didn’t want the mess and hassle of running a wire from the front door to my server cupboard, so I decided to go for a wireless solution.  Unfortunately, most wireless doorbells are just plain ugly.  In the UK they tend to be bulky and have big rubber buttons — nothing like a typical standard wired doorbell.   Luckily, I came across a Byron wired-to-wireless doorbell convertor.  It’s basically a wireless doorbell without the button that you can hide indoors.

Ok, next… I’ve got the wireless transmitter, now I need a receiver.  Rather than try to find something specific for the task, I decided to go for the cheapest option I could find.  B&Q had an ugly wireless portable doorchime from the same Byron range in their clearance section for £7.  It had both an audio chime and a flashing light, and I reckoned the flashing light would provide the simplest source of an incoming signal.

Right, now to plug it all together.  I pulled the doorchime apart to find a main circuit board containing most of the components and switches, and a separate daughter board for the flashing light.   I separated the main board from the other components.  The power source was two AA batteries (2 x 1.5v in series = 3v) so this could easily be replaced by the 3.3v source on the Arduino. 

The only other wire I needed was the signal wire that had been going to the LED daughter board.  I plugged this into the first analogue input on the Arduino.  And that’s about it in the real world… now all that’s required is some programming to make it do what we want.

The Arduino side of the programming is fairly simple.   I found an example from Roo Reynolds that did pretty much what I wanted — detect a change in analogue signal and convert it to an output on the serial line.  Here’s my version of the code, adapted a bit to add some debugging output and to change the tolerance of the analogue signal for the Byron:

int ledPin = 13;   // LED connected to digital pin 13
int potPin = 0;    // white doorbell wire to analog pin 0
int val = 0;
long time = 0;
long debounce = 1000;
void setup() {
  pinMode(ledPin, OUTPUT);   �
  Serial.begin(9600);     �
  digitalWrite(14 + potPin, HIGH);
}
void loop() {
  val = analogRead(potPin);
  if (val < 500) {    // if the circuit is completed
    if (millis()-time > debounce) {
      Serial.println("ON");
      digitalWrite(ledPin, HIGH); �
      delay(21000);   // Wait till the light would've stopped
      digitalWrite(ledPin, LOW);  �
      time = millis();
    }
  } else {
    Serial.println(". ");
    delay(1000);
  }
}

So now we have a serial/COM port receiving either “ON” or a dot if it’s off… pretty cool.  What Roo’s example didn’t explain (and what a number of comments on his blog were asking) is how to get this serial output into another program!   It’s this part of the problem that turned out to be the trickiest…

I decided to use Perl for this part of the system because it has good serial support.  My server runs Windows, so I had to replace the standard serial handling stuff with Win32::SerialPort.   Also, my standard XAMPP install didn’t include any good way to add Perl libraries, so I decided to install ActivePerl as my command-line Perl solution for this.  Here’s my Perl code…

use Win32::SerialPort;
use LWP::Simple;
my $port = Win32::SerialPort->new("COM3");
$port->databits(8);
$port->baudrate(19200);
$port->parity("none");
$port->stopbits(1);
my $count = 0;
while (1) {
    my $char = $port->lookfor();
    if ($char) {
        $char = substr $char, 0, 2;
        print " Doorbell status: " . $char . " \n";
        if ($char eq "ON") {
          print "Doorbell is on \n";
          my $content = get('http://your_action_here');
          print $content;
        } else {
          print "Doorbell is off \n";
        }
    }
    sleep(1);
}

As you’ll see, there’s a fair bit of unnecessary debugging code in there, but the bones of it are super-simple.  Read the serial buffer; check if it starts with “ON”; if so, do something useful; if not, wait one second and check again.

The “something useful” could be just about anything.  Right now, I’ve got it making an HTTP request to an SMS gateway so I get a text message every time the doorbell goes.  Eventually I’m going to have three options: SMS, Email and IM.

Longer term plans for the Arduino revolve around hooking up more kit to it.  I’m planning to build a new garage this summer, so I’ll probably buy an electric door opener and hack one of the remote controls into my Arduino project box.  That way, I could open and close the garage door remotely over the internet… or something else equally useless but cool.

Here’s the finished project box showing the USB port (left) and in place in my cupboard (right).

Comments are closed.