//By Gabeng Crew Semeton Bali
//Tolak Gus Ir Sebagai Direktur
#include <Arduino.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Keypad.h>
#include <Ultrasonic.h>
#include <EEPROM.h>
#include <esp_task_wdt.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
byte rowPins[ROWS] = {5, 4, 3, 2};
byte colPins[COLS] = {9, 8, 7, 6};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
#define TRIGGER_PIN_A 10 // Pin trigger ultrasonik Wadah A
#define ECHO_PIN_A 11 // Pin echo ultrasonik Wadah A
#define TRIGGER_PIN_B 14 // Pin trigger ultrasonik Wadah B
#define ECHO_PIN_B 15 // Pin echo ultrasonik Wadah B
#define TRIGGER_PIN_C 16 // Pin trigger ultrasonik Wadah C
#define ECHO_PIN_C 17 // Pin echo ultrasonik Wadah C
#define PUMP_A_PIN 12 // Pin relay untuk pompa di Wadah A
#define PUMP_B_PIN 13 // Pin relay untuk pompa di Wadah B
#define EEPROM_ADDR_A 0 // Alamat penyimpanan EEPROM untuk target Wadah A
#define EEPROM_ADDR_B 2 // Alamat penyimpanan EEPROM untuk target Wadah B
Ultrasonic ultrasonicA(TRIGGER_PIN_A, ECHO_PIN_A);
Ultrasonic ultrasonicB(TRIGGER_PIN_B, ECHO_PIN_B);
Ultrasonic ultrasonicC(TRIGGER_PIN_C, ECHO_PIN_C);
int targetA; // Variabel untuk menyimpan nilai target Wadah A
int targetB; // Variabel untuk menyimpan nilai target Wadah B
// Tambahkan variabel status
enum Status {
MENU_SELECTION,
ENTERING_TARGET_A,
ENTERING_TARGET_B,
ENTERING_TARGET_C,
ENTERING_TARGET_D
};
Status status = MENU_SELECTION; // Inisialisasi status awal
unsigned long lastButtonPressTime = 0;
void setup() {
Serial.begin(9600);
pinMode(PUMP_A_PIN, OUTPUT);
pinMode(PUMP_B_PIN, OUTPUT);
esp_task_wdt_init(3, true);
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for (;;);
}
display.display();
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println("Inisialisasi...");
display.display();
delay(2000); // Beri waktu singkat untuk membaca pesan
display.clearDisplay();
// Baca tinggi air dari kedua wadah saat ESP32 dinyalakan
long tinggiAirA = ultrasonicA.read();
long tinggiAirB = ultrasonicB.read();
// Set target awal sesuai dengan pembacaan tinggi air
targetA = tinggiAirA;
targetB = tinggiAirB;
display.setCursor(0, 0);
display.println("Inisialisasi selesai");
display.display();
delay(1000); // Tunggu sebentar sebelum membersihkan layar
display.clearDisplay();
// Simpan nilai target awal ke EEPROM
EEPROM.begin(2); // Ukuran data target hanya 2 byte
EEPROM.write(EEPROM_ADDR_A, targetA);
EEPROM.write(EEPROM_ADDR_B, targetB);
EEPROM.commit();
EEPROM.end();
}
void loop(){
long tinggiAirA = ultrasonicA.read(); // Baca tinggi air Wadah A
long tinggiAirB = ultrasonicB.read(); // Baca tinggi air Wadah B
long tinggiAirC = ultrasonicC.read(); // Baca tinggi air Wadah C
char key = keypad.getKey(); // Baca tombol yang ditekan pada keypad
display.clearDisplay();
// Tambahkan kondisi untuk menampilkan menu pemilihan jika status = MENU_SELECTION
if (status == MENU_SELECTION) {
display.setCursor(0, 0);
display.setTextColor(WHITE);
display.println("MENU");
display.println("A : Campur A ke C");
display.println("B : Campur B ke C");
display.println("C : Info Level Air");
display.println("D : Isi Ulang A & B");
display.display();
}
// Tambahkan kondisi untuk memasukkan nilai target A jika status = ENTERING_TARGET_A
else if (status == ENTERING_TARGET_A) {
display.setCursor(0, 0);
display.setTextColor(WHITE);
display.println("Masukkan nilai A");
display.display();
int targetInputA = 0;
while (true) {
char digit = keypad.getKey();
if (digit >= '0' && digit <= '9') {
targetInputA = targetInputA * 10 + (digit - '0');
display.clearDisplay();
display.setCursor(0, 0);
display.print("input A : ");
display.print(targetInputA);
display.println(" cm? ");
display.setCursor(50, 55);
display.println("# : OK / Back");
display.display();
} else if (digit == '#') {
// Sesuaikan nilai target A dengan perbedaan yang dimasukkan
targetA -= targetInputA;
// Simpan nilai target A ke EEPROM
EEPROM.begin(2); // Ukuran data target hanya 2 byte
EEPROM.write(EEPROM_ADDR_A, targetA);
EEPROM.commit();
EEPROM.end();
status = MENU_SELECTION; // Kembali ke menu pemilihan
break;
}
delay(100);
}
}
// Tambahkan kondisi untuk memasukkan nilai target B jika status = ENTERING_TARGET_B
else if (status == ENTERING_TARGET_B) {
display.setCursor(0, 0);
display.setTextColor(WHITE);
display.println("Masukkan nilai B");
display.display();
int targetInputB = 0;
while (true) {
char digit = keypad.getKey();
if (digit >= '0' && digit <= '9') {
targetInputB = targetInputB * 10 + (digit - '0');
display.clearDisplay();
display.setCursor(0, 0);
display.print("input B : ");
display.print(targetInputB);
display.println(" cm? ");
display.setCursor(50, 55);
display.println("# : OK / Back");
display.display();
} else if (digit == '#') {
// Sesuaikan nilai target B dengan perbedaan yang dimasukkan
targetB -= targetInputB;
// Simpan nilai target B ke EEPROM
EEPROM.begin(2); // Ukuran data target hanya 2 byte
EEPROM.write(EEPROM_ADDR_B, targetB);
EEPROM.commit();
EEPROM.end();
status = MENU_SELECTION; // Kembali ke menu pemilihan
break;
}
delay(100);
}
}
else if (status == ENTERING_TARGET_C) {
display.setCursor(0, 0);
display.setTextColor(WHITE);
display.println("Water Level");
int mappedA = map(tinggiAirA, 0, 400, 100, 0);
int mappedB = map(tinggiAirB, 0, 400, 100, 0);
int mappedC = map(tinggiAirC, 0, 400, 100, 0);
drawPercentbar(20, 10, 100, 15, mappedA, "A");
drawPercentbar(20, 28, 100, 15, mappedB, "B");
drawPercentbar(20, 46, 100, 15, mappedC, "C");
display.display();
char nextKey = keypad.getKey();
if (nextKey == '#') {
status==MENU_SELECTION;
delay(200);
}
}
else if (status == ENTERING_TARGET_D) {
display.setCursor(0, 0);
display.setTextColor(WHITE);
display.println("Isi Ulang A,B");
display.setCursor(50, 55);
display.println("# : Selesai");
display.display();
while (true) {
char nextKey = keypad.getKey();
if (nextKey == '#') {
// Lakukan reset perangkat lunak (software reset)
esp_task_wdt_deinit(); // Matikan watchdog timer agar tidak menyebabkan reset
ESP.restart();
break;
}
}
}
if (status == ENTERING_TARGET_C) {
if (millis() - lastButtonPressTime > 200 && key == '#') {
status = MENU_SELECTION;
}
}
if (key != NO_KEY) {
lastButtonPressTime = millis(); // Catat waktu terakhir kali tombol ditekan
if (key == 'A') {
status = ENTERING_TARGET_A; // Ubah status menjadi ENTERING_TARGET_A
} else if (key == 'B') {
status = ENTERING_TARGET_B; // Ubah status menjadi ENTERING_TARGET_B
} else if (key == 'C') {
status = ENTERING_TARGET_C; // Ubah status menjadi ENTERING_TARGET_C
} else if (key == 'D') {
status = ENTERING_TARGET_D; // Ubah status menjadi ENTERING_TARGET_D
}
}
//Kontrol Pompa <=350 batas air jika air terlalu sedikit pompa berhenti
if (tinggiAirA<=350){
if (tinggiAirA >= targetA+1) {
digitalWrite(PUMP_A_PIN, HIGH); // Aktifkan pompa jika tinggi air <= target dan <= 400 cm
} else {
digitalWrite(PUMP_A_PIN, LOW); // Matikan pompa jika tinggi air > target atau > 400 cm
}
}
else digitalWrite(PUMP_A_PIN, LOW);
if (tinggiAirB<=350){
if (tinggiAirB >= targetB+1 ) {
digitalWrite(PUMP_B_PIN, HIGH); // Aktifkan pompa jika tinggi air <= target dan <= 400 cm
} else {
digitalWrite(PUMP_B_PIN, LOW); // Matikan pompa jika tinggi air > target atau > 400 cm
} }else digitalWrite(PUMP_B_PIN, LOW);
Serial.print("Target A : ");
Serial.println(targetA);
Serial.print("Target B : ");
Serial.println(targetB);
Serial.print("A : ");
Serial.println(tinggiAirA);
Serial.print("B : ");
Serial.println(tinggiAirB);
delay(500); // Delay untuk stabilitas pembacaan
}
void drawPercentbar(int x,int y, int width,int height, int progress,String teks)
{
progress = progress > 100 ? 100 : progress;
progress = progress < 0 ? 0 :progress;
float bar = ((float)(width-4) / 100) * progress;
display.drawRect(x, y, width, height, WHITE);
display.fillRect(x+2, y+2, bar , height-4, WHITE);
// Display progress text
if( height >= 15){
display.setCursor((width/2) -3, y+5 );
display.setTextSize(1);
display.setTextColor(WHITE);
if( progress >=50)
display.setTextColor(BLACK, WHITE); // 'inverted' text
display.print(teks);
display.print(" ");
display.print(progress);
display.print("%");
}
}