Smart Garage Door is DIY project that converts existing Manual/Remote controlled garage door operation to be controlled by a smart device connected to internet from anywhere. The project uses Arduino you can choose any programming interface for your choice. Concepts remain same.
Advantages: Controls (Open/Close) garage door from anywhere any time, Check status of garage door from anywhere any time
Build Alternate: Buy a garage door motor that comes bundled with smart apps or smart garage door controllers.Project concept idea is based upon that garage door panels open towards the garage roof. When Garage door is open the distance between the garage roof and folded door panel is less compared to when garage door is closed. So by measuring the distance between garage roof and door panel it can be determined if garage door is open or closed.
Cost < $25 USD
Build Time < 1 day
Unlimited opportunity for Perfection & Enhancements to suite your automation cravings
Device Components/Parts:
Software:
Assembly:
Recommend to use breadboard to start and test. Once every thing working then only use pcb and soldering
NodeMCU:
NodeMcu pin D1 connected to trig pin on HC-SR04Nodemcu pin D2 connected to echo pin on HC-SR04Nodemcu pin D7 connected to in pin of 5V relayNodemcu pin GND connected to 3V -ve terminal of power supply module (Top right pin of nodemcu see image above)Nodemcu pin 3V3 connected to 3V +ve terminal of power supply module ( 2nd top right pin of nodemcu see image above)HC-SR04:
5V Relay:
Arduino Code: Make changes for your wifi and Mqtt settings
/*
GJs Smartn Garage
Using NodeMCu esp8266, Ultra sonic HC-SR04 distance sensor, wifi, mqtt,openhab
*/
#include <ESP8266WiFi.h> //Needed for wifi connection.
#include <PubSubClient.h> //Needed for MQTT communication */
// define global variable
// defines nodemcu pins numbers
const int trigPin = 5; //NodeMcu pin D1 connected to trig pin on HC-SR04
const int echoPin = 4; //Nodemcu pin D2 connected to echo pin on HC-SR04
const int relaypin = 13; //Nodemcu pin D7 connected to in pin of relay HONGWEI 5V Low trigger
// defines variables
long duration; //Time takes to get ultra sonic echo back
int distance; //Distance
String mqttclientname; //Unique name for mqtt client
String pubstr; //String for preparing message for publishing to MQTT
String gdstate; //Garage door state as reported by sensor
char msgpub[50]; // Need char array to publish to mqtt
String incmd ; //For storing MQTT subscribe message
int value = 0;
//Wifi Settings - Change to your wifi Network
const char* ssid = "<replace your home wifi ssid>" ;
const char* passwd = "<replace with your home wifi password>" ;
// MQTT Settings - Change to your MQTT broker and topic settings
IPAddress mqttserver(192,168,1,253); //"Replace YourMQTTBroker's IP or servername"
const char* outtopic = "GH/out/GarageDoor"; // Topic Sending garage door status to MQTT broker change and take note to your liking
const char* intopic = "GH/in/GarageDoor"; // Topic Getting command from MQTT broker change and take note to your liking
const char* statetopic = "GH/out/GarageDoor/State"; // Communicating Garage door status like sensor distance to MQTT broker
WiFiClient NodeMCU_WiFi; //Create an instance of wifi client
PubSubClient NodeMCU_MQTT_CL(mqttserver, 1883, NodeMCU_WiFi); //Create an instance of MQTT client, MQTT_sub_callback needs to be defined and gets executed when mqtt message arives
void connectwifi(){ //Check and connect to wifi
if (WiFi.status() != WL_CONNECTED) {
Serial.print("Connecting to ");
Serial.print(ssid);
Serial.println("...");
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, passwd); //Connect to Wifi
//Get Unique client name for mqtt client
mqttclientname="GD-";
uint8_t mac[6];
WiFi.macAddress(mac);
for (int i = 0; i < 6; ++i) {
mqttclientname += String((mac[i]));
}
if (WiFi.waitForConnectResult() != WL_CONNECTED)
return;
}
else
{
Serial.print("WiFi connected ");
Serial.print(ssid);
Serial.print(" IP Address:");
Serial.println(WiFi.localIP()); //Local IP
}
}
void connectMQTT(){ //Check and connect MQTT broker
if (WiFi.status() == WL_CONNECTED) { //Check wifi is still connected
if (!NodeMCU_MQTT_CL.connected()) {
Serial.print(" MQTT Client:");
Serial.print(mqttclientname.c_str()); //Name is derived in connectwifi
Serial.print(" is connecting to MQTT broker ");
Serial.print(mqttserver);
Serial.print("...");
NodeMCU_MQTT_CL.connect((char*) mqttclientname.c_str()); //Try connect - Get client name from connectwifi
//check status again
if (!NodeMCU_MQTT_CL.connected()) {
Serial.print("Not connected to MQTT broker...");
Serial.print(" Return Status:");
Serial.println(String(NodeMCU_MQTT_CL.state()));
return ;
}
}
else {
Serial.print("MQTT client:");
Serial.print(mqttclientname.c_str());
Serial.print(" is connected to MQTT broker:");
Serial.println(mqttserver);
Serial.print("In Topic:");
Serial.print(intopic);
Serial.print(" Out Topic:");
Serial.print(outtopic);
Serial.print(" State Topic:");
Serial.print(statetopic);
return;
}
}
}
void MQTT_sub_callback(char* topic, byte* payload, unsigned int length) {
//This gets executed everytime mqtt client.subscribe is invoked
Serial.print("MQTT_Sub_callback: Message arrived in topic - ");
Serial.print(topic);
for (int i = 0; i < length; i++) {
incmd += (char)payload[i]; //Copy in comming message to permanent variable
}
incmd.trim(); //Remove leading and trailing spaces if any
incmd += '\0'; //Add ending null terminator to message string
//InCmd.toUpperCase(); // Convert to upper case and remove spaces if any to make it case insensitive comparison
Serial.print(" with length ");
Serial.print(length);
Serial.print(" and CMD:");
Serial.println(incmd);
}
// the setup function runs once when you press reset or power the board
void setup() {
pinMode(LED_BUILTIN, OUTPUT); // initialize digital pin LED_BUILTIN as an output.
pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
pinMode(echoPin, INPUT); // Sets the echoPin as an Input
pinMode(relaypin, OUTPUT); //Sets the relay pin as putput
//pinMode(greenled, OUTPUT); // Sets the green led pin an Output
//pinMode(redled, OUTPUT); // Sets the red led Pin as an output
Serial.begin(115200); // Starts the serial communication
//Connect to wifi
//delay(5000);
Serial.println("Iniatializing......");
//Set builtin LED on and relay off
digitalWrite(LED_BUILTIN, LOW); // turn the built-in LED ON works oposite
digitalWrite(relaypin, 1); // turn relay off works opposite for low trigger relay
connectwifi();
//Connect to the MQTT broker
delay(5000);
NodeMCU_MQTT_CL.disconnect(); // Clear any old connections
connectMQTT();
//MQTT subscribe callback setup
NodeMCU_MQTT_CL.setCallback(MQTT_sub_callback);
}
void getdistance(){
distance = 0 ; // reset old value
duration = 0 ;
gdstate = "" ;
for (int i = 0; i < 3; i++) { //Get three time for consistency results as results are comming in consistent from ultrasonic sensor
digitalWrite(trigPin, LOW); // Clears the trigPin
delayMicroseconds(10); // wait for 10 micro seconds
digitalWrite(trigPin, HIGH); // Sets the trigPin on HIGH state to send ultrasound beam out
delayMicroseconds(25); // // wait for 15 micro second for beam to come back
digitalWrite(trigPin, LOW);
duration = duration + pulseIn(echoPin, HIGH, 180000UL); // Reads the echoPin, returns the sound wave travel time in microseconds and add to previous reading. Not sure why 180000UL read in one of examples
delayMicroseconds(50); // // wait for 50 micro second for next iteration
}
distance = ((duration/3)*0.034)/2; // Calculating the distance in cm keep in mind duration is sum of 3 readings so needs to take average
if (distance < 60) //Garge door is OPEN if distance is less than 60cm from roof
gdstate = "Open" ;
else
gdstate = "Close";
// Prints the distance on the Serial Monitor
Serial.print("Sensor: Duration:");
Serial.print(duration);
Serial.print(", Distance:");
Serial.print(distance);
Serial.print(", Door state:");
Serial.println(gdstate);
}
// the loop function runs over and over again forever
void loop() {
digitalWrite(LED_BUILTIN, LOW); // turn the built-in LED ON works oposite
digitalWrite(relaypin, 1) ; // Ensure relay is off
//Check and connect wifi
connectwifi();
//Check and connect MQTT
connectMQTT();
incmd = ""; //Empty the old command/message
if (!NodeMCU_MQTT_CL.subscribe(intopic)) //Check queue connection status
Serial.println("Subscribe Failed...");
NodeMCU_MQTT_CL.loop(); // keeps client active and reads message
// Read ultrasonic sensor
getdistance();
//Publish state to broker
pubstr = gdstate ;
pubstr.toCharArray(msgpub,50);
NodeMCU_MQTT_CL.publish(outtopic, msgpub); //Garage door status
pubstr = "MQTT:" + String(NodeMCU_MQTT_CL.state()) + ",Door:" + gdstate + ", Dist.:" + String(distance) + "cm, Relay:" + String(digitalRead(relaypin)) + " and CMD: " + incmd;
pubstr.toCharArray(msgpub,50); //Convert string to Char Array for publishing
Serial.println(pubstr);
NodeMCU_MQTT_CL.publish(statetopic, msgpub); // Garage door message
// Door Logic
if ((gdstate == "Open") && (incmd == "Close")) { // Close Garage door
pubstr = "Closing Garage Door .....Relay:" + String(digitalRead(relaypin)) + " and CMD: " + incmd;
pubstr.toCharArray(msgpub,50); //Convert string to Char Array for publishing
Serial.println(pubstr);
NodeMCU_MQTT_CL.publish(statetopic, msgpub);
digitalWrite(relaypin, 0); // relay on
delay(200); // Wait for relay to send signal
digitalWrite(relaypin, 1) ; // relay off
delay(1000); //Wait a second for door to close
}
if ((gdstate == "Close") && (incmd == "Open")) { // Open Garage door
pubstr = "Opening Garage Door .....Relay:" + String(digitalRead(relaypin)) + " and CMD: " + incmd;
pubstr.toCharArray(msgpub,50); //Convert string to Char Array for publishing
Serial.println(pubstr);
NodeMCU_MQTT_CL.publish(statetopic, msgpub);
digitalWrite(relaypin, 0); // relay on
delay(200); // Wait for relay to send signal
digitalWrite(relaypin, 1) ; // relay off
delay(1000); //Wait a second for door to close
}
if ( ((gdstate == "Open") && (incmd == "Open")) || ((gdstate == "Close") && (incmd == "Close")) ) { // Mismatch Command do nothing
pubstr = "Door is already :" + gdstate +"..... No action for CMD: " + incmd;
pubstr.toCharArray(msgpub,50); //Convert string to Char Array for publishing
Serial.println(pubstr);
NodeMCU_MQTT_CL.publish(statetopic, msgpub);
}
digitalWrite(LED_BUILTIN, HIGH); // turn the built-in LED OFF works oposite
Serial.println("-*-*-*-*-*-*-*-*");
delay(500); // wait half second as loop is going too fast
}
Configuration: check this page under Automation Interfaces/OpenHAB configurations