#define BLYNK_TEMPLATE_ID "TMPL6yg_Fum73"
#define BLYNK_TEMPLATE_NAME "Smart Occupancy and Space Utilization System"
#define BLYNK_AUTH_TOKEN "yUMqCiW43Y4Q2tBECZ7gpU0pzs6dt3GQ"
#define BLYNK_PRINT Serial
#include <WiFi.h>
#include <BlynkSimpleEsp32.h> // Blynk library for ESP32
#include <LiquidCrystal.h> // LCD library for non-I2C 16x2 LCD
// Wi-Fi credentials
char ssid[] = "Wokwi-GUEST";
char pass[] = "";
BlynkTimer timer; // Blynk timer for periodic updates
// Pin definitions
#define PIR_PIN 12
#define TRIG_PIN 13
#define ECHO_PIN 14
#define BUZZER_PIN 27 // Buzzer pin
// Non-I2C 16x2 LCD pins
#define LCD_RS 8
#define LCD_EN 9
#define LCD_D4 4
#define LCD_D5 5
#define LCD_D6 6
#define LCD_D7 7
LiquidCrystal lcd(LCD_RS, LCD_EN, LCD_D4, LCD_D5, LCD_D6, LCD_D7); // Non-I2C 16x2 LCD
// Global variables
int pirState = LOW;
int buzzerStatus = LOW;
long duration;
int distance;
void setup() {
Serial.begin(115200);
// Connect to Wi-Fi and Blynk
Serial.println("Connecting to WiFi...");
Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass);
while (Blynk.connect() == false) {
Serial.print(".");
delay(1000);
}
Serial.println("Connected to Blynk");
// Initialize sensors and actuators
pinMode(PIR_PIN, INPUT);
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
pinMode(BUZZER_PIN, OUTPUT);
// Initialize LCD
lcd.begin(16, 2); // Initialize 16x2 LCD
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("System Ready!");
delay(2000);
lcd.clear();
// Configure Blynk timer
timer.setInterval(1000L, myTimerEvent); // Call every second
}
void myTimerEvent() {
// PIR sensor
pirState = digitalRead(PIR_PIN);
String motionStatus = (pirState == HIGH) ? "Motion Detected" : "No Motion";
// Debugging output to Serial Monitor
if (pirState == HIGH) {
Serial.println("PIR Motion Detected!");
digitalWrite(BUZZER_PIN, HIGH);
buzzerStatus = HIGH;
} else {
Serial.println("PIR No Motion");
digitalWrite(BUZZER_PIN, LOW);
buzzerStatus = LOW;
}
// Ultrasonic sensor
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
duration = pulseIn(ECHO_PIN, HIGH);
distance = duration * 0.034 / 2;
// Output the ultrasonic distance
Serial.print("Ultrasonic Distance: ");
Serial.println(distance);
// Update LCD with information about space usage
lcd.setCursor(0, 0);
if (motionStatus == "Motion Detected") {
lcd.print("LCD On: Space Busy");
Serial.println("LCD On: Space Busy");
lcd.setCursor(0, 1);
lcd.print("Crowd Detected!");
Serial.println("Crowd Detected!");
} else {
lcd.print("LCD On: Space Clear");
Serial.println("LCD On: Space Clear");
lcd.setCursor(0, 1);
lcd.print("No Motion");
Serial.println("No Motion");
}
// Display distance on the LCD (line 2)
lcd.setCursor(0, 1);
lcd.print("Dist: ");
lcd.print(distance);
lcd.print(" cm");
Serial.print("Distance: ");
Serial.print(distance);
Serial.println(" cm");
// Send data to Blynk with clearer motion status
Blynk.virtualWrite(V0, motionStatus); // Display "Motion Detected" or "No Motion"
Blynk.virtualWrite(V1, distance); // Send distance value
Blynk.virtualWrite(V2, "PIR: " + motionStatus + " - Dist: " + String(distance) + "cm"); // Display both motion and distance on Blynk
Blynk.virtualWrite(V3, buzzerStatus); // Send buzzer state (on or off)
// Debugging outputs for serial monitor
Serial.print("PIR State: ");
Serial.println(motionStatus); // Print motion status clearly
Serial.print("Buzzer State: ");
Serial.println(buzzerStatus == HIGH ? "On" : "Off");
Serial.print("Distance: ");
Serial.println(distance);
Serial.print("Blynk State: ");
Serial.println(motionStatus);
}
void loop() {
Blynk.run(); // Run Blynk
timer.run(); // Run Blynk timer for periodic tasks
}