#include <LiquidCrystal_I2C.h>
#include <RTClib.h>
RTC_DS1307 rtc;
char daysOfTheWeek[7][24] = {
"Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday"
};
const int startHourATO = 12;
const int startMinuteATO = 0;
const int stopHourATO = 12;
const int stopMinuteATO = 30;
const int AWCday = 6;
const int startHourAWC = 12;
const int startMinuteAWC = 30;
const int stopHourAWC = 13;
const int stopMinuteAWC = 05;
long minuteOfTheDay;
long minuteATOstart;
long minuteATOstop;
long minuteAWCstart;
long minuteAWCstop;
LiquidCrystal_I2C lcd(0x27, 20, 4);
/*
HIGH ena = drive dissabled
LOW ena = drive enabled
HIGH dir = CCW = tank drain
LOW dir = CW = tank fill
tankHigh and tankLow are normally LOW; HIGH indicates no water at that level --> external pull-up
wasteHigh is normally HIGH; LOW indicates waste tank is full --> internal pull-up
freshLow is normally HIGH; LOW indicates fresh water tank is empty --> internal pull-up
*/
#define ena_1 2
#define dir_1 3
#define ena_2 4
#define dir_2 5
#define tankHigh 6
#define tankLow 7
#define freshLow 8
#define wasteHigh 9
#define purgeFill 10
#define purgeDrain 11
#define purgeChem 12
// #define txEnable 13
#define light 14 // K4
#define filter 15 // K3
#define heater 16 // K2
#define alarm 17 // K1
int state;
unsigned int a;
int blink;
long offTime = 1000;
long onTime = 1000;
unsigned long previousMillis = 0;
// Timer_2 variables
int trigger;
int cycle;
const long duration_2 = 10000; // milliseconds
long offset_2;
int b;
void setup() {
Serial.begin(9600);
lcd.init();
lcd.backlight();
pinMode(ena_1, OUTPUT);
pinMode(dir_1, OUTPUT);
pinMode(ena_2, OUTPUT);
pinMode(dir_2, OUTPUT);
pinMode(light, OUTPUT);
pinMode(filter, OUTPUT);
pinMode(heater, OUTPUT);
pinMode(alarm, OUTPUT);
pinMode(tankHigh, INPUT);
pinMode(tankLow, INPUT);
pinMode(freshLow, INPUT_PULLUP);
pinMode(wasteHigh, INPUT_PULLUP);
// pinMode(purgeFill, INPUT);
// pinMode(purgeDrain, INPUT);
// pinMode(purgeChem, INPUT);
pinMode(purgeFill, INPUT_PULLUP);
pinMode(purgeDrain, INPUT_PULLUP);
pinMode(purgeChem, INPUT_PULLUP);
if (! rtc.begin()) {
lcd.setCursor(0,1);
lcd.print("Couldn't find RTC");
while (1);
}
else {
lcd.setCursor(0,1);
lcd.print(" ");
}
// rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
DateTime now = rtc.now();
minuteOfTheDay = ((now.hour() * 60) + now.minute());
minuteATOstart = ((startHourATO * 60) + startMinuteATO);
minuteATOstop = ((stopHourATO * 60) + stopMinuteATO);
minuteAWCstart = ((startHourAWC * 60) + startMinuteAWC);
minuteAWCstop = ((stopHourAWC * 60) + stopMinuteAWC);
state = 0;
a = LOW;
blink = 0;
b = 0;
}
void loop() {
while(state == 0) {
DateTime now = rtc.now();
minuteOfTheDay = ((now.hour() * 60) + now.minute());
clock();
State();
if(state != 0) {
break;
}
lcd.setCursor(0,1);
lcd.print("OK ");
digitalWrite(alarm, LOW);
if((minuteATOstart <= minuteOfTheDay) && (minuteOfTheDay < minuteATOstop)) {
digitalWrite(dir_2, HIGH);
digitalWrite(ena_2, HIGH);
if(digitalRead(tankHigh) == HIGH) {
digitalWrite(dir_1, LOW);
digitalWrite(ena_1, LOW);
lcd.setCursor(0,2);
lcd.print("ATO ");
}
else if(digitalRead(tankHigh) == LOW) {
digitalWrite(dir_1, HIGH);
digitalWrite(ena_1, HIGH);
lcd.setCursor(0,2);
lcd.print("READY");
}
}
else if((digitalRead(purgeDrain) == LOW) && (digitalRead(purgeFill) == HIGH) && (digitalRead(purgeChem) == HIGH)) {
digitalWrite(dir_1, HIGH);
digitalWrite(ena_1, LOW);
lcd.setCursor(0,2);
lcd.print("DRAIN");
}
else if((digitalRead(purgeDrain) == HIGH) && (digitalRead(purgeFill) == LOW) && (digitalRead(purgeChem) == HIGH)) {
digitalWrite(dir_1, LOW);
digitalWrite(ena_1, LOW);
lcd.setCursor(0,2);
lcd.print("FILL ");
}
else if((digitalRead(purgeDrain) == HIGH) && (digitalRead(purgeFill) == HIGH) && (digitalRead(purgeChem) == LOW)) {
digitalWrite(dir_2, LOW);
digitalWrite(ena_2, LOW);
lcd.setCursor(0,2);
lcd.print("CHEM ");
}
else {
digitalWrite(dir_1, HIGH);
digitalWrite(ena_1, HIGH);
digitalWrite(dir_2, HIGH);
digitalWrite(ena_2, HIGH);
lcd.setCursor(0,2);
lcd.print("IDLE ");
}
}
while(state == 1) {
clock();
State();
if(state != 1) {
break;
}
lcd.setCursor(0,1);
lcd.print("FRESH");
lcd.setCursor(0,2);
lcd.print("*****");
digitalWrite(dir_1, HIGH);
digitalWrite(ena_1, HIGH);
digitalWrite(dir_2, HIGH);
digitalWrite(ena_2, HIGH);
digitalWrite(alarm, HIGH);
}
while(state == 2) {
clock();
State();
if(state != 2) {
break;
}
lcd.setCursor(0,1);
lcd.print("WASTE");
lcd.setCursor(0,2);
lcd.print("*****");
digitalWrite(dir_1, LOW);
digitalWrite(ena_1, HIGH);
digitalWrite(dir_2, LOW);
digitalWrite(ena_2, HIGH);
digitalWrite(alarm, HIGH);
}
while(state == 3) {
clock();
State();
timer_1();
if(state != 3) {
break;
}
lcd.setCursor(0,1);
lcd.print("ERROR");
lcd.setCursor(0,2);
lcd.print("*****");
digitalWrite(dir_1, LOW);
digitalWrite(ena_1, HIGH);
digitalWrite(dir_2, LOW);
digitalWrite(ena_2, HIGH);
if(blink == 0) {
digitalWrite(alarm, LOW);
digitalWrite(LED_BUILTIN, LOW);
}
else if(blink == 1) {
digitalWrite(alarm, HIGH);
digitalWrite(LED_BUILTIN, HIGH);
}
}
while(state == 4) {
int c;
clock();
State();
if(state != 4) {
break;
}
else {
b = 1;
c = 0;
}
while(b == 1) {
while(c == 0) {
clock();
if(digitalRead(tankHigh) == HIGH) {
digitalWrite(dir_1, LOW);
digitalWrite(ena_1, LOW);
lcd.setCursor(0,2);
lcd.print("AWC ");
lcd.print(c);
}
else if(digitalRead(tankHigh) == LOW) {
digitalWrite(dir_1, HIGH);
digitalWrite(ena_1, HIGH);
lcd.setCursor(0,2);
lcd.print("READY");
c = 1;
}
}
while(c == 1) {
clock();
if(digitalRead(tankLow) == LOW) {
digitalWrite(dir_1, HIGH);
digitalWrite(ena_1, LOW);
lcd.setCursor(0,2);
lcd.print("AWC ");
lcd.print(c);
}
else if(digitalRead(tankLow) == HIGH) {
digitalWrite(dir_1, HIGH);
digitalWrite(ena_1, HIGH);
lcd.setCursor(0,2);
lcd.print("AWC ");
lcd.print(c);
c = 2;
}
}
while(c == 2) {
clock();
if(digitalRead(tankHigh) == HIGH) {
digitalWrite(dir_1, LOW);
digitalWrite(ena_1, LOW);
lcd.setCursor(0,2);
lcd.print("AWC ");
lcd.print(c);
}
else if(digitalRead(tankHigh) == LOW) {
digitalWrite(dir_1, HIGH);
digitalWrite(ena_1, HIGH);
lcd.setCursor(0,2);
lcd.print("READY");
b = 0;
c = 0;
}
}
}
}
}
void clock() {
DateTime now = rtc.now();
lcd.setCursor(0,0);
if(now.month() < 10) {
lcd.print("0");
lcd.print(now.month());
}
else {
lcd.print(now.month());
}
lcd.print("/");
if(now.day() < 10) {
lcd.print("0");
lcd.print(now.day());
}
else {
lcd.print(now.day());
}
lcd.print("/");
lcd.print(now.year());
lcd.print(" ");
if(now.hour() < 10) {
lcd.print("0");
lcd.print(now.hour());
}
else {
lcd.print(now.hour());
}
lcd.print(":");
if(now.minute() < 10) {
lcd.print("0");
lcd.print(now.minute());
}
else {
lcd.print(now.minute());
}
lcd.print(":");
if(now.second() < 10) {
lcd.print("0");
lcd.print(now.second());
}
else {
lcd.print(now.second());
}
}
void State() {
DateTime now = rtc.now();
if((digitalRead(freshLow) == HIGH) && (digitalRead(wasteHigh) == HIGH)) {
if((minuteAWCstart <= minuteOfTheDay) && (minuteOfTheDay < minuteAWCstop) && (now.day() == AWCday)) {
state = 4;
}
else {
state = 0;
}
}
else if((digitalRead(freshLow) == LOW) && (digitalRead(wasteHigh) == HIGH)) {
state = 1;
}
else if((digitalRead(freshLow) == HIGH) && (digitalRead(wasteHigh) == LOW)) {
state = 2;
}
else if((digitalRead(freshLow) == LOW) && (digitalRead(wasteHigh) == LOW)) {
state = 3;
}
}
void timer_1() {
long currentMillis = millis();
if ((a == HIGH) && (currentMillis - previousMillis >= offTime)) {
a = LOW;
previousMillis = currentMillis;
blink = 1;
}
else if((a == LOW) && (currentMillis - previousMillis >= onTime)) {
a = HIGH;
previousMillis = currentMillis;
blink = 0;
}
}
void timer_2() {
long currentMillis = millis();
if(trigger == 1) {
offset_2 = currentMillis;
trigger = 0;
}
if(currentMillis < (offset_2 + duration_2)) {
cycle = 1;
}
else if(currentMillis > (offset_2 + duration_2)) {
cycle = 0;
}
}