Project tutorial
Automated Driveway Gate(s)

Automated Driveway Gate(s) © GPL3+

This tutorial is about making an automated gate for your driveway for $200 with ESP8266, Arduino, and Blynk.

  • 1,571 views
  • 0 comments
  • 4 respects

Components and supplies

Necessary tools and machines

Apps and online services

About this project

Story

Problem: My driveway is a public turn-around. Solution: gates. So we bought some gates, but getting out of the car to open two gates twice a day is pretty dumb. I looked at automated gate kits, but they range from $400 - $900. I decided to make my own, seeing that it would be more cost effective and much more fun.

Connecting the Motor Driver and Linear Actuators

The motor driver board has 10 pins; 2 gnd, 2 +5v, 2 pwm, and 4 io.

Driver - Arduino

5V - 5V

GND - GND

IN1 - D4

IN2 - D3

IN3 - D2

IN4 - D1

PWM does not have to be connected. Connect the linear actuator(s) to the black screw terminal(s). It does not matter which way you connect the linear actuator(s), but if you have two, you need to make sure that they are both connected the same way.

Connecting the ESP8266 to the Arduino

I am in the process of installing this and ran into a problem. The 3.3v logic output of the ESP8266's pins won't turn on the actuators. So I decided to connect the ESP8266 to the Arduino because the Arduino's logic level is 5v. I didn't have any logic level converters so I connected them in such a way that you don't need a logic level converter.

Arduino - ESP

A2 - D4

A3 - D3

A4 - D2

A5 - D1

optional:

A0 - 5V

A1 - GND

Powering the Microcontroller

To power this setup, I had a couple ideas. The simplest one, is to just use a 5v regulator connected to the VIN pin of the motor driver.

Setting up Blynk

This setup needs a lot of Blynk parts. Here's what it's suppose to look like when done.

Start by downloading the Blynk app on your iPhone. Sign up and make a new project named "Driveway Gate".

Then add a new esp8266 device with wifi.

Next, tap your project page and select "Button" on the popout page.

Click the button and change the "Output" pin to "V0". Change the mode to "PUSH".

All the rest of the settings for each module are shown below.

Installation

Drill a hole in the side of the waterproof enclosure for a power cable and the linear actuator cables. Add a hole on the back of the case for power and data. Once everything is connected with jumper wires, place the motor driver, Arduino and ESP8266 inside the waterproof enclosure and screw the cover on. Install the box to your gate post, run the power cable to your house and run the linear actuator cables to the linear actuator(s).

For installing the linear actuator(s), use this website.

Setting Up Arduino IDE

If you need help installing or using the Arduino IDE, go to https://www.arduino.cc/en/Guide/HomePage

In the Arduino IDE, open a new sketch and paste the code "Automated-Driveway-Gates.ino". Or, go to the Github directory and download the code. After you have your main sketch ready, open a new tab and name it "settings.h".

Paste the "settings.h" code into this new tab, and you're ready to go. Upload the code and open the serial monitor on baud rate 9600.

Code Explanation

The code is made in such a way that you can change all the settings in a separate settings.h file instead of going through and changing the code. Here's the breakdown of the settings.h.

//blynk
#define BLYNK_AUTH_TOKEN "your_auth"
#define BLYNK_GREEN "#23C48E"
#define BLYNK_RED "#D3435C"
#define BLYNK_YELLOW "#ED9D00"
#define BLYNK_BLUE "#04C0F8"
#define YOUR_LAT 43.419868
#define YOUR_LONG -72.467632

//WiFi
char WIFI_SSID[] = "your_ssid";
char WIFI_PASS[] = "your_pass";

IOT and WiFi settings.

#define emergencyButton 14    //just in case you forget your phone, click this button on the box.

//GATE
String Mode = "button"; //automatic or button
#define gateNumber 2 //how many gates; 1 or 2
int gateOpenAmount = 10; //only for automatic mode, seconds
#define gateDirection 1 //1 or 2

//linear actuator
#define inchesPerSec .39 //inches per sec of linear actuator
#define maxActuatorStroke 16 //max stroke of linear actuator
#define percentOfMaxStroke 1 //0 through 1
#define a1 2 //first linear actuator
#define a2 0 //first linear actuator
#define b1 4 //second linear actuator
#define b2 5 //second linear actuator

This is all the gate settings. You can change the settings for how your gates are setup and the info on your linear actuators. The percentOfMaxStroke is to define how much of the linear actuator is being used while opening the gates. Input can be from 0.01 - 1.

Driveway Gate code breakdown.

#define BLYNK_PRINT Serial

#include "settings.h"
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <BlynkSimpleEsp8266.h>
#include <math.h>

Including libraries.

int timer = 0;
int button;
int emergency;
int setting;
int delayAMOUNT;
int gpsSelect;
int distanceSelect;
int comingHome;
int openTest;
int closeTest;
float GPSLat;
float GPSLong;

float dist_calc=0;
float dist_calc2=0;
float diflat=0;
float diflon=0;

Making places to hold info.

BLYNK_CONNECTED() {
Blynk.syncAll();
Serial.println("Syncing...");
delay(2000);
}
BLYNK_WRITE(V0){
button = param.asInt();
}
BLYNK_WRITE(V1){
emergency = param.asInt();
}
BLYNK_WRITE(V2){
setting = param.asInt();
if (setting == 1) {
Mode = "automatic";
}
else if (setting == 0) {
Mode = "button";
}
}
BLYNK_WRITE(V3){
gateOpenAmount = param.asInt();
}

BLYNK_WRITE(V4){
delayAMOUNT = param.asInt();
}
BLYNK_WRITE(V5){
GpsParam gps(param);
GPSLat = gps.getLat();
GPSLong = gps.getLon();
}
WidgetLED led(V6);
BLYNK_WRITE(V8){
gpsSelect = param.asInt();
}
BLYNK_WRITE(V9){
distanceSelect = param.asInt();
}
BLYNK_WRITE(V10){
comingHome = param.asInt();
}
BLYNK_WRITE(V12){
openTest = param.asInt();
}
BLYNK_WRITE(V13){
closeTest = param.asInt();
}

Setting up Blynk inputs.

Serial.begin(9600);
if (gateNumber == 1){
pinMode(a1, OUTPUT);
pinMode(a2, OUTPUT);
}
else if (gateNumber == 2){
pinMode(a1, OUTPUT);
pinMode(a2, OUTPUT);
pinMode(b1, OUTPUT);
pinMode(b2, OUTPUT);
}
pinMode(emergencyButton, INPUT_PULLUP);

In setup, we start the serial and setup the pin modes.

Blynk.begin(WIFI_SSID,WIFI_PASS,BLYNK_AUTH_TOKEN);
led.on();
led.setColor(BLYNK_RED);

Here we just get the Blynk started.

void loop() {
Blynk.virtualWrite(V11, WiFi.RSSI());
if (emergencyButton == LOW){
Serial.println("Emergency Button!");
Blynk.notify("Emergency Button on Gates was just Pressed!!!");
gates();
}
if (button == 1){
Serial.println("Button pressed.");
gates();
}
if (emergency == 1){
Serial.println("M");
led.setColor(BLYNK_YELLOW);
manual();
delay(delayAMOUNT*1000);
led.setColor(BLYNK_RED);
}
if (gpsSelect != 1){
Blynk.virtualWrite(V7,calcDist(GPSLat, GPSLong, YOUR_LAT, YOUR_LONG));
if (comingHome == 1){
Serial.println(calcDist(GPSLat, GPSLong, YOUR_LAT, YOUR_LONG));
if (calcDist(GPSLat, GPSLong, YOUR_LAT, YOUR_LONG) < distanceSelect){
Serial.println("GPS triggered!");
opengates();
}
}
} Blynk.run();
}

In the loop, we handle Blynk. First we write our signal strength to virtual pin 11. Then we handle if the emergency button on the back of the box was pressed. Next, we handle the main gate button and the emergency button on Blynk. Lastly, we handle GPS and put Blynk.run(); to stay connected to the Blynk server.

void gates(){
Serial.println("Got Mail!");
if (Mode == "automatic"){
Serial.println("Mode = Automatic");
Serial.println("Opening gate...");
led.setColor(BLYNK_BLUE);
openGate();
waitForGate();
allStop();
led.setColor(BLYNK_GREEN);
Serial.println("Open.");
Serial.println("Waiting...");
delay(gateOpenAmount*1000);
Serial.println("Closing gate...");
led.setColor(BLYNK_BLUE);
closeGate();
waitForGate();
allStop();
led.setColor(BLYNK_RED);
Serial.println("Closed.");
}
else if(Mode == "button"){
Serial.println("Mode = Button");
if (timer == 0){
Serial.println("Openning gate...");
led.setColor(BLYNK_BLUE);
openGate();
waitForGate();
allStop();
led.setColor(BLYNK_GREEN);
Serial.println("Open.");
timer = 1;
}
else if(timer == 1){
Serial.println("Closing gate...");
led.setColor(BLYNK_BLUE);
closeGate();
waitForGate();
allStop();
led.setColor(BLYNK_RED);
Serial.println("Closed.");
timer = 0;
}
}
}

This is the function to open the gate(s).

void openGate(){
if (gateDirection == 1){
if (gateNumber == 1){
digitalWrite(a1, HIGH);
digitalWrite(a2, LOW);
}
else if (gateNumber == 2){
digitalWrite(a1, HIGH);
digitalWrite(a2, LOW);
digitalWrite(b1, HIGH);
digitalWrite(b2, LOW);
}
}
else if (gateDirection == 2){
if (gateNumber == 1){
digitalWrite(a1, LOW);
digitalWrite(a2, HIGH);
}
else if (gateNumber == 2){
digitalWrite(a1, LOW);
digitalWrite(a2, HIGH);
digitalWrite(b1, LOW);
digitalWrite(b2, HIGH);
}
}
}

void closeGate(){
if (gateDirection == 1){
if (gateNumber == 1){
digitalWrite(a1, LOW);
digitalWrite(a2, HIGH);
}
else if (gateNumber == 2){
digitalWrite(a1, LOW);
digitalWrite(a2, HIGH);
digitalWrite(b1, LOW);
digitalWrite(b2, HIGH);
}
}
else if (gateDirection == 2){
if (gateNumber == 1){
digitalWrite(a1, HIGH);
digitalWrite(a2, LOW);
}
else if (gateNumber == 2){
digitalWrite(a1, HIGH);
digitalWrite(a2, LOW);
digitalWrite(b1, HIGH);
digitalWrite(b2, LOW);
}
}
}

void allStop() {
if (gateNumber == 1){
digitalWrite(a1, LOW);
digitalWrite(a2, LOW);
}
else if (gateNumber == 2){
digitalWrite(a1, LOW);
digitalWrite(a2, LOW);
digitalWrite(b1, LOW);
digitalWrite(b2, LOW);
}
}

void manual() {
if (gateNumber == 1){
digitalWrite(a1, HIGH);
digitalWrite(a2, HIGH);
}
else if (gateNumber == 2){
digitalWrite(a1, HIGH);
digitalWrite(a2, HIGH);
digitalWrite(b1, HIGH);
digitalWrite(b2, HIGH);
}
}

void opengates(){
Serial.println("Mode = Button");
Serial.println("Openning gate...");
led.setColor(BLYNK_BLUE);
openGate();
waitForGate();
allStop();
led.setColor(BLYNK_GREEN);
Serial.println("Open.");
timer = 1;
}

These are the functions that I used in the next code up to make it easier.

void waitForGate() {
delay((inchesPerSec*(maxActuatorStroke/percentOfMaxStroke))*1000);
}

Also a function for making the coding for opening the gate(s) easier. It takes the inchesPerSec we already defined, and multiplies it by the max stroke divided by the percentage of the stroke.

float calcDist(float CurrentLatitude, float CurrentLongitude, float SavedLatitude, float SavedLongitude)
{
// HaverSine version
const float Deg2Rad = 0.01745329252; // (PI/180) 0.017453293, 0.0174532925
//const double EarthRadius = 6372.795; //6372.7976 In Kilo meters, will scale to other values
const float EarthRadius = 20908120.1; // In feet 20908128.6
float DeltaLatitude, DeltaLongitude, a, Distance;

// degrees to radians
CurrentLatitude = (CurrentLatitude + 180) * Deg2Rad; // Remove negative offset (0-360), convert to RADS
CurrentLongitude = (CurrentLongitude + 180) * Deg2Rad;
SavedLatitude = (SavedLatitude + 180) * Deg2Rad;
SavedLongitude = (SavedLongitude + 180) * Deg2Rad;

DeltaLatitude = SavedLatitude - CurrentLatitude;
DeltaLongitude = SavedLongitude - CurrentLongitude;

a =(sin(DeltaLatitude/2) * sin(DeltaLatitude/2)) + cos(CurrentLatitude) * cos(SavedLatitude) * (sin(DeltaLongitude/2) * sin(DeltaLongitude/2));
Distance = EarthRadius * (2 * atan2(sqrt(a),sqrt(1-a)));
Blynk.virtualWrite(V7, Distance);
return(Distance);
}

Here we use the Haversine formula to find the distance from our phone to the gate.

If anyone has any questions, please feel free to ask, seeing that this is my first tutorial.

Code

Driveway GateC/C++
#define BLYNK_PRINT Serial

#include "settings.h"
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <BlynkSimpleEsp8266.h>
#include <math.h>

char auth[] = BLYNK_AUTH_TOKEN;

int timer = 0;
int button;
int emergency;
int setting;
int delayAMOUNT;
int gpsSelect;
int distanceSelect;
int comingHome;
int openTest;
int closeTest;
float GPSLat;
float GPSLong;

float dist_calc=0;
float dist_calc2=0;
float diflat=0;
float diflon=0;

BLYNK_CONNECTED() {
  Blynk.syncAll();
  Serial.println("Syncing...");
  delay(2000);
}
BLYNK_WRITE(V0){
  button = param.asInt();
}
BLYNK_WRITE(V1){
  emergency = param.asInt();
}
BLYNK_WRITE(V2){
  setting = param.asInt();
  if (setting == 1) {
    Mode = "automatic";
  }
  else if (setting == 0) {
    Mode = "button";
  }
}
BLYNK_WRITE(V3){
  gateOpenAmount = param.asInt();
}

BLYNK_WRITE(V4){
  delayAMOUNT = param.asInt();
}
BLYNK_WRITE(V5){
  GpsParam gps(param);
  GPSLat = gps.getLat();
  GPSLong = gps.getLon();
}
WidgetLED led(V6);
BLYNK_WRITE(V8){
  gpsSelect = param.asInt();
}
BLYNK_WRITE(V9){
  distanceSelect = param.asInt();
}
BLYNK_WRITE(V10){
  comingHome = param.asInt();
}
BLYNK_WRITE(V12){
  openTest = param.asInt();
}
BLYNK_WRITE(V13){
  closeTest = param.asInt();
}

void setup() {
  Serial.begin(9600);
  if (gateNumber == 1){
    pinMode(a1, OUTPUT);
    pinMode(a2, OUTPUT);
  }
  else if (gateNumber == 2){
    pinMode(a1, OUTPUT);
    pinMode(a2, OUTPUT);
    pinMode(b1, OUTPUT);
    pinMode(b2, OUTPUT);
  }
  pinMode(emergencyButton, INPUT_PULLUP);
  Blynk.begin(BLYNK_AUTH_TOKEN,WIFI_SSID,WIFI_PASS);
  led.on();
  led.setColor(BLYNK_RED);
}

void loop() {
  Blynk.virtualWrite(V11, WiFi.RSSI());
  if (emergencyButton == LOW){
    Serial.println("Emergency Button!");
    Blynk.notify("Emergency Button on Gates was just Pressed!!!");
    gates();
  }
  if (openTest == 1){
    openGate();
  }
  if (closeTest == 1){
    closeGate();
  }
  if (button == 1){
    Serial.println("Button pressed.");
    gates();
  }
  if (emergency == 1){
    Serial.println("M");
    led.setColor(BLYNK_YELLOW);
    manual();
    delay(delayAMOUNT*1000);
    led.setColor(BLYNK_RED);
  }
  if (gpsSelect != 1){
    Blynk.virtualWrite(V7,calcDist(GPSLat, GPSLong, YOUR_LAT, YOUR_LONG));
    if (comingHome == 1){
      Serial.println(calcDist(GPSLat, GPSLong, YOUR_LAT, YOUR_LONG));
      if (calcDist(GPSLat, GPSLong, YOUR_LAT, YOUR_LONG) < distanceSelect){
        Serial.println("GPS triggered!");
        opengates();
      }
    }
  }
  Blynk.run();
}

void gates(){
  Serial.println("Got Mail!");
  if (Mode == "automatic"){
    Serial.println("Mode = Automatic");
    Serial.println("Opening gate...");
    led.setColor(BLYNK_BLUE);
    openGate();
    waitForGate();
    allStop();
    led.setColor(BLYNK_GREEN);
    Serial.println("Open.");
    Serial.println("Waiting...");
    delay(gateOpenAmount*1000);
    Serial.println("Closing gate...");
    led.setColor(BLYNK_BLUE);
    closeGate();
    waitForGate();
    allStop();
    led.setColor(BLYNK_RED);
    Serial.println("Closed.");
  }
  else if(Mode == "button"){
    Serial.println("Mode = Button");
    if (timer == 0){
      Serial.println("Openning gate...");
      led.setColor(BLYNK_BLUE);
      openGate();
      waitForGate();
      allStop();
      led.setColor(BLYNK_GREEN);
      Serial.println("Open.");
      timer = 1;
    }
    else if(timer == 1){
      Serial.println("Closing gate...");
      led.setColor(BLYNK_BLUE);
      closeGate();
      waitForGate();
      allStop();
      led.setColor(BLYNK_RED);
      Serial.println("Closed.");
      timer = 0;
    }
  }
}

void openGate(){
  if (gateDirection == 1){
    if (gateNumber == 1){
      digitalWrite(a1, HIGH);
      digitalWrite(a2, LOW);
    }
    else if (gateNumber == 2){
      digitalWrite(a1, HIGH);
      digitalWrite(a2, LOW);
      digitalWrite(b1, HIGH);
      digitalWrite(b2, LOW);
    }
  }
  else if (gateDirection == 2){
    if (gateNumber == 1){
      digitalWrite(a1, LOW);
      digitalWrite(a2, HIGH);
    }
    else if (gateNumber == 2){
      digitalWrite(a1, LOW);
      digitalWrite(a2, HIGH);
      digitalWrite(b1, LOW);
      digitalWrite(b2, HIGH);
    }
  }
}

void closeGate(){
  if (gateDirection == 1){
    if (gateNumber == 1){
      digitalWrite(a1, LOW);
      digitalWrite(a2, HIGH);
    }
    else if (gateNumber == 2){
      digitalWrite(a1, LOW);
      digitalWrite(a2, HIGH);
      digitalWrite(b1, LOW);
      digitalWrite(b2, HIGH);
    }
  }
  else if (gateDirection == 2){
    if (gateNumber == 1){
      digitalWrite(a1, HIGH);
      digitalWrite(a2, LOW);
    }
    else if (gateNumber == 2){
      digitalWrite(a1, HIGH);
      digitalWrite(a2, LOW);
      digitalWrite(b1, HIGH);
      digitalWrite(b2, LOW);
    }
  }
}

void allStop() {
  if (gateNumber == 1){
    digitalWrite(a1, LOW);
    digitalWrite(a2, LOW);
  }
  else if (gateNumber == 2){
    digitalWrite(a1, LOW);
    digitalWrite(a2, LOW);
    digitalWrite(b1, LOW);
    digitalWrite(b2, LOW);
  }
}

void manual() {
  if (gateNumber == 1){
    digitalWrite(a1, HIGH);
    digitalWrite(a2, HIGH);
  }
  else if (gateNumber == 2){
    digitalWrite(a1, HIGH);
    digitalWrite(a2, HIGH);
    digitalWrite(b1, HIGH);
    digitalWrite(b2, HIGH);
  }
}

void waitForGate() {
  delay((inchesPerSec*(maxActuatorStroke/percentOfMaxStroke))*1000);
}

void opengates(){
  Serial.println("Mode = Button");
  Serial.println("Openning gate...");
  led.setColor(BLYNK_BLUE);
  openGate();
  waitForGate();
  allStop();
  led.setColor(BLYNK_GREEN);
  Serial.println("Open.");
  timer = 1;
}


float calcDist(float CurrentLatitude, float CurrentLongitude, float SavedLatitude, float SavedLongitude)
{
// HaverSine version
    const float Deg2Rad = 0.01745329252;               // (PI/180)  0.017453293, 0.0174532925
    //const double EarthRadius = 6372.795;              //6372.7976 In Kilo meters, will scale to other values
    const float EarthRadius = 20908120.1;              // In feet  20908128.6
    float DeltaLatitude, DeltaLongitude, a, Distance;

    // degrees to radians
    CurrentLatitude = (CurrentLatitude + 180) * Deg2Rad;     // Remove negative offset (0-360), convert to RADS
    CurrentLongitude = (CurrentLongitude + 180) * Deg2Rad;
    SavedLatitude = (SavedLatitude + 180) * Deg2Rad;
    SavedLongitude = (SavedLongitude + 180) * Deg2Rad;

    DeltaLatitude = SavedLatitude - CurrentLatitude;
    DeltaLongitude = SavedLongitude - CurrentLongitude;

    a =(sin(DeltaLatitude/2) * sin(DeltaLatitude/2)) + cos(CurrentLatitude) * cos(SavedLatitude) * (sin(DeltaLongitude/2) * sin(DeltaLongitude/2));
    Distance = EarthRadius * (2 * atan2(sqrt(a),sqrt(1-a)));
    Blynk.virtualWrite(V7, Distance);
    return(Distance);
}
settings.hC/C++
#define emergencyButton 14

//blynk
#define BLYNK_AUTH_TOKEN "your_auth"
#define BLYNK_GREEN     "#23C48E"
#define BLYNK_RED       "#D3435C"
#define BLYNK_YELLOW    "#ED9D00"
#define BLYNK_BLUE      "#04C0F8"
#define YOUR_LAT        40.677364  //New York City
#define YOUR_LONG       -73.998944

//WiFi
char WIFI_SSID[] = "Apple Network 85064d";
char WIFI_PASS[] = "12344321";

//GATE
String Mode = "button";      //automatic or button
#define gateNumber 2          //how many gates; 1 or 2
int gateOpenAmount = 10;     //only for automatic mode, seconds
#define gateDirection 1       //1 or 2

//linear actuator
#define inchesPerSec .39      //inches per sec of linear actuator
#define maxActuatorStroke 12  //max stroke of linear actuator
#define percentOfMaxStroke .21 //.2 //0 through 1
#define a1 2                  //first linear actuator
#define a2 0                  //first linear actuator
#define b1 4                  //second linear actuator
#define b2 5                  //second linear actuator

Schematics

Automated Driveway Gate Schematic

Comments

Similar projects you might like

Android App-Based Home Automation System Using IOT

Project tutorial by Team Autoshack

  • 55,305 views
  • 22 comments
  • 148 respects

Self Sufficient Automated Greenhouse

Project tutorial by Shashank Prasanna

  • 8,422 views
  • 14 comments
  • 37 respects

Lights On/Off using Twitter

Project showcase by Kaustubh Agarwal

  • 4,826 views
  • 0 comments
  • 15 respects

Smart Doorbell

Project showcase by Kaustubh Agarwal

  • 69,225 views
  • 23 comments
  • 135 respects

Smart cane

by saurabhrobotic

  • 6,882 views
  • 23 comments
  • 43 respects

Automated Mung Bean Sprouts Growing Machine

Project showcase by solkit

  • 2,898 views
  • 1 comment
  • 7 respects
Add projectSign up / Login