Saturday, December 25, 2010

Arduino Wireless Garage Door Opener

First off contain yourself, that is right Matt Emerson is posting a blog page... Doesn't happen often but I wanted to put this information out there to help anyone else who is trying to do something similar.

If you are interested in programming hardware check out Arduino

The entire idea behind this project was to have my garage door open wirelessly. So I have a transmitter and a reciever, and when the receiver gets a signal it simulates someone pushing the button by closing a relay, shorting the two wires to operate the garage door. (this garage door is OLD, I am talking REALLLY OLD!!!)

Parts:
$25 - Nordic FOB http://www.sparkfun.com/products/8602
$20 - Nordic nRF24L01 http://www.sparkfun.com/products/705
$15 - RBBB (Ardunio Clone) http://shop.moderndevice.com/products/rbbb-kit
$4   - Sharp S101S02 Solid State Relay  http://www.jameco.com/webapp/wcs/stores/servlet/ProductDisplay?langId=-1&productId=164988
$.50 - Misc. Transistor that came with Ardunio kit I bought.
$.20 - Misc. Resistor that came with Ardunio kit I bought.

    Random antennae that i had....
----
$65 - Just to prove that I could. Of course the Ardunio is capable of much more then I am using it for so I plan to expand it in the future, temperature, barometric pressure, and more reads... just haven't gotten to it yet.



 And now the code:

#include
#include
#include
/* Pins:
 * Hardware SPI:
 * MISO -> 12
 * MOSI -> 11
 * SCK -> 13
 *
 * Configurable:
 * CE -> 9
 * CSN -> 10
 */
 byte data[4]; //set the data to be retreived from wireless module
 byte lastdata; // compare new data to last data
   //I am having a problem where the reciever keeps on reading "new" data in the form of a 'right' button press. but it is not new data, it is simply reading old
   // data over and over again... as evidence by the data[2] bit not changing... this data bit from the FOB is the number of button pushes since battery replacement
   // or at least it changes every button push, but does not change when faulty data is being read. So I store the last bit 2 and compare it to the new one, if
   // there is no change, toss the data out it is garbage.
 int timer = 0; // set the timer to prevent repeat button presses (bounce)
 int subtimer =0; // ser the subtimer to trigger the real timer (allows for reading of the buffer faster but only responding every so often to the fob presses)


void setup() {               
  pinMode(4, OUTPUT);  // This is the output connected to a transistor, connected to a solid state relay.
pinMode(2, OUTPUT);

  Mirf.csnPin = 10; //set the nordic CSN pin to 10
  Mirf.cePin = 9;   //ser the nordic CE  pin to 9
  Mirf.init();      //initialize the nordic

  byte rx_addr[5] = {0xE7, 0xE7, 0xE7, 0xE7, 0xE7};


  Mirf.setRADDR(rx_addr);

  Mirf.configRegister(RF_SETUP, 0x07); //Data rate 1Mbit / 0dBm
  Mirf.configRegister(EN_AA, 0x00); //Disable auto acknowledge
  Mirf.payload = 4;  //bytes to be read
  Mirf.channel = 2;  // channel used
  Mirf.config();
//  Serial.begin(9600);     //used while developing
//   Serial.println("start"); //used while developing
   Mirf.flushRx();  // start with a clean buffer, I had issues without this occassionally.
}

void loop() {


        Mirf.getData(data);  // get data from the buffer
//        Serial.print(data[0]);  //used while developing
//        Serial.println(" ");
          if (data[2] != lastdata){  // check if the data[2] is the same as last time, if it is do nothing.... bad data
            lastdata = data[2];
              switch (data[0]) {
                    case 0x00:
                    break;
                case 0x1D:
//                    Serial.println(timer); //used while developing up button
                    OpenDoor();
                    break;
                case 0x1E:
//                    Serial.println("DOWN"); //used while developing
                    OpenDoor();
                    break;
                case 0x17:
//                    Serial.println("LEFT"); //used while developing
                    OpenDoor();
                    break;
                case 0x1B:
//                    Serial.println("RIGHT"); //used while developing
                      OpenDoor();
                    break;
                case 0x0F:
                    OpenDoor();
//                    Serial.println("CENTER"); //used while developing
                    break;
                default:
                    break;           
          }
       }
  delay(5);
  // for ever 40 subtimer clicks, click one timer click
  // yes is is crude, yes it is wierd, yes I could have multiplied it out an done it with on timer
  // but you get a little crazy writing code some times....
  if (subtimer >=40) {
    timer = timer + 1; 
    subtimer = 0;   
  }
  if (timer >= 100){ //don't allow timer to get greater then 100... if it gets too high will turn massivly negative
    timer =100;
  }
  subtimer = subtimer + 1;
 
  // End of LOOP
}

void OpenDoor() {
  if (timer <= 34) { //If timer isn't ready yet, short pulse the LED, to at least let you know signal was recieved
      digitalWrite(2, HIGH); // This is used to light an LED on pin2 to make sure board is working
      delay(100);
      timer = timer + 1;
      digitalWrite(2, LOW);    // This is used to light an LED on pin2 to make sure board is working
  }
  if (timer >= 35) {  //time is ready and this will allow the garage door to operate
          timer = 0; //reset timers to allow for delay before next operation
                     // THIS IS A MUST BECAUSE THE NORDIC FOB HAS KEY BOUNCE!!!
                     // it will send multiple key presses for one physical press
          subtimer = 0;
//          Serial.println("start door");//used while developing
         digitalWrite(2, HIGH); //trigger LED on for long pulse to let you know signal recieved, door should be operating
          digitalWrite(4, HIGH); //trigger the transitor -> the solid state relay to closed (this simulates a button push of the garage door)
          delay(2000);
          digitalWrite(4, LOW); //turn off transistor after 2 second delay.
          digitalWrite(2, LOW); //turn off OPTIONAL LED for evauliting if board is working...
//          Serial.println("stop door");//used while developing
  }
}

Please let me know if you see anything horribly wrong with my code or hardware, I am very much in unknown territory here.

-Matt

6 comments:

  1. Uh....... yeah.... I''m in unknown territory too :P

    ReplyDelete
  2. Nice post. I plan to do the same, but with XBee for wireless, and add a door-left-open alert. BTW, more like $78 with shipping, right :)

    ReplyDelete
  3. Good Evening,
    I will start my own project soon and I was reading your code and couldn't understand why did you put 3 #includes with no library associated.
    Good work btw!

    ReplyDelete
  4. Good post … I learn something totally new and challenging on websites .I stumbleuρon evеryday. It's always interesting to read through content from other writers and practice something from other web sites.
    winston salem garage doors

    ReplyDelete
  5. Good post … I learn something totally new and challenging on websites .I stumbleuρon evеryday. It's always interesting to read through content from other writers and practice something from other web sites.
    winston salem garage doors

    ReplyDelete