#define trigPin1 2
#define echoPin1 3
#define trigPin2 4
#define echoPin2 5
#define buzzerPin 6
#define pirPin 7
#define buttonIgnorePIR 8
#define buttonManualBuzz 9
const unsigned long ON_TIME = 2500;
const unsigned long OFF_TIME = 2500;
const int BUZZ_FREQ = 1000;
const unsigned long IGNORE_PIR_DURATION = 120000; // 2 minutes
const unsigned long MANUAL_BUZZ_DURATION = 3000; // 3 seconds
const unsigned long UPDATE_INTERVAL = 5000; // 5 seconds
unsigned long lastToggle = 0;
bool buzzerOnState = false;
unsigned long ignorePIRStart = 0;
bool ignoringPIR = false;
bool pirTriggered = false;
bool ignoreButtonLockout = false;
unsigned long manualBuzzStart = 0;
bool manualBuzzing = false;
unsigned long lastUpdate = 0;
float getDistanceCM(int trigPin, int echoPin) {
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
long duration = pulseIn(echoPin, HIGH);
return duration * 0.0343 / 2.0;
}
void setup() {
Serial.begin(9600);
pinMode(trigPin1, OUTPUT);
pinMode(echoPin1, INPUT);
pinMode(trigPin2, OUTPUT);
pinMode(echoPin2, INPUT);
pinMode(buzzerPin, OUTPUT);
pinMode(pirPin, INPUT);
pinMode(buttonIgnorePIR, INPUT_PULLUP);
pinMode(buttonManualBuzz, INPUT_PULLUP);
noTone(buzzerPin);
}
void loop() {
unsigned long now = millis();
// --- PIR and Button States ---
bool pirState = digitalRead(pirPin) == HIGH;
bool manualBtnPressed = digitalRead(buttonManualBuzz) == LOW;
// --- Ignore PIR Button Edge Detection and Logic ---
static bool prevIgnoreBtnState = HIGH;
bool currentIgnoreBtnState = digitalRead(buttonIgnorePIR);
bool ignoreBtnFallingEdge = (prevIgnoreBtnState == HIGH && currentIgnoreBtnState == LOW);
prevIgnoreBtnState = currentIgnoreBtnState;
if (ignoreBtnFallingEdge) {
if (!ignoringPIR) {
ignoringPIR = true;
ignorePIRStart = now;
ignoreButtonLockout = true;
Serial.println("PIR ignoring started for 2 minutes...");
} else {
ignoringPIR = false;
ignoreButtonLockout = false;
Serial.println("PIR ignoring cancelled early.");
}
}
if (ignoringPIR && now - ignorePIRStart >= IGNORE_PIR_DURATION) {
ignoringPIR = false;
ignoreButtonLockout = false;
Serial.println("PIR ignoring ended (timeout).");
}
// --- Manual Buzz Button ---
if (manualBtnPressed && !manualBuzzing) {
manualBuzzing = true;
manualBuzzStart = now;
tone(buzzerPin, BUZZ_FREQ);
Serial.println("Manual buzzer triggered.");
}
if (manualBuzzing && now - manualBuzzStart >= MANUAL_BUZZ_DURATION) {
manualBuzzing = false;
noTone(buzzerPin);
}
// Skip main logic if manually buzzing
if (manualBuzzing) {
delay(50);
return;
}
// --- Sensor & Buzzer Logic every 5 seconds ---
if (now - lastUpdate >= UPDATE_INTERVAL) {
lastUpdate = now;
// PIR logic
if (!ignoringPIR && pirState) {
pirTriggered = true;
} else {
pirTriggered = false;
}
// Read Sensors
float d1 = getDistanceCM(trigPin1, echoPin1);
float d2 = getDistanceCM(trigPin2, echoPin2);
float avg = (d1 + d2) / 2.0;
Serial.print("D1: "); Serial.print(d1);
Serial.print(" cm | D2: "); Serial.print(d2);
Serial.print(" cm | Avg: "); Serial.print(avg);
Serial.print(" cm | PIR: "); Serial.println(pirTriggered ? "Motion" : "None");
// Buzzer Pattern Decision
if ((avg >= 2.0 && avg <= 50.0) && !pirTriggered) {
buzzerOnState = true;
tone(buzzerPin, BUZZ_FREQ);
lastToggle = now;
} else {
buzzerOnState = false;
noTone(buzzerPin);
}
}
// Turn buzzer off after 2.5s if it was turned on during last update
if (buzzerOnState && now - lastToggle >= ON_TIME) {
buzzerOnState = false;
noTone(buzzerPin);
}
delay(50);
}