#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// --- I2C LCD address might be 0x27 or 0x3F ---
LiquidCrystal_I2C lcd(0x27, 16, 2); // (I2C address, cols, rows)
// --- Pin setup ---
const int pirPin = PA6; // PIR sensor
const int buzzerPin = PA0; // Buzzer
const int ldrPin = PA2; // LDR analog input
const int ledPin = PA5; // LED when dark
// Motion logic
bool motionActive = false;
unsigned long motionStartTime = 0;
String lastMessage = "";
void setup() {
delay(500); // Allow power to stabilize
Serial.begin(9600);
pinMode(pirPin, INPUT);
pinMode(buzzerPin, OUTPUT);
pinMode(ledPin, OUTPUT);
// Start I2C LCD
lcd.init(); // Initialize the LCD
lcd.backlight(); // Turn on backlight
lcd.setCursor(0, 0);
lcd.print("System Starting...");
delay(1000);
lcd.clear();
}
void loop() {
// --- LDR logic ---
int lightLevel = analogRead(ldrPin);
digitalWrite(ledPin, lightLevel > 500 ? LOW : HIGH); // LED on when dark
// --- PIR logic ---
int pirState = digitalRead(pirPin);
// Detect new motion
if (pirState == HIGH && !motionActive) {
motionActive = true;
motionStartTime = millis();
digitalWrite(buzzerPin, HIGH);
updateLCD("Object Detected");
}
// Keep buzzer ON for 20s
if (motionActive) {
if (millis() - motionStartTime >= 20000) {
digitalWrite(buzzerPin, LOW);
motionActive = false;
updateLCD("Safe");
}
}
// Idle state (no motion)
if (!motionActive && pirState == LOW) {
updateLCD("Safe");
}
delay(200);
}
// Only update LCD when message changes
void updateLCD(String message) {
if (message != lastMessage) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(message);
lastMessage = message;
}
}