#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
#include <LiquidCrystal_I2C.h>
#include <RTClib.h>
LiquidCrystal_I2C lcd(0x20, 20, 4);
LiquidCrystal_I2C lcd1(0x21, 20, 4);
LiquidCrystal_I2C lcd2(0x22, 20, 4);
LiquidCrystal_I2C lcd3(0x23, 20, 4);
RTC_DS1307 rtc;
char daysOfTheWeek[7][24] = {
"Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday"
};
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
unsigned int localPort = 8888; // local port to listen for UDP packets
const char timeServer[] = "time.nist.gov";
const int NTP_PACKET_SIZE = 48;
byte packetBuffer[NTP_PACKET_SIZE];
EthernetUDP Udp;
unsigned long previousMillis;
unsigned long displayMillis;
unsigned long currentMillis;
const int durationUpdateRTC = 10000;
unsigned long offsetUpdateRTC;
long nowSec;
const int duration_1 = 10000;
const int duration_2 = 500;
const int duration_3 = 2000;
int seq;
int last;
int w;
int x;
int z;
int p;
#define txEnable 22
int address[33] = {
100, 101, 102, 103, 104, 105, 106, 107, 108, 109,
110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
120, 121, 122, 123, 124, 125, 126, 127, 128, 129,
130, 131, 132
};
int addressHold;
char data[64] = {0};
int y100;
int y200;
float y[19];
int commandEStop = 9110;
int commandStart = 1200;
int commandStop = 1300;
int commandGet = 1210;
int packet1 = 201;
int packet2 = 202;
int packet3 = 203;
int packet4 = 204;
int packet5 = 205;
int packet6 = 206;
int comRelease = 207;
// Remineralizer (address[2])
float waterLevel;
float tempRemin;
int stateRemin;
// dosing pump unit 1 (address[4])
int frequency_dp1;
long stepsPerDose_1_dp1;
long stepsPerDose_2_dp1;
long stepsPerDose_3_dp1;
long stepsPerDose_4_dp1;
// ATO/AWC 1
int ato1State;
int ato1Channel;
// ATO/AWC 2
int ato2State;
int ato2Channel;
// ATO/AWC 3
int ato3State;
int ato3Channel;
// weather station 1 (address[10])
float temp_1;
float RH_1;
float Ts_1;
float altimeter_1;
float windspeed_1;
int windDirection_1;
// weather station 2 (address[11])
float temp_2;
float RH_2;
float Ts_2;
float altimeter_2;
float windspeed_2;
int windDirection_2;
#define EStop 22
void setup() {
// You can use Ethernet.init(pin) to configure the CS pin
Serial.begin(19200);
Serial1.begin(9600);
Serial.setTimeout(1500);
while (!Serial) {
;
}
lcd.init();
lcd1.init();
lcd2.init();
lcd3.init();
lcd.backlight();
lcd1.backlight();
lcd2.backlight();
lcd3.backlight();
lcd.setCursor(0,0);
lcd.print("****initializing****");
lcd1.setCursor(0,0);
lcd1.print("********************");
lcd2.setCursor(0,0);
lcd2.print("********************");
lcd3.setCursor(0,0);
lcd3.print("********************");
if (Ethernet.begin(mac) == 0) {
lcd.setCursor(0,1);
lcd.print("Ethernet************");
Serial.println("Failed to configure Ethernet using DHCP");
delay(2000);
if (Ethernet.hardwareStatus() == EthernetNoHardware) {
lcd.setCursor(0,1);
lcd.print("Ethernet not found. ");
Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :(");
}
else if (Ethernet.linkStatus() == LinkOFF) {
lcd.setCursor(0,1);
lcd.print("Ethernet unplugged. ");
Serial.println("Ethernet cable is not connected.");
}
}
else {
lcd.setCursor(0,1);
lcd.print(" ");
}
Udp.begin(localPort);
if (! rtc.begin()) {
lcd.setCursor(0,2);
lcd.print("Couldn't find RTC");
while (1);
}
else {
lcd.setCursor(0,2);
lcd.print(" ");
}
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
DateTime now = rtc.now();
currentMillis = millis();
previousMillis = currentMillis;
displayMillis = currentMillis;
nowSec = (now.hour() * 3600)+(now.minute() * 60)+ now.second();
y200 = comRelease;
addressHold = address[2];
seq = 1;
// seq = 0;
z = 1;
}
void loop() {
DateTime now = rtc.now();
updateDisplay();
while(seq == 0) {
DateTime now = rtc.now();
for(int i = 2; i < 33; i++) {
nowSec = (now.hour() * 3600)+(now.minute() * 60)+ now.second();
Serial.print(address[i]);
Serial.print(",");
Serial.print(commandEStop);
Serial.print(",");
Serial.println(nowSec);
delay(50);
}
delay(1000);
}
// Report over serial bus.
while(seq == 1) {
DateTime now = rtc.now();
nowSec = (now.hour() * 3600)+(now.minute() * 60)+ now.second();
timerComSeq();
updateDisplay();
if(w == 1) {
last = 1;
if(z == 1) {
digitalWrite(txEnable, HIGH);
Serial.println(" "); Serial.println(" "); Serial.println(" ");
Serial.print(now.month()); Serial.print("-"); Serial.print(now.day()); Serial.print("-"); Serial.println(now.year());
Serial.print(now.hour()); Serial.print(":"); Serial.print(now.minute()); Serial.print(":"); Serial.println(now.second());
Serial.println("Remineralizer");
Serial.print("water level = "); Serial.println(waterLevel, 3);
Serial.print("temperature = "); Serial.println(tempRemin, 3);
Serial.print("remineralizer state = "); Serial.println(stateRemin);
Serial.println(" ");
Serial.println("Dosing Pump Unit 1");
Serial.print("freq = "); Serial.println(frequency_dp1);
Serial.print("Steps Per Dose 1 = "); Serial.println(stepsPerDose_1_dp1);
Serial.print("Steps Per Dose 2 = "); Serial.println(stepsPerDose_2_dp1);
Serial.print("Steps Per Dose 3 = "); Serial.println(stepsPerDose_3_dp1);
Serial.print("Steps Per Dose 4 = "); Serial.println(stepsPerDose_4_dp1);
Serial.println(" ");
Serial.print("ATO / AWC 1 state: ");
if(ato1State == 0) {
Serial.println("ATO");
}
if(ato1State == 1) {
Serial.println("AWC");
}
Serial.print("ATO / AWC 1 Channel: "); Serial.println(ato1Channel);
Serial.println(" ");
Serial.print("ATO / AWC 2 state: ");
if(ato2State == 0) {
Serial.println("ATO");
}
if(ato2State == 1) {
Serial.println("AWC");
}
Serial.print("ATO / AWC 2 Channel: "); Serial.println(ato2Channel);
Serial.println(" ");
Serial.print("ATO / AWC 3 state: ");
if(ato3State == 0) {
Serial.println("ATO");
}
if(ato3State == 1) {
Serial.println("AWC");
}
Serial.print("ATO / AWC 3 Channel: "); Serial.println(ato3Channel);
Serial.println(" ");
Serial.println("Weather Station 1");
Serial.print("temperature = "); Serial.print(temp_1, 3); Serial.println(" Degrees F");
Serial.print("relative humidity = "); Serial.print(RH_1, 3); Serial.println("%");
Serial.print("Dewpoint = "); Serial.print(Ts_1, 3); Serial.println(" Degrees F");
Serial.print("altimeter = "); Serial.print(altimeter_1, 3); Serial.println("mmHg");
Serial.print("wind = "); Serial.print(windspeed_1, 3); Serial.print("kts @ "); Serial.print(windDirection_1); Serial.println(" Degrees");
Serial.println(" ");
Serial.println("Weather Station 2");
Serial.print("temperature = "); Serial.print(temp_2, 3); Serial.println(" Degrees F");
Serial.print("relative humidity = "); Serial.print(RH_2, 3); Serial.println("%");
Serial.print("Dewpoint = "); Serial.print(Ts_2, 3); Serial.println(" Degrees F");
Serial.print("altimeter = "); Serial.print(altimeter_2, 3); Serial.println("mmHg");
Serial.print("wind = "); Serial.print(windspeed_2, 3); Serial.print("kts @ "); Serial.print(windDirection_2); Serial.println(" Degrees");
Serial.println(" "); Serial.println(" "); Serial.println(" ");
digitalWrite(txEnable, LOW);
z = 2;
}
delay(50);
}
if(w == 2 && last == 1){
if(z == 2) {
z = 1;
}
seq = address[2];
}
}
// Remineralizer unit
while(seq == address[2]) {
addressHold = address[2];
DateTime now = rtc.now();
nowSec = (now.hour() * 3600)+(now.minute() * 60)+ now.second();
timerComSeq();
updateDisplay();
if(w == 1) {
last = address[2];
if(z == 1) {
digitalWrite(txEnable, HIGH);
Serial.print(addressHold);
Serial.print(",");
Serial.println(packet1);
digitalWrite(txEnable, LOW);
z = 2;
}
delay(50);
getSerialData();
}
if(w == 2 && last == address[2]){
if(y100 == address[2] && y200 == comRelease) {
waterLevel = y[1];
tempRemin = y[2];
stateRemin = y[3];
}
if(z == 2) {
z = 1;
}
seq = address[4];
}
}
// Dosing pump unit 1
while(seq == address[4]) {
addressHold = address[4];
DateTime now = rtc.now();
nowSec = (now.hour() * 3600)+(now.minute() * 60)+ now.second();
timerComSeq();
updateDisplay();
if(w == 1) {
last = address[4];
if(z == 1) {
digitalWrite(txEnable, HIGH);
Serial.print(addressHold);
Serial.print(",");
Serial.print(packet1);
Serial.print(",");
Serial.println(stateRemin);
digitalWrite(txEnable, LOW);
z = 2;
}
delay(50);
getSerialData();
}
if(w == 2 && last == address[4]){
if(y100 == address[4] && y200 == comRelease) {
frequency_dp1 = (500000 / y[1]);
stepsPerDose_1_dp1 = (y[2] * 1000);
stepsPerDose_2_dp1 = (y[3] * 1000);
stepsPerDose_3_dp1 = (y[4] * 1000);
stepsPerDose_4_dp1 = (y[5] * 1000);
}
if(z == 2) {
z = 1;
}
seq = address[6];
}
}
// ATO / AWC 1
while(seq == address[6]) {
addressHold = address[6];
DateTime now = rtc.now();
nowSec = (now.hour() * 3600)+(now.minute() * 60)+ now.second();
timerComSeq();
updateDisplay();
if(w == 1) {
last = address[6];
if(z == 1) {
digitalWrite(txEnable, HIGH);
Serial.print(addressHold);
Serial.print(",");
Serial.print(packet1);
Serial.print(",");
Serial.println(nowSec);
digitalWrite(txEnable, LOW);
z = 2;
}
delay(50);
getSerialData();
}
if(w == 2 && last == address[6]){
if(y100 == address[6] && y200 == comRelease) {
ato1State = y[1];
ato1Channel = y[2];
}
if(z == 2) {
z = 1;
}
seq = address[7];
}
}
// ATO / AWC 2
while(seq == address[7]) {
addressHold = address[7];
DateTime now = rtc.now();
nowSec = (now.hour() * 3600)+(now.minute() * 60)+ now.second();
timerComSeq();
updateDisplay();
if(w == 1) {
last = address[7];
if(z == 1) {
digitalWrite(txEnable, HIGH);
Serial.print(addressHold);
Serial.print(",");
Serial.print(packet1);
Serial.print(",");
Serial.println(nowSec);
digitalWrite(txEnable, LOW);
z = 2;
}
delay(50);
getSerialData();
}
if(w == 2 && last == address[7]){
if(y100 == address[7] && y200 == comRelease) {
ato2State = y[1];
ato2Channel = y[2];
}
if(z == 2) {
z = 1;
}
seq = address[8];
}
}
// ATO / AWC 3
while(seq == address[8]) {
addressHold = address[8];
DateTime now = rtc.now();
nowSec = (now.hour() * 3600)+(now.minute() * 60)+ now.second();
timerComSeq();
updateDisplay();
if(w == 1) {
last = address[8];
if(z == 1) {
digitalWrite(txEnable, HIGH);
Serial.print(addressHold);
Serial.print(",");
Serial.print(packet1);
Serial.print(",");
Serial.println(nowSec);
digitalWrite(txEnable, LOW);
z = 2;
}
delay(50);
getSerialData();
}
if(w == 2 && last == address[8]){
if(y100 == address[8] && y200 == comRelease) {
ato3State = y[1];
ato3Channel = y[2];
}
if(z == 2) {
z = 1;
}
seq = address[10];
}
}
// Weather station 1
while(seq == address[10]) {
addressHold = address[10];
DateTime now = rtc.now();
nowSec = (now.hour() * 3600)+(now.minute() * 60)+ now.second();
timerComSeq();
updateDisplay();
if(w == 1) {
last = address[10];
if(z == 1) {
digitalWrite(txEnable, HIGH);
Serial.print(addressHold);
Serial.print(",");
Serial.println(packet1);
digitalWrite(txEnable, LOW);
z = 2;
}
delay(50);
getSerialData();
}
if(w == 2 && last == address[10]){
if(y100 == address[10] && y200 == comRelease) {
temp_1 = y[1];
RH_1 = y[2];
Ts_1 = y[3];
altimeter_1 = y[4];
windspeed_1 = y[5];
windDirection_1 = y[6];
}
if(z == 2) {
/* Serial.print("temperature = "); Serial.print(temp_1, 3); Serial.println(" Degrees F");
Serial.print("relative humidity = "); Serial.print(RH_1, 3); Serial.println("%");
Serial.print("Dewpoint = "); Serial.print(Ts_1, 3); Serial.println(" Degrees F");
Serial.print("altimeter = "); Serial.print(altimeter_1, 3); Serial.println("mmHg");
Serial.print("wind = "); Serial.print(windspeed_1, 3); Serial.print("kts @ "); Serial.print(windDirection_1); Serial.println(" Degrees");
*/
z = 1;
}
seq = address[11];
}
}
// Weather station 2
while(seq == address[11]) {
addressHold = address[11];
DateTime now = rtc.now();
nowSec = (now.hour() * 3600)+(now.minute() * 60)+ now.second();
timerComSeq();
updateDisplay();
if(w == 1) {
last = address[11];
if(z == 1) {
digitalWrite(txEnable, HIGH);
Serial.print(addressHold);
Serial.print(",");
Serial.println(packet1);
digitalWrite(txEnable, LOW);
z = 2;
}
delay(50);
getSerialData();
}
if(w == 2 && last == address[11]){
if(y100 == address[11] && y200 == comRelease) {
temp_2 = y[1];
RH_2 = y[2];
Ts_2 = y[3];
altimeter_2 = y[4];
windspeed_2 = y[5];
windDirection_2 = y[6];
}
if(z == 2) {
/* Serial.print("temperature = "); Serial.print(temp_2, 3); Serial.println(" Degrees F");
Serial.print("relative humidity = "); Serial.print(RH_2, 3); Serial.println("%");
Serial.print("Dewpoint = "); Serial.print(Ts_2, 3); Serial.println(" Degrees F");
Serial.print("altimeter = "); Serial.print(altimeter_2, 3); Serial.println("mmHg");
Serial.print("wind = "); Serial.print(windspeed_2, 3); Serial.print("kts @ "); Serial.print(windDirection_2); Serial.println(" Degrees");
*/
z = 1;
}
seq = 1;
}
}
}
void sendNTPpacket(const char * address) {
// set all bytes in the buffer to 0
memset(packetBuffer, 0, NTP_PACKET_SIZE);
// Initialize values needed to form NTP request
// (see URL above for details on the packets)
packetBuffer[0] = 0b11100011; // LI, Version, Mode
packetBuffer[1] = 0; // Stratum, or type of clock
packetBuffer[2] = 6; // Polling Interval
packetBuffer[3] = 0xEC; // Peer Clock Precision
// 8 bytes of zero for Root Delay & Root Dispersion
packetBuffer[12] = 49;
packetBuffer[13] = 0x4E;
packetBuffer[14] = 49;
packetBuffer[15] = 52;
// all NTP fields have been given values, now
// you can send a packet requesting a timestamp:
Udp.beginPacket(address, 123); // NTP requests are to port 123
Udp.write(packetBuffer, NTP_PACKET_SIZE);
Udp.endPacket();
}
void timerUpdateRTC() {
DateTime now = rtc.now();
nowSec = (now.hour() * 3600)+(now.minute() * 60)+ now.second();
currentMillis = millis();
int hourUTC;
int minuteUTC;
int secondUTC;
if(0 <= nowSec < 10) {
offsetUpdateRTC = currentMillis;
}
if(10 <= nowSec < 120) {
sendNTPpacket(timeServer); // send an NTP packet to a time server
// wait to see if a reply is available
delay(1000);
if (Udp.parsePacket()) {
// We've received a packet, read the data from it
Udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer
unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
unsigned long secsSince1900 = highWord << 16 | lowWord;
// Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
const unsigned long seventyYears = 2208988800UL;
// subtract seventy years:
unsigned long epoch = secsSince1900 - seventyYears;
hourUTC = ((epoch % 86400L) / 3600);
minuteUTC = ((epoch % 3600) / 60);
secondUTC = (epoch % 60);
}
// wait ten seconds before asking for the time again
if(currentMillis > (offsetUpdateRTC + durationUpdateRTC)) {
Ethernet.maintain();
offsetUpdateRTC = currentMillis;
}
int Year = now.year();
int Month = now.month();
int Day = now.day();
rtc.adjust(DateTime(Year, Month, Day, (hourUTC + 5), minuteUTC, secondUTC));
}
}
void timerComSeq() {
currentMillis = millis();
if(currentMillis < (previousMillis + duration_1)) {
w = 1;
}
if(currentMillis > (previousMillis + duration_1)) {
if(currentMillis < (previousMillis + duration_1 + duration_2)) {
w = 2;
}
if(currentMillis >= (previousMillis + duration_1 + duration_2)) {
previousMillis = currentMillis;
}
}
}
void updateDisplay() {
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());
}
lcd.setCursor(0,1);
lcd.print(p);
lcd.print(" ");
lcd.setCursor(0,2);
lcd.print(" ");
}
void getSerialData() {
byte n = Serial.available();
if (n != 0) {
byte m = Serial.readBytesUntil('\n', data, 64);
data[m] = '\0'; //null-byte
y100 = atoi(strtok(data, ","));
y200 = atoi(strtok(NULL, ","));
if(y200 == 0) {
}
if(y200 == packet1) {
y[1] = atof(strtok(NULL, ","));
y[2] = atof(strtok(NULL, ","));
y[3] = atof(strtok(NULL, ","));
/* Serial.print("address recieved = "); Serial.println(y100);
Serial.print("packet = "); Serial.println(y200);
Serial.print("y[1] = "); Serial.println(y[1], 3);
Serial.print("y[2] = "); Serial.println(y[2], 3);
Serial.print("y[3] = "); Serial.println(y[3], 3); */
delay(200);
digitalWrite(txEnable, HIGH);
Serial.print(addressHold);
Serial.print(",");
Serial.println(packet2);
digitalWrite(txEnable, LOW);
}
if(y200 == packet2) {
y[4] = atof(strtok(NULL, ","));
y[5] = atof(strtok(NULL, ","));
y[6] = atof(strtok(NULL, ","));
/* Serial.print("address recieved = "); Serial.println(y100);
Serial.print("packet = "); Serial.println(y200);
Serial.print("y[4] = "); Serial.println(y[4], 3);
Serial.print("y[5] = "); Serial.println(y[5], 3);
Serial.print("y[6] = "); Serial.println(y[6], 3); */
delay(200);
digitalWrite(txEnable, HIGH);
Serial.print(addressHold);
Serial.print(",");
Serial.println(packet3);
digitalWrite(txEnable, LOW);
}
if(y200 == packet3) {
y[7] = atof(strtok(NULL, ","));
y[8] = atof(strtok(NULL, ","));
y[9] = atof(strtok(NULL, ","));
/* Serial.print("address recieved = "); Serial.println(y100);
Serial.print("packet = "); Serial.println(y200);
Serial.print("y[7] = "); Serial.println(y[7], 3);
Serial.print("y[8] = "); Serial.println(y[8], 3);
Serial.print("y[9] = "); Serial.println(y[9], 3); */
delay(200);
digitalWrite(txEnable, HIGH);
Serial.print(addressHold);
Serial.print(",");
Serial.println(packet4);
digitalWrite(txEnable, LOW);
}
if(y200 == packet4) {
y[10] = atof(strtok(NULL, ","));
y[11] = atof(strtok(NULL, ","));
y[12] = atof(strtok(NULL, ","));
/* Serial.print("address recieved = "); Serial.println(y100);
Serial.print("packet = "); Serial.println(y200);
Serial.print("y[10] = "); Serial.println(y[10], 3);
Serial.print("y[11] = "); Serial.println(y[11], 3);
Serial.print("y[12] = "); Serial.println(y[12], 3); */
delay(200);
digitalWrite(txEnable, HIGH);
Serial.print(addressHold);
Serial.print(",");
Serial.println(packet5);
digitalWrite(txEnable, LOW);
}
if(y200 == packet5) {
y[13] = atof(strtok(NULL, ","));
y[14] = atof(strtok(NULL, ","));
y[15] = atof(strtok(NULL, ","));
/* Serial.print("address recieved = "); Serial.println(y100);
Serial.print("packet = "); Serial.println(y200);
Serial.print("y[13] = "); Serial.println(y[13], 3);
Serial.print("y[14] = "); Serial.println(y[14], 3);
Serial.print("y[15] = "); Serial.println(y[15], 3); */
delay(200);
digitalWrite(txEnable, HIGH);
Serial.print(addressHold);
Serial.print(",");
Serial.println(packet6);
digitalWrite(txEnable, LOW);
}
if(y200 == packet6) {
y[16] = atof(strtok(NULL, ","));
y[17] = atof(strtok(NULL, ","));
y[18] = atof(strtok(NULL, ","));
/* Serial.print("address recieved = "); Serial.println(y100);
Serial.print("packet = "); Serial.println(y200);
Serial.print("y[16] = "); Serial.println(y[16], 3);
Serial.print("y[17] = "); Serial.println(y[17], 3);
Serial.print("y[18] = "); Serial.println(y[18], 3); */
delay(200);
digitalWrite(txEnable, HIGH);
Serial.print(addressHold);
Serial.print(",");
Serial.println(comRelease);
digitalWrite(txEnable, LOW);
}
if(y200 == comRelease) {
}
}
}