Maxwell krolakMaxwell Krolak
Published © GPL3+

Lane Tech HS - PCL - IOT Bluetooth Garage Door Opener

Imagine a garage door opener that can be accessed from anywhere and opens your garage when your phone is near. That dream is now a reality.

IntermediateFull instructions provided4 hours3,050

Things used in this project

Hardware components

Photon
Particle Photon
×1
Breadboard (generic)
Breadboard (generic)
×1
General Purpose Transistor NPN
General Purpose Transistor NPN
×1
LED (generic)
LED (generic)
×1
Jumper wires (generic)
Jumper wires (generic)
×8
HC-05 Bluetooth Module
HC-05 Bluetooth Module
×1
Garage Door opener
×1
Android device
Android device
×1

Software apps and online services

Firebase
Google Firebase
I used this program for the web interface and is not needed for the main project.
atom
I used this program for the web interface and is not needed for the main project.
particle web ide

Hand tools and fabrication machines

Hot glue gun (generic)
Hot glue gun (generic)
Soldering iron (generic)
Soldering iron (generic)

Story

Read more

Schematics

Garage Door Opener Circuit

This is the circuit excluding my garage door opener.

garagedooropener_bb_awgu4N5OBK.png

Code

Original Source Code

Arduino
This code manages the adding and tracking of phones and the opening of the garage door.
#include "Device.h"

Device devices[10];

//version of the code stored for auto update feature on website
const double version = 2.0;

//Flag variables for position of the door
int lastPos = 0;
int lastOpen = 0;
int open = 0;


//flag variable for adding device
bool addClosestPhone = false;
//flag variable for setting password
bool setPas = false;

//Temp string holds the information gotten with the last call to the AT+INQ?
String tempString = "";
//Holds the nessesary information for the flagged methods
String tempInfo = "";


//Stores the distance value were the door will open 
int distance = 65500;
//Stores the amount of current devices in the device array[]
int deviceNum = 0;


//Methods beinging defined for the Particle.function();
int addClstPhn(String s);
int setPassword(String pas);
int setDistance(String d);
int toggleGarage(String d);


void setup() {
  //Initilizing Serial1 for bluetooth and Serial for debugging
  Serial.begin(9600);
  Serial1.begin(38400);
  
  //Pin for transister
  pinMode(6,OUTPUT);
  
  //Function and variable definitions for particle cloud
  //Used in web interface
  Particle.function("addClstPhn", addClstPhn);
  Particle.function("setDistance", setDistance);
  Particle.function("setPassword", setPassword);
  Particle.function("toggleGarage", toggleGarage);
  Particle.variable("version", version);
  Particle.variable("isOpen", open);
  
  
  //Initilization of bluetooth module
  Serial1.println("AT");
  delay(100);
  Serial1.println("AT+CMODE=1");
  delay(100);
  Serial1.println("AT+ROLE=1");
  delay(100);
  Serial1.println("AT+INQM:1,10,10");
  delay(100);
  Serial1.println("AT+CLASS=0");
  delay(100);
  Serial1.println("AT+INIT");
  delay(100);
  readAll();
  
  Serial1.println("AT+INQ");
}

void loop() {

  //Wating for charecter to become available for read and adding it to current string
  if (Serial1.available()) {
    tempString += (char)Serial1.read();
  }

  //Waits for the at+inq call to end before calling other bluetooth commands
  if (tempString.endsWith("OK") || tempString.endsWith("FAIL")) {
     Serial.println(tempString);
    

    int delta = openCloseGarage(tempString)-lastPos;
    if(delta!=0){
        open=delta+lastPos;
    }
    lastPos = open;
    
    if(addClosestPhone)addClstPhn(tempString);
    if(setPas)setPassword(tempInfo);


    Serial1.println("AT+INQ");
    tempString = "";
  }
  


  if(lastOpen != open){
      digitalWrite(6,HIGH);
      delay(500);
      digitalWrite(6,LOW);
      lastOpen = open;
  }
}


//Sets the distance
int setDistance(String d) {
    distance=d.toInt();
    return 1;
}

//Adds the closest phone to the bluetooth module using the data obtained from the at+inq call
int addClstPhn(String d) {
  if (addClosestPhone) {
    Device tempD1 = Device();
    for (int i = 0, start = 0; i < d.length(); i++) {
      if (d.charAt(i) == '\n' || i + 1 == d.length()) {
        Device tempD2 = parseDeviceString(d.substring(start, i));
        if (tempD2.signal > tempD1.signal)tempD1 = tempD2;
        start = i + 1;
      }
    }
    
    
    
    Serial1.println("AT+pair=" + tempD1.id + ",15");
    readAll();
    
    while(!Serial1.available());
    d = readAll();
    d = d.trim();
    Serial.println(d);
    if(d.equals("OK")){
        Serial.println("here   " + tempD1.id);
        addDevice(tempD1);   
    }
    
    addClosestPhone = false;
    return 1;
  } else {
    addClosestPhone = true;
    return 0;
  }


}

//Sets the password of the device by setting a flag and waiting for all other calls to the bluetooth module have ended
int setPassword(String pas) {
  if (setPas) {
    Serial1.println("AT+PSWD=" + pas);
    readAll();
    setPas = false;
    return 1;
  } else {
    tempInfo = pas;
    setPas = true;
    return 0;
  }
}

//Inputs a single line of the at+inq response and outputs device object representing the data
Device parseDeviceString(String s) {
  if (!s.equalsIgnoreCase("OK")) {
    String temp = "";
    long hexVal = 0;
    int i = 0;
    s.replace("+INQ:", "");
    for (; i < s.length() && s.charAt(i) != ','; i++) {
      temp += s.charAt(i);
    }

    for (i = i + 2; i < s.length(); i++) {
      if (s.charAt(i) == ',') {
        char tempA[s.length() - i + 1];
        ("0x" + s.substring(i + 1)).toCharArray(tempA, s.length() - i + 1);
        i = s.length();
        s = "";
        hexVal = strtol(tempA, NULL, 0);

      }
    }
    temp.replace(":", ",");

    return Device(hexVal, temp);
  }
  return Device();
}

//Using the bluetooth module's data as input returns weather or not the garage should be open or closed
bool openCloseGarage(String d){
    for (int i = 0, start = 0; i < d.length(); i++) {
      if (d.charAt(i) == '\n' || i + 1 == d.length()) {
        Device tempD2 = parseDeviceString(d.substring(start, i));
        Serial.println(String(distance) + " " + String(tempD2.signal));
        Serial.println(String(isValidDevice(tempD2.id)) + tempD2.id + " " + devices[0].id);
        if(tempD2.signal > distance && isValidDevice(tempD2.id)!=-1) return true;
        start = i + 1;
      }
    }
    return false;
}

//Adds the Device specifed to the array returning true if succsessful 
//and returns false if the array is full or the device is already in the array 
bool addDevice(Device d) {
  if (deviceNum < 10 && isValidDevice(d.id)==-1) {
    devices[deviceNum] = d;
    deviceNum++;
    return true;
  }
  return false;
}

//Removes specified device from the array and returns a boolean representing its sucsess 
bool removeDevice(String id) {
    int i = isValidDevice(id);
    if(i != -1){
      devices[i] = devices[deviceNum];
      devices[deviceNum-1] = Device();
      deviceNum--;
      return true;
  }
  return false;
}


//Returns the position in the device array that contains a device with the same bluetooth address
int isValidDevice(String id){
    for (int i = 0; i < deviceNum; i++) {
        if (devices[i].id.equals(id)) {
            return i;
        }
    }
    return -1;
}

//Reads all incoming data from the blueooth module and returning the data as a String
String readAll() {
  String s = "";
  while (Serial1.available()) {
    s += (char)(Serial1.read());
    delay(100);
  }
  return s;
}

//Toggles the state of the garage door independant of the positions of the phones
int toggleGarage(String d){
    open = (open*-1)+1;
    return 1;
}

Credits

Maxwell krolak

Maxwell krolak

2 projects • 6 followers
Maxwell Krolak

Maxwell Krolak

3 projects • 6 followers
Lane Tech Junior

Comments