Saturday, November 6, 2010

Garage Status Monitor details

For my garage status monitor, I wanted two functions:
  • Tell whether the door was open or closed
  • Ambient temperature reading
The temperature part was easy. It's just a standard TMP36 temperature sensor that is hooked up to the Arduino analog pin 0. The sensor returns an integer millivolt reading that can be converted a temperature reading in one line of code.

I had several options for detecting the state of the garage door, but I settled on cheap and easy by using a roller contact switch. It is mounted on a wood shelf just ahead of where the top edge of the door comes to rest when it is open. When the circuit is closed, the Arduino knows the garage door is open.

Getting the signal upstairs could also be done a bunch of different ways. I had been fiddling with XBee radios for a while so I thought I'd use a set for this. The Arduino has an Xbee shield mounted, which uses up the ICSP headers and the first eight digital I/O pins.

The receiver XBee radio is hooked to my PC via an XBee Explorer USB adapter. It shows up as COM7, and I have both XBees setup to work at 9600 bps.

When the garage door is closed, it transmits a plain English sentence like this for the moment:


I say "for the moment" because my ultimate goal is to make a receiver device to hang in the kitchen that just displays a red or green light, and maybe the temperature on a pair of 7-segment LEDs. The only thing I have in place so far to represent the output is a PuTTY window running on my machine.
Here's the code for the Arduino:

const int switchPin = 10; // The pin used for the switch.
const int ledPin = 13; // The pin used for the LED to display status locally.
const int tempPin = 0; // analog pin for the temperature sensor.

int buttonState = 0; // variable for reading the switch status

void setup() {
// Get the LED pin setup as an output.
// Using the on-board LED for this.
pinMode(ledPin, OUTPUT);

// Get the switch pin setup as an input.
pinMode(switchPin, INPUT);

// Get serial communications ready to rock.

void loop(){
// Get the state of the switch.
buttonState = digitalRead(switchPin);

// Is the circuit closed?
// If so, the garage door is open, so...
if (buttonState == HIGH) {
digitalWrite(ledPin, HIGH);
Serial.print("GARAGE DOOR IS OPEN. ");
digitalWrite(ledPin, LOW);
Serial.print("GARAGE DOOR IS CLOSED. ");

Serial.print("TEMP IS ");

// Pause for five seconds.

float getTemp()
// Read the temperature from the sensor.
int tempReading = analogRead(tempPin);

float voltage = tempReading * 5.0 / 1024.0;

// Convert the voltage to temperature.
float tempC = (voltage - 0.5) * 100;
float tempF = tempC * 1.8 + 32;

// I like Fahrenheit, so return it.
return tempF;

Pictures of the setup:


  1. Really cool setup! Have you looked into the Netduino? I was looking at the Arduino and Netduino, but ultimately decided on the Netduino as it use the .Net Micro Framework, allowed me to code in C# and use Visual Studio. I am working on a Garage Door opener that can be opened using an Android phone with the ability to setup accounts for multiple users (running off a Netduino and a Windows box with MySQL).

  2. Thanks, Tom! I'm a C# developer by trade, and I snagged a Netduino a couple weeks ago to experiment with. I like what you can do with it, however, I'm not so happy about the fact that serial-over-USB can't be done while in the IDE. I'm now trying to get the Netduino to work with a 16x2 LCD shield for the next project that I'm embarking on. I'll be posting about it soon.

  3. Can you post more about the Windows Service you are using and how you're posting it to the web?? I'm doing some home automation, but I would like to see how you're incorporating the windows service and such. Thanks, Vinnie Vu

  4. I recently had to fiddle with one of my garage door to have it shut properly. Is the typical travel of the door precise enough for the kind of switch you are using? Do you miss door openings or the contrary does your switch receive too much force from time to time? I was thinking of mounting a shutter board on top of the door and using it with a slotted optical switch.

  5. @JammerX19: Are you sure about the serial over USB in the (c#) IDE? I'm not sure this is correct.

  6. First off, I like the project. I think I may take the idea and put it into my home.

    I'm thinking though that maybe, if you really set on keeping only one physical switch, wouldn't it be more appropriate to have the switch at the 'closed' location instead of at the 'fully open' location? I'm thinking that having the switch at the close point would more accurately reflect when it was 'open' at any degree, like 1 inch open, to fully open. Currently you only indicate when the door is fully open.

    I really like the idea of using only the XBees instead of a board and xbee if you don't need to do so. I just started using them for my FEZ robot to control it remotely or have it send status messages back to my PC. Great piece of hardware.

  7. Vinnie - the windows service is very simple and just listens on the serial port that my XBee Explorer sits on. When it receives a status change from the gadget down in the garage, it stores an entry in my SQL Server Express instance running on the home server. Then I have an ASP.NET web site that gives me the history of that information.

    However, my intention was never really to have a computer in the midst of all of this. Having the server intercept the message is a stop-gap measure. My real goal is to have a small box on the kitchen counter that has a red or green light to indicate whether the door is open. I just haven't gotten that far.

  8. @ZotDitzMyo - I have found that the travel on my garage door is imprecise, and so I'm always tinkering with some sort of spongy material to put at the top of the garage door where it meets the switch. This material takes up the space but compresses easily so it won't destroy the switch if the door happens to open all the way instead of just 98%.

    Your idea of a shutter board sounds cool. Can you elaborate?

  9. @Anonymous - When last I read up on the subject, you couldn't do serial I/O over USB while the board is hooked up to the Visual Studio IDE. If that has changed, I'll be thrilled.

  10. @Dan M. - You're right, that would have worked better, however, my placement was limited by the location of a power outlet for the AC adapter to run the board, and also the fact that I do get a small amount of water through the garage door during heavy rains, so I wanted my mechanism up high in the ceiling.

    As for simplifying the circuit to just the radio, that's a great idea. I'm just new enough to not know how it should be done.

  11. There's a bug in your code. This line:

    float voltage = tempReading * 5.0 / 1024.0;

    Should be:

    float voltage = tempReading * 5.0 / 1023.0;

    Even though there are 1024 possible values for the ADC reading, the maximum value is 1023. At 5V, the reading is 1023. Your formula must return 5V for tempReading of 1023, so you have to divide by 1023, not 1024.