MEMBUAT ALARM BANJIR IOT


A. ILUSTRASI PROGRAM 


B. BERIKUT VIDEO TUTORIAL:


C. ALAT DAN BAHAN

1. Esp 32 Dev Kit: 

https://s.shopee.co.id/7VES2T6xNd

2. Sensor Ultrasonik: 

https://s.shopee.co.id/20tVUPuj03

3. LCD I2C: 

https://s.shopee.co.id/1qa8bL8yZc

4. Buzzer: 

https://s.shopee.co.id/4fuJyarp28

5. Breadboard tipe 400: 

https://s.shopee.co.id/7prISLdLnx

6. Kabel Jumper Male-male: 

https://s.shopee.co.id/20tVVkNbsB

7. Kabel jumper Male- female: 

https://s.shopee.co.id/gO7uTIYe2

8. LED mini: 

https://s.shopee.co.id/AUs6vOXVuY

9. Resistor: 

https://s.shopee.co.id/4LHTa7tASg


D. DAFTAR PIN YANG DIGUNAKAN

berikut adalah daftar lengkap pemetaan pin (pinout) beserta fungsinya agar kamu tidak salah saat mencolokkan kabel jumper:

1. Komponen Utama (Sensor, LED, & Buzzer)

Nama KomponenPin pada KomponenDihubungkan ke Pin ESP32Keterangan
Sensor HC-SR04TRIGD12 (GPIO 12)Pin Pemicu sinyal ultrasonik
ECHOD14 (GPIO 14)Pin Penerima pantulan sinyal
LED HijauAnoda (+)D25 (GPIO 25)Indikator status AMAN
LED KuningAnoda (+)D33 (GPIO 33)Indikator status SIAGA / WASPADA
LED MerahAnoda (+)D32 (GPIO 32)Indikator status BAHAYA
Buzzer (Pasif)Positif (+)D26 (GPIO 26)Alarm suara (menggunakan fitur PWM)
⚠️ Catatan Penting LED: Gunakan resistor 220 Ω atau 330 Ω yang dipasang secara seri dengan LED untuk membatasi arus agar LED dan pin GPIO ESP32 tidak rusak. Resistor dapat dipasang pada kaki Anoda (kaki panjang) maupun kaki Katoda (kaki pendek). Hubungkan LED sesuai polaritas, yaitu Anoda (+) ke pin GPIO ESP32 (melalui resistor) dan Katoda (−) ke GND.

.

2. Komunikasi LCD I2C

Untuk LCD yang menggunakan modul I2C backpack, pin datanya wajib dipasang pada pin hardware I2C bawaan (default) ESP32 DevKit V1:

  • SDA --> Hubungkan ke pin D21 (GPIO 21)

  • SCL --> Hubungkan ke pin D22 (GPIO 22)

3. Jalur Daya (VCC & GND)

Semua komponen membutuhkan aliran listrik (daya) agar bisa menyala. Kamu bisa menggabungkannya di breadboard:

  • VCC / V+ / VIN (Sensor HC-SR04 & LCD I2C) --> Hubungkan ke pin VIN atau 5V pada ESP32 (agar mendapat pasokan daya optimal dari USB laptop).

  • GND / Minus (-) (Semua Sensor, LCD, LED, Buzzer) ---> Gabungkan semua menjadi satu jalur dan hubungkan ke pin GND pada ESP32.


4. Resitor pada pin echo

Sensor HC-SR04 bekerja dengan tegangan 5V, sehingga pin ECHO akan mengeluarkan sinyal digital sebesar 5V. Sementara itu, pin input pada ESP32 hanya aman menerima tegangan maksimal 3.3V. Jika kamu mencolokkan langsung pin ECHO (5V) ke ESP32 (3.3V) dalam jangka waktu lama, pin ESP32 kamu bisa terbakar atau rusak.

Kombinasi Resistor yang Digunakan:

Kamu membutuhkan dua buah resistor dengan nilai sebagai berikut:

  • Resistor R1 = 1 kΩ (1.000 Ω atau 1000 Ohm)
  • Resistor R2 = 2 kΩ (2.000 Ω atau 2000 Ohm)
Alternatif: Jika resistor 2 kΩ sulit ditemukan, kamu dapat menggunakan 2,2 kΩ (2200 Ohm) karena nilainya masih aman untuk menurunkan tegangan sinyal ECHO HC-SR04 ke level yang sesuai dengan ESP32.

Cara Merakitnya (Sirkuit Pembagi Tegangan):

  1. Hubungkan pin ECHO pada sensor HC-SR04 ke salah satu kaki Resistor R1 (1 kΩ).
  2. Hubungkan kaki Resistor R1 (1 kΩ) yang lainnya ke pin GPIO 14 (D14) ESP32.
  3. Pada titik yang sama (pertemuan antara Resistor R1 dan GPIO 14 ESP32), hubungkan salah satu kaki Resistor R2 (2 kΩ).
  4. Hubungkan kaki Resistor R2 (2 kΩ) yang lainnya ke GND (Ground).

Cara Kerja Rangkaian

Rangkaian pembagi tegangan (Voltage Divider) menggunakan Resistor R1 (1 kΩ) dan Resistor R2 (2 kΩ) untuk menurunkan tegangan sinyal ECHO dari 5 Volt menjadi sekitar 3,3 Volt. Dengan demikian, tegangan yang masuk ke GPIO 14 ESP32 berada pada batas aman sehingga tidak merusak mikrokontroler.

Catatan: Apabila Resistor 2 kΩ tidak tersedia, Resistor 2,2 kΩ dapat digunakan sebagai pengganti karena tetap menghasilkan tegangan keluaran yang aman untuk ESP32.


E. KODE PROGRAM

/*********************************************************

      FLOOD EARLY WARNING SYSTEM IoT - FIXED PRODUCTION

      ESP32 DevKit V1 + HC-SR04 + LCD + BLYNK

      by   Santri Fisika

**********************************************************/


/********************* BLYNK *****************************/

#define BLYNK_TEMPLATE_ID   "ISI_TEMPLATE_ID"

#define BLYNK_TEMPLATE_NAME "Flood Monitoring"

#define BLYNK_AUTH_TOKEN    "ISI_AUTH_TOKEN"


/********************* LIBRARY ***************************/

#include <WiFi.h>

#include <BlynkSimpleEsp32.h>

#include <Wire.h>

#include <LiquidCrystal_I2C.h>


/********************* WIFI ******************************/

char ssid[] = "NAME_WIFI";

char pass[] = "PASSWORD_WIFI";

/********************* LCD *******************************/

LiquidCrystal_I2C lcd(0x27, 16, 2);


/********************* PIN ESP32 DEVKIT V1 *******************************/

#define TRIG_PIN      12   // Hubungkan ke pin D12

#define ECHO_PIN      14   // Hubungkan ke pin D14


#define BUZZER_PIN    26   // Hubungkan ke pin D26


#define LED_HIJAU     25   // Hubungkan ke pin D25

#define LED_KUNING    33   // Hubungkan ke pin D33

#define LED_MERAH     32   // Hubungkan ke pin D32


/******************** TIMER ******************************/

BlynkTimer timer;


/******************** VARIABEL ***************************/

float jarak = 0;

float tinggiAir = 0;

float persen = 0;

String statusAir = "";

String statusLama = "";


/******************** KALIBRASI **************************/

const float tinggiBak = 40.0;   // Jarak maksimum saat kosong (cm)

const float batasPenuh = 10.0;  // Jarak terdekat saat air penuh (cm)


/******************** FILTER *****************************/

const byte jumlahSampling = 10;

float dataSensor[jumlahSampling];

byte indexData = 0;


/*********************************************************

          MEMBACA SENSOR HC-SR04 (VERSI SUKSES KAMU)

**********************************************************/

float bacaJarak()

{

  digitalWrite(TRIG_PIN, LOW);

  delayMicroseconds(2);


  digitalWrite(TRIG_PIN, HIGH);

  delayMicroseconds(10);

  digitalWrite(TRIG_PIN, LOW);


  // pulseIn dengan timeout 30ms (30000us) agar tidak mengunci saat tanpa objek

  long durasi = pulseIn(ECHO_PIN, HIGH, 30000);


  if (durasi == 0) 

  {

    return tinggiBak; // Jika di luar jangkauan/timeout, set ke jarak dasar bak

  }


  float cm = (float)durasi * 0.0343 / 2.0;

  return cm;

}


/*********************************************************

            FILTER MOVING AVERAGE

**********************************************************/

float filterSensor()

{

  dataSensor[indexData] = bacaJarak();

  indexData++;


  if (indexData >= jumlahSampling)

  {

    indexData = 0;

  }


  float total = 0;

  for (int i = 0; i < jumlahSampling; i++)

  {

    total += dataSensor[i];

  }


  return total / jumlahSampling;

}


/*********************************************************

          HITUNG TINGGI AIR DAN PERSENTASE

**********************************************************/

void hitungKetinggian()

{

  jarak = filterSensor();


  // Pembatasan logika matematika sirkuit

  if (jarak > tinggiBak) jarak = tinggiBak;

  if (jarak < batasPenuh) jarak = batasPenuh;


  // Tinggi Air = Jarak dasar dikurangi sisa jarak sensor

  tinggiAir = tinggiBak - jarak;


  // Kalkulasi Persentase

  float rentangUkur = tinggiBak - batasPenuh;

  if (rentangUkur > 0) {

    persen = (tinggiAir / rentangUkur) * 100.0;

  } else {

    persen = 0;

  }

  

  persen = constrain(persen, 0, 100);

}


/*********************************************************

              MENENTUKAN STATUS AIR

**********************************************************/

void cekStatus()

{

  if (persen <= 10)       statusAir = "AMAN";

  else if (persen < 50)  statusAir = "SIAGA";

  else if (persen < 70)  statusAir = "WASPADA";

  else                    statusAir = "BAHAYA";

}


/*********************************************************

          SERIAL MONITOR (RAPID OUTPUT PREVENTION)

**********************************************************/

void tampilSerial()

{

  Serial.println("================================");

  Serial.print("Jarak Sensor : "); Serial.print(jarak); Serial.println(" cm");

  Serial.print("Tinggi Air   : "); Serial.print(tinggiAir); Serial.println(" cm");

  Serial.print("Persentase   : "); Serial.print(persen); Serial.println(" %");

  Serial.print("Status       : "); Serial.println(statusAir);

}


/*********************************************************

                  LCD ANTI FLICKER

**********************************************************/

void tampilLCD()

{

  static int persenLama = -1;

  static String statusLamaLCD = "";


  if ((int)persen != persenLama || statusAir != statusLamaLCD)

  {

    persenLama = (int)persen;

    statusLamaLCD = statusAir;


    lcd.clear(); 

    lcd.setCursor(0, 0);

    lcd.print("TINGGI AIR:");

    lcd.print((int)persen);

    lcd.print("%");


    lcd.setCursor(0, 1);

    lcd.print("STATUS:");

    lcd.print(statusAir);

  }

}


/*********************************************************

                  LED INDIKATOR

**********************************************************/

void indikatorLED()

{

  static unsigned long lastBlink = 0;

  static bool ledState = false;


  if (statusAir == "AMAN")

  {

    digitalWrite(LED_HIJAU, HIGH);

    digitalWrite(LED_KUNING, LOW);

    digitalWrite(LED_MERAH, LOW);

  }

  else if (statusAir == "SIAGA")

  {

    digitalWrite(LED_HIJAU, LOW);

    digitalWrite(LED_KUNING, HIGH);

    digitalWrite(LED_MERAH, LOW);

  }

  else if (statusAir == "WASPADA")

  {

    digitalWrite(LED_HIJAU, LOW);

    digitalWrite(LED_MERAH, LOW);

    

    if (millis() - lastBlink >= 300)

    {

      lastBlink = millis();

      ledState = !ledState;

      digitalWrite(LED_KUNING, ledState);

    }

  }

  else // BAHAYA

  {

    digitalWrite(LED_HIJAU, LOW);

    digitalWrite(LED_KUNING, LOW);

    digitalWrite(LED_MERAH, HIGH);

  }

}


/*********************************************************

                      BUZZER

**********************************************************/

void alarmBuzzer()

{

  static unsigned long lastBuzzer = 0;

  static bool buzzerState = false;


  if (statusAir == "AMAN")

  {

    ledcWrite(BUZZER_PIN, 0);

    return;

  }


  if (statusAir == "SIAGA")

  {

    if (millis() - lastBuzzer >= 2000)

    {

      lastBuzzer = millis();

      buzzerState = !buzzerState;

      if (buzzerState) ledcWriteNote(BUZZER_PIN, NOTE_E, 6);

      else ledcWrite(BUZZER_PIN, 0);

    }

  }

  else if (statusAir == "WASPADA")

  {

    if (millis() - lastBuzzer >= 400)

    {

      lastBuzzer = millis();

      buzzerState = !buzzerState;

      if (buzzerState) ledcWriteNote(BUZZER_PIN, NOTE_G, 6);

      else ledcWrite(BUZZER_PIN, 0);

    }

  }

  else // BAHAYA

  {

    ledcWriteNote(BUZZER_PIN, NOTE_C, 7);

  }

}


/****************************************************

           CEK KONEKSI WIFI & BLYNK

****************************************************/

void cekKoneksi()

{

  if (WiFi.status() != WL_CONNECTED) {

    WiFi.begin(ssid, pass);

  }

  

  if (WiFi.status() == WL_CONNECTED && !Blynk.connected()) {

    Blynk.connect();

  }

}


/****************************************************

          KIRIM DATA KE BLYNK

****************************************************/

void kirimBlynk()

{

  if (Blynk.connected())

  {

    Blynk.virtualWrite(V1, jarak);      

    Blynk.virtualWrite(V2, tinggiAir);

    Blynk.virtualWrite(V3, persen);

    Blynk.virtualWrite(V4, statusAir);

  }

}


/****************************************************

          PUSH NOTIFICATION

****************************************************/

void notifikasiBanjir()

{

  if (statusAir == "BAHAYA" && statusLama != "BAHAYA")

  {

    Blynk.logEvent("banjir", "⚠️ PERINGATAN!\nStatus BAHAYA\nKetinggian Air = " + String((int)persen) + "%");

  }

  statusLama = statusAir;

}


/****************************************************

              UPDATE SISTEM UTAMA

****************************************************/

void updateSystem()

{

  hitungKetinggian();

  cekStatus();

  tampilLCD();

  tampilSerial();

  indikatorLED();

  alarmBuzzer();

  kirimBlynk();

  notifikasiBanjir();

}


/****************************************************

              SETUP (FUNGSI UTAMA)

****************************************************/

void setup()

{

  Serial.begin(115200);


  // Inisialisasi LCD

  lcd.begin();

  lcd.backlight();

  lcd.clear();

  lcd.setCursor(0, 0);

  lcd.print("Flood Warning");

  lcd.setCursor(0, 1);

  lcd.print("Initializing...");


  // Inisialisasi Pin Sensor HC-SR04

  pinMode(TRIG_PIN, OUTPUT);

  pinMode(ECHO_PIN, INPUT);


  // Inisialisasi Pin LED

  pinMode(LED_HIJAU, OUTPUT);

  pinMode(LED_KUNING, OUTPUT);

  pinMode(LED_MERAH, OUTPUT);


  // Inisialisasi Buzzer PWM

  ledcAttach(BUZZER_PIN, 2000, 8); 


  // PRA-INISISALISASI FILTER 

  float jarakAwal = bacaJarak();

  for (int i = 0; i < jumlahSampling; i++) {

    dataSensor[i] = jarakAwal;

  }


  // Koneksi Awal

  WiFi.begin(ssid, pass);

  Blynk.config(BLYNK_AUTH_TOKEN);


  delay(2000);

  lcd.clear();


  // Pengaturan Polling Timer Sehat (1 detik sekali)

  timer.setInterval(1000L, updateSystem); 

  timer.setInterval(15000L, cekKoneksi); // Memeriksa jaringan secara berkala tanpa menginterupsi loop

}


/****************************************************

              LOOP (FUNGSI UTAMA)

****************************************************/

void loop()

{

  if (WiFi.status() == WL_CONNECTED) {

    Blynk.run();

  }

  timer.run();

}


F. CARA MENGHUBUNGKAN KE BLYNK:

Langkah 1: Buat Datastream di Blynk Web Console

  1. Masuk ke akun Blynk kamu via browser di laptop (Blynk Console).
  2. Buka Developer Zone --> My Templates --> Pilih template "Flood Monitoring" (atau buat baru jika belum ada).
  3. Masuk ke tab Datastreams, klik New Datastream, dan pilih Virtual Pin.
  4. Buat 4 buah Datastream sesuai dengan variabel yang kita kirim di kode program:

Nama Datastream

PIN Virtual

Data Type

MIN

MAX

Jarak Sensor

V1

Double / Float

0

40

Tinggi Air

V2

Float

0

30

Persentase Air

V3

Integer / Int

0

100

Status Air

V4

String

-

-

  1. Klik Save di pojok kanan atas setelah keempat pin virtual dibuat.

Langkah 2: Desain Dashboard di Aplikasi HP (Blynk App)

  1. Buka aplikasi Blynk di Android atau iOS kamu.
  2. Pilih project Flood Monitoring.
  3. Masuk ke mode edit (Developer Mode dengan ikon kunci inggris/pengaturan).
  4. Tambahkan komponen (Widget) berikut ke layar HP kamu:
    • Gauge (V3): Untuk menampilkan Persentase Air (0-100%) dalam bentuk grafik lingkaran yang menarik.
    • Value Display (V2): Untuk menampilkan Tinggi Air dalam satuan cm.
    • Value Display (V4): Untuk menampilkan teks Status Air (AMAN, SIAGA, WASPADA, BAHAYA).
  5. Wajib: Di pengaturan tiap Widget tersebut, arahkan pilihan Data / Datastream ke nomor Pin Virtual yang sesuai (V1, V2, V3, atau V4).

Langkah 3: Mengaktifkan Notifikasi (Blynk Event)

Agar fitur Blynk.logEvent("banjir", ...) di kodemu bisa mengirimkan Push Notification ke HP saat air masuk status BAHAYA, kamu harus mendaftarkan nama Event-nya terlebih dahulu di website Blynk.

  1. Di Blynk Console Web, buka menu Events (di sebelah tab Datastream).
  2. Klik Add New Event.
  3. Isi nama Event Code dengan kata: banjir (harus huruf kecil semua, sama persis dengan yang ada di kode C++).
  4. Pada bagian Notification, aktifkan (Centang) pilihan Send notification to app.
  5. Klik Save di kanan atas.

Langkah 4: Nyalakan Hotspot / WiFi Rumah

Pastikan pada baris kode paling atas, kamu sudah mengganti:

  • NAMA_WIFI dengan SSID Hotspot HP atau Router rumahmu.
  • PASSWORD_WIFI dengan kata sandi WiFi tersebut.
  • ISI_AUTH_TOKEN dengan token dari Blynk Dashboard kamu.

💡 Penting: ESP32 hanya mendukung jaringan WiFi frekuensi 2.4 GHz. Jadi jika kamu menggunakan tethering dari HP, pastikan pengaturannya diset ke 2.4 GHz (bukan 5 GHz).

Setelah semuanya terkonfigurasi, nyalakan ESP32 menggunakan adaptor dinding. Saat air didekatkan ke sensor, indikator di aplikasi Blynk HP kamu akan langsung bergerak secara otomatis dan real-time!

 

Cara Mendapatkan Blynk Token

  1. Masuk ke Blynk Web Console:

Buka situs Blynk Console di browsermu dan masuk menggunakan akun yang sudah kamu buat.

  1. Buka Menu Search / Devices:

Di bilah menu paling kiri, klik ikon Search (ikon berbentuk kompas atau kaca pembesar) àlalu pilih menu Devices.

  1. Pilih Perangkat Kamu:

Klik pada nama perangkat yang sudah kamu hubungkan dengan template kemarin (misalnya bernama Flood Monitoring atau ESP32 Device).

  1. Buka Tab Device Info:

Di halaman perangkat tersebut, klik tab Device Info yang berada di bagian atas tengah.

  1. Salin Kode "Firmware Configuration":

Di sebelah kanan layar, kamu akan melihat kotak hitam bertuliskan Firmware Configuration. Di dalam kotak itu sudah terjajar rapi 3 baris kode seperti ini:

C++

#define BLYNK_TEMPLATE_ID   "TMPLxxxxxx"

#define BLYNK_TEMPLATE_NAME "Flood Monitoring"

#define BLYNK_AUTH_TOKEN    "xxxxxxxxxxxxxxxxxxxxxxxx"

Klik tombol Click to copy di pojok kanan atas kotak hitam tersebut.

Langkah Terakhir di Arduino IDE:

Setelah kamu klik copy, kembali ke aplikasi Arduino IDE tempat kodemu berada.

Blok atau hapus 3 baris kode lamamu yang di bagian atas:

C++

// Hapus ini:

#define BLYNK_TEMPLATE_ID   "ISI_TEMPLATE_ID"

#define BLYNK_TEMPLATE_NAME "Flood Monitoring"

#define BLYNK_AUTH_TOKEN    "ISI_AUTH_TOKEN"

Lalu Paste (Ctrl + V) kode yang baru saja kamu salin dari web Blynk tadi ke posisi tersebut.

Setelah diganti dengan token asli bawaan akunmu, lakukan Upload ulang ke ESP32. Begitu proses selesai, ESP32 akan langsung otomatis terhubung ke internet dan status perangkat di web Blynk akan berubah menjadi Online!

 

Tidak ada komentar:

Posting Komentar