Go Down

Topic: Garage Door Timeout (Read 3162 times) previous topic - next topic


Jul 15, 2011, 06:13 am Last Edit: Jul 15, 2011, 05:32 pm by Arrch Reason: 1
Well, this is my first major project that's been put into practice. This project came about after leaving the garage door open a few times going to work, so the wife asked me for something to manage that. The first thought was to be able to check and control it remotely, which is something I'd like to implement eventually, but for now, this does the trick. I created a Garage Door class that is there just for the sake of object oriented design, it's not really necessary.

It's programmed with a 10 minute timeout. If after 10 minutes, the garage is still open it "presses the button" to try to close it. To account for errors in it not closing, it will try again after 20 seconds until it reads it as closed. If after 5 tries, it's still not closed, it enters fail mode and blinks a red led.

Code: [Select]
// Sketch: GarageDoorSketch.pde
// Adds a timeout to the garage door in case it is left open for an extended period

#include "GarageDoor.h" // Simple class for controlling a garage door

#define readPin 5 // Pulled high with 10k resistor.
#define failLED 6 // Connected to LED
#define relayPin 7 // Connected to a relay and LED
#define maxCloses 5 // Number of times we attemopt to close before entering fail mode

GarageDoor garage(readPin, relayPin, failLED); // Create the garage door with the provided pins

// Global Variables
unsigned long openTimeout = 600; // in seconds, time door has remained open before trying to close
unsigned long timeToClose = 25; // in seconds, estimated time it takes to try and close the door
unsigned long lastClosed = millis(); // Keeps track of the last time the garage was closed.
bool isClosing = false; // Keeps track of whether or not we are trying to close the garage
int closeAttempts = 0; // The number of times we've tried to close the garage
bool failMode = false; // Keeps track of if we are in fail mode
unsigned long startedClosing = 0; // Keeps track of the time when we tried to start closing the garage

void setup() {
 // Do Nothing

void loop() {
 unsigned long time = millis(); // Get the current time
 if (garage.isClosed()) { // Check if the garage is closed
   lastClosed = time; // It is, so set the time it was last read as closed to now
   isClosing = false; // It's closed, so we don't have to try anymore if we were
   closeAttempts = 0; // Reset the attempts for next time
   failMode = false; // Clear failMode if we were in it
 } else { // The garage is open
   if (failMode) { // Check if we are we in fail mode
     garage.blinkFailLED(); // We are, so blink our LED
   } else if (isClosing) { // Check if we're trying to close the garage
     if ( (time - startedClosing) > (timeToClose * 1000) ) { // Are we past our close timeout (Time it takes to close the garage)
       if (closeAttempts >= maxCloses) // We are, so check if we've hit out attempt threshold
         failMode = true; // We have, so enter failMode
         tryToClose(); // We haven't, so try to close the garage
   } else { // It's open, but we haven't tried to close it
     if ( (time - lastClosed) > (openTimeout * 1000) ) // Are we past out timeout for leaving it open
       tryToClose(); // We are, try to close it
 delay(200); // Small delay

void tryToClose() {
 garage.toggle(); // Push the button to close
 isClosing = true; // We are now trying to close it
 startedClosing = millis(); // Set the time we started to close as now.
 closeAttempts++; // Add one to our attempts

Code: [Select]
// File: GarageDoor.h
// Description: A class for managing a garage door.

#ifndef GarageDoor_h
#define GarageDoor_h

#include "WProgram.h"

class GarageDoor {
   GarageDoor(int statusPin, int togglePin, int failPin); // Constructor
   bool isClosed(); // Check if garage is closed
   void toggle(); // Press the button to open/close
   void blinkFailLED(); // Blink the fail LED for one second
   int _statusPin; // Keeps track of status
   int _togglePin; // Simulates a button press to close garage
   int _failPin; // Flashes when close attempts have failed


Code: [Select]
// File: GarageDoor.cpp
// Implements the GarageDoor class

#include "WProgram.h"
#include "GarageDoor.h"

#define SECOND 1000 // One Second
#define CLOSED LOW // A low pin means a closed garage

GarageDoor::GarageDoor(int statusPin, int togglePin, int failPin)
 _statusPin = statusPin;
 pinMode(_statusPin, INPUT);
 _togglePin = togglePin;
 pinMode(_togglePin, OUTPUT);
 _failPin = failPin;
 pinMode(_failPin, OUTPUT);
bool GarageDoor::isClosed()
 int state = digitalRead(_statusPin);
 if (state == CLOSED)
   return true;
   return false;

void GarageDoor::toggle()
 // Pushes the button for 1 second
 digitalWrite(_togglePin, HIGH);
 digitalWrite(_togglePin, LOW);

void GarageDoor::blinkFailLED()
 // Blinks the LED for one second
 digitalWrite(_failPin, HIGH);
 digitalWrite(_failPin, LOW);



Some pictures of the setup...

Shorting these two pins simulates pressing the garage door button, so I hooked up some speaker wire to it and ran it to the jumpers on my secondary circuit.

Reed Switch pinned to the wall, two small magnets connected to the garage door.

Circuitry on the roof. Used a small perf board for the secondary circuitry and a Picoduino to run the ATMega.

Spliced a cheap USB cable and a wall-to-usb charger to provide regulated power.

I know it's a bit overdone, and I'm sure there are readily available commercial products for this, but where's the fun in that? Eventually, I'll add wireless communication to it, just working on a class that helps provide authorization to prevent any unscrupulous individuals from opening the garage :).


NIce job and well documented!
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)


it obviously works - so well done you
I suspect, however, that the reed relay should be connected the other way round
coil to arduino
pins to control box!
there are only 10 types of people
them that understands binary
and them that doesn't


Jul 15, 2011, 05:05 pm Last Edit: Jul 15, 2011, 05:31 pm by Arrch Reason: 1
You're right. The schematic was wrong, it's hooked up correctly and I fixed the schematic.


Very cool. You should add an override function for times you need to be in the garage, say soldering wire. Maybe a delay for 10 minutes (to start) then try to close. Something like that.


Very cool. You should add an override function for times you need to be in the garage, say soldering wire. Maybe a delay for 10 minutes (to start) then try to close. Something like that.

Yeah, that was something the wife suggested. The garage door has a lock/unlock switch that I can move the wire to to prevent it from closing it while it's locked, I'll probably just do that when I get the chance instead of adding more wiring and another switch. The only disadvantage is that it's essentially just disconnecting the button, so the Arduino doesn't know the difference and will inevitably enter fail mode.

Go Up