#include <ESP32Servo.h>
#include <DHT.h>
// — Konfigurasi pin —
const int tombolMulai = 13;
const int tombolSelesai = 12;
const int trigPin = 4;
const int echoPin = 2;
const int trig2Pin = 19;
const int echo2Pin = 18;
const int servoPin = 27;
const int servo2Pin = 26;
const int dhtPin = 25;
const int proxPin = 22; // <— output sensor proximity NPN
#define DHTTYPE DHT22
Servo tutupSampah;
Servo servoPengarah;
DHT dht(dhtPin, DHTTYPE);
bool isOpen = false;
bool sessionActive = false;
unsigned long openTime = 0;
const int openDuration = 10000; // 10 s
int totalRupiah = 0;
// — variabel DHT —
float kelembapanTerakhir = 0.0;
unsigned long lastDHTReadTime = 0;
const unsigned long dhtInterval = 2000; // 2 s
// — deklarasi fungsi —
void bukaTutupSampah();
float ukurKetinggianSampah();
float ukurKepenuhanSampah();
void setup() {
Serial.begin(115200);
pinMode(tombolMulai , INPUT_PULLUP);
pinMode(tombolSelesai, INPUT_PULLUP);
pinMode(trigPin , OUTPUT);
pinMode(echoPin , INPUT);
pinMode(trig2Pin, OUTPUT);
pinMode(echo2Pin, INPUT);
pinMode(proxPin , INPUT_PULLUP); // <— pull-up internal sensor NPN
tutupSampah.setPeriodHertz(50);
tutupSampah.attach(servoPin , 500, 2400);
tutupSampah.write(90); // tutup
servoPengarah.setPeriodHertz(50);
servoPengarah.attach(servo2Pin, 500, 2400);
servoPengarah.write(90); // netral
dht.begin();
Serial.println("Tekan tombol mulai untuk memulai pengelolaan sampah.");
Serial.println(" ");
}
void loop() {
unsigned long now = millis();
// — baca DHT periodik —
if (now - lastDHTReadTime >= dhtInterval) {
float h = dht.readHumidity();
if (!isnan(h)) kelembapanTerakhir = h;
lastDHTReadTime = now;
}
// — mulai sesi —
if (digitalRead(tombolMulai) == LOW && !sessionActive) {
sessionActive = true;
bukaTutupSampah(); // buka tutup
openTime = now;
isOpen = true;
Serial.println("===============");
Serial.println("Proses dimulai.");
Serial.println("===============");
}
// — akhiri sesi —
if (sessionActive && digitalRead(tombolSelesai) == LOW) {
Serial.println("===============");
Serial.println("Proses diakhiri.");
Serial.println("===============");
Serial.printf("Total pendapatan: Rp %d\n", totalRupiah);
totalRupiah = 0;
tutupSampah.write(90); // tutup kembali
isOpen = false;
sessionActive = false;
delay(2000);
Serial.println("Sistem siap, menunggu pengguna selanjutnya.");
}
// — analisis setelah pintu dibiarkan terbuka 10 s —
if (isOpen && (now - openTime >= openDuration)) {
tutupSampah.write(90); // tutup
Serial.println("Tunggu sebentar, sistem sedang memproses botol anda.");
delay(2000);
// — 1. deteksi lembab —
float kelembapan = kelembapanTerakhir;
Serial.printf("Identifikasi Sampah Organik: %.1f %%\n", kelembapan);
if (kelembapan > 80.0) {
Serial.println("Sampah basah terdeteksi.");
servoPengarah.write(135);
delay(2000);
servoPengarah.write(90);
}
else {
// — 2. deteksi logam via sensor proximity —
bool logam = digitalRead(proxPin) == LOW; // NPN aktif LOW
if (logam) {
Serial.println("Sampah logam terdeteksi.");
servoPengarah.write(135);
delay(2000);
servoPengarah.write(90);
} else {
// — 3. klasifikasi botol via ultrasonik —
float tinggi = ukurKetinggianSampah();
Serial.printf("Ketinggian Botol: %.1f cm\n", tinggi);
if (tinggi >= 8 && tinggi <= 14) {
Serial.println("Botol besar (+500)");
totalRupiah += 500;
servoPengarah.write(45);
delay(2000);
servoPengarah.write(90);
}
else if (tinggi >= 16 && tinggi <= 18) {
Serial.println("Botol sedang (+200)");
totalRupiah += 200;
servoPengarah.write(45);
delay(2000);
servoPengarah.write(90);
}
else {
Serial.println("Sampah tidak dikenali.");
servoPengarah.write(135);
delay(2000);
servoPengarah.write(90);
}
}
}
// — lapor kepenuhan —
float persen = ukurKepenuhanSampah();
Serial.printf("Tingkat Penumpukan Sampah: %.1f %%\n", persen);
Serial.printf("Total pendapatan sementara: Rp %d\n", totalRupiah);
// — siap terima botol berikut —
bukaTutupSampah();
openTime = millis();
isOpen = true;
}
}
// ========================== fungsi bantu ==========================
void bukaTutupSampah() {
tutupSampah.write(0); // buka
// Serial.println("======================================");
// Serial.println("Tutup terbuka, silahkan masukkan botol");
// Serial.println("======================================");
}
float ukurKetinggianSampah() {
digitalWrite(trigPin, LOW); delayMicroseconds(2);
digitalWrite(trigPin, HIGH); delayMicroseconds(10);
digitalWrite(trigPin, LOW);
long dur = pulseIn(echoPin, HIGH, 30000);
return (dur == 0) ? 100 : dur * 0.034 / 2.0;
}
float ukurKepenuhanSampah() {
digitalWrite(trig2Pin, LOW); delayMicroseconds(2);
digitalWrite(trig2Pin, HIGH); delayMicroseconds(10);
digitalWrite(trig2Pin, LOW);
long dur = pulseIn(echo2Pin, HIGH, 30000);
if (dur == 0) return 0;
float jarak = dur * 0.034 / 2.0; // cm
const float tinggi = 35.0; // cm
float isi = tinggi - jarak;
return constrain((isi / tinggi) * 100.0, 0, 100);
}