// https://curiousscientist.tech/blog/date-and-time-based-watering-system
#include <Wire.h>
#include <RTClib.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
RTC_DS1307 RTC;
//--------------------------------
bool newData; //new data on serial
bool watering = false; //status if watering is allowed or not
bool wateredtoday = false;
int wateringhour = 9; // water at 9:00 o'clock in the morning (24h time format!)
float wateringlength = 6000; //10 sec default watering (pumping time)
const int relaypin = 2;
const int switchpin = 3;
int switchstate = 0;
char receivedCommand;
//--------------------------------
void setup()
{
//------------------------------------------------------
lcd.init(); // initialize the lcd
lcd.init();
lcd.backlight();
//------------------------------------------------------
pinMode(relaypin, OUTPUT);
pinMode(switchpin, INPUT);
Serial.begin(9600);
Wire.begin();
RTC.begin();
//Refreshing time
//remove "!", compile, upload to refresh the time in the RTC module
//the time will be set to the time of the compilation
if (! RTC.isrunning())
{
Serial.println("RTC is NOT running!");
// following line sets the RTC to the date & time this sketch was compiled
RTC.adjust(DateTime(__DATE__, __TIME__));
}
Serial.println("Irrigation system.");
//Fancy startup
lcd.clear();
lcd.setCursor(0,0); //Defining positon to write from first row,first column .
lcd.print("Watering System");
lcd.setCursor(0,1);
lcd.print("Start in 5..."); //You can write 16 Characters per line .
delay(1000); //wait 3 sec
lcd.setCursor(0,1);
lcd.print("Start in 4..."); //You can write 16 Characters per line .
delay(1000); //wait 3 sec
lcd.setCursor(0,1);
lcd.print("Start in 3..."); //You can write 16 Characters per line .
delay(1000); //wait 3 sec
lcd.setCursor(0,1);
lcd.print("Start in 2..."); //You can write 16 Characters per line .
delay(1000); //wait 3 sec
lcd.setCursor(0,1);
lcd.print("Start in 1..."); //You can write 16 Characters per line .
delay(1000); //wait 3 sec
}
void loop()
{
printtime();
checkSerial();
checktime();
switchcheck();
executecommand();
}
//----------------------------------------------------------------------------------
void checkSerial()
{
//First we check if there is data on the serial port, i.e. we sent a command
if (Serial.available() > 0)
{
receivedCommand = Serial.read();
newData = true;
}
//if there is a command, then we step inside and go through the possible commands
if (newData == true) {
if(receivedCommand == 'w') //w = watering
{
watering = true; //change the boolean, so the watering will be ENABLED
}
if(receivedCommand == 's') //s = stop
{
watering = false; //change the boolean, so the watering will be DISABLED
}
}
else
{}
newData = false;
}
//----------------------------------------------------------------------------------
void executecommand() //execute the commands, i.e. checking which flag is en/dis-abled
{
if(watering == true)
{
//start pump
digitalWrite(relaypin, HIGH);
//------------------------------------------------------
//---print info on LCD
lcd.clear();
lcd.setCursor(0,0); //Defining positon to write from first row,first column .
lcd.print("Watering");
lcd.setCursor(0,1);
lcd.print("Running"); //You can write 16 Characters per line .
//---Run pump for some time (defined in the beginning of the code as a variable)
delay(wateringlength);
//---Shut down pump, set pin to LOW
digitalWrite(relaypin, LOW);
//---Clean screen
lcd.clear();
//---Disable watering
watering = false;
//--Change the value of the bool, so we'll know that the watering had happened
wateredtoday = true;
}
else
{
//do not do anything
}
//---------------------------
}
//----------------------------------------------------------------------------------
void printtime()
{
//it is just a basic RTC and LCD exercise: reading the date and time and printing it with some formatting
DateTime now = RTC.now();
//-----------------
//--First line
lcd.clear();
lcd.setCursor(0,0); //Defining positon to write from first row,first column .
lcd.print(now.year());
lcd.setCursor(4,0);
lcd.print(".");
lcd.setCursor(5,0);
lcd.print(now.month());
lcd.setCursor(7,0);
lcd.print(".");
lcd.setCursor(8,0);
lcd.print(now.day());
lcd.setCursor(11,0);
lcd.print("water");
//-----------------
//--Second line
lcd.setCursor(0,1);
lcd.print(now.hour()); //You can write 16 Characters per line .
lcd.setCursor(2,1);
lcd.print(":");
lcd.setCursor(3,1);
lcd.print(now.minute());
lcd.setCursor(5,1);
lcd.print(":");
lcd.setCursor(6,1);
lcd.print(now.second());
lcd.setCursor(10,1);
//if the watering had happened, then we print it on the screen.
if(wateredtoday == true)
{lcd.print("true");}
else
{lcd.print("false");}
//----------------------------------------
Serial.print(now.year(), DEC);
Serial.print('/');
Serial.print(now.month(), DEC);
Serial.print('/');
Serial.print(now.day(), DEC);
Serial.print(' ');
Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.print(':');
Serial.print(now.second(), DEC);
Serial.println();
delay(1000);
}
//----------------------------------------------------------------------------------
void checktime()
{
//Here, we check the time, so we can see if the watering should be started
DateTime now = RTC.now();
//after the watering time occured, we switch the variable back to false so when the
//time occurs again (i.e. it is 9:00 in the morning) the watering will be started again
if(now.hour() == (wateringhour +1))
{
//Serial.println("Watered");
wateredtoday = false;
}
//If it is time to water, and we haven't watered, we enable watering
if(now.hour() == wateringhour && wateredtoday == false)
{
//Serial.println("Not watered");
watering = true;
wateredtoday = true;
}
}
void switchcheck()
{
//We check the switch which is used to manually run the pump
//this does not change ANYTHING with the regular, scheduled pumping.
//Serial.println("SwitchCheck");
switchstate = digitalRead(switchpin); //read the pin
if (switchstate == HIGH) {
//Serial.println("switch is HIGH");
//Serial.println(digitalRead(switchpin));
digitalWrite(relaypin, HIGH);
} else {
digitalWrite(relaypin, LOW);
//Serial.println("switch is LOW");
// Serial.println(digitalRead(switchpin));
}
}