/********** KODE ESP32 JEMURAN OTOMATIS + BLYNK IOT (VERSI FINAL) **********/
#define BLYNK_TEMPLATE_ID "TMPL694vPGUTA"
#define BLYNK_TEMPLATE_NAME "jemuran otomatis"
#define BLYNK_AUTH_TOKEN "i9LxDU-nxzgYu1OCAszPxjFakta7phmf"
#include <WiFi.h>
#include <BlynkSimpleEsp32.h>
#include <DHT.h>
#include <ESP32Servo.h>
/********** WIFI & BLYNK **********/
char auth[] = BLYNK_AUTH_TOKEN;
char ssid[] = "Wokwi-GUEST";
char pass[] = "";
/********** PIN & KONFIGURASI **********/
#define LDR_PIN 34
#define RAIN_PIN 35
#define DHT_PIN 15
#define SERVO_PIN 27
#define BUZZER_PIN 25 // pakai LED sebagai buzzer
#define DHTTYPE DHT22
#define BUZZER_DURATION 60000 // 1 menit
/********** OBJEK **********/
Servo jemuran;
DHT dht(DHT_PIN, DHTTYPE);
BlynkTimer timer;
/********** VARIABEL GLOBAL **********/
bool statusJemuran = false; // false = Masuk, true = Keluar
unsigned long buzzerStartTime = 0;
unsigned long beepTimer = 0;
bool buzzerAktif = false;
bool beepState = false;
/********** FUNGSI STATUS LDR **********/
String kondisiLDR(int nilaiLDR) {
if (nilaiLDR > 3000) return "Cerah";
else if (nilaiLDR > 1500) return "Mendung";
else return "Gelap";
}
/********** FUNGSI STATUS HUJAN **********/
String statusHujan(int nilaiHujan) {
return nilaiHujan < 2500 ? "Hujan" : "Kering";
}
/********** FUNGSI UTAMA **********/
void bacaSensorDanKirimBlynk() {
int ldr = analogRead(LDR_PIN);
int rain = analogRead(RAIN_PIN);
float suhu = dht.readTemperature();
float hum = dht.readHumidity();
bool cerah = ldr > 2500;
bool mendung = ldr <= 2500 && ldr > 1500;
bool gelap = ldr <= 1500;
bool hujan = rain < 2500;
bool buzzerOn = false;
String status;
/********** SERVO OTOMATIS **********/
if (cerah && !hujan) {
jemuran.write(0); // keluar
status = "Keluar";
statusJemuran = true;
} else {
jemuran.write(90); // masuk
status = "Masuk";
statusJemuran = false;
}
/********** BUZZER / LED **********/
unsigned long sekarang = millis();
if (hujan) {
if (!buzzerAktif) { buzzerAktif = true; buzzerStartTime = sekarang; }
if (sekarang - buzzerStartTime <= BUZZER_DURATION) buzzerOn = true;
else buzzerAktif = false;
} else if (mendung || gelap) {
if (!buzzerAktif) { buzzerAktif = true; buzzerStartTime = sekarang; }
if (sekarang - buzzerStartTime <= BUZZER_DURATION) {
if (sekarang - beepTimer >= (gelap ? 800 : 300)) {
beepTimer = sekarang;
beepState = !beepState;
}
buzzerOn = beepState;
} else buzzerAktif = false;
} else {
buzzerOn = false;
buzzerAktif = false;
}
digitalWrite(BUZZER_PIN, buzzerOn ? HIGH : LOW); // LED sebagai buzzer
/********** KIRIM KE BLYNK **********/
Blynk.virtualWrite(V1, suhu); // Suhu
Blynk.virtualWrite(V2, hum); // Kelembapan
Blynk.virtualWrite(V3, statusJemuran ? "Keluar" : "Masuk"); // Status jemuran → teks
Blynk.virtualWrite(V4, buzzerOn ? "0" : "1"); // Status buzzer
Blynk.virtualWrite(V5, kondisiLDR(ldr)); // Status LDR → teks
Blynk.virtualWrite(V6, statusHujan(rain)); // Status hujan → teks
/********** SERIAL MONITOR **********/
Serial.println("================================");
Serial.print("LDR : "); Serial.print(ldr); Serial.print(" ("); Serial.print(kondisiLDR(ldr)); Serial.println(")");
Serial.print("Hujan : "); Serial.print(rain); Serial.print(" → "); Serial.println(statusHujan(rain));
Serial.print("Suhu : "); Serial.print(suhu); Serial.println(" C");
Serial.print("Kelembapan : "); Serial.print(hum); Serial.println(" %");
Serial.print("Status : "); Serial.println(status);
Serial.print("Buzzer : "); Serial.println(buzzerOn ? "OFF" : "ON");
Serial.println("================================");
}
/********** SETUP **********/
void setup() {
Serial.begin(115200);
jemuran.attach(SERVO_PIN);
dht.begin();
pinMode(BUZZER_PIN, OUTPUT); // LED sebagai buzzer
digitalWrite(BUZZER_PIN, LOW);
Serial.println("Sistem Jemuran Otomatis Siap");
Blynk.begin(auth, ssid, pass);
timer.setInterval(1000L, bacaSensorDanKirimBlynk); // tiap 1 detik
}
/********** LOOP **********/
void loop() {
Blynk.run();
timer.run();
}