#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
#include <RTClib.h>
RTC_DS1307 rtc;
LiquidCrystal_I2C lcd(0x27, 20, 4);
int tahun;
byte bulan, hari, jam, menit, detik;
bool settingTime = false;
bool settingDate = false;
String timeInput = "";
String dateInput = "";
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
byte rowPins[ROWS] = {13, 12, 14, 27};
byte colPins[COLS] = {26, 25, 33, 32};
Keypad I2_keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
// inisialisasi variabel menu
enum MenuState {
MAIN_MENU,
SUB_MENU_A,
SUB_MENU_B,
SUB_MENU_C,
SUB_MENU_D,
SUB_MENU_E,
SUB_MENU_F,
SUB_MENU_G,
SET_DATE,
SET_TIME
};
MenuState currentMenu = MAIN_MENU;
// inisialisasi pin I/O
const int trigPin = 4;
const int echoPin = 35;
// set parameter default sensor level air
float setPoint = 500; // default settingan awal
//inisialisasi variabel default
String input = "";
//inisisialisasi data tanaman
String tanam = "-";
String a1 = "Pakcoy", a2 = "Kangkung", a3 ="Bayam";
int tanam1 = 0;
// update jam
unsigned long lastUpdateMillis = 0; //
const unsigned long keypadScanInterval = 100; // Ubah interval pemindaian sesuai kebutuhan
void setup() {
//set awala pin I/O
pinMode(15, OUTPUT);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
lcd.init();
lcd.backlight();
//inisiasi keypad start
// I2_keypad.begin();
if (!rtc.begin()) {
Serial.println("Couldn't find RTC");
Serial.flush();
while (1) delay(10);
}
if (!rtc.isrunning()) {
Serial.println("RTC is NOT running, let's set the time!");
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
displayInitialInfo();
}
void loop() {
char key = I2_keypad.getKey();
static char lastKey = NO_KEY;
unsigned long currentMillis = millis();
static unsigned long lastKeyPressTime = 0;
static const unsigned long debounceDelay = 10; // waktu tunggu respon button
if (key != NO_KEY && key != lastKey) {
lastKey = key;
lastKeyPressTime = currentMillis;
handleKeypadInput(key); // Tanggapi hanya jika tombol belum ditekan dalam jangka waktu debounce
}
if (currentMillis - lastKeyPressTime >= debounceDelay) {
lastKey = NO_KEY; // Reset lastKey jika waktu debounce telah berlalu
}
//update tanggal dan jam
if (currentMillis - lastUpdateMillis >= 1000) {
updateDateTime();
lastUpdateMillis = currentMillis;
}
readDistance();
}
void handleKeypadInput(char key) {
switch (currentMenu) {
case MAIN_MENU:
menuMain(key);
break;
case SUB_MENU_A:
subsubmenuA(key);
break;
case SUB_MENU_B:
subsubmenuB(key);
break;
case SUB_MENU_C:
subsubmenuC(key);
break;
case SUB_MENU_D:
subsubmenuD(key);
break;
case SUB_MENU_F:
subsubmenuF(key);
break;
case SUB_MENU_G:
subsubmenuG(key);
break;
}
}
void displayInitialInfo() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("HidroPonik V1.2");
lcd.setCursor(0, 2);
lcd.print("Tanaman : "+tanam);
lcd.setCursor(0, 3);
lcd.print("Umur : "+ String(tanam1) +" Hari");
updateDateTime(); // Tampilkan tanggal dan jam di sini
currentMenu = MAIN_MENU;
}
void updateDateTime() {
DateTime now = rtc.now();
tahun = now.year();
bulan = now.month();
hari = now.day();
jam = now.hour();
menit = now.minute();
detik = now.second();
if (detik >= 60) {
detik = 0;
menit++;
if (menit >= 60) {
menit = 0;
jam++;
if (jam >= 24) {
jam = 00;
}
}
}
// Tampilkan tanggal dan jam hanya jika sedang berada di halaman utama
if (currentMenu == MAIN_MENU || currentMenu == SUB_MENU_G) {
lcd.setCursor(0, 1);
lcd.print(" ");
lcd.setCursor(0, 1);
lcd.print(hari);
lcd.print("/");
lcd.print(bulan);
lcd.print("/");
lcd.print(tahun);
lcd.print(" | ");
lcd.print(jam);
lcd.print(":");
if (menit < 10) {
lcd.print("0");
}
lcd.print(menit);
lcd.print(":");
if (detik < 10) {
lcd.print("0");
}
lcd.print(detik);
lcd.backlight();
}
}
void menuMain(char key) {
switch (key) {
case 'A':
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("1. Info Tanaman");
lcd.setCursor(0, 1);
lcd.print("2. Tanam Baru");
lcd.setCursor(0, 2);
lcd.print("3. Tanam Manual");
lcd.setCursor(0, 3);
lcd.print("Tkn B u/ menu lain");
currentMenu = SUB_MENU_A;
break;
}
}
void subsubmenuA(char key) {
switch (key) {
case 'B':
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("4. Ubah Jam & Tgl");
lcd.setCursor(0, 1);
lcd.print("5. Info Parameter");
lcd.setCursor(0, 3);
lcd.print("Tkn C u/ ke menu");
currentMenu = SUB_MENU_B;
break;
case '1':
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Nama : Pakcoy");
lcd.setCursor(0, 1);
lcd.print("Umur : "+ String(tanam1) +" hari");
lcd.setCursor(0, 2);
lcd.print("Panen : 240 Hari");
lcd.setCursor(0, 3);
lcd.print("Tkn A u/ info lain");
currentMenu = SUB_MENU_C;
break;
case '2':
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Pilih tanaman :");
lcd.setCursor(0, 1);
lcd.print("1. Pakcoy");
lcd.setCursor(0, 2);
lcd.print("2. Kangkung");
lcd.setCursor(0, 3);
lcd.print("3. Bayam");
currentMenu = SUB_MENU_D;
break;
case '3':
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Input Data Tanaman");
currentMenu = SUB_MENU_E;
break;
case '#':
displayInitialInfo();
break;
case 'C':
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("1. Info Tanaman");
lcd.setCursor(0, 1);
lcd.print("2. Tanam Baru");
lcd.setCursor(0, 2);
lcd.print("3. Tanam Manual");
lcd.setCursor(0, 3);
lcd.print("Tkn B u/ menu lain");
currentMenu = SUB_MENU_A;
break;
}
}
void subsubmenuB(char key) {
switch (key) {
case '4':
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Tgl | Jam :");
lcd.setCursor(0, 1);
updateDateTime(); // Tampilkan tanggal dan jam di sini
lcd.setCursor(0, 3);
lcd.print("Tkn * u/ Setting");
currentMenu = SUB_MENU_G;
break;
case '5':
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Parameter Sekarang");
lcd.setCursor(0, 1);
lcd.print("1. PH : 7 - 10");
lcd.setCursor(0, 2);
lcd.print("2. TDS : 1230 - 1500");
lcd.setCursor(0, 3);
lcd.print("3. Suhu : 28 - 20 C");
delay(3000);
displayInitialInfo();
currentMenu = MAIN_MENU;
break;
case 'C':
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("1. Info Tanaman");
lcd.setCursor(0, 1);
lcd.print("2. Tanam Baru");
lcd.setCursor(0, 2);
lcd.print("3. Tanam Manual");
lcd.setCursor(0, 3);
lcd.print("Tkn B u/ menu lain");
currentMenu = SUB_MENU_A;
break;
case '#':
displayInitialInfo();
break;
}
}
void subsubmenuC(char key) {
float distance = 0;
switch (key) {
case 'A':
distance = readDistance();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("PH : 5 ");
lcd.setCursor(0, 1);
lcd.print("TDS : 1200 PPM");
lcd.setCursor(0, 2);
lcd.print("Suhu : 22 C");
lcd.setCursor(0, 3);
lcd.print("Air : " + String(distance) + " cm ");
delay(3000);
displayInitialInfo();
currentMenu = MAIN_MENU;
break;
case 'C':
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("1. Info Tanaman");
lcd.setCursor(0, 1);
lcd.print("2. Tanam Baru");
lcd.setCursor(0, 2);
lcd.print("3. Tanam Manual");
lcd.setCursor(0, 3);
lcd.print("Tkn B u/ menu lain");
currentMenu = SUB_MENU_A;
break;
case '#':
displayInitialInfo();
break;
}
}
void subsubmenuD(char key) {
switch (key) {
case '1':
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Tanam Pakcoy ?");
lcd.setCursor(0, 1);
lcd.print("Masa Panen 240 Hari");
lcd.setCursor(0, 3);
lcd.print("A. Ya | B. Batal");
currentMenu = SUB_MENU_F;
break;
case 'C':
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("1. Info Tanaman");
lcd.setCursor(0, 1);
lcd.print("2. Tanam Baru");
lcd.setCursor(0, 2);
lcd.print("3. Tanam Manual");
lcd.setCursor(0, 3);
lcd.print("Tkn B u/ menu lain");
currentMenu = SUB_MENU_A;
break;
}
}
float readDistance() {
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
long duration = pulseIn(echoPin, HIGH);
float distance = duration * 0.034 / 2;
return distance;
}
void subsubmenuF(char key) {
float distance = 0;
long selisihDetik = 0;
int selisihHari = 0;
int selisihJam = 0;
int selisihMenit = 0;
int selisihDetikSisa = 0;
DateTime now;
DateTime waktuAwal;
switch (key) {
case 'A':
now = rtc.now();
waktuAwal = DateTime(2023, 9, 24, 12, 0, 0); // Gantilah dengan waktu awal yang Anda inginkan
selisihDetik = (now - waktuAwal).totalseconds();
selisihHari = selisihDetik / 86400; // 86400 detik dalam sehari
selisihDetik = selisihDetik % 86400; // Sisa detik setelah menghitung hari
selisihJam = selisihDetik / 3600; // 3600 detik dalam sejam
selisihDetik = selisihDetik % 3600; // Sisa detik setelah menghitung jam
selisihMenit = selisihDetik / 60; // 60 detik dalam satu menit
selisihDetikSisa = selisihDetik % 60; // Sisa detik
tanam1 = selisihMenit;
distance = readDistance();
if (distance < setPoint) {
digitalWrite(15, HIGH);
} else {
digitalWrite(15, LOW);
}
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Tanaman Pakcoy");
lcd.setCursor(0, 1);
lcd.print("Berhasil Di Tanam");
delay(3000);
displayInitialInfo();
currentMenu = MAIN_MENU;
break;
case 'B':
digitalWrite(15, LOW);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Tanaman Pakcoy");
lcd.setCursor(0, 1);
lcd.print("Berhasil Di Batalkan");
delay(3000);
displayInitialInfo();
currentMenu = MAIN_MENU;
break;
case 'C':
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("1. Info Tanaman");
lcd.setCursor(0, 1);
lcd.print("2. Tanam Baru");
lcd.setCursor(0, 2);
lcd.print("3. Tanam Manual");
lcd.setCursor(0, 3);
lcd.print("Tkn B u/ menu lain");
currentMenu = SUB_MENU_A;
break;
}
}
void subsubmenuG(char key) {
int year, month, day, hour, minute, second;
DateTime newTime;
switch (key) {
case '*':
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Masukan Tahun : ");
lcd.setCursor(0, 3);
lcd.print("Tkn # u/ Oke");
year = getData();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Masukan Bulan : ");
lcd.setCursor(0, 3);
lcd.print("Tkn # u/ Oke");
month = getData();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Masukan Tgl : ");
lcd.setCursor(0, 3);
lcd.print("Tkn # u/ Oke");
day = getData();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Masukan Jam : ");
lcd.setCursor(0, 3);
lcd.print("Tkn # u/ Oke");
hour = getData();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Masukan Menit : ");
lcd.setCursor(0, 3);
lcd.print("Tkn # u/ Oke");
minute = getData();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Masukan Detik : ");
lcd.setCursor(0, 3);
lcd.print("Tkn # u/ Oke");
second = getData();
newTime = DateTime(year, month, day, hour, minute, second);
rtc.adjust(newTime);
displayInitialInfo();
break;
case 'C':
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("1. Info Tanaman");
lcd.setCursor(0, 1);
lcd.print("2. Tanam Baru");
lcd.setCursor(0, 2);
lcd.print("3. Tanam Manual");
lcd.setCursor(0, 3);
lcd.print("Tkn B u/ menu lain");
currentMenu = SUB_MENU_A;
break;
}
}
int getData() {
String inputBuffer = "";
lcd.setCursor(0, 1);
while (true) {
char c = I2_keypad.getKey();
if (c == '#') {
break;
} else if (isDigit(c)) {
inputBuffer += c;
lcd.print(c);
}
}
return inputBuffer.toInt();
}