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 Komponen | Pin pada Komponen | Dihubungkan ke Pin ESP32 | Keterangan |
| Sensor HC-SR04 | TRIG | D12 (GPIO 12) | Pin Pemicu sinyal ultrasonik |
| ECHO | D14 (GPIO 14) | Pin Penerima pantulan sinyal | |
| LED Hijau | Anoda (+) | D25 (GPIO 25) | Indikator status AMAN |
| LED Kuning | Anoda (+) | D33 (GPIO 33) | Indikator status SIAGA / WASPADA |
| LED Merah | Anoda (+) | D32 (GPIO 32) | Indikator status BAHAYA |
| Buzzer (Pasif) | Positif (+) | D26 (GPIO 26) | Alarm suara (menggunakan fitur PWM) |
.
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)
Cara Merakitnya (Sirkuit Pembagi Tegangan):
- Hubungkan pin ECHO pada sensor HC-SR04 ke salah satu kaki Resistor R1 (1 kΩ).
- Hubungkan kaki Resistor R1 (1 kΩ) yang lainnya ke pin GPIO 14 (D14) ESP32.
- Pada titik yang sama (pertemuan antara Resistor R1 dan GPIO 14 ESP32), hubungkan salah satu kaki Resistor R2 (2 kΩ).
- 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
- Masuk ke akun Blynk kamu via browser di laptop (Blynk
Console).
- Buka Developer Zone --> My Templates --> Pilih template "Flood Monitoring" (atau buat baru
jika belum ada).
- Masuk ke tab Datastreams, klik New Datastream, dan
pilih Virtual Pin.
- 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 |
- |
- |
- Klik Save di pojok kanan atas setelah keempat pin virtual
dibuat.
Langkah 2:
Desain Dashboard di Aplikasi HP (Blynk App)
- Buka aplikasi Blynk di Android atau iOS kamu.
- Pilih project Flood Monitoring.
- Masuk ke mode edit (Developer Mode dengan ikon kunci
inggris/pengaturan).
- 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).
- 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.
- Di Blynk Console Web, buka menu Events (di sebelah tab
Datastream).
- Klik Add New Event.
- Isi nama Event Code dengan kata: banjir (harus huruf kecil semua, sama persis
dengan yang ada di kode C++).
- Pada bagian Notification, aktifkan (Centang) pilihan Send
notification to app.
- 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
- Masuk ke Blynk Web Console:
Buka situs Blynk
Console di browsermu dan masuk menggunakan akun yang sudah kamu
buat.
- Buka Menu Search / Devices:
Di bilah menu paling kiri, klik
ikon Search (ikon
berbentuk kompas atau kaca pembesar) Ã lalu pilih menu Devices.
- Pilih Perangkat Kamu:
Klik pada nama perangkat yang
sudah kamu hubungkan dengan template kemarin (misalnya bernama Flood
Monitoring atau ESP32 Device).
- Buka Tab Device Info:
Di halaman perangkat tersebut,
klik tab Device Info yang berada
di bagian atas tengah.
- 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