Sistem Monitoring Ketinggian Air Berbasis IoT

Sistem ini memantau ketinggian air sungai/bendungan menggunakan sensor Ultrasonik dan mikrokontroler Wemos D1 Mini. Data dikirimkan ke aplikasi Blynk dan peringatan otomatis dikirimkan via WhatsApp.

โŒจ๏ธ Source Code C++ (Terbaru)

Kode ini telah disesuaikan dengan kredensial Blynk, Fonnte, dan logika notifikasi anti-spam (kirim WA 1 kali saat naik ke Bahaya, dan 1 kali saat turun ke Siaga). Silakan salin semua kode di bawah ini:

ketinggian_air.ino
#define BLYNK_TEMPLATE_ID "TMPL6len-jLFP"
#define BLYNK_TEMPLATE_NAME "Ketinggian Air"
#define BLYNK_AUTH_TOKEN "ar5AJo1dfJNqZCUksZV9uh5mSzUtewhq"

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <LiquidCrystal_I2C.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClientSecure.h>

// --- UBAH NAMA & PASSWORD WIFI ANDA DI SINI ---
char ssid[] = "NamaWiFiAnda";
char pass[] = "PasswordWiFiAnda";

LiquidCrystal_I2C lcd(0x27, 16, 2); 

#define TRIG D5
#define ECHO D6
#define BUZZER D3

long durasi;
int jarak;
String statusAir = "";
bool statusBahaya = false; // Flag untuk mencegah spam WA

String tokenFonnte = "nZt98yxmFpkutEQQWQT2"; 
String nomorTujuan = "085183218388"; 

unsigned long previousMillis = 0;
const long interval = 2000;

void kirimWA(String pesan) {
  WiFiClientSecure client;
  client.setInsecure();
  HTTPClient https;
  https.begin(client, "https://api.fonnte.com/send");
  https.addHeader("Content-Type", "application/x-www-form-urlencoded");
  https.addHeader("Authorization", tokenFonnte);
  String data = "target=" + nomorTujuan + "&message=" + pesan;
  https.POST(data);
  https.end();
}

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

  pinMode(TRIG, OUTPUT);
  pinMode(ECHO, INPUT);
  pinMode(BUZZER, OUTPUT);

  Wire.begin(D2, D1); 
  lcd.init();
  lcd.backlight();
  lcd.clear();

  lcd.setCursor(0,0);
  lcd.print("Menghubungkan...");
  Serial.println("Menghubungkan ke WiFi dan Blynk...");

  Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass);

  lcd.clear();
  lcd.print("Sistem Siap");
  Serial.println("Sistem Siap!");
  delay(2000); 
  lcd.clear();
}

void loop() {
  Blynk.run();

  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;

    // Trigger Sensor
    digitalWrite(TRIG, LOW);
    delayMicroseconds(2);
    digitalWrite(TRIG, HIGH);
    delayMicroseconds(10);
    digitalWrite(TRIG, LOW);

    durasi = pulseIn(ECHO, HIGH, 30000);
    jarak = durasi * 0.034 / 2;
    if (durasi == 0) { jarak = 999; }

    // Hitung Tinggi Air dari dasar (Asumsi sensor 100cm dari dasar)
    int tinggiAir = 100 - jarak;
    if (tinggiAir < 0) { tinggiAir = 0; }

    // LOGIKA STATUS & NOTIFIKASI
    if (tinggiAir >= 76) { 
      statusAir = "BAHAYA";
      digitalWrite(BUZZER, HIGH);
      
      // Kirim WA HANYA SEKALI saat baru masuk Bahaya
      if (!statusBahaya) {
        String pesan = "โš ๏ธ BAHAYA!\nAir sangat tinggi.\nTinggi Air: " + String(tinggiAir) + " cm";
        kirimWA(pesan);
        Blynk.logEvent("bahaya_air", "Air sangat tinggi!");
        statusBahaya = true; // Kunci agar tidak spam
      }
    }
    else if (tinggiAir >= 51) { 
      statusAir = "SIAGA";
      digitalWrite(BUZZER, LOW);

      // Kirim WA HANYA SEKALI saat air SURUT dari Bahaya ke Siaga
      if (statusBahaya) {
        String pesan = "๐Ÿ“‰ UPDATE: Air surut ke status SIAGA.\nTinggi Air: " + String(tinggiAir) + " cm";
        kirimWA(pesan);
        statusBahaya = false; // Buka kunci agar bisa ngirim Bahaya lagi
      }
    }
    else if (tinggiAir >= 26) {
      statusAir = "WASPADA";
      digitalWrite(BUZZER, LOW);
      statusBahaya = false; // Pastikan kunci terbuka
    }
    else { 
      statusAir = "NORMAL";
      digitalWrite(BUZZER, LOW);
      statusBahaya = false; // Pastikan kunci terbuka
    }

    // Update Layar LCD
    lcd.setCursor(0,0);
    lcd.print("Tinggi: "); lcd.print(tinggiAir); lcd.print(" cm   "); 
    lcd.setCursor(0,1);
    lcd.print("Status: "); lcd.print(statusAir); lcd.print("       "); 

    // Update Blynk
    Blynk.virtualWrite(V0, tinggiAir);
    Blynk.virtualWrite(V1, statusAir);
    
    // Tampil di Serial Monitor
    Serial.print("Tinggi Air: ");
    Serial.print(tinggiAir);
    Serial.print(" cm | Status: ");
    Serial.println(statusAir);
  }
}

๐Ÿ”Œ Skema Rangkaian Ulang (Review)

Ultrasonik (HC-SR04)

  • VCC โž” 5V
  • GND โž” G
  • TRIG โž” D5
  • ECHO โž” D6

LCD I2C 16x2

  • VCC โž” 5V
  • GND โž” G
  • SDA โž” D2
  • SCL โž” D1

Buzzer Aktif

  • Positif (+) โž” D3
  • Negatif (-) โž” G

๐Ÿงช Uji Coba Logika Notifikasi

Geser perlahan dari Normal โž” Bahaya, lalu turunkan ke Siaga untuk melihat simulasi WhatsApp!

0cm (Posisi Air) 100cm
Tinggi = 100 - Jarak
Tinggi Air:
0 cm
Tinggi: 0 cm
Status: NORMAL
Buzzer MATI
๐Ÿ’ฌ Notifikasi WA
Menunggu trigger...