#include <LiquidCrystal_I2C.h>
#include <RTClib.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);
RTC_DS1307 rtc;
char daysOfTheWeek[7][24] = {
"Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday"
};
// RX 0
// TX 1
#define pulse1 2
#define pulse2 3
#define pulse3 4
#define pulse4 5
#define ena 6
// TX3 14
// RX3 15
// TX2 16
// RX2 17
// TX1 18
// RX1 19
// SDA 20
// SCL 21
#define manual_1 22
#define manual_2 23
#define manual_3 24
#define manual_4 25
#define white 26
#define red 27
#define green 28
#define yellow 29
#define txEnable 30
#define Disable 36
#define Enable 37
#define callForWater 38
#define circPump 39
#define boostPump 40
#define heaterInterrupt 41
#define inletValve 43
#define outletValve 44
#define alarm 45
#define k1 46
int uSec = 1250;
long pulPerDose_1 = 2000;
long pulPerDose_2 = 2000;
long pulPerDose_3 = 2000;
long pulPerDose_4 = 2000;
int seq;
int last;
int w;
// MPX5010DP variables
#define mpx A0
const float ADC_mV = 4.8828125;
const float sensorOffset = 0.0;
const float sensitivity = 4.413;
const float mmH2O_inH2O = 25.34;
const float levelMin = 6.0;
const float levelMax = 32.0;
float waterLevel;
// Timer_1 variables
const int interval_1 = 20; // 1800 seconds
const int duration_1 = 5; // 600 seconds
long offset_1;
long nowSec;
int y = 1500;
int z = 500;
unsigned long previousMillis;
unsigned long currentMillis;
// Timer_2 variables
int trigger;
int cycle;
const int duration_2 = 2500; // milliseconds
long offset_2;
// Serial communication
int address_1 = 101;
int commandStart = 1200;
int commandStop = 1300;
int responseStart = 1250;
int responseStop = 1350;
int responseError = 1500;
int response;
void setup() {
// Sets the two pins as Outputs
pinMode(ena,OUTPUT);
pinMode(pulse1,OUTPUT);
pinMode(pulse2,OUTPUT);
pinMode(pulse3,OUTPUT);
pinMode(pulse4,OUTPUT);
pinMode(circPump,OUTPUT);
pinMode(boostPump,OUTPUT);
pinMode(heaterInterrupt,OUTPUT);
pinMode(inletValve,OUTPUT);
pinMode(outletValve,OUTPUT);
pinMode(alarm,OUTPUT);
pinMode(k1,OUTPUT);
pinMode(white,OUTPUT);
pinMode(red,OUTPUT);
pinMode(green,OUTPUT);
pinMode(yellow,OUTPUT);
pinMode(Enable, INPUT_PULLUP);
pinMode(Disable, INPUT_PULLUP);
pinMode(callForWater, INPUT_PULLUP);
pinMode(manual_1, INPUT);
pinMode(manual_2, INPUT);
pinMode(manual_3, INPUT);
pinMode(manual_4, INPUT);
lcd.init();
lcd.backlight();
digitalWrite(white, HIGH);
digitalWrite(red, LOW);
digitalWrite(green, LOW);
digitalWrite(yellow, LOW);
lcd.setCursor(0,0);
lcd.print("****initializing****");
lcd.setCursor(0,2);
lcd.print(">>>>>");
Serial1.begin(9600);
delay(1000);
digitalWrite(circPump, LOW);
digitalWrite(boostPump, LOW);
digitalWrite(heaterInterrupt, LOW);
digitalWrite(inletValve, LOW);
digitalWrite(outletValve, LOW);
digitalWrite(alarm, HIGH);
digitalWrite(k1, LOW);
digitalWrite(white, HIGH);
digitalWrite(red, HIGH);
digitalWrite(green, LOW);
digitalWrite(yellow, LOW);
lcd.setCursor(0,2);
lcd.print(">>>>>>>>>>");
delay(1000);
digitalWrite(ena, HIGH);
digitalWrite(alarm, LOW);
digitalWrite(white, HIGH);
digitalWrite(red, HIGH);
digitalWrite(green, LOW);
digitalWrite(yellow, HIGH);
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();
lcd.setCursor(0,2);
lcd.print(">>>>>>>>>>>>>>>");
delay(1000);
seq = 5;
last = 6;
nowSec = (now.hour() * 3600)+(now.minute() * 60)+ now.second();
offset_1 = nowSec;
digitalWrite(white, HIGH);
digitalWrite(red, HIGH);
digitalWrite(green, HIGH);
digitalWrite(yellow, HIGH);
lcd.setCursor(0,2);
lcd.print(">>>>>>>>>>>>>>>>>>>>");
delay(1000);
}
void loop() {
DateTime now = rtc.now();
// Dissable
while(seq == 0) {
digitalWrite(ena, HIGH);
digitalWrite(white, LOW);
digitalWrite(red, HIGH);
digitalWrite(green, LOW);
digitalWrite(yellow, LOW);
digitalWrite(circPump, LOW);
digitalWrite(boostPump, LOW);
digitalWrite(heaterInterrupt, HIGH);
digitalWrite(inletValve, LOW);
digitalWrite(outletValve, LOW);
digitalWrite(alarm, HIGH);
digitalWrite(k1, HIGH);
waterLevel = ((((analogRead(mpx) * ADC_mV) - sensorOffset) / sensitivity) /mmH2O_inH2O);
updateDisplay();
timer_2();
serialCom();
if(waterLevel >= (levelMax + 2) || waterLevel <= (levelMin - 1.5)) {
lcd.setCursor(0,2);
lcd.print("NO HEAT LEVEL K1");
}
else {
lcd.setCursor(0,2);
lcd.print("NO HEAT STOP K1");
}
if(digitalRead(Enable) == LOW) {
seq = 5;
delay(1000);
}
}
// refill
while(seq == 20) {
last = 20;
waterLevel = ((((analogRead(mpx) * ADC_mV) - sensorOffset) / sensitivity) /mmH2O_inH2O);
if(waterLevel <= (levelMin - 1.5)) {
digitalWrite(heaterInterrupt, HIGH);
trigger = 1;
timer_2();
seq = 0;
break;
}
delay(1500);
while(levelMax > waterLevel) {
digitalWrite(circPump, LOW);
digitalWrite(boostPump, LOW);
digitalWrite(heaterInterrupt, HIGH);
digitalWrite(inletValve, HIGH);
digitalWrite(outletValve, LOW);
digitalWrite(alarm, LOW);
digitalWrite(k1, HIGH);
digitalWrite(white, HIGH);
digitalWrite(red, LOW);
digitalWrite(green, LOW);
digitalWrite(yellow, HIGH);
waterLevel = ((((analogRead(mpx) * ADC_mV) - sensorOffset) / sensitivity) /mmH2O_inH2O);
updateDisplay();
timer_2();
serialCom();
lcd.setCursor(0,2);
lcd.print("NO HEAT INLET K1");
if(waterLevel >= levelMax) {
digitalWrite(circPump, HIGH);
digitalWrite(boostPump, LOW);
digitalWrite(heaterInterrupt, LOW);
digitalWrite(inletValve, LOW);
digitalWrite(outletValve, LOW);
digitalWrite(alarm, LOW);
lcd.setCursor(0,2);
lcd.print("CIRC PUMP K1");
delay(2000);
}
if(digitalRead(Disable) == LOW) {
digitalWrite(inletValve, LOW);
trigger = 1;
seq = 0;
delay(10);
break;
}
}
delay(500);
if(seq == 0) {
trigger = 1;
timer_2();
serialCom();
seq = 0;
}
else {
last = 1;
seq = 1;
}
}
// Call For Water
while(seq == 18) {
last = 6;
waterLevel = ((((analogRead(mpx) * ADC_mV) - sensorOffset) / sensitivity) /mmH2O_inH2O);
updateDisplay();
timer_1();
digitalWrite(white, LOW);
digitalWrite(red, LOW);
digitalWrite(green, HIGH);
digitalWrite(yellow, HIGH);
if(w < 10) {
digitalWrite(boostPump, HIGH);
lcd.setCursor(0,2);
lcd.print("PUMP ");
delay(100);
w = w + 1;
}
if(w == 10) {
digitalWrite(outletValve, HIGH);
lcd.setCursor(0,2);
lcd.print("PUMP OUTLET ");
}
if(waterLevel < levelMin) {
seq = 20;
}
if(digitalRead(callForWater) == HIGH) {
digitalWrite(outletValve, LOW);
digitalWrite(boostPump, LOW);
delay(10);
w = 0;
seq = 5;
}
}
// Dosing pump 1
while(seq == 1) {
last = 2;
delay(1000);
digitalWrite(ena, LOW);
digitalWrite(k1, HIGH);
digitalWrite(white, HIGH);
digitalWrite(red, LOW);
digitalWrite(green, LOW);
digitalWrite(yellow, HIGH);
digitalWrite(alarm, LOW);
updateDisplay();
lcd.setCursor(0,2);
lcd.print("CIRC PUMP K1");
for(long x = 0; x < pulPerDose_1; x++) {
digitalWrite(pulse1,HIGH);
delayMicroseconds(uSec);
digitalWrite(pulse1,LOW);
delayMicroseconds(uSec);
if(digitalRead(Disable) == LOW) {
digitalWrite(ena, HIGH);
seq = 0;
delay(10);
break;
}
}
delay(500);
digitalWrite(ena, HIGH);
if(seq == 0) {
seq = 0;
}
else {
seq = 2;
}
}
// Dosing pump 2
while(seq == 2) {
last = 3;
delay(1000);
digitalWrite(ena, LOW);
digitalWrite(k1, HIGH);
digitalWrite(white, HIGH);
digitalWrite(red, LOW);
digitalWrite(green, LOW);
digitalWrite(yellow, HIGH);
digitalWrite(alarm, LOW);
updateDisplay();
lcd.setCursor(0,2);
lcd.print("CIRC PUMP K1");
for(long x = 0; x < pulPerDose_2; x++) {
digitalWrite(pulse2,HIGH);
delayMicroseconds(uSec);
digitalWrite(pulse2,LOW);
delayMicroseconds(uSec);
if(digitalRead(Disable) == LOW) {
digitalWrite(ena, HIGH);
seq = 0;
delay(10);
break;
}
}
delay(500);
digitalWrite(ena, HIGH);
if(seq == 0) {
seq = 0;
}
else {
seq = 3;
}
}
// Dosing pump 3
while(seq == 3) {
last = 4;
delay(1000);
digitalWrite(ena, LOW);
digitalWrite(k1, HIGH);
digitalWrite(white, HIGH);
digitalWrite(red, LOW);
digitalWrite(green, LOW);
digitalWrite(yellow, HIGH);
digitalWrite(alarm, LOW);
updateDisplay();
lcd.setCursor(0,2);
lcd.print("CIRC PUMP K1");
for(long x = 0; x < pulPerDose_3; x++) {
digitalWrite(pulse3,HIGH);
delayMicroseconds(uSec);
digitalWrite(pulse3,LOW);
delayMicroseconds(uSec);
if(digitalRead(Disable) == LOW) {
digitalWrite(ena, HIGH);
seq = 0;
delay(10);
break;
}
}
delay(500);
digitalWrite(ena, HIGH);
if(seq == 0) {
seq = 0;
}
else {
seq = 4;
}
}
// Dosing pump 4
while(seq == 4) {
last = 6;
delay(1000);
digitalWrite(ena, LOW);
digitalWrite(k1, HIGH);
digitalWrite(white, HIGH);
digitalWrite(red, LOW);
digitalWrite(green, LOW);
digitalWrite(yellow, HIGH);
digitalWrite(alarm, LOW);
updateDisplay();
lcd.setCursor(0,2);
lcd.print("CIRC PUMP K1");
for(long x = 0; x < pulPerDose_4; x++) {
digitalWrite(pulse4,HIGH);
delayMicroseconds(uSec);
digitalWrite(pulse4,LOW);
delayMicroseconds(uSec);
if(digitalRead(Disable) == LOW) {
digitalWrite(ena, HIGH);
seq = 0;
delay(10);
break;
}
}
delay(500);
digitalWrite(ena, HIGH);
if(seq == 0) {
seq = 0;
}
else {
seq = 5;
}
}
// Enable hold
while(seq == 5) {
updateDisplay();
digitalWrite(white, LOW);
digitalWrite(red, HIGH);
digitalWrite(green, LOW);
digitalWrite(yellow, HIGH);
if(digitalRead(Enable) == LOW) {
seq = 5;
}
else if(digitalRead(Enable) == HIGH) {
seq = last;
delay(1000);
digitalWrite(red, LOW);
digitalWrite(yellow, LOW);
}
}
// Normal state
while(seq == 6) {
last = 6;
digitalWrite(white, LOW);
digitalWrite(red, LOW);
digitalWrite(green, HIGH);
delay(20);
waterLevel = (((analogRead(mpx) * ADC_mV - sensorOffset) / sensitivity) /mmH2O_inH2O);
digitalWrite(circPump, LOW);
digitalWrite(boostPump, LOW);
digitalWrite(heaterInterrupt, LOW);
digitalWrite(inletValve, LOW);
digitalWrite(outletValve, LOW);
digitalWrite(alarm, LOW);
digitalWrite(k1, LOW);
delay(1);
if(waterLevel < levelMin) {
seq = 20;
trigger = 1;
timer_2();
}
delay(20);
if(waterLevel >= (levelMax + 2)) {
seq = 0;
}
if(digitalRead(Disable) == LOW) {
seq = 0;
}
if(digitalRead(callForWater) == LOW) {
w = 0;
seq = 18;
}
if(digitalRead(manual_1) == HIGH ||
digitalRead(manual_2) == HIGH ||
digitalRead(manual_3) == HIGH ||
digitalRead(manual_4) == HIGH) {
seq = 7;
}
delay(20);
updateDisplay();
timer_1();
}
// Dosing Pump Jog
while(seq == 7) {
last = 6;
if(digitalRead(manual_1) == HIGH ||
digitalRead(manual_2) == HIGH ||
digitalRead(manual_3) == HIGH ||
digitalRead(manual_4) == HIGH) {
seq = 7;
}
else {
seq = last;
}
while(digitalRead(manual_1) == HIGH) {
digitalWrite(ena, LOW);
digitalWrite(white, LOW);
digitalWrite(red, LOW);
digitalWrite(green, HIGH);
digitalWrite(yellow, HIGH);
lcd.setCursor(6,0);
lcd.print("DP1");
delay(10);
for(long x = 0; x < 25; x++) {
digitalWrite(pulse1,HIGH);
delayMicroseconds(uSec * 4);
digitalWrite(pulse1,LOW);
delayMicroseconds(uSec * 4);
}
if(digitalRead(manual_1) == LOW) {
digitalWrite(ena, HIGH);
}
}
while(digitalRead(manual_2) == HIGH) {
digitalWrite(ena, LOW);
digitalWrite(white, LOW);
digitalWrite(red, LOW);
digitalWrite(green, HIGH);
digitalWrite(yellow, HIGH);
lcd.setCursor(6,0);
lcd.print("DP2");
delay(10);
for(long x = 0; x < 25; x++) {
digitalWrite(pulse2,HIGH);
delayMicroseconds(uSec * 4);
digitalWrite(pulse2,LOW);
delayMicroseconds(uSec * 4);
}
if(digitalRead(manual_2) == LOW) {
digitalWrite(ena, HIGH);
}
}
while(digitalRead(manual_3) == HIGH) {
digitalWrite(ena, LOW);
digitalWrite(white, LOW);
digitalWrite(red, LOW);
digitalWrite(green, HIGH);
digitalWrite(yellow, HIGH);
lcd.setCursor(6,0);
lcd.print("DP3");
delay(10);
for(long x = 0; x < 25; x++) {
digitalWrite(pulse3,HIGH);
delayMicroseconds(uSec * 4);
digitalWrite(pulse3,LOW);
delayMicroseconds(uSec * 4);
}
if(digitalRead(manual_3) == LOW) {
digitalWrite(ena, HIGH);
}
}
while(digitalRead(manual_4) == HIGH) {
digitalWrite(ena, LOW);
digitalWrite(white, LOW);
digitalWrite(red, LOW);
digitalWrite(green, HIGH);
digitalWrite(yellow, HIGH);
lcd.setCursor(6,0);
lcd.print("DP4");
delay(10);
for(long x = 0; x < 25; x++) {
digitalWrite(pulse4,HIGH);
delayMicroseconds(uSec * 4);
digitalWrite(pulse4,LOW);
delayMicroseconds(uSec * 4);
}
if(digitalRead(manual_4) == LOW) {
digitalWrite(ena, HIGH);
}
}
}
}
void updateDisplay() {
DateTime now = rtc.now();
lcd.setCursor(0,1);
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());
}
lcd.print(" ");
lcd.setCursor(0,3);
if(waterLevel < 10.00) {
lcd.print("0");
lcd.print(waterLevel);
lcd.print("inH2O ");
}
if(waterLevel >= 10.00) {
lcd.print(waterLevel);
lcd.print("inH2O");
}
if(seq == 0) {
lcd.setCursor(0,0);
lcd.print("********ALARM*******");
}
if(seq == 1) {
lcd.setCursor(0,0);
lcd.print("Auto Top-Off | DP1 ");
}
if(seq == 2) {
lcd.setCursor(0,0);
lcd.print("Auto Top-Off | DP2 ");
}
if(seq == 3) {
lcd.setCursor(0,0);
lcd.print("Auto Top-Off | DP3 ");
}
if(seq == 4) {
lcd.setCursor(0,0);
lcd.print("Auto Top-Off | DP4 ");
}
if(seq == 5) {
lcd.setCursor(0,0);
lcd.print("Program Hold........");
lcd.setCursor(0,2);
lcd.print(" ");
}
if(seq == 6) {
lcd.setCursor(0,0);
lcd.print("Ready ");
lcd.setCursor(0,2);
lcd.print(" ");
}
if(seq == 18) {
lcd.setCursor(0,0);
lcd.print("Call For Water ");
}
if(seq == 20) {
lcd.setCursor(0,0);
lcd.print("Auto Top-Off | Fill ");
}
}
void timer_1() {
DateTime now = rtc.now();
nowSec = (now.hour() * 3600)+(now.minute() * 60)+ now.second();
currentMillis = millis();
if(offset_1 >= 86400) {
offset_1 = 0;
}
if(nowSec < (offset_1 + interval_1)) {
digitalWrite(circPump, LOW);
if(seq == 6) {
digitalWrite(yellow, LOW);
lcd.setCursor(16,2);
lcd.print(" ");
}
if(seq == 18) {
lcd.setCursor(16,2);
lcd.print(" ");
}
}
if(nowSec >= (offset_1 + interval_1)) {
if(nowSec < (offset_1 + interval_1 + duration_1)) {
digitalWrite(circPump, HIGH);
if(seq == 6) {
lcd.setCursor(16,2);
lcd.print("CIRC");
}
if(seq == 18) {
lcd.setCursor(16,2);
lcd.print("CIRC");
}
if( currentMillis < (previousMillis + y)) {
digitalWrite(yellow, LOW);
}
if( currentMillis > (previousMillis + y)) {
if( currentMillis < (previousMillis + y + z)) {
digitalWrite(yellow, HIGH);
}
if( currentMillis >= (previousMillis + y + z)) {
previousMillis = currentMillis;
}
}
}
if(nowSec >= (offset_1 + interval_1 + duration_1)) {
offset_1 = nowSec;
}
}
}
void timer_2() {
currentMillis = millis();
if(trigger == 1) {
offset_2 = currentMillis;
trigger = 0;
}
if(currentMillis < (offset_2 + duration_2)) {
digitalWrite(txEnable, HIGH);
cycle = 1;
}
if(currentMillis > (offset_2 + duration_2)) {
digitalWrite(txEnable, LOW);
cycle = 0;
}
}
void serialCom() {
if(cycle == 1){
lcd.setCursor(18,3);
lcd.print("TX");
if(seq == 20) {
Serial1.println((address_1 + commandStart));
}
if(seq == 0) {
Serial1.println((address_1 + commandStop));
}
}
if(cycle == 0) {
lcd.setCursor(18,3);
lcd.print("RX");
if(seq == 20) {
response = Serial1.parseInt();
if((response - address_1) == responseStart) {
seq = 20;
}
if((response - address_1) == responseStop) {
last = 20;
seq = 0;
}
if((response - address_1) == responseError) {
seq = 0;
}
}
}
}