#include <Arduino.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include <time.h>
// WiFi config
const char* ssid = "Wokwi-GUEST";
const char* password = "";
// LCD config
int lcdColumns = 20;
int lcdRows = 4;
int lcdAddr = 0x27;
LiquidCrystal_I2C lcd(lcdAddr, lcdColumns, lcdRows);
// Ultrasonic sensor pins
#define TRIG_PIN 5
#define ECHO_PIN 18
// LED untuk simulasi pompa
#define LED_PIN 2
// Fungsi mendapatkan nama hari
String getDayName(String dateStr) {
struct tm t = {};
sscanf(dateStr.c_str(), "%d-%d-%d", &t.tm_year, &t.tm_mon, &t.tm_mday);
t.tm_year -= 1900;
t.tm_mon -= 1;
mktime(&t);
const char* days[] = {"Minggu", "Senin", "Selasa", "Rabu", "Kamis", "Jumat", "Sabtu"};
return String(days[t.tm_wday]);
}
// HCSR04 baca jarak (dalam cm)
float readDistanceCM() {
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
long duration = pulseIn(ECHO_PIN, HIGH);
return duration * 0.034 / 2.0;
}
void setup() {
Serial.begin(115200);
lcd.init();
lcd.backlight();
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
pinMode(LED_PIN, OUTPUT);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
lcd.clear();
delay(1000);
Serial.println("Connecting to WiFi...");
lcd.print("Connecting to WiFi...");
}
lcd.clear();
Serial.println("Connected to WiFi");
}
void loop() {
String weatherData = getWeatherData();
String displayDate;
String rainRanges[5];
int rangeCount = 0;
float totalDebit = calculateRainInfo(weatherData, displayDate, rainRanges, rangeCount);
String hari = getDayName(displayDate);
// Baca elevasi air (dalam cm)
float distance = readDistanceCM();
float maxElev = 200.0;
float sisaElev = distance - maxElev;
float Elev = maxElev - sisaElev;
if (sisaElev < 0) sisaElev = 0; // overflow
float sisaElev_m = sisaElev / 100.0;
// Hitung sisa volume tampungan
float sisaVolume = sisaElev_m * 13.6 * 14.52; // m3
// Log tambahan
Serial.println("----- LOG MONITORING -----");
Serial.println("Tanggal : " + displayDate);
Serial.println("Hari : " + hari);
Serial.println("Elevasi muka air : " + String(Elev, 1) + " cm");
Serial.println("Volume hujan : " + String(totalDebit, 2) + " m3");
Serial.println("Sisa tampungan : " + String(sisaVolume, 2) + " m3");
// Tampilkan ke LCD
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(hari + " " + displayDate);
if (rangeCount > 0) {
lcd.setCursor(0, 1);
lcd.print(rainRanges[0]);
if (rangeCount > 1) {
lcd.setCursor(0, 2);
lcd.print(rainRanges[1]);
}
}
lcd.setCursor(0, 3);
lcd.print("Q: " + String(totalDebit, 1) + " m3");
delay(2000); // jeda tampilan
int delayAfterLoop = 0;
if (totalDebit > sisaVolume) {
float selisih = totalDebit - sisaVolume;
int ledTime = selisih * 100; // waktu nyala LED (ms)
delayAfterLoop = ledTime;
Serial.println("Status : Tampungan overflow!");
Serial.println("Selisih : " + String(selisih, 2) + " m3");
Serial.println("Pompa aktif : " + String(ledTime) + " ms");
digitalWrite(LED_PIN, HIGH);
delay(ledTime);
digitalWrite(LED_PIN, LOW);
} else {
Serial.println("Status : Tampungan mencukupi.");
Serial.println("Pompa aktif : 0 ms");
}
Serial.println("---------------------------\n");
delay(30000 + delayAfterLoop); // loop ulang setiap 30 detik + waktu LED
}
String getWeatherData() {
HTTPClient http;
String weatherData;
String url = "https://api.open-meteo.com/v1/forecast?latitude=-7.286917&longitude=112.76397&hourly=precipitation&timezone=auto";
http.begin(url);
int httpCode = http.GET();
if (httpCode > 0 && httpCode == HTTP_CODE_OK) {
weatherData = http.getString();
} else {
Serial.println("Error getting weather data");
}
http.end();
return weatherData;
}
float calculateRainInfo(String weatherData, String &displayDate, String rainRanges[], int &rangeCount) {
DynamicJsonDocument doc(16384);
DeserializationError error = deserializeJson(doc, weatherData);
if (error) return 0;
JsonArray times = doc["hourly"]["time"];
JsonArray rains = doc["hourly"]["precipitation"];
float totalQ = 0.0;
String currentDay = times[0].as<String>().substring(0, 10);
displayDate = currentDay;
bool inRange = false;
String rangeStart, rangeEnd;
for (int i = 0; i < times.size(); i++) {
String timeStr = times[i].as<String>();
if (!timeStr.startsWith(currentDay)) break;
float rain = rains[i].as<float>();
int hour = timeStr.substring(11, 13).toInt();
if (rain > 0.5) {
if (!inRange) {
rangeStart = (hour < 10 ? "0" : "") + String(hour) + ".00";
inRange = true;
}
float x = 0;
if (rain > 0.5 && rain <= 3.0) x = 0.15413;
else if (rain > 3.0 && rain <= 5.5) x = 0.18198;
else if (rain > 5.5 && rain <= 8.0) x = 0.19677;
else if (rain > 8.0 && rain <= 10.5) x = 0.21253;
else if (rain > 10.5) x = 0.22273;
float q = 0.278 * 1536 * 0.74 * (x / 24.0) * pow(24.0, 2.0 / 3.0);
totalQ += q;
rangeEnd = (hour < 10 ? "0" : "") + String(hour + 1) + ".00";
} else if (inRange) {
if (rangeCount < 5) {
rainRanges[rangeCount++] = rangeStart + "-" + rangeEnd;
}
inRange = false;
}
}
if (inRange && rangeCount < 5) {
rainRanges[rangeCount++] = rangeStart + "-" + rangeEnd;
}
return totalQ;
}
Sensor Ultrasonik HC-SR04
untuk mendeteksi
elevasi muka air
Nyala lampu
LED mewakili
nyala pompa