#define BLYNK_TEMPLATE_ID "TMPL389vcVfoD"
#define BLYNK_TEMPLATE_NAME "smart dustbin"

#include <WiFi.h>
#include <BlynkSimpleEsp32.h>
#include <ESP32Servo.h>


// Blynk credentials
char auth[] = "Qa-pqFlXhRju1kOu8PVZAbYn-9muhuEn";
char ssid[] = "Wokwi-GUEST";
char password[] = "";

// Ultrasonic sensor 1 (lid control)
const int trigPin1 = 5;
const int echoPin1 = 18;
// Ultrasonic sensor 2 (fill level)
const int trigPin2 = 19;
const int echoPin2 = 21;

// Servo motor
const int servoPin = 2;
Servo servo;
const int openAngle = 0;
const int closeAngle = 90;

// Fill level threshold (percentage)
const int fillLevelThreshold = 80;

// Function to measure distance using ultrasonic sensor
long measureDistance(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.034 / 2;
}

// Function to control the servo motor
void controlServo(int angle) {
  servo.write(angle);
  delay(10); // Small delay to allow the servo to move
}

void setup() {
  // Initialize serial communication
  Serial.begin(115200);

  // Connect to WiFi
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi...");
  }
  Serial.println("Connected to WiFi");

  // Initialize Blynk
  Blynk.begin(auth, ssid, password);

  // Initialize servo
  servo.attach(servoPin);
  controlServo(closeAngle); // Start with lid closed

  // Set pin modes for ultrasonic sensors
  pinMode(trigPin1, OUTPUT);
  pinMode(echoPin1, INPUT);
  pinMode(trigPin2, OUTPUT);
  pinMode(echoPin2, INPUT);
}

void loop() {
  Blynk.run(); // Run Blynk

  // Ultrasonic sensor 1 (lid control)
  long distance1 = measureDistance(trigPin1, echoPin1);
  Serial.print("Distance 1: ");
  Serial.print(distance1);
  Serial.println(" cm");

  if (distance1 < 10) { // Adjust distance as needed
    controlServo(openAngle);
  } else {
    controlServo(closeAngle);
  }

  // Ultrasonic sensor 2 (fill level)
  long distance2 = measureDistance(trigPin2, echoPin2);
  Serial.print("Distance 2: ");
  Serial.print(distance2);
  Serial.println(" cm");

  // Calculate fill level (0-100%)
  int fillLevel = map(distance2, 0, 100, 100, 0); // Assuming max distance is 100cm
  fillLevel = constrain(fillLevel, 0, 100); // Ensure fill level stays within 0-100

  // Send fill level to Blynk app
  Blynk.virtualWrite(V1, fillLevel);

  // Trigger alert if fill level exceeds threshold
  if (fillLevel > fillLevelThreshold) {
    Serial.println("Fill level exceeded threshold!");
    Blynk.logEvent("dustbin_is_full_"); // Send Blynk notification
  }
  delay(100); // Small delay before next measurement
}