#include <Servo.h>
// === PIN DEFINISI ===
#define TRIG_PIN 3
#define ECHO_PIN 4
#define PIR_PIN 2
#define BUZZER_PIN 6
#define SERVO_PIN 9
Servo gateServo;
// === KONSTANTA DAN VARIABEL ===
const int bukaSudut = 90;
const int tutupSudut = 0;
const int batasJarak = 50;
const int intervalPrint = 1000; // 1 detik
unsigned long lastPrintTime = 0;
unsigned long lastToneTime = 0;
bool toneState = false;
void setup() {
Serial.begin(9600);
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
pinMode(PIR_PIN, INPUT);
pinMode(BUZZER_PIN, OUTPUT);
gateServo.attach(SERVO_PIN);
gateServo.write(tutupSudut); // Gerbang awal tertutup
noTone(BUZZER_PIN); // Pastikan buzzer mati
}
void loop() {
int jarak = bacaJarak();
bool pirTerdeteksi = digitalRead(PIR_PIN);
bool kondisiBuka = (jarak < batasJarak && pirTerdeteksi);
// === LOGIKA AKSI ===
nyalakanAlarm(kondisiBuka);
gateServo.write(kondisiBuka ? bukaSudut : tutupSudut);
// === CETAK SERIAL MONITOR SETIAP 1 DETIK ===
if (millis() - lastPrintTime >= intervalPrint) {
Serial.print("Jarak: ");
Serial.print(jarak);
Serial.print(" cm ; PIR: ");
Serial.print(pirTerdeteksi ? "Detected" : "Not Detected");
Serial.print(" ; Gerbang: ");
Serial.println(kondisiBuka ? "Terbuka" : "Tertutup");
lastPrintTime = millis();
}
delay(50); // Delay ringan
}
int bacaJarak() {
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
long durasi = pulseIn(ECHO_PIN, HIGH, 30000); // timeout 30 ms
if (durasi == 0) return 999; // Tidak terbaca
return durasi * 0.034 / 2; // cm
}
void nyalakanAlarm(bool status) {
unsigned long now = millis();
if (status) {
if (!toneState && now - lastToneTime >= 600) {
tone(BUZZER_PIN, 1000); // Nada 1000 Hz
toneState = true;
lastToneTime = now;
}
if (toneState && now - lastToneTime >= 200) {
noTone(BUZZER_PIN); // Matikan nada setelah 200 ms
toneState = false;
lastToneTime = now;
}
} else {
noTone(BUZZER_PIN); // Matikan buzzer sepenuhnya
toneState = false;
}
}