#define BLYNK_TEMPLATE_ID "TMPL61gaM49_d"
#define BLYNK_TEMPLATE_NAME "Smart waste management"
#define BLYNK_AUTH_TOKEN "_zFriQP277d5ZGWWzFf_88OUZsrqCpf9"
#define BLYNK_PRINT Serial

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

char auth[] = BLYNK_AUTH_TOKEN;
char ssid[] = "Wokwi-GUEST";
char pass[] = "";


#define TRIGGER_PIN_KERING   13 // Pin yang terhubung ke pin TRIGGER sensor ultrasonik sampah kering
#define ECHO_PIN_KERING      12 // Pin yang terhubung ke pin ECHO sensor ultrasonik sampah kering
#define TRIGGER_PIN_BASAH    27 // Pin yang terhubung ke pin TRIGGER sensor ultrasonik sampah basah
#define ECHO_PIN_BASAH       14 // Pin yang terhubung ke pin ECHO sensor ultrasonik sampah basah
#define TRIGGER_PIN_3        25 // Pin yang terhubung ke pin TRIGGER sensor ultrasonik ketiga                                   
#define ECHO_PIN_3           26 // Pin yang terhubung ke pin ECHO sensor ultrasonik ketiga
#define SOIL_PIN             32 // Pin yang terhubung ke sensor kelembaban tanah
#define SERVO_PIN            2  // Pin yang terhubung ke pin kontrol servo motor
#define DATASTREAM_PIN       V3 // Pin virtual yang akan digunakan untuk datastream
#define NOTIF_KERING_PIN     V1 // Pin virtual untuk notifikasi tempat sampah kering
#define NOTIF_BASAH_PIN      V2 // Pin virtual untuk notifikasi tempat sampah basah
#define LED_KERING_PIN       V4 // Pin virtual untuk LED tempat sampah kering
#define LED_BASAH_PIN        V5 // Pin virtual untuk LED tempat sampah basah

Servo myservo;
NewPing sonarKering(TRIGGER_PIN_KERING, ECHO_PIN_KERING, 200);
NewPing sonarBasah(TRIGGER_PIN_BASAH, ECHO_PIN_BASAH, 200);
NewPing sonar3(TRIGGER_PIN_3, ECHO_PIN_3, 200);

int threshold = 5; // Ambang batas (threshold) 5 cm
const int trashLevelKering = 4000;
const int trashLevelBasah = 1365;
int soilMoistureValue = 0;
int soilmoist = 0;
bool ultrasonicReadComplete = false;
bool soilActive = false;
BlynkTimer timer;

void setup() {
  Serial.begin(9600);
  delay(1000); // Wait for serial monitor to open

  Blynk.begin(auth, ssid, pass); // Mulai koneksi Blynk
  Serial.println("Connected to Blynk");

  myservo.attach(SERVO_PIN);
  pinMode(SOIL_PIN, INPUT);

  // Setup pin virtual untuk datastream
  Blynk.virtualWrite(DATASTREAM_PIN, trashLevelKering, trashLevelBasah); // Menginisialisasi datastream dengan level sampah awal

  // Setup timer untuk memantau status tempat sampah setiap 1 detik
  timer.setInterval(1000L, checkTrashStatus);
}

void loop() {
  Blynk.run(); // Tetapkan agar Blynk berjalan dalam loop
  timer.run(); // Jalankan timer Blynk
}

void checkTrashStatus() {
  int distanceKering = sonarKering.ping_cm();
  int distanceBasah = sonarBasah.ping_cm();
  int distance3 = sonar3.ping_cm();

  Serial.print("Distance Kering: ");
  Serial.println(distanceKering);
  Serial.print("Distance Basah: ");
  Serial.println(distanceBasah);
  Serial.print("Distance 3: ");
  Serial.println(distance3);

  Blynk.virtualWrite(DATASTREAM_PIN, distanceKering, distanceBasah);

  if (distanceKering <= threshold) {
    Blynk.virtualWrite(NOTIF_KERING_PIN, "Tempat sampah kering sudah full!"); 
    Blynk.virtualWrite(LED_KERING_PIN, 255); 
  } else {
    Blynk.virtualWrite(NOTIF_KERING_PIN, "Tempat sampah kering belum full."); 
    Blynk.virtualWrite(LED_KERING_PIN, 0); 
  }

  if (distanceBasah <= threshold) {
    Blynk.virtualWrite(NOTIF_BASAH_PIN, "Tempat sampah basah sudah full!"); 
    Blynk.virtualWrite(LED_BASAH_PIN, 255); 
  } else {
    Blynk.virtualWrite(NOTIF_BASAH_PIN, "Tempat sampah basah belum full."); 
    Blynk.virtualWrite(LED_BASAH_PIN, 0); 
  }

  if (distance3 <= threshold) {
    soilMoistureValue = analogRead(SOIL_PIN);
    soilmoist = map(soilMoistureValue, trashLevelKering, trashLevelBasah, 0, 100);

    if (soilmoist >= 100) {
      soilmoist = 100;
    } else if (soilmoist <= 0) {
      soilmoist = 0;
    }

    Serial.print("Soil Moisture: ");
    Serial.println(soilmoist);

    if (soilmoist > 50) {
      Blynk.virtualWrite(NOTIF_BASAH_PIN, "Sampah basah masuk!");
      Blynk.virtualWrite(LED_BASAH_PIN, 255);
      moveServoRight();
      delay(3000); 
      stopServo();
    } else {
      Blynk.virtualWrite(NOTIF_KERING_PIN, "Sampah kering masuk!");
      Blynk.virtualWrite(LED_KERING_PIN, 255);
      moveServoLeft();
      delay(3000); 
      stopServo();
    }
  } else {
    stopServo();
  }

  ultrasonicReadComplete = true;
}


void moveServoLeft() {
  myservo.write(0); 
}

void moveServoRight() {
  myservo.write(180); 
}

void stopServo() {
  myservo.write(90); 
}
soil-moistureBreakout