#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// Inisialisasi LCD dengan alamat I2C 0x27 (bisa berbeda tergantung modul)
LiquidCrystal_I2C lcd(0x27, 16, 2);
// Definisikan pin
const int modeButtonPin = 2;
const int upButtonPin = 3;
const int downButtonPin = 4;
const int relayCWPin = 8;
const int relayCCWPin = 9;
const int relayFillWaterPin = 10;
const int relaySpinnerPin = 11;
const int relayDrainPin = 12;
// Variabel status mesin cuci
enum Mode {CUCI, BILAS, SPIN};
Mode currentMode = CUCI;
bool isRunning = false;
bool isNormalMode = true; // Normal atau cepat
bool isFillingWater = false;
unsigned long startTime;
unsigned long washTime = 5000; // Waktu pencucian dalam ms (default 5 detik)
unsigned long rinseTime = 3000; // Waktu pembilasan dalam ms (default 3 detik)
unsigned long spinTime = 2000; // Waktu pengeringan dalam ms (default 2 detik)
unsigned long fillWaterTime = 60000; // Waktu pengisian air 5 liter dalam ms (default 1 menit)
unsigned long countdownTime;
unsigned long elapsedTime;
// Fungsi untuk menampilkan menu utama
void displayMenu() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Mode: ");
switch (currentMode) {
case CUCI:
lcd.print("Cuci ");
break;
case BILAS:
lcd.print("Bilas");
break;
case SPIN:
lcd.print("Spin ");
break;
}
lcd.setCursor(0, 1);
lcd.print("Normal: ");
lcd.print(isNormalMode ? "Ya" : "Tidak");
}
// Fungsi untuk mengubah mode pencucian
void changeMode() {
if (!isRunning) {
currentMode = (Mode)((currentMode + 1) % 3);
displayMenu();
}
}
// Fungsi untuk menaikkan waktu pencucian
void increaseTime() {
if (!isRunning) {
switch (currentMode) {
case CUCI:
washTime += 1000;
break;
case BILAS:
rinseTime += 1000;
break;
case SPIN:
spinTime += 1000;
break;
}
displayTime();
}
}
// Fungsi untuk menurunkan waktu pencucian
void decreaseTime() {
if (!isRunning) {
switch (currentMode) {
case CUCI:
if (washTime > 1000) washTime -= 1000;
break;
case BILAS:
if (rinseTime > 1000) rinseTime -= 1000;
break;
case SPIN:
if (spinTime > 1000) spinTime -= 1000;
break;
}
displayTime();
}
}
// Fungsi untuk menampilkan waktu pencucian
void displayTime() {
lcd.setCursor(0, 0);
lcd.print("Waktu ");
switch (currentMode) {
case CUCI:
lcd.print("Cuci : ");
lcd.print(washTime / 1000);
break;
case BILAS:
lcd.print("Bilas: ");
lcd.print(rinseTime / 1000);
break;
case SPIN:
lcd.print("Spin : ");
lcd.print(spinTime / 1000);
break;
}
lcd.print(" s");
}
// Fungsi untuk memulai proses pencucian
void startProcess() {
isRunning = true;
startTime = millis();
switch (currentMode) {
case CUCI:
countdownTime = isNormalMode ? washTime : washTime / 2;
break;
case BILAS:
countdownTime = isNormalMode ? rinseTime : rinseTime / 2;
break;
case SPIN:
countdownTime = isNormalMode ? spinTime : spinTime / 2;
break;
}
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Proses dimulai");
digitalWrite(relayCWPin, HIGH);
digitalWrite(relayFillWaterPin, HIGH);
isFillingWater = true;
}
// Fungsi untuk menjalankan proses pencucian
void runProcess() {
elapsedTime = millis() - startTime;
unsigned long remainingTime = countdownTime - elapsedTime;
if (isFillingWater) {
if (elapsedTime >= fillWaterTime) {
digitalWrite(relayFillWaterPin, LOW);
isFillingWater = false;
}
} else {
if (remainingTime > 0) {
lcd.setCursor(0, 1);
lcd.print("Sisa: ");
lcd.print(remainingTime / 1000);
lcd.print(" detik ");
} else {
isRunning = false;
digitalWrite(relayCWPin, LOW);
digitalWrite(relayCCWPin, LOW);
digitalWrite(relaySpinnerPin, LOW);
digitalWrite(relayDrainPin, HIGH); // Mulai drain air
delay(10000); // Drain selama 10 detik
digitalWrite(relayDrainPin, LOW);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Selesai");
lcd.setCursor(0, 1);
lcd.print("Ambil Cucian");
}
}
}
void setup() {
// Inisialisasi pin
pinMode(modeButtonPin, INPUT_PULLUP);
pinMode(upButtonPin, INPUT_PULLUP);
pinMode(downButtonPin, INPUT_PULLUP);
pinMode(relayCWPin, OUTPUT);
pinMode(relayCCWPin, OUTPUT);
pinMode(relayFillWaterPin, OUTPUT);
pinMode(relaySpinnerPin, OUTPUT);
pinMode(relayDrainPin, OUTPUT);
// Inisialisasi LCD
lcd.init();
lcd.backlight();
displayMenu();
}
void loop() {
// Baca status tombol
if (digitalRead(modeButtonPin) == LOW) {
delay(200); // Debounce delay
changeMode();
}
if (digitalRead(upButtonPin) == LOW) {
delay(200); // Debounce delay
increaseTime();
}
if (digitalRead(downButtonPin) == LOW) {
delay(200); // Debounce delay
decreaseTime();
}
if (digitalRead(modeButtonPin) == LOW && !isRunning) {
delay(200); // Debounce delay
startProcess();
}
if (isRunning) {
runProcess();
}
}