/* CARA PENGUNAAN:
1. tombol START warna hijau (untuk menyalakan mesin cuci)
2. tombol STOP warna merah (untuk mematikan mesin cuci)
3. tombol MENU warna kuning ( untuk setting waktu cuci, delay forward, delay reverse, dan delay off)
4. tombol TAMBAH warna putih (untuk menambah delay time pada tiap parameter di dalam MENU)
5. tombol KURANG warna hitam (untuk mengurangi delay time pada tiap parameter di dalam MENU)
CARA SETTING WAKTU PADA MENU:
1. tekan tombol KUNING untuk masuk MENU.
2. pilih parameter waktu yang ingin diubah (ada 4 pilihan parameter
"WAKTU CUCI", "FORWARD DURATION", "REVERSE DURATION", dan "STOP DURATION")
3. gunakan tombol TAMBAH/KURANG untuk merubah delay time
4. tekan START untuk keluar dari MENU.
5. mesin cuci langsung MENYALA.
*/
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <TM1637Display.h>
// Adjust these pins to match your connections
const int CLK = 11;
const int DIO = 12;
// Definisi nilai heksadesimal untuk huruf S, T, dan O (sesuaikan dengan peta segmen)
const uint8_t SEG_IP[] = {0x6d ,0x78, 0x3f, 0x73,};
const uint8_t DONE[] = {0x5e, 0x3f, 0x54, 0x79};
const uint8_t A [] = {0x77, 0x40};
const uint8_t b [] = {0x7c, 0x40};
const uint8_t C [] = {0x39, 0x40};
const uint8_t d [] = {0x5E, 0x40};
const uint8_t F [] = {0x71, 0x40};
const uint8_t r [] = {0x31, 0x40};
int inputPin = 2; // Input pin with pull-up resistor
int m_forward = 5; // Relay 1 (forward) control pin
int m_reverse = 6; // Relay 2 (reverse) control pin
int tombolStop = 3; // Pin untuk tombol stop
int tombolMenu = 4; // Pin untuk tombol menu
const int buzzerPin = 7; // 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;
bool isSettingComplete = true; // Variabel baru untuk menandai selesai pengaturan
// 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)
// TM1637 display setup
TM1637Display display(CLK, DIO); // Adjust pins based on your wiring
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(tombolMenu, INPUT_PULLUP); // Atur pin tombol menu sebagai input
display.setBrightness(7); // Set brightness level
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 ((menuStatus < 1) &&(!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) {
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?");
display.setSegments(SEG_IP);
for (int i = 0; i < 8; i++) {
tone(buzzerPin, notes[i]); // Play the note
delay(durations[i]);
noTone(buzzerPin); // Stop the note
}
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));
display.showNumberDec(remainingTime % 60000 / 1000, true, 2, 2); // Display seconds
display.showNumberDecEx(remainingTime / 60000, 0b01000000, true, 2, 4); // Display minutes
//SAAT TOMBOL START DITEKAN, TIMER MULAI MENGHITUNG DAN MOTOR BERJALAN
if (currentTime - startTime >= menit*(value)) {
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
display.setSegments(SEG_IP);
// Timer ends
for (int i = 0; i < 8; i++) {
tone(buzzerPin, notes[i]); // Play the note
delay(durations[i]);
noTone(buzzerPin); // Stop the note
}
} 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);
}
}
}
//jika motor sudah running, tombol MENU tidak berfungsi.
keylock = (digitalRead(tombolMenu) == LOW);
// Cek tombol menu dan tambah secara bersamaan
if ((keylock) && (!timerActive) && digitalRead(tombolMenu) == LOW) {
menuStatus = (menuStatus + 1); // Toggle menu status
delay(300);
}
// Tampilkan menu jika menuStatus != 0
if (menuStatus != 0) {
showMenu();
}
}
void showMenu() {
//MENU TAMPILAN
lcd.setCursor(0, 0);
switch (menuStatus) {
case 1:
lcd.print("WAKTU NYUCI ");
lcd.setCursor(0, 1);
lcd.print("Aktual: " + String(value) + " Menit ");
display.setSegments(C, 2, 4);
display.showNumberDec(value, true, 2, 2);
break;
case 2:
lcd.print("FORWARD DURATION");
lcd.setCursor(0, 1);
lcd.print("Aktual: " + String(forwardDuration / 1000)+ " Detik ");
display.setSegments(F, 2, 4);
display.showNumberDec(forwardDuration / 1000, true, 2, 2);
break;
case 3:
lcd.print("REVERSE DURATION");
lcd.setCursor(0, 1);
lcd.print("Aktual: " + String(reverseDuration / 1000) + " Detik ");
display.showNumberDec(reverseDuration / 1000, true, 2, 2);
display.setSegments(r, 2, 4);
break;
case 4:
lcd.print("STOP DURATION ");
lcd.setCursor(0, 1);
lcd.print("Aktual: " + String(stopDuration / 1000) + " Detik ");
display.setSegments(d, 2, 4);
display.showNumberDec(stopDuration / 1000, true, 2, 2);
break;
default:
if (menuStatus >=4) {
menuStatus = 0; // Keluar dari menu
isSettingComplete = true; // Reset untuk pengaturan berikutnya
lcd.setCursor(1, 0);
lcd.clear();
lcd.print(" SETTINGAN");
lcd.setCursor(0, 1);
lcd.print(" SELESAI!");
display.setSegments(DONE);
}
break;
}
// Logika untuk mengubah nilai saat dalam menu (menggunakan tombol tambah dan kurang)
if (digitalRead(inputPin) == 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(100); // Delay untuk menghindari penambahan nilai berulang kali
}
if (digitalRead(tombolStop) == 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(100); // Delay untuk menghindari pengurangan nilai berulang kali
}
// Perbarui tampilan nilai aktual
}