#include <Wire.h>
#include <LiquidCrystal_I2C.h>
int inputPin = 2; // Input pin with pull-up resistor
int m_forward = 3; // Relay 1 (forward) control pin
int m_reverse = 4; // Relay 2 (reverse) control pin
int tombolStop = 5; // Pin untuk tombol stop
int tombolTambah = 6; // Pin untuk tombol tambah
int tombolKurang = 7; // Pin untuk tombol kurang
int tombolMenu = 8; // Pin untuk tombol menu
const int buzzerPin = 9; // Pin connected
bool keylock =false;
long value = 10; // Nilai awal
long menit = 60000;
unsigned long startTime = 0;
bool timerActive = false;
unsigned long remainingTime = 0; // New variable for remaining time
LiquidCrystal_I2C lcd(0x27, 16, 2); // Initialize the LCD with its I2C address (0x27) and dimensions (16x2)
unsigned long startMillis; // Start time
unsigned long currentMillis; // Current time
int forwardDuration = 18000; // Forward duration (in milliseconds)
int reverseDuration = 18000; // Reverse duration (in milliseconds)
int stopDuration = 3000; // Stop duration (in milliseconds)
bool isForward = true; // Forward/reverse status
int menuStatus = 0; // 0: normal, 1: menu utama, 2: value, 3: forward, 4: reverse, 5: stop
int selectedOption = 1;
// Define the notes and their durations (adjust as needed)
int notes[] = {220, 246, 261,246, 261, 293, 370, 393}; // Contoh: G4, F4, G4, F4, G4, A4, B4, C5
// Durasi setiap nada (dalam milidetik)
int durations[] = {200, 200, 450, 200, 200, 450, 450, 1000}; // Durations (in milliseconds)
void setup() {
Serial.begin(9600);
pinMode(inputPin, INPUT_PULLUP);
pinMode(m_forward, OUTPUT);
pinMode(m_reverse, OUTPUT);
pinMode(tombolStop, INPUT_PULLUP); // Atur pin tombol sebagai input
pinMode(tombolTambah, INPUT_PULLUP); // Atur pin tombol tambah sebagai input
pinMode(tombolKurang, INPUT_PULLUP); // Atur pin tombol kurang sebagai input
pinMode(tombolMenu, INPUT_PULLUP); // Atur pin tombol menu sebagai input
lcd.init(); // Initialize the LCD
lcd.backlight(); // Turn on the
lcd.setCursor(0, 0); // Set the cursor to the first row
lcd.print("TIMER MESIN CUCI"); // Display initial message
lcd.setCursor(0, 1); // Set the cursor to the first row
lcd.print(" BY ANDRI"); // Display initial message
digitalWrite(m_forward, LOW);
digitalWrite(m_reverse, LOW);
startMillis = millis(); // Record start time
}
void loop() {
if ((!timerActive) && digitalRead(inputPin) == LOW) {
// Input pull-up active, start the timer
startTime = millis();
timerActive = true;
lcd.clear();
Serial.println("CUCI DIMULAI!");
lcd.setCursor(1, 0); // Set the cursor to the first row
lcd.print("CUCI DIMULAI!!"); // Display initial message
}
if (timerActive) {
// Cek status tombol stop
if (digitalRead(tombolStop) == LOW) {
for (int i = 0; i < 8; i++) {
tone(buzzerPin, notes[i]); // Play the note
delay(durations[i]);
noTone(buzzerPin); // Stop the note
}
timerActive = false;
digitalWrite(m_forward, LOW);
digitalWrite(m_reverse, LOW);
Serial.println("CUCIAN DI OFF!!");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("CUCIAN DI OFF!!");
lcd.setCursor(0, 1);
lcd.print(" ADA PERLU APA?");
return; // Keluar dari fungsi loop()
}
unsigned long currentTime = millis();
remainingTime = menit * value - (currentTime - startTime); // Calculate remaining time
lcd.setCursor(0, 1); // Set cursor to the second row
lcd.print("Waktu: " + String(remainingTime / 60000) + "Mnt " + String((remainingTime % 60000) / 1000)+ "dtk ");
Serial.print("Waktu: " + String(remainingTime / 60000) + ":" + String((remainingTime % 60000) / 1000));
if (currentTime - startTime >= menit*(value)) {
// Timer ends
timerActive = false;
digitalWrite(m_forward, LOW); // Turn off relay 1
digitalWrite(m_reverse, LOW); // Turn off relay 2
Serial.println("NYUCINYA UDAH SELESAI BANG!!");
lcd.clear();
lcd.setCursor(0, 0); // Set the cursor to the first row
lcd.print(" CUCI SELESAI!!"); // Display initial message
} else {
currentMillis = millis();
// Move forward for 5 seconds
if (isForward && currentMillis - startMillis < forwardDuration) {
digitalWrite(m_forward, HIGH);
digitalWrite(m_reverse, LOW);
}
// Reverse for 5 seconds after moving forward
else if (!isForward && currentMillis - startMillis < reverseDuration) {
digitalWrite(m_forward, LOW);
digitalWrite(m_reverse, HIGH);
}
// Stop for 1 second before changing direction
else if (currentMillis - startMillis < forwardDuration + stopDuration) {
digitalWrite(m_forward, LOW);
digitalWrite(m_reverse, LOW);
}
// Switch direction after completing the duration
else {
isForward = !isForward;
startMillis = currentMillis; // Reset start time
digitalWrite(m_forward, LOW);
digitalWrite(m_reverse, LOW);
}
}
}
//pengunci tombol
keylock = (digitalRead(tombolMenu) == LOW);
// Cek tombol menu dan tambah secara bersamaan
if ((keylock) && (!timerActive) && digitalRead(tombolMenu) == LOW) {
menuStatus = (menuStatus + 1) % 5; // Toggle menu status
delay(500);
}
// Tampilkan menu jika menuStatus != 0
if (menuStatus != 0) {
showMenu();
}
}
void showMenu() {
lcd.setCursor(0, 0);
switch (menuStatus) {
case 1:
lcd.print("WAKTU NYUCI ");
lcd.setCursor(0, 1);
lcd.print("Aktual: " + String(value) + " Menit");
break;
case 2:
lcd.print("FORWARD DURATION");
lcd.setCursor(0, 1);
lcd.print("Aktual: " + String(forwardDuration / 1000)+ " Detik");
break;
case 3:
lcd.print("REVERSE DURATION");
lcd.setCursor(0, 1);
lcd.print("Aktual: " + String(reverseDuration / 1000) + " Detik");
break;
case 4:
lcd.print("STOP DURATION ");
lcd.setCursor(0, 1);
lcd.print("Aktual: " + String(stopDuration / 1000) + " Detik ");
break;
default:
break;
}
// Logika untuk mengubah nilai saat dalam menu (menggunakan tombol tambah dan kurang)
if (digitalRead(tombolTambah) == LOW) {
switch (menuStatus) {
case 1:
value++;
break;
case 2:
forwardDuration += 1000; // Tambah 1 detik
break;
case 3:
reverseDuration += 1000; // Tambah 1 detik
break;
case 4:
stopDuration += 1000; // Tambah 1 detik
break;
}
delay(30); // Delay untuk menghindari penambahan nilai berulang kali
}
if (digitalRead(tombolKurang) == LOW) {
switch (menuStatus) {
case 1:
if (value > 0) {
value--;
}
break;
case 2:
if (forwardDuration > 0) {
forwardDuration -= 1000; // Kurangi 1 detik
}
break;
case 3:
if (reverseDuration > 0) {
reverseDuration -= 1000; // Kurangi 1 detik
}
break;
case 4:
if (stopDuration > 0) {
stopDuration -= 1000; // Kurangi 1 detik
}
break;
}
delay(30); // Delay untuk menghindari pengurangan nilai berulang kali
}
// Perbarui tampilan nilai aktual
lcd.setCursor(0, 1);
switch (menuStatus) {
case 4:
lcd.print("Aktual: " + String(stopDuration / 1000) + " Detik");
break;
}
}