#define BLYNK_TEMPLATE_ID "TMPL6y8bkhniY"
#define BLYNK_TEMPLATE_NAME "ULTRASONIK DAN DHT ALDY"
#define BLYNK_AUTH_TOKEN "r_i3dsSMXPHdPIHw3GlmxXhouWWcb4Ys"

#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>
#include <DHT.h>

// WiFi
char ssid[] = "Wokwi-GUEST";
char pass[] = "";

// Pin sensor
#define TRIG_PIN 5
#define ECHO_PIN 18

#define DHTPIN 13
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);

// Virtual pin untuk Blynk
#define VIRTUAL_PIN_DISTANCE V0
#define VIRTUAL_TEMP V1
#define VIRTUAL_HUM V2

BlynkTimer timer;

// === Fungsi Kirim Data Ultrasonik ===
void sendDistance() {
  // Trigger sensor
  digitalWrite(TRIG_PIN, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIG_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG_PIN, LOW);

  // Baca waktu echo (timeout 30ms = 5 meter)
  long duration = pulseIn(ECHO_PIN, HIGH, 30000);
  float distance = duration * 0.0343 / 2;

  // ====== KALIBRASI MANUAL DI SINI ======
  // Misal sensor terbaca 374 cm, tapi penggaris/meteran bilang 371 cm → selisih 3 cm
  distance = distance - 3.0;

  // Validasi hasil
  if (distance <= 0 || distance > 450) {
    distance = -1;
  }

  // Tampilkan di Serial
  Serial.print("Distance: ");
  if (distance == -1) {
    Serial.println("Out of range");
  } else {
    Serial.print(distance);
    Serial.println(" cm");
  }

  // Kirim ke Blynk
  Blynk.virtualWrite(VIRTUAL_PIN_DISTANCE, distance);
}

// === Fungsi Kirim Data Suhu dan Kelembaban ===
void sendDHTReadings() {
  float suhu = dht.readTemperature();
  float kelembaban = dht.readHumidity();

  if (isnan(suhu) || isnan(kelembaban)) {
    Serial.println("Gagal membaca dari sensor DHT22!");
    return;
  }

  Serial.print("Temperature: ");
  Serial.print(suhu);
  Serial.println(" °C");

  Serial.print("Humidity: ");
  Serial.print(kelembaban);
  Serial.println(" %");

  // Kirim ke Blynk
  Blynk.virtualWrite(VIRTUAL_TEMP, suhu);
  Blynk.virtualWrite(VIRTUAL_HUM, kelembaban);
}

void setup() {
  Serial.begin(115200);

  pinMode(TRIG_PIN, OUTPUT);
  pinMode(ECHO_PIN, INPUT);

  dht.begin();

  Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass);

  // Set interval pengiriman data
  timer.setInterval(1000L, sendDistance);       // setiap 1 detik
  timer.setInterval(2000L, sendDHTReadings);    // setiap 2 detik
}

void loop() {
  Blynk.run();
  timer.run();
}