#include <Wire.h>
#include <I2C_RTC.h>
#include <LiquidCrystal_I2C.h>
#include <EEPROM.h>
static DS3231 RTC;
LiquidCrystal_I2C lcd(0x27, 16, 02);
#define rain_sense A0
#define set_hr_up 2
#define set_hr_down 3
#define select_preset 4
#define relay 5
#define buzzer 6
//for button debounce
int debounceDelay = 50;
int buttonState1 = HIGH;
int lastButtonState1 = HIGH;
unsigned long lastDebounceTime1 = 0;
int buttonState2 = HIGH;
int lastButtonState2 = HIGH;
unsigned long lastDebounceTime2 = 0;
int buttonState3 = HIGH;
int lastButtonState3 = HIGH;
unsigned long lastDebounceTime3 = 0;
int hr_to_run1 = 12; //time to run
int hr_to_run2 = 1;
int selected = 3; //function select 1 - 3
bool watered = false;
void setup()
{
Serial.begin(9600);
RTC.begin();
lcd.begin(16, 02);
lcd.backlight();
pinMode(set_hr_up, INPUT_PULLUP);
pinMode(set_hr_down, INPUT_PULLUP);
pinMode(select_preset, INPUT_PULLUP);
pinMode(relay, OUTPUT);
pinMode(buzzer, OUTPUT);
// RTC.setDay(22);
// RTC.setMonth(5);
// RTC.setYear(2020);
// RTC.setHours(18);
// RTC.setMinutes(47);
// RTC.setSeconds(56);
//RTC.setDate(22,07,29);
//RTC.setTime(22,10,20);
hr_to_run1 = readEEPROM(1);
hr_to_run2 = readEEPROM(2);
if (hr_to_run1 == 255 || hr_to_run2 == 255) {
writeEEPROM(1, 12);
writeEEPROM(2, 12);
hr_to_run1 = readEEPROM(1);
hr_to_run2 = readEEPROM(2);
}
lcd.clear();
}
void loop()
{
int water_level = analogRead(rain_sense);
int hrs = RTC.getHours();
int mnt = RTC.getMinutes();
lcd.setCursor(11, 0);
lcd.print(hrs);
lcd.print(":");
lcd.print(mnt);
lcd.setCursor(0, 0);
lcd.print("Run1: ");
lcd.print(hr_to_run1);
lcd.print(" ");
lcd.setCursor(0, 1);
lcd.print("Run2: ");
lcd.print(hr_to_run2);
lcd.print(" ");
int rain_s = analogRead(rain_sense);
lcd.setCursor(11, 1);
if (rain_s > 500) {
lcd.print("Sunny");
if (hrs == hr_to_run1 || hrs == hr_to_run2) {
if (!watered && selected == 3) {
Serial.println("watering");
digitalWrite(relay, HIGH);
tone(buzzer, 1000);
delay(1000);
noTone(buzzer);
delay(4000);
digitalWrite(relay, LOW);
watered = true;
}
} else {
watered = false;
}
}else{
lcd.print("Rainy");
}
int select = digitalRead(select_preset);
int hrs_b = digitalRead(set_hr_up);
int mnt_b = digitalRead(set_hr_down);
debounceButton(select, lastButtonState1, lastDebounceTime1, buttonState1, "select");
debounceButton(hrs_b, lastButtonState2, lastDebounceTime2, buttonState2, "up");
debounceButton(mnt_b, lastButtonState3, lastDebounceTime3, buttonState3, "down");
}
void debounceButton(int reading, int &lastButtonState, unsigned long &lastDebounceTime, int &buttonState, String func) {
if (reading != lastButtonState) {
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
if (reading != buttonState) {
buttonState = reading;
if (buttonState == LOW) {
if (func == "select") {
tone(buzzer, 2000);
delay(100);
noTone(buzzer);
selected ++;
selected = selected > 3 ? 1 : selected;
if (selected == 1) {
lcd.setCursor(9, 0);
lcd.print("<");
lcd.setCursor(9, 1);
lcd.print(" ");
} else if (selected == 2) {
lcd.setCursor(9, 0);
lcd.print(" ");
lcd.setCursor(9, 1);
lcd.print("<");
} else if (selected == 3) {
lcd.setCursor(9, 0);
lcd.print(" ");
lcd.setCursor(9, 1);
lcd.print(" ");
writeEEPROM(1, hr_to_run1);
writeEEPROM(2, hr_to_run2);
lcd.setCursor(10, 1);
lcd.print("Save!");
tone(buzzer, 1500);
delay(100);
tone(buzzer, 1000);
delay(100);
tone(buzzer, 500);
delay(100);
noTone(buzzer);
delay(800);
lcd.print(" ");
lcd.clear();
}
}
if (selected < 3) {
if (func == "up") {
tone(buzzer, 2000);
delay(100);
noTone(buzzer);
if (selected == 1) {
hr_to_run1 ++;
hr_to_run1 = hr_to_run1 > 24 ? 1 : hr_to_run1;
} else if (selected == 2) {
hr_to_run2 ++;
hr_to_run2 = hr_to_run2 > 24 ? 1 : hr_to_run2;
}
}
if (func == "down") {
tone(buzzer, 2000);
delay(100);
noTone(buzzer);
if (selected == 1) {
hr_to_run1 --;
hr_to_run1 = hr_to_run1 < 1 ? 24 : hr_to_run1;
} else if (selected == 2) {
hr_to_run2 --;
hr_to_run2 = hr_to_run2 < 1 ? 24 : hr_to_run2;
}
}
}
}
}
}
lastButtonState = reading;
}
void writeEEPROM(int adrs, int data) {
EEPROM.write(adrs, data);
Serial.println("Data written to EEPROM");
}
int readEEPROM(int adrs) {
return EEPROM.read(adrs);
}