Дмитрий Батьковичь
Published © MIT

Second Life of an ESP32 Gate Barrier

Project "Never Again Muck!"

IntermediateFull instructions provided8 hours173
Second Life of an ESP32 Gate Barrier

Things used in this project

Hardware components

Espressif ESP32 Development Board - Developer Edition
Espressif ESP32 Development Board - Developer Edition
×1
60W PCIe 12V 5A Power Supply
Digilent 60W PCIe 12V 5A Power Supply
×1
Dual H-Bridge motor drivers L298
SparkFun Dual H-Bridge motor drivers L298
×1
Geared DC Motor, 12 V
Geared DC Motor, 12 V
×1
Reed Switch, SPST-NO
Reed Switch, SPST-NO
×2
Switch Replacement Magnet, Honeywell 2SS
Switch Replacement Magnet, Honeywell 2SS
×2

Software apps and online services

Arduino IDE
Arduino IDE

Story

Read more

Schematics

sheme_4oohh8NLDH.png

Code

skech

Arduino
#include <Arduino.h>
#include <WiFi.h>
#include <WebServer.h>
#include <ESPTunnel.h>
#include "index_page.h"

// Motor control pins (H-bridge)
#define MOTOR_FORWARD_PIN    GPIO_NUM_16  // Pin for forward movement (opening)
#define MOTOR_BACKWARD_PIN   GPIO_NUM_17  // Pin for backward movement (closing)
// Reed switch pins (limit switches)  
#define REED_OPEN_PIN        GPIO_NUM_18  // Reed switch for open position
#define REED_CLOSED_PIN      GPIO_NUM_19  // Reed switch for closed position
// WiFi
#define WIFI_SSID "MY_WIFI"
#define WIFI_PASSWORD "MY_WIFI_PASSWORD"
// To World Tunnel// Domain and secret registred in https://device-tunnel.top/
#define TUNNEL_DOMAIN "my-barrier.sytes.net" 
#define TUNNEL_SECRET ""

WebServer server(80);

bool needsOpened = false;
bool realOpened = false;

char buffer[4096]; //page render buffer
void sendPage(const char* page, ...){
  va_list args;
  va_start(args, page);
  vsnprintf_P(buffer, sizeof(buffer), page, args);
  va_end(args);
  server.send(200, "text/html", buffer);
}

void indexPage() {
  sendPage(indexPageHtml, needsOpened ? "open" : "closed");
}
void redirect(const char* url){
  server.sendHeader("Location", url, true);  
  server.send(302, "text/plain", "");
}

void stopMotor() {
  digitalWrite(MOTOR_FORWARD_PIN, LOW);
  digitalWrite(MOTOR_BACKWARD_PIN, LOW);
}
//TODO MAX WORK TIME
void startOpening() {
  digitalWrite(MOTOR_BACKWARD_PIN, LOW);
  digitalWrite(MOTOR_FORWARD_PIN, HIGH);
}
void startClosing() {
  digitalWrite(MOTOR_FORWARD_PIN, LOW);
  digitalWrite(MOTOR_BACKWARD_PIN, HIGH);
}

void setup() {
  Serial.begin(115200);

 // Pin setup
  pinMode(MOTOR_FORWARD_PIN, OUTPUT);
  pinMode(MOTOR_BACKWARD_PIN, OUTPUT);
  pinMode(REED_OPEN_PIN, INPUT_PULLUP);
  pinMode(REED_CLOSED_PIN, INPUT_PULLUP);
  stopMotor();  // Stop motor at startup
  
  // Determine initial real position
  if (digitalRead(REED_OPEN_PIN) == LOW) {
    realOpened = true;
    needsOpened = true; // Assume if open, then should be open
    Serial.println("Initial position: OPEN");
  } else if (digitalRead(REED_CLOSED_PIN) == LOW) {
    realOpened = false;
    needsOpened = false; // Assume if closed, then should be closed
    Serial.println("Initial position: CLOSED");  
  } else {
    realOpened = false;
    needsOpened = false; // Default closed
    Serial.println("Initial position: UNKNOWN (assume CLOSED)");
  }

  Serial.print("Connecting to WiFi ");
  Serial.println(WIFI_SSID);

  WiFi.mode(WIFI_STA);
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.print(" IP address: ");
  Serial.println(WiFi.localIP());

  Serial.println("Run tunnel");
  startPrivateTunnel(TUNNEL_DOMAIN, "wicket", TUNNEL_SECRET);
  //debugPrivateTunnel(TUNNEL_DOMAIN, "wicket", TUNNEL_SECRET);

  Serial.println("Run web server");

  server.on("/wicket/open", [] {
    needsOpened = true;
    Serial.println("OPEN Barrier");
    redirect("/wicket");
  });
  server.on("/wicket/close", [] {
    needsOpened = false;
    Serial.println("CLOSE Barrier");
    redirect("/wicket");
  });
  server.on("/wicket",  indexPage);
  server.on("/", [] {
    redirect("/wicket");
  });

  server.begin();
}

void loop() {
  server.handleClient();

  // Update real position by sensors
  if (digitalRead(REED_OPEN_PIN) == LOW) {
    realOpened = true;
  } else if (digitalRead(REED_CLOSED_PIN) == LOW) {
    realOpened = false;
  }

  if (needsOpened && !realOpened) {
    startOpening();
  } else if (!needsOpened && realOpened) {
    startClosing();
  } else {
    stopMotor();
  }

  delay(50);
}

Credits

Bahrik

Thanks to Bahrik.

Comments