#include <Wire.h>
#include <LiquidCrystal_I2C.h>

// Inisialisasi objek LCD
LiquidCrystal_I2C lcd(0x27, 20, 4);

// Pin definisi untuk sensor ultrasonik
const int trigPin = 5;
const int echoPin = 18;

// Rentang tinggi pakan
const int minTinggi = 10;
const int maxTinggi = 2;

//indikator
int indikator = 17;

//Buzzer
const int buzzer = 23;

//limit
int travel_Home = 33;
int travel_Max = 32;
int upper = 35;
int lower = 34;

//Switch Auto/Man
int mode = 12;

//tombol manual
int cw = 13;
int ccw = 15;
int up = 4;
int down = 16;

//nema
int dir_RL = 25;
int dir_UD = 27;
int pul_RL = 26;
int pul_UD = 14;

// Waktu terakhir Motor aktif
unsigned long lastActivationTime = 0;

// Waktu tunggu antara aktivasi motor (dalam milidetik) - 12 jam (dalam milidetik)
const unsigned long activationInterval = 15000; //12 * 60 * 60 * 1000;

void setup() 
{
  // Inisialisasi LCD
  lcd.init();
  lcd.backlight();

  // Inisialisasi pin untuk sensor ultrasonik
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);

  // Indikator Pin Relay
  pinMode(indikator, OUTPUT);

  //Buzzer
  pinMode(buzzer, OUTPUT);

  //limit
  pinMode(travel_Home, INPUT_PULLUP);
  pinMode(travel_Max, INPUT_PULLUP);
  pinMode(upper, INPUT_PULLUP);
  pinMode(lower, INPUT_PULLUP);

  //switch auto/man
  pinMode(mode, INPUT_PULLUP);

  //tombol manual
  pinMode(cw, INPUT_PULLUP);
  pinMode(ccw, INPUT_PULLUP);
  pinMode(up, INPUT_PULLUP);
  pinMode(down, INPUT_PULLUP);

  //nema
  pinMode(dir_RL, OUTPUT);
  pinMode(dir_UD, OUTPUT);
  pinMode(pul_RL, OUTPUT);
  pinMode(pul_UD, OUTPUT);

  // Mengaktifkan Serial Monitor untuk debug
  Serial.begin(9600);
}

void loop() 
{
  // Variabel untuk menyimpan waktu pantulan gelombang ultrasonik
  long duration, cm;
  
  // Mengirimkan sinyal ultrasonik
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  // Menerima waktu pantulan gelombang ultrasonik
  duration = pulseIn(echoPin, HIGH);

  // Menghitung ketinggian pakan dalam cm
  cm = duration * 0.034 / 2;

  // Menampilkan ketinggian pakan di Serial Monitor
  Serial.print("Ketersediaan Pakan: ");
  Serial.print(cm);
  Serial.println(" cm");
  delay(1000);

  // Menghitung persentase ketinggian pakan dalam tangki
  int persentase = map(cm, minTinggi, maxTinggi, 0, 100);

  // Menampilkan hasil di LCD
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Stock Pakan:");
  lcd.print(persentase);
  lcd.print("%");
  lcd.setCursor(0, 1);
  lcd.print("Feeding :");
  if (digitalRead(indikator) == HIGH)
    {
      lcd.print("ON");
    }
  else 
    {
      lcd.print("OFF");
    }

  //kontrol manual feeding
  bailout:
  if(digitalRead(mode) == LOW)
    {
      if(digitalRead(cw) == LOW && digitalRead(travel_Max) == LOW)
        {
          digitalWrite(dir_RL, HIGH);
          digitalWrite(pul_RL, HIGH); 
          delayMicroseconds(20); 
          digitalWrite(pul_RL, LOW); 
          delayMicroseconds(20);
          goto bailout; 
        }
      else if(digitalRead(ccw) == LOW && digitalRead(travel_Home) == LOW)
        {
          digitalWrite(dir_RL, LOW);
          digitalWrite(pul_RL, HIGH); 
          delayMicroseconds(20); 
          digitalWrite(pul_RL, LOW); 
          delayMicroseconds(20);
          goto bailout; 
        }
      else if(digitalRead(up) == LOW && digitalRead(upper) == LOW)
        {
          digitalWrite(dir_UD, HIGH);
          digitalWrite(pul_UD, HIGH);
          delayMicroseconds(20); 
          digitalWrite(pul_UD, LOW); 
          delayMicroseconds(20);
          goto bailout; 
        }
       else if(digitalRead(down) == LOW && digitalRead(lower) == LOW) 
        {
          digitalWrite(dir_UD, LOW);
          digitalWrite(pul_UD, HIGH);
          delayMicroseconds(20);
          digitalWrite(pul_UD, LOW);
          delayMicroseconds(20);
          goto bailout;
        }
    }

  // Kontrol feeding berdasarkan jadwal waktu
  unsigned long currentTime = millis();
  if (currentTime - lastActivationTime >= activationInterval) 
    {
      if(digitalRead(mode) == HIGH)
        {
          out:
          //aktif feeding
          digitalWrite(indikator, HIGH);
          if(digitalRead(travel_Home) == HIGH)
            {
              lastActivationTime = currentTime;  // Perbarui waktu terakhir solenoid valve aktif
              home:
              digitalWrite(dir_RL,LOW); 
              for(int x = 0; x < 32000; x++) 
                {
                  digitalWrite(pul_RL,HIGH);
                  delayMicroseconds(20);
                  digitalWrite(pul_RL,LOW);
                  delayMicroseconds(20);
                  if(digitalRead(travel_Home) == LOW)
                    {
                      goto out;
                    }
                  else
                    {
                      goto home;
                    }  
                }  
            } 
          else if(digitalRead(upper) == HIGH)
            {
              lastActivationTime = currentTime;  // Perbarui waktu terakhir solenoid valve aktif
              digitalWrite(dir_UD, LOW);
              for(int y = 0; y < 32000; y++)
                {
                  down:
                  digitalWrite(pul_UD, HIGH);
                  delayMicroseconds(20);
                  digitalWrite(pul_UD, LOW);
                  delayMicroseconds(20);
                  if(digitalRead(lower) == HIGH)
                    {
                      goto out;
                    }
                  else
                    {
                      goto down;
                    }  
                }
            }  
          else if(digitalRead(travel_Home) == LOW && digitalRead(lower) == HIGH)
            {
              lastActivationTime = currentTime;  // Perbarui waktu terakhir solenoid valve aktif
              outpro1:      
              delay(2000);
              digitalWrite(dir_RL,HIGH); 
              for(int x = 0; x < 32000; x++) 
                {
                  digitalWrite(pul_RL,HIGH);
                  delayMicroseconds(20);
                  digitalWrite(pul_RL,LOW);
                  delayMicroseconds(20);
                  if (digitalRead(travel_Max) == HIGH)
                    {
                       goto outproses2;
                    }
                }
              delay(2000);
              digitalWrite(dir_UD, LOW);
              for(int y = 0; y < 32000; y++)
                {
                  digitalWrite(pul_UD,HIGH);
                  delayMicroseconds(20);
                  digitalWrite(pul_UD,LOW);
                  delayMicroseconds(20);
                }              
              delay(2000);
              proses1:
              digitalWrite(dir_UD, HIGH);
              for(int y = 0; y < 32000; y++)
                {
                  digitalWrite(pul_UD,HIGH);
                  delayMicroseconds(20);
                  digitalWrite(pul_UD,LOW);
                  delayMicroseconds(20);
                  if(digitalRead(lower) == HIGH)
                    {
                      goto outpro1;
                    }
                  else
                    {
                      goto proses1;
                    }   
                }
              lastActivationTime = currentTime;  // Perbarui waktu terakhir solenoid valve aktif
            }
      else 
        {
          outproses2:
          digitalWrite(indikator, LOW);
        }
      }
    }
  delay(1000); // Delay untuk mengurangi frekuensi pembacaan

  //Buzzer indikator level vitamin & pestisida
  if(persentase <= 25 ) 
    {
      tone(buzzer, 1000);
    }
  else if(persentase >= 50)
    {
      noTone(buzzer);
    }
}
NOCOMNCVCCGNDINLED1PWRRelay Module
A4988
A4988