IOT 23 — ESP32 simulation

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

Components

Sketch code

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

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

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

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

//LED Gerbang
#define LED_GREEN 14  
#define LED_RED   12  


#define SERVO_PIN 13

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

#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;

String uidTerdaftar[] = {
  "0",
  "1"
};
const int JUMLAH_UID = sizeof(uidTerdaftar) / sizeof(uidTerdaftar[0]);



LiquidCrystal_I2C lcd(LCD_ADDR, 16, 2);

const int SERVO_FREQ_HZ   = 50;  
const int SERVO_RESOLUSI  = 16;   
const int SERVO_MIN_US    = 544;  
const int SERVO_MAX_US    = 2400; 

void servoTulisSudut(int sudut) {
  int pulseUs = map(sudut, 0, 180, SERVO_MIN_US, SERVO_MAX_US);
  uint32_t periodeUs = 1000000UL / SERVO_FREQ_HZ; // 20000 us utk 50Hz
  uint32_t maxDuty = (1UL << SERVO_RESOLUSI) - 1;
  uint32_t duty = (uint32_t)(((uint64_t)pulseUs * maxDuty) / periodeUs);
  ledcWrite(SERVO_PIN, duty);
}
HardwareSerial RFIDSerial(2);

bool slot1Terisi = false;
bool slot2Terisi = false;

unsigned long lastBacaJarak = 0;
unsigned long palangDibukaSejak = 0;
bool palangSedangTerbuka = false;

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

void setup() {
  Serial.begin(115200);
  RFIDSerial.begin(9600, SERIAL_8N1, RFID_RX, RFID_TX);

  pinMode(TRIG1, OUTPUT);
  pinMode(ECHO1, INPUT);
  pinMode(TRIG2, OUTPUT);
  pinMode(ECHO2, INPUT);

  pinMode(LED_SLOT1, OUTPUT);
  pinMode(LED_SLOT1_GREEN, OUTPUT);
  pinMode(LED_SLOT2, OUTPUT);
  pinMode(LED_SLOT2_GREEN, OUTPUT);
  pinMode(LED_GREEN, OUTPUT);
  pinMode(LED_RED, OUTPUT);

  ledcAttach(SERVO_PIN, SERVO_FREQ_HZ, SERVO_RESOLUSI);
  servoTulisSudut(SUDUT_PALANG_TUTUP);

  Serial.println("[TEST] Servo: gerak ke 90 derajat...");
  servoTulisSudut(SUDUT_PALANG_BUKA);
  delay(1500);
  Serial.println("[TEST] Servo: kembali ke 0 derajat...");
  servoTulisSudut(SUDUT_PALANG_TUTUP);
  delay(1500);
  Serial.println("[TEST] Servo selesai.");

  Wire.begin(LCD_SDA, LCD_SCL);
  lcd.init();
  lcd.backlight();
  lcd.print("Sistem Parkir");
  lcd.setCursor(0, 1);
  lcd.print("Siap...");
  delay(1500);
  lcd.clear();

  Serial.println("Sistem parkir siap.");
}

void loop() {
  unsigned long now = millis();

  if (now - lastBacaJarak >= INTERVAL_BACA_JARAK) {
    lastBacaJarak = now;
    updateStatusSlot();
  }

  cekRFID();
  cekInputManual();

  if (palangSedangTerbuka && (now - palangDibukaSejak >= DURASI_PALANG_TERBUKA)) {
    tutupPalang();
  }

  if (pesanSementara == "" || now > pesanSementaraSampai) {
    pesanSementara = "";
    tampilkanStatusNormal();
  }
}

long bacaJarakCM(int trigPin, int echoPin