Automating a Gate Project

Hello, I'm just starting to use Arduino and I still don't fully understand its features.

In this project I want to automate a gate that already has a motor and board with opening controls and photocell sensors.

What I intend to do is use the ESP32 as an intermediary between the sensors and the gate activation.

For example, in the code below I identified the photocells to be switched on at 7PM and switched off at 6AM. I will place a magnetic sensor to check whether the gate is already open or closed, and depending on the time, open or close it with a command.

I'm from Brazil, this is why the comments on the code are on Portuguese

#include <WiFi.h>
#include <WiFiUdp.h>
#include <Wire.h>
#include <RTClib.h>

// Configurações da Rede
const char* ssid = "username";
const char* password = "password";

// Informações de data e Hora
RTC_DS3231 rtc;

const int gateSensor = 2; // Pino onde o sensor do portão está conectado
const int photocellsPin = 3;  // Pino onde as fotocélulas estão conectadas
const int commandGatePin = 4; // Pino para o comando de abertura do portão

void setup(){

  pinMode(gateSensor INPUT); // Pino em modo de entrada de informações
  pinMode(photocellsPin, OUTPUT); // Pino em modo de saida de informações
  pinMode(commandGatePin, OUTPUT); // Pino em modo de saida de informações


  // Conecção WiFi
  Serial.begin(115200);
  delay(1000);

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  Serial.println("\nConnecting");

  while(WiFi.status() != WL_CONNECTED){
    Serial.print(".");
    delay(100);
  }

  Serial.println("\nConnected to the WiFi network");
  Serial.println(WiFi.ssid());
  Serial.print("Local ESP32 IP: ");
  Serial.println(WiFi.localIP());

}

void loop(){

  // Obtém a hora atual
  int realTime = hour();
  
  // Obtém o estado do sensor do portão
  int gateState = digitalRead(gateSensor);

    // Verifica a hora atual e o estado do sensor para tomar decisões
  if (realTime == 19) {
    if (gateState == HIGH) {
      // Sensor HIGH às 19:00h, libera as fotocélulas
      digitalWrite(photocellsPin, HIGH);
    } else {
      // Sensor LOW às 19:00h, libera as fotocélulas e envia comando de fechamento do portão
      digitalWrite(photocellsPin, HIGH);
      digitalWrite(commandGatePin, HIGH);
    }
  } else if (realTime == 6) {
    if (gateState == LOW) {
      // Sensor LOW às 6:00h, desativa as fotocélulas
      digitalWrite(photocellsPin, LOW);
    } else {
      // Sensor HIGH às 6:00h, destiva as fotocélulas e envia comando de abertura do portão
      digitalWrite(photocellsPin, LOW);
      digitalWrite(commandGatePin, HIGH);
    }
  } else {
    // Em outros horários, desativa as fotocélulas e os comandos do portão
    digitalWrite(commandGatePin, LOW);
  }
  
  // Outras ações ou código podem ser adicionados aqui
  
  delay(1000); // Aguarde 1 segundo antes de verificar novamente

}

Welcome! I have seen a similar project on here a few months back. Use "automate gate" in the search box to find them. What is your question? What you are saying can definitely be done with about any of the Arduinos. With the addition of WiFi you made an excellent choice.

Can you post an annotated schematic showing how you plan on wiring this together. Be sure to show all connections, power, ground, power sources. Links to technical information on each of the devices will help a lot especially the motors and sensors. Knowing your skill set would help in properly answering this question. We have people from first projects to many years experience.

1 Like

Hello @dev-barreto,

here is something to play around for you :wink: :

#define WOKWI

/*
  Forum: https://forum.arduino.cc/t/automating-a-gate-project/1168477
  Wokwi: https://wokwi.com/projects/375852170316319745

  If "WOKWI" is defined ( see #define WOKWI in line 1) the WiFi parts are excluded from the sketch
  as they are not required for the first steps

*/


#include <WiFi.h>
#include <WiFiUdp.h>
#include <Wire.h>
#include <RTClib.h>

// Configurações da Rede
const char* ssid = "Wokwi-GUEST";
const char* password = "";

// Informações de data e Hora
RTC_DS3231 rtc;

constexpr byte gateSensor = 2; // Pino onde o sensor do portão está conectado
constexpr byte photocellsPin = 4;  // Pino onde as fotocélulas estão conectadas // **** from 3 to 4
constexpr byte commandGatePin = 15; // Pino para o comando de abertura do portão // **** from 4 to 15
constexpr byte gateStatePin   = 19;

enum gateModes {MORNING, EVENING, RESTOFDAY, UNKNOWN};
gateModes gateMode = UNKNOWN;

byte gateState = LOW;

void setup() {

  pinMode(gateSensor, INPUT_PULLUP); // Pino em modo de entrada de informações  // ****** Added PULLUP
  pinMode(photocellsPin, OUTPUT); // Pino em modo de saida de informações // White on = HIGH
  pinMode(commandGatePin, OUTPUT); // Pino em modo de saida de informações  // Blue on = HIGH
  pinMode(gateStatePin, OUTPUT);      // Pin to show the state of the gate (Green on = Open/HIGH)

  // Connect rtc
  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    Serial.flush();
    abort();
  }
  Serial.begin(115200);
  delay(1000);

#ifndef WOKWI
  // Conecção WiFi
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password, 6);
  Serial.println("\nConnecting");
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(100);
  }
  Serial.println("\nConnected to the WiFi network");
  Serial.println(WiFi.ssid());
  Serial.print("Local ESP32 IP: ");
  Serial.println(WiFi.localIP());
#endif
  Serial.println("Start of loop()");
}

void loop() {
  // Obtém a hora atual
  int realTime = getHour(false);  // change parameter to "true" for RTC time and "false" for fake Hour
  gateState = getGateState();
  byte mode = 0;
  switch (realTime) {
    case 6 : openGate();
      break;
    case 19 : closeGate();
      break;
    default : standardHandling();
      break;
  }
}

int getFakeHour() {
  static int hour = 0;
  if (Serial.available()) {
    char c = Serial.read();
    switch (c) {
      case  'm' : hour = 6;   //m for Morning routine
        break;
      case  'e' : hour = 19;  // e for Evening routine
        break;
      case  'r' : hour = 12;  // r for Rest of Day routine
        break;
    }
  }
  return hour;
}

int getHour(boolean trueTime) {
  if (!trueTime) {
    return getFakeHour();
  }
  static int lastSecond = -1;
  DateTime now = rtc.now();
  if (now.second() != lastSecond) {
    Serial.printf("%.2d:%.2d:%.2d\n", now.hour(), now.minute(), now.second());
    lastSecond = now.second();
  }
  return now.hour();
}


void openGate() {
  if (gateMode == MORNING) {
    return;
  }
  if (gateState == HIGH) {
    // Sensor HIGH às 19:00h, libera as fotocélulas
    digitalWrite(photocellsPin, HIGH);
  } else {
    // Sensor LOW às 19:00h, libera as fotocélulas e envia comando de fechamento do portão
    digitalWrite(photocellsPin, HIGH);
    digitalWrite(commandGatePin, HIGH);
  }
  gateMode = MORNING;
  Serial.println("MORNING");
}

void closeGate() {
  if (gateMode == EVENING) {
    return;
  }
  if (gateState == LOW) {
    // Sensor LOW às 6:00h, desativa as fotocélulas
    digitalWrite(photocellsPin, LOW);
  } else {
    // Sensor HIGH às 6:00h, destiva as fotocélulas e envia comando de abertura do portão
    digitalWrite(photocellsPin, LOW);
    digitalWrite(commandGatePin, HIGH);
  }
  gateMode = EVENING;
  Serial.println("EVENING");
}

void standardHandling() {
  if (gateMode == RESTOFDAY) {
    return;
  }
  // Em outros horários, desativa as fotocélulas e os comandos do portão
  digitalWrite(photocellsPin, LOW);
  digitalWrite(commandGatePin, LOW);
  gateMode = RESTOFDAY;
  Serial.println("REST OF DAY");
}



byte getGateState() {
  static byte gState = LOW;
  static byte lastStateRead = LOW;
  static unsigned long lastChange = 0;
  byte actState = digitalRead(gateSensor);
  if (actState != lastStateRead) {
    lastStateRead = actState;
    lastChange = millis();
  }
  if (millis() - lastChange > 30 && gState != lastStateRead) {
    gState = lastStateRead;
    digitalWrite(gateStatePin, gState);
  }
  return gState;
}

You can test it on Wokwi, see here https://wokwi.com/projects/375852170316319745

Feel free to use the platform for further testing and development also ...

I have excluded the WiFi part (by #ifdefs so they are still in the code) as they are not relevant at this stage.

This is the wiring:

image

  • Blue led = Gate Command Pin
  • White led = Photocell Pin
  • Green led = Gate status (HIGH/LOW)
  • Slide switch = to the left gateState = HIGH, to the right gateState = LOW
  • The RTC chip is a DS 1307 but it can be (mis)used as a DS3231 with the same lib :wink:
  • The function getHour(); can be used with the parameter true or false.
    • In case of true it returns the RTC data.
    • In case of false it can be controlled by Serial input:
      • "m" returns 6 o'clock -> Morning
      • "e" returns 19 o'clock -> Evening
      • "r" returns 12 o'clock -> Rest of the Day setting
  • The getGateState() function uses debouncing by millis() to cope with the bouncing issues of mechanical switches.

This way you can test the routines for the three settings immediately.

The routines to control the gate and photocell are written in a way that they are only performed once when a change "RESTOFDAY" -> "MORNING" -> "RESTOFDAY" -> "EVENING" -> "RESTOFDAY" -> ... takes place.

I am not sure if the standardHandling() procedure for RESTOFDAY is really what you intend but you will surely find out ...

Good luck and have fun!
ec2021

1 Like

Helped a lot heres is the new code, without the door sensor for now:

#include <NTPClient.h>
#include <WiFiUdp.h>
#include <WiFi.h>

#define LED 2
#define command 4
#define sensor 19

const char* ssid = "SSID_NETWORK";
const char* password = "PASS_NETWORK";

WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org");

bool dayTime () {
  int currentHour = timeClient.getHours();

  int dayStartTime = 6;
  int dayEndTime = 19;

  if (currentHour >= dayStartTime && currentHour < dayEndTime) {
    return true;
  } else {
    return false;
  }
}


void setup() {

    Serial.begin(115200);
    WiFi.begin(ssid, password);

    while (WiFi.status() != WL_CONNECTED) {
        delay(1000);
        Serial.println("Conectando ao WiFi...");
    }

    Serial.println("Conectado ao WiFi.");
    digitalWrite(LED, HIGH);
    delay(100);
    digitalWrite(LED, LOW);
    timeClient.begin();
    timeClient.setTimeOffset(-3 * 3600);


    pinMode (LED, OUTPUT);
    pinMode (sensor, OUTPUT);
    pinMode (command, OUTPUT);
}
void loop() {

    timeClient.update();
    Serial.println(dayTime());

    if (dayTime()) {
      digitalWrite(LED, LOW);
      digitalWrite(sensor, LOW);
    } else {
      digitalWrite(LED, HIGH);
      digitalWrite(sensor, HIGH);
    }
    
  delay(100);
}

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.