#include <Arduino.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <RTClib.h>
// Pin untuk sensor kelembaban tanah
const int moisturePin1 = 34; // Pin untuk sensor kelembaban tanah 1
const int moisturePin2 = 35; // Pin untuk sensor kelembaban tanah 2
const int moisturePin3 = 32; // Pin untuk sensor kelembaban tanah 3
const int moisturePin4 = 33; // Pin untuk sensor kelembaban tanah 4
// Pin untuk output (relay)
const int relayPin1 = 19; // Pin untuk mengontrol relay 1
const int relayPin2 = 18; // Pin untuk mengontrol relay 2
const int relayPin3 = 26; // Pin untuk mengontrol relay 3
// Ambang batas kelembapan tanah untuk menentukan kondisi
const int dryThreshold = 60; // Persentase kelembapan di bawah 60% menandakan tanah kering
// Durasi aktif relay setelah pemupukan dipicu (dalam milidetik)
const unsigned long relayActiveDuration = 60 ; // 5 menit
// Inisialisasi objek LCD I2C
LiquidCrystal_I2C lcd(0x27, 16, 2); // Alamat LCD I2C: 0x27, ukuran 16x2 karakter
// Inisialisasi objek RTC DS1307
RTC_DS1307 rtc;
// Struktur untuk menyimpan jadwal pemupukan
struct FertilizeSchedule {
uint8_t dayOfWeek; // Hari dalam seminggu (1 = Minggu, 2 = Senin, dst.)
uint8_t hour;
uint8_t minute;
};
// Array untuk menyimpan jadwal pemupukan
FertilizeSchedule schedules[] = {
{3, 23, 2}, // Pemupukan setiap hari Minggu pukul 10:00
{3, 23, 4}, // Pemupukan setiap hari Selasa pukul 15:30
// Tambahkan jadwal pemupukan lain di sini
};
// Jumlah jadwal pemupukan
const int numSchedules = sizeof(schedules) / sizeof(schedules[0]);
// Variabel untuk melacak status relay
bool isRelayActive = false;
unsigned long relayActivationTime = 0;
// Fungsi untuk mengaktifkan relay berdasarkan jadwal
void activateRelay(DateTime now) {
for (int i = 0; i < numSchedules; i++) {
FertilizeSchedule schedule = schedules[i];
if (now.dayOfTheWeek() == schedule.dayOfWeek &&
now.hour() == schedule.hour &&
now.minute() == schedule.minute) {
// Aktifkan relay sesuai dengan jadwal pemupukan yang cocok
//digitalWrite(relayPin1, HIGH);
digitalWrite(relayPin2, HIGH);
digitalWrite(relayPin3, HIGH);
isRelayActive = true;
relayActivationTime = millis(); // Catat waktu mulai aktif relay
//lcd.clear();
lcd.setCursor(5, 0);
lcd.print("PUPUK");
Serial.println("Relays activated for fertilization.");
break; // Keluar dari loop setelah jadwal ditemukan
}
}
}
void setup() {
// Inisialisasi LCD
lcd.init();
lcd.backlight(); // Hidupkan backlight LCD
// Atur pin relay sebagai output
pinMode(relayPin1, OUTPUT);
pinMode(relayPin2, OUTPUT);
pinMode(relayPin3, OUTPUT);
digitalWrite(relayPin1, LOW); // Pastikan relay mati secara awal
digitalWrite(relayPin2, LOW);
digitalWrite(relayPin3, LOW);
// Inisialisasi Serial Monitor
Serial.begin(9600);
Serial.println("Soil Moisture Sensor");
// Inisialisasi RTC
if (!rtc.begin()) {
Serial.println("Error: RTC tidak terdeteksi. Pastikan koneksi dan alamat RTC benar.");
while (1); // Berhenti jika RTC tidak terdeteksi
}
// Jika RTC tidak memiliki waktu, atur waktu default
if (!rtc.isrunning()) {
Serial.println("RTC tidak berjalan, atur waktu default.");
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
}
void loop() {
// Baca nilai kelembaban dari masing-masing sensor
int moistureValue1 = analogRead(moisturePin1);
int moistureValue2 = analogRead(moisturePin2);
int moistureValue3 = analogRead(moisturePin3);
int moistureValue4 = analogRead(moisturePin4);
// Hitung nilai rata-rata kelembapan dari keempat sensor
float averageMoisture = (moistureValue1 + moistureValue2 + moistureValue3 + moistureValue4) / 4.0;
float moisturePercentage = map(averageMoisture, 1000, 4095, 0, 100.0); // Konversi ke persentase
// Tampilkan nilai kelembapan pada LCD
lcd.setCursor(0, 0);
lcd.print((int)moisturePercentage);
lcd.print("%");
// Tampilkan nilai kelembapan pada Serial Monitor
Serial.print("Average Moisture: ");
Serial.print(moisturePercentage);
Serial.println("%");
// Periksa kondisi kelembapan dari nilai rata-rata sensor
if (moisturePercentage < dryThreshold) {
// Kelembapan di bawah ambang batas tanah kering
digitalWrite(relayPin1, HIGH); // Hidupkan relay
//digitalWrite(relayPin2, HIGH);
//digitalWrite(relayPin3, HIGH);
lcd.setCursor(4, 0);
//lcd.print("Tanah kering ");
Serial.println("Relay ON");
} else {
// Kelembapan mencukupi
digitalWrite(relayPin1, LOW); // Matikan relay
//digitalWrite(relayPin2, LOW);
//digitalWrite(relayPin3, LOW);
lcd.setCursor(4, 0);
//lcd.print("Tanah lembab ");
Serial.println("Relay OFF");
}
// Periksa apakah relay aktif dan durasi aktif sudah melewati batas
if (isRelayActive && (millis() - relayActivationTime >= relayActiveDuration)) {
// Matikan relay setelah durasi tertentu
//digitalWrite(relayPin1, LOW);
digitalWrite(relayPin2, LOW);
digitalWrite(relayPin3, LOW);
isRelayActive = false;
Serial.println("Relays deactivated after 1 minutes.");
//lcd.clear();
lcd.setCursor(5, 0);
lcd.print("selesai");
}
// Ambil waktu dari RTC
DateTime now = rtc.now();
// Tampilkan waktu dan tanggal pada LCD
lcd.setCursor(0, 1);
lcd.print(now.hour() < 10 ? "0" : ""); // Tambahkan angka 0 di depan jika jam < 10
lcd.print(now.hour());
lcd.print(":");
lcd.print(now.minute() < 10 ? "0" : ""); // Tambahkan angka 0 di depan jika menit < 10
lcd.print(now.minute());
lcd.setCursor(8, 1);
lcd.print(now.day());
lcd.print("/");
lcd.print(now.month());
lcd.print("/");
lcd.print(now.year()); // Hanya menampilkan dua digit terakhir tahun
// Tampilkan waktu pada Serial Monitor
Serial.print("Time: ");
Serial.print(now.hour());
Serial.print(":");
Serial.print(now.minute());
Serial.print(":");
Serial.println(now.second());
// Aktifkan relay berdasarkan jadwal
activateRelay(now);
// Tunggu sebentar sebelum membaca ulang sensor
delay(1000); // Delay satu detik (1000 milidetik)
}