icon

Automated Driveway Gates Version 2

0 3569 Medium

K Gray

K Gray

Created October 5, 2022 © MIT

 

Automated Driveway Gates Version 2

This is a second tutorial for making DIY automated driveway gates for relatively cheap using Arduino, ESP32, Raspberry Pi, and Blynk!

 

Level: Intermediate

Work in progress

Time to build: 5 hours

 

 

Things used in this project

Hardware components

 DFRobot FireBeetle ESP32 ×1   DFRobot 2x15A Motor DriverThis product is now discontinued. This product is a good equivalent: https://www.dfrobot.com/product-1861.html?tracking=wrvW2zWgzSBdRH8U94Hohk2UquGYvPgFFtGJgEKdKSuZRlj9IzpymV0Oa7jM0Ywv×1   DFRobot Waterproof Ultrasonic Sensor ×1   RGB LED Strip (Not Individually Addressable)I got 2x IP65 LED Flex Strip RGB 60LEDs/Meter 16.4 Foot; both of my gates are 12ft long.×1   LD1117V33 3.3V LDO ×1  Capacitor 10 µFCapacitor 10 µF ×2   12V 350W Power Supply ×1   DFRobot 50A Current Sensor ×1  

Software apps and online services

BlynkBlynk    

Hand tools and fabrication machines

Soldering iron (generic)Soldering iron (generic)    Solder Wire, Lead FreeSolder Wire, Lead Free    Drill / Driver, CordlessDrill / Driver, Cordless    

Story

 

 

 

 

The Story

Hello!

This tutorial is a second version of my previous award winning Automated Driveway Gates project. It includes new upgraded linear actuators that have built-in hall sensors, a new mainboard consisting of an ESP32, a new double motor driver module capable of 15A @ 13.8V per channel, and a new waterproof ultrasonic sensor!

 

 

 

The Parts

As I just explained, there are many new and better components in this build.

 

2x PA-04-HS 12V 12A IP65 Hall Effect Linear Actuators ( I also bought both bracket types)1x DFRobot FireBeetle ESP321x DFRobot 2x15A Motor Driver (now discontinued, but they have a new version capable of 12A per channel)1x DFRobot 50A AC/DC Current Sensor1x DFRobot Waterproof Ultrasonic Sensor1x LD1117v33 3.3V 800mA voltage regulator IC2x 10µF Electrolytic Capacitors for the regulator1x 12V 350W Power Supply2x 12V IP65 RGB LED Strips4x NPN MOSFETs (I use STP90NF03L)

 

 

DFRobot

Dfrobot is an awesome electronics company! They kindly sponsored their parts to me for this project. They have anything you could need for any project of every type! You can check my other projects for more awesome things you can build with their parts. Check them out here! https://www.dfrobot.com

 

 

 

Wiring

The wiring may look complicated, but is pretty straightforward once you dive in ?.

 

Motor Driver - FireBeetle:

M2Speed - IO17M2Dir - IO13M1Speed - IO16M1Dir - IO14+5V - VCCGND - GND 

Ultrasonic Sensor - FireBeetle:

+3.3V - +3.3VGND - GNDRX - IO22TX - IO21 

Spot Light - FireBeetle:

Transistor Gate - IO12 

LED Strips - FireBeetle:

1st transistor gate - IO252nd transistor gate - IO273rd transistor gate - IO5 

Magnet Lock - FireBeetle:

Transistor Gate - IO2 

Current Sensor - FireBeetle:

AO - A0 

If this description doesn't make sense (I would totally agree), you can follow the schematic that I drew:

Schematic

Schematic

 

 

 

Blynk

Blynk has been updated ?! Personally, I don't like the new version; it is harder to use, has less features than the previous one, and is pricey.

This is how the desktop template should look when completed:

Blynk Desktop Dashboard

 

Here is the mobile app Template:

Mobile App Dashboard

 

If you need help setting up Blynk, refer to the documentation found here:

https://docs.blynk.io/en/

 

 

 

Code

The code is quite long for this project! Keep in mind that you will probably have to change some things to get it to work how you would like for your setup. For example, my left actuator seemed to open slower than it closed, so I had to adjust the opening and closing functions to account for that.  For a full code description, please check out the original Hackster project here: https://www.hackster.io/k-gray/automated-driveway-gates-version-2-6d9b2e

 

 

 

Wrapping Up

Finished box:

Finshed box with everything wired.

Finshed box with everything wired.

That was all for this tutorial! If you liked it, give it a thumbs up! Please feel free to post in the comments for any questions, ideas, advice, suggestions, and so on!

Check out this link for more awesome projects:

https://www.hackster.io/k-gray

 

Schematics

 

Schematic

 

Code

 

 

GitHub Repository

 

Kgray44 / Automated-Driveway-Gate-Updated

0 0

 

This is an updated project of my Automated--Driveway-Gates! — Read More

https://www.hackster.io/k-gray/automated-driveway-gates-version-2-6d9b2e

Latest commit to the master branch on 10-28-2022

Download as zip


 

 

CODE
#define BLYNK_TEMPLATE_ID "************"
#define BLYNK_DEVICE_NAME "********"
#define BLYNK_AUTH_TOKEN "*******************************"
#define BLYNK_PRINT Serial

#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
#include <SoftwareSerial.h>

#define motorAspeed   16//D11
#define motorBspeed   17//D10
#define motorAdir     14//D6
#define motorBdir     13//D7
#define hall          26//D3
#define ultra1        22
#define ultra2        21
#define currentIn     A0
#define pinRed        D4
#define pinGreen      D3
#define pinBlue       4//D12
#define magnet        D9//D13
#define light         4//D12

/* Current Sensor (currently not working)
const int numReadings = 30;
float readings[numReadings];      // the readings from the analog input
int inde = 0;                  // the inde of the current reading
float total = 0;                  // the running total
float average = 0;                // the average
float currentValue = 0;
*/
int ppi = 300; //pulses per inch (for the PA-04 Linear Actuator).  Change this according to your specs.
int usedAct = 6; //inches of actuator used

char ssid[] = "************";//WiFi network name
char pass[] = "********";//WiFi network password

//Gate button value for Blynk
int button;

int timer;

//current sensor value
float voltage;

//ultrasonic sensor
unsigned char data[4] = {};
float distance;
float inches;
int car;
int carDist = 24;//alter this value! This value is distance in inches before something is activated

int tim = 10000;

long hallCount;

//gate status flag
boolean flag = false;

//LED strip starting values
int red = 255;
int green = 255;
int blue = 255;

SoftwareSerial ultraSerial;

//BLYNK_CONNECTED(){
//  Blynk.syncAll();
//}

BLYNK_WRITE(V0){
  button = param.asInt();
}

BLYNK_WRITE(V1){
  red = param.asInt();
}

BLYNK_WRITE(V2){
  green = param.asInt();
}

BLYNK_WRITE(V3){
  blue = param.asInt();
}

BLYNK_WRITE(V4){
  int spotlight = param.asInt();
  if (spotlight){
    digitalWrite(light, HIGH);
  }
  else {
    digitalWrite(light, LOW);
  }
}

String string;
BLYNK_WRITE(V10) {
  string = param.asStr();
  if (string == "restart"){
    Blynk.virtualWrite(V10, "Restarting...");
    Serial.println("Restarting...");
    delay(2000);
    ESP.restart();
  }
}

//gate status flag
boolean isOpen = false;

//PWM information
const int freq = 5000;
const int resolution = 8;
const int redChannel = 1;
const int greenChannel = 2;
const int blueChannel = 3;
const int motorA = 4;
const int motorB = 5;

void setup() {
  Serial.begin(115200);
  ultraSerial.begin(9600, SWSERIAL_8N1, ultra1, ultra2, false); // RX, TX

  if (!ultraSerial) { // If the object did not initialize, then its configuration is invalid
    Serial.println("Invalid SoftwareSerial pin configuration, check config"); 
  } 
  
  //set pinModes
  pinMode(motorAspeed, OUTPUT);
  pinMode(motorBspeed, OUTPUT);
  pinMode(motorAdir, OUTPUT);
  pinMode(motorBdir, OUTPUT);
  pinMode(pinRed, OUTPUT);
  pinMode(pinGreen, OUTPUT);
  pinMode(pinBlue, OUTPUT);
  pinMode(hall, INPUT_PULLUP);
  pinMode(currentIn, INPUT);
  pinMode(magnet, OUTPUT);
  pinMode(light, OUTPUT);
  
  //attach PWM channels to the correct pins
  ledcAttachPin(pinRed, redChannel);
  ledcAttachPin(pinGreen, greenChannel);
  ledcAttachPin(pinBlue, blueChannel);
  ledcAttachPin(motorAspeed, motorA);
  ledcAttachPin(motorBspeed, motorB);
  
  //setup the PWM channels
  ledcSetup(redChannel, freq, resolution);
  ledcSetup(greenChannel, freq, resolution);
  ledcSetup(blueChannel, freq, resolution);
  ledcSetup(motorA, freq, resolution);
  ledcSetup(motorB, freq, resolution);  
  
  //connect to the WiFi
  wificonnect();

  //Start Blynk
  Serial.println("Blynk Starting...");
  Blynk.config(BLYNK_AUTH_TOKEN);
  
  //Start OTA
  Serial.println("OTA Starting...");
  OTAStart();

  //open the gates all the way at the beginning to set the hall sensor back at 0
  Serial.println("Begin opening...");
  delay(1000);
  beginOpen();
  hallCount = ppi*usedAct;
  isOpen = true;
  Serial.println("Attaching interrupt...");
  attachInterrupt(digitalPinToInterrupt(hall), interruptName, FALLING);//Interrupt initialization
  //then close to the correct place, keeping track of the hall count
  Serial.println("Closing to correct place...");
  close();
  Serial.println("Done closing!");
  Serial.println("Ready");
  isOpen = false;
}

void loop() {
  /*current sensor reading (currently not working)
  currentVal();
  if (currentValue >= 20.00){
    ledcWrite(motorA, 0);
    ledcWrite(motorB, 0);
    digitalWrite(hall, HIGH);
    Serial.println("Current too high!");
  }
  current = (analogRead(currentIn)-510)*5/1024/0.04-0.04;//calculate current value
  Blynk.virtualWrite(V7,current);
  */
  
  //if WiFi was lost, reconnect
  if (WiFi.status() == WL_CONNECTION_LOST){
    Serial.println("Connection lost...");
    wificonnect();
  }
  
  //handle the OTA
  ArduinoOTA.handle();
  
  //ultrasonic sensor reading
  for (int i=0;i<4;i++){
    Serial.println("Checkdist();");
    ArduinoOTA.handle();
    checkDist();
  }
  Blynk.virtualWrite(V8,inches);
  if (inches <= carDist){
    Serial.println("Car");
    Blynk.virtualWrite(V9, HIGH);
  }
  else {
    Blynk.virtualWrite(V9, LOW);
  }
  
  //if Blynk button pressed, switch the flag
  if (button == HIGH){
    flag = !flag;
  }
  
  //check to see if the flag is true, then check if the gates are closed and open them
  if (flag == true && isOpen == false) {
    digitalWrite(magnet, LOW);
    delay(100);
    open();
    isOpen = true;
  }
  //else, check to see if the gates are open, and close them
  else if (flag == false && isOpen == true) {
    close();
    delay(100);
    digitalWrite(magnet, HIGH);
    isOpen = false;
  }
  
  //write the Blynk values to the LED strips
  ledcWrite(redChannel, red);
  ledcWrite(greenChannel, green);
  ledcWrite(blueChannel, blue);

  //run Blynk, yield() to prevent unwanted resets, and delay 1 millisecond to keep track of time
  Blynk.run();
  yield();
  delay(1);
}

void wificonnect(){
  Serial.println("WiFi Connecting...");
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, pass);
  while (WiFi.status() != WL_CONNECTED){
    Serial.print(".");
    delay(500);
    delay(500);
  }
  Serial.println("");
  while (WiFi.waitForConnectResult() != WL_CONNECTED) {
    Serial.println("Connection Failed! Rebooting...");
    delay(5000);
    ESP.restart();
  }
}

void checkDist(){
  retry:
  do {
    for (int i = 0; i < 4; i++){
      data[i] = ultraSerial.read();
    }
  }
  while (ultraSerial.read() == 0xff);

  ultraSerial.flush();

  if (data[0] == 0xff)
  {
    int sum;
    sum = (data[0] + data[1] + data[2]) & 0x00FF;
    if (sum == data[3])
    {
      distance = (data[1] << 8) + data[2];
      if (distance > 20)
      {
        inches = distance / 25.4; //mm to inches
        Serial.print(distance / 10);
        Serial.println("in");
      } else
      {
        inches = 0;
        Serial.println("Below the lower limit");
      }
    } else goto retry;//Serial.println("ERROR");
  }
  delay(100);
}

void beginOpen(){
  bodo:
  digitalWrite(motorAdir, HIGH);
  digitalWrite(motorBdir, HIGH);
  ledcWrite(motorA, 255);
  ledcWrite(motorB, 255);
  yield();
  timer++;
  delay(1);
  while (timer < 24000){
    yield();
    goto bodo;
  }
  timer = 0;
  Serial.println("Done!");
  ledcWrite(motorA, 0);
  ledcWrite(motorB, 0);
}

void open(){
  int times=0;

  hallCount = 0;
  redo:
  digitalWrite(motorAdir, HIGH);
  digitalWrite(motorBdir, HIGH);
  ledcWrite(motorA, 255);
  ledcWrite(motorB, 255);

  //while (digitalRead(hall) == HIGH){yield();}
  
  while (hallCount < ppi*usedAct){
    yield();

    Serial.print("Hall count: ");
    Serial.println(hallCount);
    
    goto redo;
  }
  delay(500);
  tedo:
  digitalWrite(motorAdir, HIGH);
  digitalWrite(motorBdir, HIGH);
  ledcWrite(motorA, 255);
  ledcWrite(motorB, 255);
  times++;
  delay(1);
  yield();
  while (times < 7000){
    goto tedo;
  }
  times=0;
  yield();
  ledcWrite(motorA, 0);
  ledcWrite(motorB, 0);
}

void close(){
  hallCount = ppi*usedAct;
  redone:
  digitalWrite(motorAdir, LOW);
  digitalWrite(motorBdir, LOW);
  ledcWrite(motorA, 255);
  ledcWrite(motorB, 255);
  

  while (hallCount > 0){
    yield();

    Serial.print("Hall count: ");
    Serial.println(hallCount);
    
    goto redone; //goto endy;
  }
  yield();
  ledcWrite(motorA, 0);
  ledcWrite(motorB, 0);
  digitalWrite(motorAdir, HIGH);
  digitalWrite(motorBdir, HIGH);
  Serial.println("Gates closed");
}

void OTAStart(){
    // Port defaults to 8266
   ArduinoOTA.setPort(8266);

  // Hostname defaults to esp8266-[ChipID]
   ArduinoOTA.setHostname("DrivewayESP");

  // No authentication by default
   ArduinoOTA.setPassword("maker");
  
  // Password can be set with it's md5 value as well
  // MD5(admin) = 21232f297a57a5a743894a0e4a801fc3
  // ArduinoOTA.setPasswordHash("21232f297a57a5a743894a0e4a801fc3");

  ArduinoOTA.onStart([]() {
    //open();
    String type;
    if (ArduinoOTA.getCommand() == U_FLASH) {
      type = "sketch";
    } else { // U_FS
      type = "filesystem";
    }

    // NOTE: if updating FS this would be the place to unmount FS using FS.end()
    Serial.println("Start updating " + type);
  });
  ArduinoOTA.onEnd([]() {
    Serial.println("\nEnd");
  });
  ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
    Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
  });
  ArduinoOTA.onError([](ota_error_t error) {
    Serial.printf("Error[%u]: ", error);
    if (error == OTA_AUTH_ERROR) {
      Serial.println("Auth Failed");
    } else if (error == OTA_BEGIN_ERROR) {
      Serial.println("Begin Failed");
    } else if (error == OTA_CONNECT_ERROR) {
      Serial.println("Connect Failed");
    } else if (error == OTA_RECEIVE_ERROR) {
      Serial.println("Receive Failed");
    } else if (error == OTA_END_ERROR) {
      Serial.println("End Failed");
    }
  });
  ArduinoOTA.begin();
  Serial.println("Ready");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
}


ICACHE_RAM_ATTR void interruptName() {
  if (isOpen == false){
    hallCount++;
    
    if (hallCount >= ppi*usedAct){
      //ledcWrite(motorA, 0);
      //ledcWrite(motorB, 0);
      
      digitalWrite(hall, HIGH);
      hallCount = ppi*usedAct;
      //delay(1000);
    }
  }
  else if (isOpen == true){
    hallCount--;
    
    if (hallCount <= 0){
      ledcWrite(motorA, 0);
      ledcWrite(motorB, 0);

      digitalWrite(hall, HIGH);
      hallCount = 0;
      //delay(1000);
    }
  }
  //currentVal();
}

/*void currentVal() {
  //total= total - readings[inde];
  //readings[inde] = 
  currentValue = analogRead(currentIn); //Raw data reading
//Data processing:510-raw data from analogRead when the input is 0;
// 5-5v; the first 0.04-0.04V/A(sensitivity); the second 0.04-offset val;
  //readings[inde] = 
  currentValue = (currentValue-512)*3.30/4095/0.04-0.04;
  //total= total + readings[inde];
  //inde = inde + 1;
  //if (inde >= numReadings)
  //  inde = 0;
  //average = total/numReadings;   //Smoothing algorithm (http://www.arduino.cc/en/Tutorial/Smoothing)
  //currentValue= average;
  Serial.println(currentValue);
  //return(currentValue);
    //delay(1);
}*/
License
All Rights
Reserved
licensBg
0