Introduction: The IButton Garage-door Opener (Arduino)

About: I'm a social-worker, working with 12 - 23 year-olds. I used to be a printer. In 2018 I opened a small makerspace (www.imdib.nl) in my house, where I have lasercutters, 3d-printers, Arduino's, Mindstorms and ot…

I've made an iButton garagedoor opener and logger.

On a Dutch (kind of) eBay (www.marktplaats.nl) I found some iButtons and readers very cheap. I had no idea what to do with them, but I bought them anyway.
My garage opens with a push on a button, so it must be possible to get that working with the iButton.
I also found some really cheap (0,50 euro) displays, so it would be nice if I also can make a screen to show me who entered when.
The project is now existing in three parts:

  1. The iButton opening the door
  2. A clock keeping track of times and dates
  3. A screen showing the information
So to keep things understandable I try first to figure out the three parts separately.

Step 1: You Will Need

Parts
  • iButton(s)
  • iButton reader
  • Arduino
  • 2 push buttons
  • power supply
  • 2 10 kOhms resistors
  • 220 Ohms resistor
  • 2,2 kOhms resistor
  • 10 kOhms potmeter
  • LCD-display with HD44780 controller
  • NPN transistor
  • relais
  • 1N4001 diode
  • some wire
  • PCB

Tools
  • soldering iron
  • solder
  • snips
  • breadboard
  • computer with Arduino software
  • a LED

Step 2: IButton Opening the Door

Start playing with it
So I bought the parts. Now I had to find out how the things work. Trough the Arduino-site (www.arduino.cc) I found the "Fridzing" drawing on http://tushev.org/articles/electronics/42-how-it-works-ds18b20-and-arduino. I also found the 1-Wire library there. 1-Wire is the name of the communication method used by the iButtons.
With this drawing and the library it was easy to wire everything and get it running.

How to wire up
According to the schematics, I took my Arduino, a breadboard, the iButton reader, a 2,2 kOhms resistor, three wires and a LED.
I wired it a little bit different than the drawing. My iButton reader had only two wires.
  • a wire from 5V on the Arduino to the + lane on the breadboard
  • the resistor from the + lane to the first lane on the breadboard
  • a wire from the first lane (where also the resistor is) to pin 2 on the Arduino
  • the grey wire of the iButton reader to the first lane of the breadboard
  • the black wire of the iButton reader to the - lane of the breadboard
  • a wire from the - lane to the GND of the Arduino
  • put the LED with the long leg (anode) in pin 13 of the Arduino and the short leg (cathode) in GND

Now I run the sketch (code) like shown in iButton.pde and entered the code like it is shown in small letters on the iButton.

To be able to run this sketch, I first have to download the library from the site shown above and put this in the [library] folder in the [Arduino] folder. If you don't have a [library] folder in your [arduino] folder, you should make one. Next you have to restart the Arduino program for it to know the new library is there. (trust me, if you don't restart the program, you can try, and try, and try, but it will not work)

If I put the right iButton in the reader, the LED will light up for a short moment. If I put in the wrong iButton the LED won't light up.
The first part is working now. If I connect pin 13 to a relays in stead of a LED and I connect that relays to the button that open my garage door, my garage door will probably open.

Step 3: The Garage Door

Before I went any further I first wanted to check wether the button opening my garage really worked by just connecting two wires. To be sure that I didn't kill myself, I first measured how much volts are going trough the button. I simply removed the button from the wall and put my multimeter on the two screws on the back. I had a reading of 21 V DC, so that might bite, but probably won't kill me if I accidentally touch it.
Now I simply connected the two screws with a piece of wire and the door opened.

Adding the relay

My theory worked so now it was time to add the relay to my design. On the "Fritzing" drawing you can see how I did that. 
I moved the iButton to port 12 to make more room on the Arduino to ad the clock and the LCD later on.
The Arduino will switch the transistor (I used a BC338 that I had laying around, but any 5V NPN general purpose will probably do) and the transistor will switch the relay. The green wires going from the relay will be connected to the screws on the back of the button that opens the garage.
The diode should be there to help the relay. (I'm not sure why anymore, but just put it there, the relay will live longer)

Step 4: The Clock

I didn't have the LCD-display yet, so the next step would be to figure out how to get the clock going. I don't want to use any external parts, like a RTC-IC (Real Time Clock) or an internet connection or anything. The Arduino has an internal crystal in it, so it must be possible to make a clock with just the Arduino and two buttons to set the time and date.

The wiring
The wiring is just adding two buttons, so that is not so hard.
To get buttons working releiable on a Arduino, you need to use a pull down resistor (connected to the GND) or a pull up resistor (connected to the +5V). 
This 10 kOhm resistor takes care that the button is LOW or HIGH, when it is not pushed. I used a pull up resistor, so my buttons are HIGH when they are not pushed.
(learn everything you never wanted to know on buttons on Arduinos here: https://www.instructables.com/id/Arduino-Button-Tutorial/)
  • connect a wire from the +strip of the breadboard to +5V on the Arduino
  • connect a wire from the -strip of the breadboard to GND on the Arduino
  • put two buttons in the breadboard
  • connect a 10kOhm resistor between one leg of the button and the +strip (2 x)
  • connect a wire from the same leg of the button where the resistor is connected, to pin 8 of the Arduino (and to pin 9 from the other button)
  • connect a wire from the other leg of the buttons to de -strip (2 x)

The Sketch
I tried to write my own sketch, using the function [millis] on the Arduino, but that was not so easy as I thought it would be, so I searched www.arduino.cc and found some nice libraries and sketches. The only thing was that the sketches all used something external to set the time (internet, serial port or RTC). I wanted to use the two buttons to set the time, so there was still some programming to do for me.
I still didn't have the LCD, so the serial-monitor function of the Arduino-software will be my screen for now. 
Before you can run the sketch, you will have to download the library from here: http://www.arduino.cc/playground/Code/Time and put it in your [arduino] folder. (and restart the Arduino-software)

The code
#include <Time.h> //adding the time-library

int knoptijd = 400; //setting all the variables (sorry for the Dutch names)
int uur = 12;
int minuut = 15;
int seconde = 0;
int dag = 10;
int maand = 9;
int jaar = 2011;
int knopset = 10;
int knopmode = 11;
int setwaarde = 0;
int modewaarde = 0;


void setup() {
  pinMode(knopset, INPUT);
  pinMode(knopmode, INPUT);
  Serial.begin(9600);
   setTime(uur,minuut,seconde,dag,maand,jaar); //setting the starttime for the clock when it starts up

}

 void loop(){
setklok();
digitalClockDisplay();
delay(1000);
}

void setklok(){ //setting the clock
modewaarde = digitalRead(knopmode);
if (modewaarde == LOW){ //if the [mode]button is pusched
Serial.println("tijd instellen");
//setting the hours
Serial.println("uur");
Serial.println(uur);
delay(knoptijd);
modewaarde = digitalRead(knopmode);
while (modewaarde == HIGH){
delay(knoptijd);
setwaarde = digitalRead(knopset);
if (setwaarde == LOW){
uur++;
if (uur > 24) uur = 1;
Serial.println(uur);
}
modewaarde = digitalRead(knopmode);
}

// setting the minutes
Serial.println("minuut");
Serial.println(minuut);
delay(knoptijd);
modewaarde = digitalRead(knopmode);
while (modewaarde == HIGH){
delay(knoptijd);
setwaarde = digitalRead(knopset);
if (setwaarde == LOW){
minuut++;
if (minuut > 59) minuut = 0;
Serial.println(minuut);
}
modewaarde = digitalRead(knopmode);
}

//setting the month
Serial.println("maand");
Serial.println(maand);
delay(knoptijd);
modewaarde = digitalRead(knopmode);
while (modewaarde == HIGH){
delay(knoptijd);
setwaarde = digitalRead(knopset);
if (setwaarde == LOW){
maand++;
if (maand > 12) maand = 1;
Serial.println(maand);
}
modewaarde = digitalRead(knopmode);
}

//setting the day
Serial.println("dag");
Serial.println(dag);
delay(knoptijd);
modewaarde = digitalRead(knopmode);
while (modewaarde == HIGH){
delay(knoptijd);
setwaarde = digitalRead(knopset);
if (setwaarde == LOW){
dag++;
if (maand == 1 || maand == 3 || maand == 5 || maand == 7 || maand == 8 || maand == 10 || maand == 12){
if (dag > 31) dag = 1;
}
if (maand == 4 || maand == 6 || maand == 9 || maand == 11){
if (dag > 30) dag = 1;
}
if (maand == 2){
if (dag > 28) dag = 1;
}
Serial.println(dag);
}
modewaarde = digitalRead(knopmode);
}


setTime(uur,minuut,seconde,dag,maand,jaar);
}
}

void digitalClockDisplay(){ //printing time and date

Serial.print(hour());
printDigits(minute());
Serial.print(" ");
Serial.print(day());
Serial.print("/");
Serial.print(month());
Serial.println();
}

void printDigits(int digits){
// utility function for digital clock display: prints preceding colon and leading 0
Serial.print(":");
if(digits < 10)
Serial.print('0');
Serial.print(digits);

Attachments

Step 5: The LCD

Finally the LCD arrived.
Now I need to figure out how the thing works, so again, www.arduino.cc is my friend. I found the LCD-library and sketches at http://arduino.cc/en/Tutorial/LiquidCrystal. The next step is connecting the LCD to the Arduino according to the drawing on the Arduino-site. I had some old flat cable laying around that I used to connect the LCD. I don't have the right connectors, so I used some other connectors that I did have. Shielding them with "shrinktubes?" makes them very usable.
Two pins on the LCD should be connected to the GND so I make a little wire bridge.
The pin-setting on my LCD is not in one row but like this:

15 - 16
13 - 14
11 - 12
  9 - 10
  7 - 8
  5 - 6
  3 - 4
  1 - 2

Only pin 1 and pin 15 are marked.

One wire should go through a 10 kOhm potmeter. This was a problem when I wired everything up. I wired everything exactly like on the Arduino site and ran the sketch that comes with the Arduino software, but it seemed like the LCD was not working. After trying everything and checking all wires ten times, I turned the potentiometer all the way down and it worked!

Step 6: Adding It All Together

Al the parts work separately on the breadboard. Now it is time to put them al together on a PCB.

The PCB
I'm not into etching and making your own PCBs, so I will put everything on a "hole-board".

First put in all your components and then start wiring and soldering. I colored the +5V on the back of my PCB red and the GND black.
I added some header-pins so I can pin my PCB on top of the Arduino. The corner of the PCB above pin 12 of the Arduino had to come off because it was not in line with the holes in my board.
The wire going to pin 13 on the drawing is moved to pin 7. Pin 13 will blink when the Arduino starts up, so that means that the garage door would open and close and open and close every time the Arduino starts up.

In the separate sketches I made (and copied from others), I changed the pin numbers to the pins that are used now and I ran all three sketches. Everything is working!

Step 7: The Final Sketch

Now I need to put all three sketches together into one working sketch!
I used the clock-sketch as the base to add the other two sketches to. I added functionality to block iButtons and the Arduino will log the last 10 entries.
The bug that was in my first sketch is fixed now. If you used the code that was posted here before the 2nd of October 2011, than change it for this code. If you already tinkered with it, just let me know and I will explain an easy way to fix the bug.

The sketch:

#include                           //adding the time-library
#include                  //adding the LCD library
#include                        //adding the iButton library

LiquidCrystal lcd(11, 10, 5, 4, 3, 2);     //the pins that the LCD is connected on

int knoptijd = 400;                        //setting all the variables for the clock part(sorry for the Dutch names)
int uur = 12;
int minuut = 15;
int seconde = 0;
int dag = 10;
int maand = 9;
int jaar = 2011;
int knopset = 9;
int knopmode = 8;
int setwaarde = 0;
int modewaarde = 0;

OneWire  ds(12);                            //setting the variables for the iButton part
byte addr[8];
int but1[6] = {0,149,107,48,13,0};          //*************the code of the iButtton****************
String name1 = "Burton";                    //name should always be 6 digits
byte uit1 = 1;
int but2[6] = {0,65,177,47,13,0};       
String name2 = "Aca   ";
byte uit2 = 1;
int but3[6] = {0,235,75,138,9,0};      
String name3 = "Peter ";
byte uit3 = 1;
int but4[6] = {0,3,0,0,0,0};        
String name4 = "But 4 ";
byte uit4 = 1;
int but5[6] = {0,87,171,46,13,0};   
String name5 = "Jelle ";
byte uit5 = 1;

String keyStatus="";
byte welkeBut = 0;
String name = "";
String geheugen[10]= {"leeg10","leeg 9","leeg 8","leeg 7","leeg 6","leeg 5","leeg 4","leeg 3","leeg 2","leeg 1"};
int memHour[10]= {99,99,99,99,99,99,99,99,99,99};
int memMinute[10]= {99,99,99,99,99,99,99,99,99,99};
int memDay[10]= {99,99,99,99,99,99,99,99,99,99};
int memMonth[10]= {99,99,99,99,99,99,99,99,99,99};
int i = 0;

void setup()  {
  pinMode(knopset, INPUT);
  pinMode(knopmode, INPUT);
  pinMode(7, OUTPUT);                    //opening the door
  lcd.begin(20, 2);                      //set up the size of the LCD
   setTime(uur,minuut,seconde,dag,maand,jaar); //setting the starttime for the clock when it starts up

}

 void loop(){  
    setklok();                            //testing for times that must change
    digitalClockDisplay();                //displaying the clock
    delay(1000);
      getKeyCode();                       //getting the iButton code
      testKeyCode();                      //testing the iButton code
      modeklok();
 }
 
 void setklok(){                              //setting the clock
   modewaarde = digitalRead(knopmode);
   if (modewaarde == LOW){                    //if the [mode]button is pusched
     lcd.clear();
     lcd.print("tijd instellen");
     lcd.setCursor(0, 1);                                     //setting the hours
     lcd.print("uur:  ");
     lcd.setCursor(9, 1);
     lcd.print(uur);
     lcd.print("   ");
     delay(knoptijd);
     modewaarde = digitalRead(knopmode);
     while (modewaarde == HIGH){
       delay(knoptijd);
       setwaarde = digitalRead(knopset);
       if (setwaarde == LOW){
         uur++;
         if (uur > 24) uur = 1;
         lcd.setCursor(9,1);
         lcd.print(uur);   
         lcd.print("   ");
       }
       modewaarde = digitalRead(knopmode);
     }
     
                                               // setting the minutes
     lcd.setCursor(0, 1);
     lcd.print("minuut");
     lcd.setCursor(9, 1);
     lcd.print(minuut);
     lcd.print("   ");
     delay(knoptijd);
     modewaarde = digitalRead(knopmode);
     while (modewaarde == HIGH){
       delay(knoptijd);
       setwaarde = digitalRead(knopset);
       if (setwaarde == LOW){
         minuut++;
         if (minuut > 59) minuut = 0;
         lcd.setCursor(9, 1);
         lcd.print(minuut);
         lcd.print("   ");
       } 
       modewaarde = digitalRead(knopmode);   
     }
     
                                               //setting the month
        lcd.setCursor(0, 1);
        lcd.print("maand ");
        lcd.setCursor(9, 1);
        lcd.print(maand);
        lcd.print("   ");
     delay(knoptijd);
     modewaarde = digitalRead(knopmode);
     while (modewaarde == HIGH){
       delay(knoptijd);
       setwaarde = digitalRead(knopset);
       if (setwaarde == LOW){
         maand++;
         if (maand > 12) maand = 1;
         lcd.setCursor(9, 1);
         lcd.print(maand);
         lcd.print("   ");
       } 
       modewaarde = digitalRead(knopmode);   
     }
     
                                               //setting the day
     lcd.setCursor(0, 1);
     lcd.print("dag   ");
     lcd.setCursor(9, 1);
     lcd.print(dag);
     lcd.print("   ");
     delay(knoptijd);
     modewaarde = digitalRead(knopmode);
     while (modewaarde == HIGH){
       delay(knoptijd);
       setwaarde = digitalRead(knopset);
       if (setwaarde == LOW){
         dag++;
         if (maand == 1 || maand == 3 || maand == 5 || maand == 7 || maand == 8 || maand == 10 || maand == 12){
           if (dag > 31) dag = 1; 
         }
         if (maand == 4 || maand == 6 || maand == 9 || maand == 11){
           if (dag > 30) dag = 1; 
         }
         if (maand == 2){
           if (dag > 28) dag = 1; 
         }
         lcd.setCursor(9, 1);
         lcd.print(dag);
         lcd.print("   ");
       } 
       modewaarde = digitalRead(knopmode);   
     }
           
       
   setTime(uur,minuut,seconde,dag,maand,jaar);
   lcd.clear();
   }
}
 
 void digitalClockDisplay(){          //printing time and date
  lcd.setCursor(0,0);
  lcd.print("                    ");
  lcd.setCursor(0,0);
    lcd.print(hour());
    printDigits(minute());
    lcd.print(" ");
    lcd.print(day());
    lcd.print("/");
    lcd.print(month());
    lcd.print(" ");
}

void printDigits(int digits){
  // utility function for digital clock display: prints preceding colon and leading 0
  lcd.print(":");
  if(digits < 10)
    lcd.print('0');
  lcd.print(digits);
}

void getKeyCode(){                  //getting the code from the iButton
  byte present = 0;
  byte data[12];
  keyStatus="";
  
  if ( !ds.search(addr)) {
      ds.reset_search();
      return;
  }

  if ( OneWire::crc8( addr, 7) != addr[7]) {
      keyStatus="CRC invalid";
      return;
  }
  
  if ( addr[0] != 0x01) {
      keyStatus="not DS1990A";
      return;
  }
  keyStatus="ok";
  ds.reset();
}


void modeklok(){                              //testing for the bottom-button  ############################
   setwaarde = digitalRead(knopset);
   if (setwaarde == LOW){                    //if the [set]button is pusched
     lcd.clear();
     lcd.print("Iem. buiten sluiten?");
         lcd.setCursor(0, 1);                                     //checking the memory
         lcd.print(geheugen[9]);
         lcd.print(" ");
         lcd.print(memHour[9]);
         lcd.print(":");
         lcd.print(memMinute[9]);
         lcd.print(" ");
         lcd.print(memDay[9]);
         lcd.print("/");
         lcd.print(memMonth[9]);
         lcd.print(" ");

     delay(knoptijd);
     setwaarde = digitalRead(knopset);
     i=8;
     while (modewaarde == HIGH){
       if (setwaarde == LOW){
         i--;
 
         lcd.setCursor(0,1);
         lcd.print(geheugen[i]);
         lcd.print(" ");
         lcd.print(memHour[i]);
         lcd.print(":");
         lcd.print(memMinute[i]);
         lcd.print(" ");
         lcd.print(memDay[i]);
         lcd.print("/");
         lcd.print(memMonth[i]);
         lcd.print(" ");

         delay(knoptijd);
         if(i==0){
           lcd.clear();
           
           lcd.setCursor(0, 1);                                     //putting the last enter back on the screen
           lcd.print(geheugen[9]);
           lcd.print(" ");
           lcd.print(memHour[9]);
           lcd.print(":");
           lcd.print(memMinute[9]);
           lcd.print(" ");
           lcd.print(memDay[9]);
           lcd.print("/");
           lcd.print(memMonth[9]);
           lcd.print(" ");
           
           loop();
           return;
         }
       }
       setwaarde = digitalRead(knopset);
       modewaarde = digitalRead(knopmode); 
     }

   delay(knoptijd);

     i = 0;
     while(i == 0){                                       //keeping out iButton 1
     lcd.setCursor(0,0);
     lcd.print("buitensluiten?  ja->");
     lcd.setCursor(0,1);
     lcd.print(name1);
     lcd.print("         nee->");
     delay(knoptijd);                                    //dubble waiting time here
     delay(knoptijd);
     modewaarde = digitalRead(knopmode);
     setwaarde = digitalRead(knopset);
     if (modewaarde == LOW){
       uit1 = 0;
       lcd.setCursor(0,0);
       lcd.print("buitengesloten!     ");              //get out
       delay(1000);
       i=1;
     }
     if (setwaarde == LOW){
       uit1 = 1;
       lcd.setCursor(0,0);
       lcd.print("mag er in           ");              //come in
       delay(1000);
       i=1;
     }
   }
 
     i = 0;
     while(i == 0){                                       //keeping out iButton 2
     lcd.setCursor(0,0);
     lcd.print("buitensluiten?  ja->");
     lcd.setCursor(0,1);
     lcd.print(name2);
     lcd.print("         nee->");
     delay(knoptijd);                                    //dubble waiting time here
     delay(knoptijd);
     modewaarde = digitalRead(knopmode);
     setwaarde = digitalRead(knopset);
     if (modewaarde == LOW){
       uit2 = 0;
       lcd.setCursor(0,0);
       lcd.print("buitengesloten!     ");              //get out
       delay(1000);
       i=1;
     }
     if (setwaarde == LOW){
       uit2 = 1;
       lcd.setCursor(0,0);
       lcd.print("mag er in           ");              //come in
       delay(1000);
       i=1;
     }
   }
   
       i = 0;
     while(i == 0){                                       //keeping out iButton 3
     lcd.setCursor(0,0);
     lcd.print("buitensluiten?  ja->");
     lcd.setCursor(0,1);
     lcd.print(name3);
     lcd.print("         nee->");
     delay(knoptijd);                                    //dubble waiting time here
     delay(knoptijd);
     modewaarde = digitalRead(knopmode);
     setwaarde = digitalRead(knopset);
     if (modewaarde == LOW){
       uit3 = 0;
       lcd.setCursor(0,0);
       lcd.print("buitengesloten!     ");              //get out
       delay(1000);
       i=1;
     }
     if (setwaarde == LOW){
       uit3 = 1;
       lcd.setCursor(0,0);
       lcd.print("mag er in           ");              //come in
       delay(1000);
       i=1;
     }
   }
   
       i = 0;
     while(i == 0){                                       //keeping out iButton 4
     lcd.setCursor(0,0);
     lcd.print("buitensluiten?  ja->");
     lcd.setCursor(0,1);
     lcd.print(name4);
     lcd.print("         nee->");
     delay(knoptijd);                                    //dubble waiting time here
     delay(knoptijd);
     modewaarde = digitalRead(knopmode);
     setwaarde = digitalRead(knopset);
     if (modewaarde == LOW){
       uit4 = 0;
       lcd.setCursor(0,0);
       lcd.print("buitengesloten!     ");              //get out
       delay(1000);
       i=1;
     }
     if (setwaarde == LOW){
       uit4 = 1;
       lcd.setCursor(0,0);
       lcd.print("mag er in           ");              //come in
       delay(1000);
       i=1;
     }
   }
   
       i = 0;
     while(i == 0){                                       //keeping out iButton 5
     lcd.setCursor(0,0);
     lcd.print("buitensluiten?  ja->");
     lcd.setCursor(0,1);
     lcd.print(name5);
     lcd.print("         nee->");
     delay(knoptijd);                                    //dubble waiting time here
     delay(knoptijd);
     modewaarde = digitalRead(knopmode);
     setwaarde = digitalRead(knopset);
     if (modewaarde == LOW){
       uit5 = 0;
       lcd.setCursor(0,0);
       lcd.print("buitengesloten!     ");              //get out
       delay(1000);
       i=1;
     }
     if (setwaarde == LOW){
       uit5 = 1;
       lcd.setCursor(0,0);
       lcd.print("mag er in           ");              //come in
       delay(1000);
       i=1;
     }
   }
   
   lcd.clear();

   }
}






void testKeyCode(){                            //check if the iButton presented is the right one
  lcd.setCursor(0, 1);
    if(keyStatus=="ok"){
    if(addr[1] == but1[1] && addr[2] == but1[2] && addr[3] == but1[3] && addr[4] == but1[4] && uit1 == 1){welkeBut=1; name = name1;}
    if(addr[1] == but2[1] && addr[2] == but2[2] && addr[3] == but2[3] && addr[4] == but2[4] && uit2 == 1){welkeBut=2; name = name2;}
    if(addr[1] == but3[1] && addr[2] == but3[2] && addr[3] == but3[3] && addr[4] == but3[4] && uit3 == 1){welkeBut=3; name = name3;}
    if(addr[1] == but4[1] && addr[2] == but4[2] && addr[3] == but4[3] && addr[4] == but4[4] && uit4 == 1){welkeBut=4; name = name4;}
    if(addr[1] == but5[1] && addr[2] == but5[2] && addr[3] == but5[3] && addr[4] == but5[4] && uit5 == 1){welkeBut=5; name = name5;}

    if(welkeBut == 1 || welkeBut == 2 || welkeBut == 3 || welkeBut == 4 || welkeBut == 5){
        lcd.print(name);
        lcd.print(" ");
        lcd.print(hour());
        printDigits(minute());
        lcd.print(" ");
        lcd.print(day());
        lcd.print("/");
        lcd.print(month());
        lcd.print(" ");
        digitalWrite(7, HIGH);
        delay(500);
        digitalWrite(7, LOW);
        bewaren();                        //put last visit in memory
    }
        
        if(welkeBut != 1 && welkeBut != 2 && welkeBut != 3 && welkeBut != 4 && welkeBut != 5){
          digitalWrite(7, LOW);
          lcd.print("                    ");
          lcd.setCursor(0, 1);
          byte i;
          for( i = 5; i >0; i--) {
            lcd.print(":");
            lcd.print(addr[i], DEC);
             }
           delay(1000);
           lcd.setCursor(0, 1);
           lcd.print("                    ");
           }
          }
          else {
            welkeBut = 0;
            if (keyStatus!="") {
              lcd.setCursor(0, 1);
              lcd.print(keyStatus);
              delay(1000);
              lcd.setCursor(0, 1);
              lcd.print("                    ");
            }
          }
}

void bewaren(){                                      //put last visit in memory
  geheugen[0] = geheugen[1];
  geheugen[1] = geheugen[2];
  geheugen[2] = geheugen[3];
  geheugen[3] = geheugen[4];
  geheugen[4] = geheugen[5];                        //every visit is moving one memory-location down
  geheugen[5] = geheugen[6];
  geheugen[6] = geheugen[7];
  geheugen[7] = geheugen[8];
  geheugen[8] = geheugen[9];
  geheugen[9] = name;                                //the newest visit is added
  
  memHour[0] = memHour[1];                          //the same for the hours
  memHour[1] = memHour[2];
  memHour[2] = memHour[3];
  memHour[3] = memHour[4];
  memHour[4] = memHour[5];
  memHour[5] = memHour[6];
  memHour[6] = memHour[7];
  memHour[7] = memHour[8];
  memHour[8] = memHour[9];
  memHour[9] = hour();

  memMinute[0] = memMinute[1];  
  memMinute[1] = memMinute[2];  
  memMinute[2] = memMinute[3];  
  memMinute[3] = memMinute[4];  
  memMinute[4] = memMinute[5];  
  memMinute[5] = memMinute[6];  
  memMinute[6] = memMinute[7];  
  memMinute[7] = memMinute[8];  
  memMinute[8] = memMinute[9];  
  memMinute[9] = minute();  
  
  memDay[0] = memDay[1];  
  memDay[1] = memDay[2];  
  memDay[2] = memDay[3];  
  memDay[3] = memDay[4];  
  memDay[4] = memDay[5];  
  memDay[5] = memDay[6];  
  memDay[6] = memDay[7];  
  memDay[7] = memDay[8];  
  memDay[8] = memDay[9];  
  memDay[9] = day();  

  memMonth[0] = memMonth[1];  
  memMonth[1] = memMonth[2];  
  memMonth[2] = memMonth[3];  
  memMonth[3] = memMonth[4];  
  memMonth[4] = memMonth[5];  
  memMonth[5] = memMonth[6];  
  memMonth[6] = memMonth[7];  
  memMonth[7] = memMonth[8];  
  memMonth[8] = memMonth[9];  
  memMonth[9] = month();  

}

Step 8: The Housing

To fit everything, I'm going to make an aluminum housing. It will be 13 cm x 8 cm x 6 cm.
  • First make a drawing. (this is a good moment to find flaws in your design)
  • Get a piece of aluminum
  • Cut out the pieces (or saw if you don't have have a cutter)
  • Next you bend it in the right shape. (if you don't have a bender, you can do it on the edge of a table, using a steel profile and wood clamps)
  • To hold the Arduino and PCB, you need to drill holes in the bottom. You can mark these through the holes in the Arduino-board. 
  • With some bolts (M3 = 3mm), you can montage the Arduino.
  • One bolt should go through the PCB. You will need this later to fine-tune the buttons on the PCB.
  • Drill the holes in the top plate. The top plate should support the LCD and the rods going to the buttons. Drill the holes on the places where the holes in the LCD are and right above the buttons on the PCB. You also need holes at the four corners of the front plate.
  • With a Dremel (or wannabe Dremel) you cut out the hole for the LCD. You need to cut it a little bit to small.
  • With a file in a vise you make the hole the right size.
  • If you want, you can spray paint the case. (I just painted the front black)
  • For the buttons I used slot bolts, but they are just to close to each other so I have to make them a little bit smaller on one side.
  • Make the holes above the buttons square if you want to use slot bolts as buttons.
  • Cut two bushes so they are just long enough that it fits between the top plate and the buttons on the PCB. There must be enough space in-between to fit a nut (I used a nylock nut)
  • Next you need to glue the bushes in place. (I use hot glue because I like hot glue)
  • Cut the slot bolts exactly the right size and keep them in place with the nut.
  • Screw the top plate in place.
  • Finetune the buttons with the little nut under the PCB.
  • Next make the sides of the box. (I used perforated material that fits snugly, so I don't need to use bolts)
  • Drill holes in the side plates for the cables
  • Connect the cables going to the garage door opening button and to the iButton-reader. (put the cables trough the holes in the side plates)
  • Put everything together.
  • Finally I made the bolts black with a marker.



Step 9: Installing the IButton System

To finnish it al up, we just need to connect everything.
The iButton-reader has to go though the doorframe to the outside. You need to drill a hole for the wire to go trough. 4 mm is big enough. If you drill this hole from the outside in, you want to drill slightly upwards, so water can not run in.
On the outside you need to make the hole a bid bigger. In my case; 10 mm for the body of the iButton-reader and 18 mm for the outer rim. I had to make the wires a little bit longer to get to my controller. Be careful nog to switch the wires around.
Now it is easy to install the iButton Reader.

The wires coming from the relay should go to the screws on the back of the button that opens the garage. It doesn't matter what way around.

Now it is time to plug the Arduino in and see if it is working!

Step 10: The Controls

I gave the garage door-opener a couple of functions:
  • On the top-line of the LCD you can see the time and date.
  • On the bottom-line you can see who entered last including the time and date, he entered.
  • If you push the top button, you can set the clock and first change the hour by pushing the bottom-button. If you push the top-button again, you change the minutes with the bottom-button. Next comes date and month.
  • If you push the bottom-button, you can skip trough the 10 last entries. Every time you push the bottom-button, you will go back one in time.
  • When you first push the bottom-button and than the top-button, you can block or de-block iButtons. All iButtons will appear with the question to block it: top-button is yes, bottom-button is no.