#include <LiquidCrystal_I2C.h>
#define I2C_ADDR 0x27
#define LCD_COLUMNS 20
#define LCD_LINES 4
#define LED_PIN3 7 // Backyard
#define LED_PIN2 8 // Frontyard
#define LED_PIN1 9 // Footpath
LiquidCrystal_I2C lcd(I2C_ADDR, LCD_COLUMNS, LCD_LINES);
uint8_t heart[8] = {
0b00000,
0b01010,
0b11111,
0b11111,
0b11111,
0b01110,
0b00100,
0b00000,
};
// The pins and state for the relay modules.
const int relay1Pin = 12;
const int relay2Pin = 11;
const int relay3Pin = 10;
byte relay1State = LOW;
byte relay2State = LOW;
byte relay3State = LOW;
// The pins and state for the buttonss.
const int button1Pin = 5;
const int button2Pin = 4;
const int button3Pin = 3;
const int button4Pin = 2; //Interrupt
byte button1State = LOW;
byte button2State = LOW;
byte button3State = LOW;
volatile int button4State; //for subroutine
const unsigned long shortRun = 2.0 * 60.0 * 60.0 * 1000.0; //2 hours
const unsigned long longRun = 3.0 * 60.0 * 60.0 * 1000.0; //3 hours
unsigned long TimeLeft1 = 0.0;
unsigned long TimeLeft2 = 0.0;
unsigned long TimeLeft3 = 0.0;
unsigned long currentMillis = 0;
unsigned long startRelay1Millis = 0;
unsigned long startRelay2Millis = 0;
unsigned long startRelay3Millis = 0;
void(* resetFunc) (void) = 0;
void buttonInterrupt() {
button4State = digitalRead(button4Pin);
if (button4State == HIGH) {
digitalWrite(relay1Pin,LOW);
digitalWrite(relay2Pin,LOW);
digitalWrite(relay3Pin,LOW);
button1State = LOW;
button2State = LOW;
button3State = LOW;
digitalWrite(LED_PIN1,LOW);
digitalWrite(LED_PIN2,LOW);
digitalWrite(LED_PIN3,LOW);
resetFunc();
Serial.println("All stopped!");
button4State = LOW;
}
}
void setup() {
lcd.createChar(3, heart);
// Init display
lcd.init();
lcd.backlight();
// Print something
lcd.setCursor(3, 0);
lcd.print("Rod's Watering");
lcd.setCursor(3, 1);
lcd.print(" System");
lcd.setCursor(1, 2);
lcd.print(" v1.10 ");
lcd.setCursor(10, 3);
lcd.print("\x03");
// Set pins as output.
pinMode(relay1Pin, OUTPUT);
pinMode(relay2Pin, OUTPUT);
pinMode(relay3Pin, OUTPUT);
//Set pins for input.
pinMode(button1Pin, INPUT);
pinMode(button2Pin, INPUT);
pinMode(button3Pin, INPUT);
pinMode(button4Pin, INPUT);
pinMode(LED_PIN3, OUTPUT);
pinMode(LED_PIN2, OUTPUT);
pinMode(LED_PIN1, OUTPUT);
attachInterrupt(digitalPinToInterrupt(button4Pin), buttonInterrupt, CHANGE);
Serial.begin(9600);
}
void loop() {
// put your main code here, to run repeatedly:
if(buttonPressed(button1Pin)) {
Serial.print("Green pressed! - ");
Serial.print(shortRun);
Serial.print(" milliseconds - ");
Serial.println(button1State);
if (button1State == HIGH) {
Serial.println(" Button 1 state is already HIGH");
}
else { if (button1State == LOW && button2State == LOW && button3State == LOW) {
button1State = HIGH;
Serial.println(" Button 1 state is HIGH");
startRelay1Millis = millis();
}
}
}
if(buttonPressed(button2Pin)) {
Serial.print("Blue pressed! - ");
Serial.print(shortRun);
Serial.print(" milliseconds - ");
Serial.println(button2State);
if (button2State == HIGH) {
Serial.println(" Button 2 state is already HIGH");
}
else { if (button1State == LOW && button2State == LOW && button3State == LOW) {
button2State = HIGH;
Serial.println(" Button 2 state is HIGH");
startRelay2Millis = millis();
}
}
}
if(buttonPressed(button3Pin)) {
Serial.print("Yellow pressed! - ");
Serial.print(longRun);
Serial.print(" milliseconds - ");
Serial.println(button3State);
if (button3State == HIGH) {
Serial.println(" Button 3 state is already HIGH");
}
else { if (button1State == LOW && button2State == LOW && button3State == LOW) {
button3State = HIGH;
Serial.println(" Button 3 state is HIGH");
startRelay3Millis = millis();
}
}
}
currentMillis = millis();
if (button1State == HIGH) {
TimeLeft1 = (shortRun - currentMillis - startRelay1Millis) / 60000.0;
lcd.setCursor(3, 0);
lcd.print("Rod's Watering");
lcd.setCursor(3, 1);
lcd.print(" System");
lcd.setCursor(1, 2);
lcd.print(" Watering footpath ");
lcd.setCursor(4, 3);
lcd.print(TimeLeft1);
lcd.setCursor(8, 3);
lcd.print("minutes \x03");
uint8_t heart2[8] = {0};
for (int i = 0; i < 8; i++) {
heart2[i] = heart[i];
lcd.createChar(3, heart2);
delay(100);
}
if (currentMillis - startRelay1Millis <= shortRun) {
digitalWrite(relay1Pin,HIGH);
digitalWrite(LED_PIN1,HIGH);
}
if (currentMillis - startRelay1Millis >= shortRun) {
digitalWrite(relay1Pin,LOW);
digitalWrite(LED_PIN1,LOW);
button1State = LOW;
}
}
if (button2State == HIGH) {
TimeLeft2 = (shortRun - currentMillis - startRelay2Millis) / 60000.0;
lcd.setCursor(3, 0);
lcd.print("Rod's Watering");
lcd.setCursor(3, 1);
lcd.print(" System");
lcd.setCursor(1, 2);
lcd.print("Watering frontyard");
lcd.setCursor(4, 3);
lcd.print(TimeLeft2);
lcd.setCursor(7, 3);
lcd.print(" minutes \x03");
uint8_t heart2[8] = {0};
for (int i = 0; i < 8; i++) {
heart2[i] = heart[i];
lcd.createChar(3, heart2);
delay(100);
}
if (currentMillis - startRelay2Millis <= shortRun) {
digitalWrite(relay2Pin,HIGH);
digitalWrite(LED_PIN2,HIGH);
}
if (currentMillis - startRelay2Millis >= shortRun) {
digitalWrite(relay2Pin,LOW);
digitalWrite(LED_PIN2,LOW);
button2State = LOW;
}
}
if (button3State == HIGH) {
TimeLeft3 = (longRun - currentMillis - startRelay3Millis) / 60000.0;
lcd.setCursor(3, 0);
lcd.print("Rod's Watering");
lcd.setCursor(3, 1);
lcd.print(" System");
lcd.setCursor(1, 2);
lcd.print("Watering back yard");
lcd.setCursor(4, 3);
lcd.print(TimeLeft3);
lcd.setCursor(8, 3);
lcd.print("minutes \x03");
uint8_t heart2[8] = {0};
for (int i = 0; i < 8; i++) {
heart2[i] = heart[i];
lcd.createChar(3, heart2);
delay(100);
}
if (currentMillis - startRelay3Millis <= longRun) {
digitalWrite(relay3Pin,HIGH);
digitalWrite(LED_PIN3,HIGH);
}
if (currentMillis - startRelay3Millis >= longRun) {
digitalWrite(relay3Pin,LOW);
digitalWrite(LED_PIN3,LOW);
button3State = LOW;
}
}
} // end of void loop
// Generic function to check if a button is pressed
int buttonPressed(uint8_t button) {
static uint16_t lastStates = 0;
uint8_t state = digitalRead(button);
if (state != ((lastStates >> button) & 1)) {
lastStates ^= 1 << button;
return state == HIGH;
}
return false;
}