Security System — Esp32 Devkit C V4 simulation

An interactive Esp32 Devkit C V4 circuit simulation you can run free in your browser on Velxio, by tareq-neoaz.

Components

Sketch code

#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
#include <Keypad.h>
#include <ESP32Servo.h>

// ===== TFT =====
#define TFT_CS   4
#define TFT_DC   2
#define TFT_RST  16
Adafruit_ILI9341 tft(TFT_CS, TFT_DC, TFT_RST);

// ===== PINS =====
#define LED_GREEN 5
#define LED_RED   17
#define ALARM_LED 22
#define PIR_PIN   34
#define REED_PIN  35
#define LDR_PIN   36
#define SERVO_PIN 15

Servo doorLock;

// ===== KEYPAD =====
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};
byte rowPins[ROWS] = {13, 12, 14, 27};
byte colPins[COLS] = {26, 25, 33, 32};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);

// ===== SYSTEM STATES =====
enum SystemState { DISARMED, ARMING, ARMED, TRIGGERED };
SystemState currentState = DISARMED;

// ===== SECURITY VARS =====
String correctPIN = "1234";
String enteredPIN = "";
int failedAttempts = 0;
unsigned long timer = 0;
int countdown = 0;
String alarmReason = "";

// Variables to stop screen flickering
int lastPIR = -1;
int lastDoor = -1;
int lastLDR = -1;

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

  pinMode(LED_GREEN, OUTPUT);
  pinMode(LED_RED, OUTPUT);
  pinMode(ALARM_LED, OUTPUT);
  
  pinMode(PIR_PIN, INPUT);
  pinMode(REED_PIN, INPUT_PULLUP);
  pinMode(LDR_PIN, INPUT);

  tft.begin();
  tft.setRotation(4);
  tft.fillScreen(0x0000);
  
  // --- Draw Static UI ---
  tft.fillRect(0, 0, 320, 40, 0x001F);
  tft.setFont(NULL);
  tft.setTextSize(3);
  tft.setTextColor(0xFFFF, 0x001F);
  tft.setCursor(85, 8); 
  tft.print("FORTRESS");
  
  tft.drawLine(0, 130, 320, 130, 0x7BEF); 
  tft.drawRect(5, 145, 310, 85, 0x7BEF); 
  tft.drawRect(6, 146, 308, 83, 0x7BEF); 

  tft.setTextSize(2);
  tft.setTextColor(0xFFFF, 0x0000);
  tft.setCursor(10, 60); tft.print("PIR: ");
  tft.setCursor(10, 85); tft.print("DOR: ");
  tft.setCursor(10, 110); tft.print("LDR: ");

  doorLock.attach(SERVO_PIN);
  doorLock.write(90); // Unlocked

  updateStateDisplay();
}

void loop() {
  char key = keypad.getKey();
  if (key) handleKeyPress(key);

  // === STATE MACHINE ===
  switch (currentState) {
    case DISARMED:
      digitalWrite(LED_GREEN, HIGH);
      digitalWrite(LED_RED, LOW);
      digitalWrite(ALARM_LED, LOW);
      doorLock.write(90);
      updateSensors();
      delay(50); // Give Velxio time to breathe
      break;

    case ARMING:
      digitalWrite(LED_GREEN, LOW);
      digitalWrite(LED_RED, HIGH);
      if (millis() - timer > 1000) {
        countdown--;
        timer = millis();
        updateStateDisplay(); 
        if (countdown <= 0) {
          currentState = ARMED;
          updateStateDisplay();
        }
      }
      delay(50);
      break;

    case ARMED:
      digitalWrite(LED_GREEN, LOW);
      if (millis() - timer > 500) {
        digitalWrite(LED_RED, !digitalRead(LED_RED));
        timer = millis();
      }
      doorLock.write(0);
      digitalWrite(ALARM_LED, LOW);

More projects by tareq-neoaz