////////////////////////////////////////////////////////////////////////////////
// Name:       FloraGardenUno-02  ETHERNET version                            //
// http://robotigs.com/robotigs/includes/bots_header.php?idbot=18             //
//             An Arduino Uno is used to switch a relais to output 12 Vdc     //
// Created by: HARB rboek2@gmail.com april 2019 GPL copyrights                //
// Platform:   Arduino UNO Rev3                                               //
// As outputs the following modules are mounted:                              //
// - Standard Arduino Onboard LED (PWM)                                       //
//           http://robotigs.nl/robotigs/includes/parts_header.php?idpart=185 //
// - 3 color LED (PWM)                                                        //
//           http://robotigs.nl/robotigs/includes/parts_header.php?idpart=293 //
// - Activ loudspeaker / buzzer                                               //
//           http://robotigs.nl/robotigs/includes/parts_header.php?idpart=240 //
// - 220 Vac Relay                                                            //
//           http://robotigs.nl/robotigs/includes/parts_header.php?idpart=189 //
// As inputs the following modules are mounted:                               //
// - DS1302 Real Time Clock                                                   //
//           http://robotigs.nl/robotigs/includes/parts_header.php?idpart=27  //
// - Temp DS18B20                                                             //
//           http://robotigs.nl/robotigs/includes/parts_header.php?idpart=180 //
// - LDR                                                                      //
//           http://robotigs.nl/robotigs/includes/parts_header.php?idpart=46  //
// For communications are mounted:                                            //
// - Standard Serial Monitor output                                           //
//            http://robotigs.nl/robotigs/includes/parts_header.php?idpart=43 //
// - Lan ENC28J60 unit                                                        //
//           http://robotigs.nl/robotigs/includes/parts_header.php?idpart=313 //
////////////////////////////////////////////////////////////////////////////////





////////////////////////////////////////////////////////////////////////////////
// EEPROM MEMORY MAP:                                                         //
// Start End  Number Description                                              //
// 0000  0000      1   Never use this memory location to be AVR compatible    //
// 0001  0001      1   tuinLDRtreshold *10 to switch DAY=0/NIGHT=1023     LDR //
// 0002  0002      1   Number of minutes tuinWaterDelay after dark        ALL //
// 0003  0003      1 WATER1 tuinWater1prog program 1=off 2=on 3=auto   RELAY1 //
// 0004  0004      1   Number of minutes tuinWater1spray water on      RELAY1 //
// 0005  0005      1 WATER2 tuinWater2prog program 1=off 2=on 3=auto   RELAY2 //
// 0006  0006      1   Number of minutes tuinWater2spray water on      RELAY2 //
// 0007  0007      1 WATER3 tuinWater3prog program 1=off 2=on 3=auto   RELAY3 //
// 0008  0008      1   Number of minutes tuinWater3spray water on      RELAY3 //
// 0009  0009      1 WATER4 tuinWater4Pprog program 1=off 2=on 3=auto  RELAY4 //
// 0010  0010      1   Number of minutes tuinWater4spray water on      RELAY4 //
////////////////////////////////////////////////////////////////////////////////




// SET PRECOMPILER OPTIONS *****************************************************
  // Initialse conditional compiling, uncomment to include, comment to exclude -
  // Do comment the next line for runtime versions -----------------------------
  #define RS232                   //Uncomment to include Serial Monitor sections
  //#ifdef RS232     //Only include these lines if the variable has been defined

  //Define the needed header files for the precompiler, no charge if not used --
  #include <stdio.h>       //http://quadpoint.org/projects/arduino-ds1302 DS1302
             // http://robotigs.com/robotigs/includes/parts_header.php?idpart=27
             
  #include <DS1302.h>                   //Copyright (c) 2009, Matt Sparks DS1302
             // http://robotigs.com/robotigs/includes/parts_header.php?idpart=27
             
  #include <EEPROM.h>                      //Needed for read or write in EEPROM
             // http://robotigs.nl/robotigs/includes/parts_header.php?idpart=312

  #include <OneWire.h>   //Library can be installed through Arduino IDE DS18B20
             // http://robotigs.nl/robotigs/includes/parts_header.php?idpart=180
             
  #include <UIPEthernet.h>      //ENC28J60 by https://github.com/ntruchsess LAN
             // http://robotigs.nl/robotigs/includes/parts_header.php?idpart=313
             
  // Define precompiler variables, runs faster & doesn`t use RAM ---------------
  // Define PINS ---------------------------------------------------------------
  OneWire term1(A0);        //Connects to pin 17, but may be any DIO pin DS1820
  #define ldrPin       A1        //Define to which DA converter pin connects LDR
  #define Relay1Pin    A5       //12Vdc output switch pin connects WATER1 RELAY1
  #define Relay2Pin    A4       //12Vdc output switch pin connects WATER2 RELAY2
  #define Relay3Pin    A3       //12Vdc output switch pin connects WATER3 RELAY3
  #define Relay4Pin    A2       //12Vdc output switch pin connects WATER4 RELAY4
  #define buzActPin     3          //Define DIO output pin connects ACTIV BUZZER
  #define ledRedPin     4         //3 Colour LED, which PWM pin connects RED LED
  #define ledGrePin     5       //3 Colour LED, which PWM pin connects GREEN LED
  #define ledBluPin     6        //3 Colour LED, which PWM pin connects BLUE LED
  #define kIoPin        7                             //Input/Output, DAT DS1302
  #define kCePin        8                              //Chip Enable, RST DS1302
  #define kSclkPin      9                             //Serial Clock, CLK DS1302
  //#define SpiMISO    12                      //PB3 -- MISO/PCINT3  SPI pin LAN
  //#define SpiMOSI    11                       //PB2 -- MOSI/PCINT2 SPI pin LAN
  //#define SpiSCK     13                        //PB1 -- SCK/PCINT1 SPI pin LAN
  //#define SpiSS      10                         //PB0 -- SS/PCINT0 SPI pin LAN
    // 0, 1 = Serial monitor aansluiting
    // Pin 2 is de enige vrije pin op dit moment


  //Define EEPROM variables ----------------------------------------------------
  int     tuinLDRtreshold =  40;   //tuinLDRtreshold *10 switch DAY=0/NIGHT=1023
  int     tuinWaterDelay  =  10;        //Number of minutes delay after dark ALL
  int     tuinWater1prog  =   1;     //WATER1 program 1=off 2=on 3=auto   RELAY1
  int     tuinWater1spray =  10;             //Number of minutes water on RELAY1
  int     tuinWater2prog  =   1;     //WATER2 program 1=off 2=on 3=auto   RELAY2
  int     tuinWater2spray =  10;             //Number of minutes water on RELAY2
  int     tuinWater3prog  =   1;     //WATER3 program 1=off 2=on 3=auto   RELAY3
  int     tuinWater3spray =  10;             //Number of minutes water on RELAY3
  int     tuinWater4prog  =   1;     //WATER4 program 1=off 2=on 3=auto   RELAY4
  int     tuinWater4spray =  10;             //Number of minutes water on RELAY4

  //Define DATABASE VARIABLES --------------------------------------------------
  String  tuinKlok; //Timestamp format PgSql yyyy-mm-dd hh:mm:ss DateTime DS1302
  float   tuinSoilTemp;                    //Soil temperature in Celsius DS18B20
  word    tuinLDR         =    0;  //Contains last light measurement, 0-1023 LDR
  bool    tuinRelay1      = HIGH;      //Status HIGH=off or LOW=on WATER1 RELAY1
  bool    tuinRelay2      = HIGH;      //Status HIGH=off or LOW=on WATER2 RELAY2
  bool    tuinRelay3      = HIGH;      //Status HIGH=off or LOW=on WATER3 RELAY3
  bool    tuinRelay4      = HIGH;      //Status HIGH=off or LOW=on WATER4 RELAY4

  //Define VARIABLES -----------------------------------------------------------
  bool   ledOnBoardVal  = LOW;   //You choose HIGH=on or LOW=off for LED_BUILTIN
  byte    msWait         = 2;           //Test your patience during the test LED
  byte    brillance      = 0;    //Brightness of any color, just to test PWM LED
  byte    present        = 0;   //Used for oneWire, present = ds.reset() DS18B20
  byte    i;                  //Used for oneWire, loopcounter byte array DS18B20
  byte    data[12];           //Used for oneWire to store data read from DS18B20
  byte    type1_s        = 0;        //Type 0 = ok, except old DS1820=1, DS18B20
  byte    addr1[8];              //Array with first 8 bytes, inc/address DS18B20
  String  commandStr     = "";              //Commands received by html INTERNET
  String  html           = "";               //Creating response string INTERNET
  word    bodyLength     = 0;         //Creating response string length INTERNET
  int     command        = 0;     //Which user command received by html INTERNET
  uint8_t mac[6]         = {0x00,0x01,0x02,0x03,0x04,0x06};                //LAN
                            // Ethernet MAC address - must be unique on your LAN
  bool    ledBlueVal     = LOW;      //toggleBlueLed HIGH-on or LOW-off blue LED
  String  starttime      = "19:00";        //Sprinklertimer to switch ON  DS1302
  String  finishtime     = "20:00";       //Sprinklertimer to switch OFF  DS1302
  String  clocktime;             //Sprinklertimer to compare start finish DS1302
  char    buf[50];                                       //Needed to read DS1302
  word    readCounter    = 0;     //Read sensors if counted down to zero SENSORS
  word    readTimer      = 9999;  //Fill readCounter after reaching zero SENSORS
  
  String  tmp            = "";                            //Can be used anywhere
  String  tempo          = "";                            //Can be used anywhere


  //Initialise objects ---------------------------------------------------------
  EthernetServer server(80);      //Prepair an internet connection as server LAN
  EthernetClient client;      //Create an object for the internet connection LAN
  DS1302 rtc(kCePin, kIoPin, kSclkPin);    //Create object by name of rtc DS1302
//END OF PRECOMPILER OPTIONS ---------------------------------------------------



void setup() { //Setup runs once ***********************************************
  disable_jtag();         //Disable jtag to free port C, enabled by default JTAG

  //EEPROMfirstTime();                //First time use, write values into EEPROM
  tuinLDRtreshold = EEPROM.read( 1);        //*10 to switch DAY=0/NIGHT=1023 LDR
  tuinWaterDelay  = EEPROM.read( 2);    //Number of minutes delay after dark ALL
  tuinWater1prog  = EEPROM.read( 3);   //WATER1 program 1=off 2=on 3=auto RELAY1
  tuinWater1spray = EEPROM.read( 4);         //Number of minutes water on RELAY1
  tuinWater2prog  = EEPROM.read( 5);   //WATER2 program 1=off 2=on 3=auto RELAY2
  tuinWater2spray = EEPROM.read( 6);         //Number of minutes water on RELAY2
  tuinWater3prog  = EEPROM.read( 7);   //WATER3 program 1=off 2=on 3=auto RELAY3
  tuinWater3spray = EEPROM.read( 8);         //Number of minutes water on RELAY3
  tuinWater4prog  = EEPROM.read( 9);   //WATER4 program 1=off 2=on 3=auto RELAY4
  tuinWater4spray = EEPROM.read(10);         //Number of minutes water on RELAY4

  Serial.begin(57600);              //Nothing more needed for the Serial Monitor

  pinMode(ledRedPin, OUTPUT);           //Make the LED connection output RED LED
  pinMode(ledGrePin, OUTPUT);         //Make the LED connection output GREEN LED
  pinMode(ledBluPin, OUTPUT);          //Make the LED connection output BLUE LED
  pinMode(LED_BUILTIN, OUTPUT);  //Arduino boards contain an onboard BUILTIN LED
    
  pinMode(buzActPin, OUTPUT);                 //Set this pin as output to BUZZER
  pinMode(Relay1Pin, OUTPUT);         //Arduino boards contain an onboard RELAY1
  digitalWrite(Relay1Pin, tuinRelay1);                 //Switches OFF the RELAY1
  pinMode(Relay2Pin, OUTPUT);         //Arduino boards contain an onboard RELAY2
  digitalWrite(Relay2Pin, tuinRelay2);                 //Switches OFF the RELAY2
  pinMode(Relay3Pin, OUTPUT);         //Arduino boards contain an onboard RELAY3
  digitalWrite(Relay3Pin, tuinRelay3);                 //Switches OFF the RELAY3
  pinMode(Relay4Pin, OUTPUT);         //Arduino boards contain an onboard RELAY4
  digitalWrite(Relay4Pin, tuinRelay4);                 //Switches OFF the RELAY4

  //Start objects --------------------------------------------------------------
  DS1820_init();      //Determins the type of DS1820 and reads properties DS1820
  rtc.writeProtect(false);                                              //DS1302
  rtc.halt(false);                                                      //DS1302
  //Time t(2019, 04, 24, 20, 11, 00, Time::kWednesday);  //UNCOMMENT TO SET TIME
  //rtc.time(t); //Set the time and date on the chip       UNCOMMENT TO SET TIME
  Ethernet.begin(mac);                       //Configure IP address via DHCP LAN
  server.begin();                                    //Start listening at he LAN
  
  //Test hardware and software -------------------------------------------------
  beep(10);                       //Create a test beep with KY-012 active BUZZER
  show_LAN();                                       //Shows DHCP settings of LAN
  test_LEDs();            //PWM fade in and fade out for all 4 LEDs on board LED
  //test_RELAY();                          //Switches ON for 2 seconds the RELAY
  beep(10);                       //Create a test beep with KY-012 active BUZZER
  Serial.println("Setup completed");     //Show the user the setup is done RS232
} //End of setup ---------------------------------------------------------------



void loop() { //KEEP ON RUNNING THIS LOOP FOREVER ******************************
  readTime();        //Reading the time and format results into variables DS1302
  readSensors();          //Read several sensors at timed intervals only SENSORS
  checkInternet();     //Check if a request available and if so then respond LAN
} //End of void loop() ----------------------- KEEP ON RUNNING THIS LOOP FOREVER



void readSensors() { //Read several sensors at timed intervals only ************
  if (readCounter == 0){       //Only perform measurements if counted down TIMER
    analogWrite(ledGrePin, 5);              //Green HIGH=on, LOW=off activityLED
    tuinLDR = analogRead(ldrPin);                  //Read voltage on pin A15 LDR
    //DS1820_read();                //Reads the temperature in Celsius from DS1802
  
    readCounter  =  readTimer;                         //RESET the counter TIMER
    refreshAnswer();                  //Replace the old answer by a new one DATA
    setActuators();                              //Calculate and set all OUTPUTS
    toggle_ledOnBoard();         //Toggles the LED_BUILTIN  ON or OFF onboardLED

    //Serial.println(html);                     //Show activity to the user RS232
    digitalWrite(ledGrePin, LOW);            //Blue HIGH=on, LOW=off activityLED
  }else{                                //Meaning counter was not yet zero TIMER
    readCounter--;                        //Decrement of the timer counter TIMER
  } //End of if (moistureCnt1 == 0)Perform measurements if counted down    TIMER
} //Exit readSensors -----------------------------------------------------------




void setActuators(){ //Calculate and set all OUTPUTS ***************************
  //setRelay1();                    //WATERING1 switch, calculate and set RELAY1
  //setRelay2();                    //WATERING2 switch, calculate and set RELAY2
  //setRelay3();                    //WATERING3 switch, calculate and set RELAY3
  //setRelay4();                    //WATERING4 switch, calculate and set RELAY4
  setSprinkler();     //Switches sprinkler ON or OFF according to setting RELAY2
} //Exit setActuators ----------------------------------------------------------


void checkInternet(){  //Check if a request available and if so then respond LAN
  client = server.available();                 //Listen for incoming clients LAN
  if (client) {                                //We have an internet request LAN
    commandStr = "";                      //Reset the commands received INTERNET
    digitalWrite(ledBluPin, HIGH);           //Blue HIGH=on, LOW=off activityLED
    Serial.println("-> New Connection\n");        //Show status on monitor RS232
    boolean currentLineIsBlank = true;  //An http request ends with a blank line

    while (client.connected())  {           //Start reading incoming request LAN
      if (client.available()) {            //Already received next byte from LAN
        char c = client.read();                             //Read next byte LAN
        commandStr += c;            //Add received character to command INTERNET
        if (c == '\n' && currentLineIsBlank)  {  //Meaning request has ended LAN
           Serial.print("Instructie1: ");
           Serial.println(commandStr);
           break;                                 //We are done here so continue
        } //End of if (c == '\n' && currentLineIsBlank) //Meaning end of request
        if (c == '\n') {  //Request has not ended yet you're starting a new line
          currentLineIsBlank = true;  //Now check if next one is also blank line
        } else if (c != '\r') {  //You've gotten a character on the current line
          currentLineIsBlank = false;  //So next character cannot finish request
        } //End of if (c == '\n') {                  //Request has not ended yet
      } //End of if (client.available())   //Already received next byte from LAN
    } //End of  while (client.connected())  //Start reading incoming request LAN

    if (isDigit(commandStr[6])){              //Check if we received any command
      tempo = commandStr.substring(6, 10);           //Extract command 0001-9999
      command = tempo.toInt();          //Translate the function to a executable
           Serial.print("Instructie2: "); 
           Serial.println(command); 
      switch (command) {                         //Go to the according procedure

            case 131: //*********************** Instructie 131 => WATERSLOT1 off
              tuinWater1prog = 1;      //0=unknown, 1=off, 2=on, 3=auto, set OFF
              EEPROM.write(4, tuinWater1prog);       //Write 1 byte into EEPROM
              //setRelay1();                  //Switch, calculate and set RELAY1
              setSprinkler();    //Switch sprinkler ON/OFF according to settings
            break; //case 131:                  Instructie 131 => WATERSLOT1 off

            case 132: //************************ Instructie 132 => WATERSLOT1 on
              tuinWater1prog = 2;       //0=unknown, 1=off, 2=on, 3=auto, set ON
              EEPROM.write(4, tuinWater1prog);       //Write 1 byte into EEPROM
              //setRelay1();                  //Switch, calculate and set RELAY1
              setSprinkler();    //Switch sprinkler ON/OFF according to settings
            break; //case 132:                   Instructie 132 => WATERSLOT1 on
            
            case 133: //********************** Instructie 133 => WATERSLOT1 auto
              tuinWater1prog = 3;     //0=unknown, 1=off, 2=on, 3=auto, set AUTO
              EEPROM.write(4, tuinWater1prog);       //Write 1 byte into EEPROM
              //setRelay1();                  //Switch, calculate and set RELAY1
              setSprinkler();    //Switch sprinkler ON/OFF according to settings
            break; //case 133:                 Instructie 133 => WATERSLOT1 auto

            case 134: //*** Instructie 134 => Minuten per sproeibeurt WATERSLOT1
              tempo = commandStr.substring(11, 15);//Extract parameter 0000-0256
              tuinWater1spray = tempo.toInt();    //Convert to decimal PARAMETER
              EEPROM.write(5, tuinWater1spray);      //Write 1 byte into EEPROM
              //setRelay1();        //GROEILED1 switch, calculate and set RELAY1
              setSprinkler();    //Switch sprinkler ON/OFF according to settings
            break; //Case 84             Instructie 84 => Set Aantal uur per dag


        case 139: //************************ Adjust clock with given time DS1302
          tuinKlok = "";     //Formatteer zowel nieuw antwoord alsook zetformaat
            tmp = commandStr.substring(10, 14);       //Extract jaar naar string
            tuinKlok = tmp;                         //Voeg toe aan http response
            tuinKlok += "-";                        //Voeg toe aan http response
            int jaar = tmp.toInt();            //Maak een bruikbare klok setting

            tmp = commandStr.substring(15, 17);      //Extract maand naar string
            tuinKlok += tmp;
            tuinKlok += "-";
            int maand = tmp.toInt();           //Maak een bruikbare klok setting

            tmp = commandStr.substring(18, 20);        //Extract dag naar string
            tuinKlok += tmp;
            tuinKlok += " ";
            int dag = tmp.toInt();             //Maak een bruikbare klok setting
              
            tmp = commandStr.substring(21, 23);        //Extract uur naar string
            tuinKlok += tmp;
            tuinKlok += ":";
            int uur = tmp.toInt();             //Maak een bruikbare klok setting

            tmp = commandStr.substring(24, 26);     //Extract minuut naar string
            tuinKlok += tmp;
            tuinKlok += ":";
            int minuut = tmp.toInt();          //Maak een bruikbare klok setting

            tmp = commandStr.substring(27, 29);    //Extract seconde naar string
            tuinKlok += tmp;
            int seconde = tmp.toInt();         //Maak een bruikbare klok setting

            //Time t(jaar, maand, dag, uur, minuut, seconde, Time::kWednesday);
            //rtc.time(t);                   //Set the time and date on the chip
         break; //End of case 209:           Adjust clock with given time DS1302

      } //End of the list with possible precedures -----------------------------
    } //End of if (isDigit(commandStr[5]))      Check if we received any command

    Serial.println("   sendHttpResponse");                   //Show status RS232
    sendHttpResponse();                                  //Sends measurementsLAN
    Serial.println("   Done sendHttpResponse");                   //Status RS232
    delay(10);               //Give the web browser time to receive the data LAN
    client.stop();                                        //Close the connection
    Serial.println("   Disconnected\n");         //Show status on monitor RS232
    digitalWrite(ledBluPin, LOW);            //Blue HIGH=on, LOW=off activityLED
  } //End of if (client) {                     //We have an internet request LAN
} //Exit checkInternet ---------------------------------------------------------



void sendHttpResponse() {  //Sends measurements LAN ****************************
  refreshAnswer();                    //Replace the old answer by a new one DATA
  client.println("HTTP/1.1 200 OK");      //Start answer to the request INTERNET
  client.println("Connection: close");   //Close after html is finished INTERNET
  client.print("Content-Length: "); //Finish html after amount of chars INTERNET
  client.println (bodyLength);    //The amount of calculated characters INTERNET
  client.println("Content-Type: text/html");  //Needed to be compatible INTERNET
  client.println(" /n \n");                 //Needed to end the headers INTERNET
  client.println(html);  //Broadcast the message to be shown in browser INTERNET
} //Exit sendHttpResponse ------------------------------------------------------



void setSprinkler(void){ //Switches sprinkler ON or OFF according to settings **
  if (tuinWater1prog == "3"){         //If the AUTO mode is selected then 3=AUTO
    if (tuinLDR < tuinLDRtreshold){                 //And only if it is dark LDR
        tuinRelay2 = 1;                                   //Switch the relay OFF
      }else{                                             //So it is not dark yet
        tuinRelay2 = 1;                                   //Switch the relay OFF
      }  //End of  if (ldrVal > ldrTrs){            //And only if it is dark LDR
  }else{ //Meaning (prgVal1 <> "2"){       Meaning the AUTO mode is not selected
     if (tuinWater1prog == "1"){      //If the currently chosen program is 1=OFF
      tuinRelay2 = 1;                                        //Switch relay2 OFF
    }                   //End of calculating sprinkler setting for program 1=OFF
    
    if (tuinWater1prog == "2"){        //If the currently chosen program is 2=ON
      tuinRelay2 = 0;                                      //Switch the relay ON
    }                   //End of calculating sprinkler settings for program 1=ON
  } //End of (prgVal1 == "2"){        //If the AUTO mode is selected then 2=AUTO
  
  if (tuinRelay2 == 1){                                      //Switch OFF RELAY2
    digitalWrite(ledGrePin,0);                            //Switch OFF GREEN LED
    digitalWrite(Relay2Pin, 1);        //Turn the sprinkler ON=0 or OFF=1 RELAY2
    
  }else{                                                 //Else switch ON RELAY2
    analogWrite(ledGrePin,10);                             //Switch ON green LED
    digitalWrite(Relay2Pin, 0);        //Turn the sprinkler ON=0 or OFF=1 RELAY2
  } //End of if (Relay2val == "1"){                              //Switch RELAY2
} //Exit setSprinkler ----------------------------------------------------------

 

void toggleBlueLed(void){ //Toggles ON or OFF the blue LED *********************
  if (ledBlueVal > 0){
    ledBlueVal = 0;
    digitalWrite(ledBluPin, 0);               //Set according to switch blue LED
  }else{
    ledBlueVal = 20;                                              //Toggle value
    analogWrite(ledBluPin, ledBlueVal);       //Set according to switch blue LED
  }
} //Exit toggle_ledBin ---------------------------------------------------------



void sprinkler_timer(void) { //Check what we should do with the sprinkler RELAY2
  if (tuinRelay2 == HIGH) {       //Menaning it is OFF, See if must switch it on
    if (clocktime > starttime and clocktime < finishtime) {  //Switch conditions
       tuinRelay2 = LOW;                     //Set the value to switch ON RELAY2
       digitalWrite(Relay2Pin, tuinRelay2);                   //Switch ON RELAY2
       analogWrite(ledGrePin, 50);                           //Turn ON green LED
       beep(30);                       //Create a beep with KY-012 active BUZZER
    }            //End of  if (clocktime >= starttime and clocktime < finishtime
  }else{   //Else of (Relay2val == HIGH) Meaning it is ON,see if must switch OFF
    if (clocktime > finishtime) {                        //Switch OFF conditions
       tuinRelay2 = HIGH;                   //Set the value to switch OFF RELAY2
       digitalWrite(Relay2Pin, tuinRelay2);                  //Switch OFF RELAY2
       analogWrite(ledGrePin, 0);                           //Turn OFF green LED
       beep(30);                       //Create a beep with KY-012 active BUZZER
    } //End of if (clocktime > finishtime) {             //Switch OFF conditions
  } //End of else of (Relay2val == HIGH) Meaning it is ON,see if must switch OFF
} //Exit refreshAnswer replace the old answer by a new one WIFI ----------------



void refreshAnswer(void) { //Replace the old answer by a new one ***************
  html  = String(tuinKlok) + " ";                      //First all sensor values
  html += String(tuinSoilTemp) + " ";
  html += String(tuinLDR) + " ";
  html += String(tuinRelay1) + " ";                   //Next all output settings
  html += String(tuinRelay2) + " ";
  html += String(tuinRelay3) + " ";
  html += String(tuinRelay4) + " ";
  html += String(tuinLDRtreshold) + " ";             //Finally All user settings
  html += String(tuinWaterDelay) + " ";   
  html += String(tuinWater1prog) + " "; 
  html += String(tuinWater1spray) + " ";
  html += String(tuinWater2prog) + " "; 
  html += String(tuinWater2spray) + " ";
  html += String(tuinWater3prog) + " "; 
  html += String(tuinWater3spray) + " ";
  html += String(tuinWater4prog) + " "; 
  html += String(tuinWater4spray) + " ";
  bodyLength = html.length();    //Calculate the number of characters to be sent
} //Exit refreshAnswer replace the old answer by a new one ---------------------


void readTime(){ //DS1302 Reading the time and format results into variables ***
   Time t = rtc.time();            //Get the current time and date from the chip
   snprintf(buf, sizeof(buf), "%04d-%02d-%02d %02d:%02d:%02d",       //Format as
           t.yr, t.mon, t.date,       //Desired by the Pgsql timestamp data type
           t.hr, t.min, t.sec);
   tuinKlok = buf ;                  //Used to export to the postgreSQL database
   snprintf(buf, sizeof(buf), "%02d:%02d", t.hr, t.min);  //Format as timeswitch
   clocktime = buf;                               //Used to calculate the switch
} //End of DS1302 Reading the time and format results into variables -----------




void DS1820_read(void) { //Reads the temperature from DS1820 in Celsius ********
  term1.reset();                              //Reset whatever still was running
  term1.select(addr1);                      //Set the parameters for the library
  term1.write(0x44);       //Start conversion, with parasite power on at the end
  delay(800);     //Maybe 750ms is enough, maybe not, takes a lot of time though
  present = term1.reset();              //We assume that the conversion is ready
  term1.select(addr1);                      //Set the parameters for the library
  term1.write(0xBE);                                          // Read Scratchpad
  for ( i = 0; i < 9; i++) {                                   //We need 9 bytes
    data[i] = term1.read();
  }
  int16_t raw = (data[1] << 8) | data[0];                      //Rotate the data
  tuinSoilTemp = (float)raw / 16.0;    //Untill they are in the correct position
} //Exit DS1820_read -----------------------------------------------------------



void DS1820_init(void) { //Determins the type of DS1820 thermometer1 ***********
  if (!term1.search(addr1)) {
    term1.reset_search();
    delay(250);
    return;
  }
  if (OneWire::crc8(addr1, 7) != addr1[7]) {
      return;
  }
  switch (addr1[0]) {         //The first ROM byte indicates which  tupe of chip
    case 0x10:
      type1_s = 1;
      break;
    case 0x28:
      type1_s = 0;
      break;
    case 0x22:
      type1_s = 0;
      break;
    default:
      return;
  } 
  term1.reset();
  term1.select(addr1);
  term1.write(0x44, 1);    //Start conversion, with parasite power on at the end
  delay(800);     //Maybe 750ms is enough, maybe not, takes a lot of time though
  present = term1.reset();
  term1.select(addr1);    
  term1.write(0xBE);                                           //Read Scratchpad
  for ( i = 0; i < 9; i++) {                                   //We need 9 bytes
    data[i] = term1.read();
  }

  int16_t raw = (data[1] << 8) | data[0];
  if (type1_s) {
    raw = raw << 3; // 9 bit resolution default
    if (data[7] == 0x10) {       // "count remain" gives full 12 bit resolution
      raw = (raw & 0xFFF0) + 12 - data[6];
    }
  } else {     //// default is 12 bit resolution, 750 ms conversion time
    byte cfg = (data[4] & 0x60);     
    // at lower res, the low bits are undefined, so let's zero them
    if (cfg == 0x00) raw = raw & ~7;  // 9 bit resolution, 93.75 ms
    else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
    else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
  }
  tuinSoilTemp = (float)raw / 16.0;
} //Exit DS1820_init -----------------------------------------------------------


/*

void EEPROMfirstTime() { //First time use, write values into EEPROM ************
  EEPROM.write( 1, 40);    //tuinLDRtreshold *10 to switch DAY=0/NIGHT=1023 LDR
  EEPROM.write( 2, 30);                //Number of minutes delay after dark ALL
  EEPROM.write( 3,  1);//tuinWater1prog WATER1 program 1=off 2=on 3=auto RELAY1
  EEPROM.write( 4, 10);     //tuinWater1spray Number of minutes water on RELAY1
  EEPROM.write( 5,  1);//tuinWater2prog WATER2 program 1=off 2=on 3=auto RELAY2
  EEPROM.write( 6, 10);     //tuinWater2spray Number of minutes water on RELAY2
  EEPROM.write( 7,  1);//tuinWater3prog WATER3 program 1=off 2=on 3=auto RELAY3
  EEPROM.write( 8, 10);     //tuinWater3spray Number of minutes water on RELAY3
  EEPROM.write( 9,  1);//tuinWater4prog WATER4 program 1=off 2=on 3=auto RELAY4
  EEPROM.write(10, 10);     //tuinWater4spray Number of minutes water on RELAY4
} //Exit EEPROMfirstTime -------------------------------------------------------

*/

void show_LAN(){ //Shows DHCP settings of LAN **********************************
  Serial.print  ("Ethernet.localIP: ");
  Serial.println(Ethernet.localIP());
} //Exit test_LAN --------------------------------------------------------------


void test_RELAY(){ //Switches ON for 2 seconds all RELAY ***********************
  digitalWrite(Relay1Pin, LOW);                         //Switches ON the RELAY1
  delay (2000);                                             //Wait for 2 seconds
  digitalWrite(Relay1Pin, HIGH);                       //Switches OFF the RELAY1
  digitalWrite(Relay2Pin, LOW);                         //Switches ON the RELAY2
  delay (2000);                                             //Wait for 2 seconds
  digitalWrite(Relay2Pin, HIGH);                       //Switches OFF the RELAY2
  digitalWrite(Relay3Pin, LOW);                         //Switches ON the RELAY3
  delay (2000);                                             //Wait for 2 seconds
  digitalWrite(Relay3Pin, HIGH);                       //Switches OFF the RELAY3
  digitalWrite(Relay4Pin, LOW);                         //Switches ON the RELAY4
  delay (2000);                                             //Wait for 2 seconds
  digitalWrite(Relay4Pin, HIGH);                       //Switches OFF the RELAY4
} //End of test_Relay(){ Switches ON for 2 seconds the RELAY -------------------




void test_LEDs(void){ //PWM fade in and fade out for all 4 LEDs on board *******
  brillance = 0;                 //Brightness of any color, just to test PWM LED

  while (brillance<255){
    analogWrite(ledRedPin, brillance);        //Set LED to desired PWM value RED
    brillance++;
    delay (msWait);
  }
  while (brillance>0){
    analogWrite(ledRedPin, brillance);        //Set LED to desired PWM value RED
    brillance--;
    delay (msWait);
  }
  analogWrite(ledRedPin, 0);            //Set LED to desired PWM value = off RED

  while (brillance<255){
    analogWrite(ledGrePin, brillance);      //Set LED to desired PWM value GREEN
    brillance++;
    delay (msWait);
  }
  while (brillance>0){
    analogWrite(ledGrePin, brillance);      //Set LED to desired PWM value GREEN
    brillance--;
    delay (msWait);
  }
  analogWrite(ledGrePin, 0);          //Set LED to desired PWM value = off GREEN

  while (brillance<255){
    analogWrite(ledBluPin, brillance);       //Set LED to desired PWM value BLUE
    brillance++;
    delay (msWait);
  }
  while (brillance>0){
    analogWrite(ledBluPin, brillance);       //Set LED to desired PWM value BLUE
    brillance--;
    delay (msWait);
  }
  analogWrite(ledBluPin, 0);           //Set LED to desired PWM value = off BLUE

  while (brillance<255){
    analogWrite(LED_BUILTIN, brillance);  //Set to desired PWM value LED_BUILTIN
    brillance++;
    delay (msWait);
  }
  while (brillance>0){
    analogWrite(LED_BUILTIN, brillance);  //Set to desired PWM value LED_BUILTIN
    brillance--;
    delay (msWait);
  }
  analogWrite(LED_BUILTIN, 0);  //Set LED to desired PWM value = off LED_BUILTIN
} //Exit test_LEDs -------------------------------------------------------------

void beep(uint8_t ms) {      //Create a beep (x5ms) with KY-012 active BUZZER **
  digitalWrite(buzActPin,HIGH);                                 //Turn on BUZZER
  while (ms > 0){                     //Timer of the duration of the beep BUZZER
    delay(5);                                         //Wait milliseconds BUZZER
    ms--;                              //Countdown untill we reached zero BUZZER
  }                 //Timer of the duration has been counted down to zero BUZZER
  digitalWrite(buzActPin,LOW);                  //Turn annoying sound off BUZZER
} //Exit beep ------------------------------------------------------------------



void toggle_ledOnBoard(void){ //Toggles the LED_BUILTIN on-board LED on or off *
  ledOnBoardVal = !ledOnBoardVal;                                 //Toggle value
  digitalWrite(LED_BUILTIN, ledOnBoardVal);     //Set Arduino boards onboard LED
} //Exit toggle_ledBin ---------------------------------------------------------




void disable_jtag(void) { //Disable jtag to free port C, enabled by default ****
#if defined(JTD)                           //Not all AVR controller include jtag
  MCUCR |= ( 1 << JTD );                                //Write twice to disable
  MCUCR |= ( 1 << JTD );                                       //So stutter once
#endif                                            //End of conditional compiling
} //Exit jtag_disable ----------------------------------------------------------




////////////////////////////////////////////////////////////////////////////////
// PIN ALLOCATIONS TABLE ARDUINO UNO                                          //
// Board -Atmel- PIN - IDE - Function          - Connection               ALT //
//                                                                            //
// CONNECTIONS RAILS TOP LEFT: DIGITAL PWM<~> ******************************* //
// SCL   -  28 - PC5 -19/A5- ADC5/SCL/PCINT13  -                          TWI //
// SDA   -  27 - PC4 -18/A4- ADC4/SDA/PCINT12  -                          TWI //
// AREF  -  21 - REF -     - AREF              -                              //
// GND   -  22 - GND -     - GND               -                              //
// 13    -  19 - PB5 -  13 - SCK/PCINT5        - LAN SPI SCK  LED_BUILTIN/SPI //
// 12    -  18 - PB4 -  12 - MISO/PCINT4       - LAN SPI MISO             SPI //
// ~11   -  17 - PB3 -  11 - MOSI/OC2A/PCINT3  - LAN SPI MOSI             PWM //
// ~10   -  16 - PB2 -  10 - SS/OC1B/PCINT2    - LSN SPI SS               PWM //
// ~9    -  15 - PB1 -   9 - OC1A/PCINT1       - DS1302 CLK               PWM //
// 8     -  14 - PB0 -   8 - PCINT0/CLK0/ICP1  - DS1302 RST               DIO //
//                                                                            //
// CONNECTIONS RAILS TOP RIGHT: DIGITAL PWM<~> ****************************** //
// 7     -  13 - PD7 -   7 - PCINT23/AIN1      - DS1302 DAT               DIO //
// ~6    -  12 - PD6 -   6 - PCINT22/OCA0/AIN0 - ledBluPin                PWM //
// ~5    -  11 - PD5 -   5 - PCINT21/OC0B/T1   - ledGrePin                PWM //
// ~4    -   6 - PD4 -   4 - PCINT20/XCK/T0    - ledRedPin                PWM //
// ~3    -   5 - PD3 -   3 - PCINT19/OC2B/INT1 - buzActPin                INT //
// ~2    -   4 - PD2 -   2 - PCINT18/INT0      -                          INT //
// TX->1 -   3 - PD1 -   1 - PCINT17/TXD       - Serial monitor           TXD //
// RX<-0 -   2 - PD0 -   0 - PCINT16/RCD       - Serial monitor           RCD //
//                                                                            //
// CONNECTIONS RAILS BOTTOM LEFT: POWER ************************************* //
// 5V    -   7 - VCC -      - VCC              - Output to breadboard     VCC //
// RES   -   1 - RES -      - PCINT14/RESET    -                          RES //
// 3.3V  -     -     -     -                   -                              //
// 5V    -     -     -     -                   -                              //
// GND   -     -     -     -                   -                              //
// GND   -     -     -     -                   -                              //
// Vin   -     -     -     -                   -                              //
//                                                                            //
// CONNECTIONS RAILS BOTTOM RIGHT: ANALOG IN ******************************** //
// A0    -  23 - PC0 -A0/14- ADC0/PCINT8       - DS18B20                  ADC //
// A1    -  24 - PC1 -A1/15- ADC1/PCINT9       - ldrPin                   ADC //
// A2    -  25 - PC2 -A2/16- ADC2/PCINT10      - Relay1                   ADC //
// A3    -  26 - PC3 -A3/17- ADC3/PCINT12      - Relay2                   ADC //
// A4    -  27 - PC4 -A4/18- ADC4/SDA/PCINT12  - Relay3                   TWI //
// A5    -  28 - PC5 -A5/19- ADC5/SCL/PCINT13  - Relay4                   TWI //
////////////////////////////////////////////////////////////////////////////////
// EEPROM MEMORY MAP:                                                         //
// Start End  Number Description                                              //
// 0000  0000      1   Never use this memory location to be AVR compatible    //
// 0001  0001      1   tuinLDRtreshold *10 to switch DAY=0/NIGHT=1023     LDR //
// 0002  0002      1   Number of minutes tuinWaterDelay after dark        ALL //
// 0003  0003      1 WATER1 tuinWater1prog program 1=off 2=on 3=auto   RELAY1 //
// 0004  0004      1   Number of minutes tuinWater1spray water on      RELAY1 //
// 0005  0005      1 WATER2 tuinWater2prog program 1=off 2=on 3=auto   RELAY2 //
// 0006  0006      1   Number of minutes tuinWater2spray water on      RELAY2 //
// 0007  0007      1 WATER3 tuinWater3prog program 1=off 2=on 3=auto   RELAY3 //
// 0008  0008      1   Number of minutes tuinWater3spray water on      RELAY3 //
// 0009  0009      1 WATER4 tuinWater4Pprog program 1=off 2=on 3=auto  RELAY4 //
// 0010  0010      1   Number of minutes tuinWater4spray water on      RELAY4 //
////////////////////////////////////////////////////////////////////////////////
//345678911234567892123456789312345678941234567895123456789612345678971234567898
////////////////////////////////////////////////////////////////////////////////
// FUSES (can always be altered by using the STK500)                          //
// On-Chip Debug Enabled: off                            (OCDEN=0)            //
// JTAG Interface Enabled: off                           (JTAGEN=0)           //
// Preserve EEPROM mem through the Chip Erase cycle: On  (EESAVE = 0)         //
// Boot Flash section = 2048 words, Boot startaddr=$3800 (BOOTSZ=00)          //
// Boot Reset vector Enabled, default address=$0000      (BOOTSTR=0)          //
// CKOPT fuse (operation dependent of CKSEL fuses        (CKOPT=0)            //
// Brown-out detection level at VCC=2,7V;                (BODLEVEL=0)         //
// Ext. Cr/Res High Freq.; Start-up time: 16K CK + 64 ms (CKSEL=1111 SUT=11)  //
//                                                                            //
// LOCKBITS (are dangerous to change, since they cannot be reset)             //
// Mode 1: No memory lock features enabled                                    //
// Application Protect Mode 1: No lock on SPM and LPM in Application Section  //
// Boot Loader Protect Mode 1: No lock on SPM and LPM in Boot Loader Section  //
////////////////////////////////////////////////////////////////////////////////