IOT 23 — ESP32 simulation

An interactive ESP32 circuit simulation you can run free in your browser on Velxio, by mi1797128.

Components

Sketch code

#define BLYNK_TEMPLATE_ID "TMPL66YpLpOkk"
#define BLYNK_TEMPLATE_NAME "Parking Simulation"
#define BLYNK_AUTH_TOKEN    "TczAT-hqqwxCDAZI0Gui_lo0DO_faWRJ"

#define BLYNK_PRINT Serial

#include <WiFi.h>
#include <BlynkSimpleEsp32.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>


char ssid[] = "indomaret";
char pass[] = "indo1234";


// Ultrasonic 1
#define TRIG1 5
#define ECHO1 23

// Ultrasonic 2
#define TRIG2 32
#define ECHO2 35

// LED slot
#define LED_SLOT1 26
#define LED_SLOT1_GREEN 25
#define LED_SLOT2 33
#define LED_SLOT2_GREEN 15

// LED indikator kapasitas
#define LED_GREEN 14
#define LED_RED   12

// Servo palang
#define SERVO_PIN 13

// LCD I2C
#define LCD_SDA 21
#define LCD_SCL 22
#define LCD_ADDR 0x27

// RFID UART2
#define RFID_RX 18
#define RFID_TX 19


const int JARAK_TERISI_CM = 10;
const int TOTAL_SLOT = 2;

const int SUDUT_PALANG_BUKA = 90;
const int SUDUT_PALANG_TUTUP = 0;

const unsigned long DURASI_PALANG_TERBUKA = 4000;
const unsigned long INTERVAL_BACA_JARAK = 300;
const unsigned long INTERVAL_RECONNECT = 5000;

// Servo: ESP32 Arduino Core 3.x
const int SERVO_FREQ_HZ = 50;
const int SERVO_RESOLUSI = 16;
const int SERVO_MIN_US = 544;
const int SERVO_MAX_US = 2400;

// GANTI DENGAN UID KARTU ASLI YANG SUDAH DIBACA
String uidTerdaftar[] = {
  "0",
  "1"
};

const int JUMLAH_UID =
    sizeof(uidTerdaftar) / sizeof(uidTerdaftar[0]);


LiquidCrystal_I2C lcd(LCD_ADDR, 16, 2);
HardwareSerial RFIDSerial(2);
BlynkTimer timer;

bool slot1Terisi = false;
bool slot2Terisi = false;
bool palangSedangTerbuka = false;

unsigned long lastBacaJarak = 0;
unsigned long palangDibukaSejak = 0;
unsigned long lastReconnectAttempt = 0;

String pesanSementara = "";
unsigned long pesanSementaraSampai = 0;


long bacaJarakCM(int trigPin, int echoPin);
void updateStatusSlot();
int hitungSlotKosong();
void cekRFID();
void cekInputManual();
bool uidDiizinkan(String uid);
void prosesAkses(String uid);
void bukaPalang();
void tutupPalang();
void kedipLED(int pin, int kali);
void tampilkanStatusNormal();
void tampilkanPesanSementara(
    String baris1, String baris2, unsigned long durasiMs);
void kirimDataBlynk();
void tampilkanStatusKapasitas();


BLYNK_WRITE(V6) {
  int perintah = param.asInt();

  if (perintah == 1) {
    Serial.println("[BLYNK] Permintaan buka palang");

    if (hitungSlotKosong() <= 0) {
      tampilkanPesanSementara(
          "Parkir penuh!", "Akses ditolak", 2000);
      kedipLED(LED_RED, 3);
    } else {
      tampilkanPesanSementara(
          "Buka dari Blynk", "Akses diterima", 1500);
      bukaPalang();
    }

    // Reset agar tombol siap digunakan kembali
    Blynk.virtualWrite(V6, 0);
  }
}

BLYNK_WRITE(V7) {
  int perintah = param.asInt();

  if (perintah == 1) {
    Serial.println("[BLYNK] Perintah tutup palang");
    tutupPalang();
    Blynk.virtualWrite(V7, 0);
  }
}


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

  RFIDSerial.begin(9600, SERIAL_8N1, RFID_RX, RFID_TX);

  pinMode(TRIG1, OUTPUT);
  pinMode(ECHO1, INPUT);
  p