#define BLYNK_TEMPLATE_ID "TMPL6KhuuUEcj"
#define BLYNK_TEMPLATE_NAME "Sistem Air"
#define BLYNK_PRINT Serial
#include <Arduino.h>
#include <WiFi.h>
#include <BlynkSimpleEsp32.h>
#include <NewPing.h>
#include <Preferences.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#define TRIGGER_PIN1 18
#define ECHO_PIN1 19
#define TRIGGER_PIN2 17
#define ECHO_PIN2 5
#define MAX_DISTANCE 200
#define RELAY_PIN 23
#define I2C_SDA 4
#define I2C_SCL 15
NewPing sonar1(TRIGGER_PIN1, ECHO_PIN1, MAX_DISTANCE);
NewPing sonar2(TRIGGER_PIN2, ECHO_PIN2, MAX_DISTANCE);
LiquidCrystal_I2C lcd(0x27, 16, 2); // Alamat I2C bisa berbeda, sesuaikan jika perlu
char auth[] = "-S6E4OgcW0Bv9IP70slIDevth7hKoLE6"; // Ganti dengan Auth Token dari Blynk
char ssid[] = "Wokwi-GUEST"; // Ganti dengan nama WiFi
char pass[] = ""; // Ganti dengan password WiFis
bool automaticMode = true;
bool relayState = false;
unsigned int lastDistance1 = 0;
unsigned int lastDistance2 = 0;
Preferences preferences;
BlynkTimer timer;
void checkWaterLevel();
void updateLCD();
void setup() {
Serial.begin(115200);
Blynk.begin(auth, ssid, pass);
pinMode(RELAY_PIN, OUTPUT);
preferences.begin("tankState", false);
automaticMode = preferences.getBool("autoMode", true);
relayState = preferences.getBool("relayState", false);
lastDistance1 = preferences.getUInt("lastDist1", 0);
lastDistance2 = preferences.getUInt("lastDist2", 0);
digitalWrite(RELAY_PIN, relayState ? HIGH : LOW); // Set relay state to last saved state
lcd.init();
lcd.backlight();
timer.setInterval(1000L, checkWaterLevel); // Check water level setiap detik
// Menampilkan posisi air terakhir di Blynk saat startup
Blynk.virtualWrite(V1, lastDistance1);
Blynk.virtualWrite(V2, lastDistance2);
updateLCD();
}
void loop() {
if (WiFi.status() == WL_CONNECTED) {
Blynk.run();
}
timer.run();
}
void checkWaterLevel() {
if (automaticMode) {
unsigned int distance1 = sonar1.ping_cm();
unsigned int distance2 = sonar2.ping_cm();
Serial.print("Tank 1 Distance: ");
Serial.print(distance1);
Serial.print(" cm, Tank 2 Distance: ");
Serial.print(distance2);
Serial.println(" cm");
if ((distance1 > 0 && distance1 < 10) || (distance2 > 0 && distance2 < 10)) { // Ubah nilai threshold sesuai kebutuhan
if (!relayState) {
digitalWrite(RELAY_PIN, HIGH); // Hidupkan relay
relayState = true;
preferences.putBool("relayState", true); // Simpan state relay
if (WiFi.status() == WL_CONNECTED) {
Blynk.logEvent("Water level is low in one of the tanks, motor turned on!"); // Kirim notifikasi ke Blynk
}
}
} else {
if (relayState) {
digitalWrite(RELAY_PIN, LOW); // Matikan relay
relayState = false;
preferences.putBool("relayState", false); // Simpan state relay
}
}
if (distance1 != lastDistance1) {
lastDistance1 = distance1;
preferences.putUInt("lastDist1", lastDistance1); // Simpan posisi air terakhir tangki 1
}
if (distance2 != lastDistance2) {
lastDistance2 = distance2;
preferences.putUInt("lastDist2", lastDistance2); // Simpan posisi air terakhir tangki 2
}
if (WiFi.status() == WL_CONNECTED) {
Blynk.virtualWrite(V1, distance1); // Kirim data jarak ke Virtual Pin V1 di Blynk
Blynk.virtualWrite(V2, distance2); // Kirim data jarak ke Virtual Pin V2 di Blynk
}
updateLCD();
}
}
void updateLCD() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(automaticMode ? "Mode: AUTO" : "Mode: MANUAL");
lcd.setCursor(0, 1);
lcd.print("T1:");
lcd.print(lastDistance1);
lcd.print("cm T2:");
lcd.print(lastDistance2);
lcd.print("cm");
}
BLYNK_WRITE(V3) {
int pinValue = param.asInt();
automaticMode = pinValue == 1;
preferences.putBool("autoMode", automaticMode); // Simpan state mode otomatis
updateLCD();
}
BLYNK_WRITE(V4) {
if (!automaticMode) {
int relayStateValue = param.asInt();
relayState = relayStateValue == 1;
digitalWrite(RELAY_PIN, relayState ? HIGH : LOW);
preferences.putBool("relayState", relayState); // Simpan state relay
}
}