////////////////////////////////////////////////////////////////////////////////
// Name:       FloraPropagator2560-03 2019 ETHERNET version                   //
// http://robotigs.com/robotigs/includes/bots_header.php?idbot=17             //
//             Robot that controls propagator                                 //
// Created by: HARB rboek2@gmail.com march 2019 GPL copyrights                //
// Platform:   Arduino Mega 2560                                              //
// 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:                               //
// - DS1307 Real Time Clock                                                   //
//           http://robotigs.nl/robotigs/includes/parts_header.php?idpart=289 //
// - DHT22 air temperature and air humidity sensor                            //
//           http://robotigs.nl/robotigs/includes/parts_header.php?idpart=252 //
// - Temp DS18B20                                                             //
//           http://robotigs.nl/robotigs/includes/parts_header.php?idpart=180 //
// 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 WATER propWaterProg program 1=off 2=on 3=auto     RELAY1 //
// 0002  0002      1   If capac1 reaches this propWaterON*10 then set  RELAY1 //
// 0003  0003      1   Number seconds*10 propWaterSecs water on        RELAY1 //
// 0004  0004      1 GROEILED1 propLED1Prog program 1=off 2=on 3=auto  RELAY2 //
// 0005  0005      1   Number of propLED1hours around noon groeiled1   RELAY2 //
// 0006  0006      1 VERWARMING propHeatProg program 1=off 2=on 3=auto RELAY3 //
// 0007  0007      1   propHeatON/10 (0-25,5) aanschakeltemperatuur    RELAY3 //
// 0008  0008      1   propHeatOFF/10 (0-25,5) uitschakeltemperatuur   RELAY3 //
// 0009  0009      1 GROEILED2 propLED2prog program 1=off 2=on 3=auto  RELAY4 //
// 0010  0010      1   Number of propLED2hours around noon groeiled2   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 <DHT.h> //Needed for DHT22 and DHT11 Temperature and humidity sensors
             // http://robotigs.nl/robotigs/includes/parts_header.php?idpart=252
  #include <EEPROM.h>                       //Needed for read or write in EEPROM
             // http://robotigs.nl/robotigs/includes/parts_header.php?idpart=312
  #include <RTClib.h>        //Manipulates clock DS1307 via I2C needs Wire.h lib
             // http://robotigs.nl/robotigs/includes/parts_header.php?idpart=289
  #include <Wire.h>                //Needed ao by RTClib: Two Wire Interface lib
              // http://robotigs.nl/robotigs/includes/parts_header.php?idpart=31
  #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(17);         //Connects to pin 17, but may be any DIO pin DS1820
  #define buzActPin    A7          //Define DIO output pin connects ACTIV BUZZER
  #define DHTPIN        4                   //Which DIO input pin connects DHT22
  #define DHTTYPE   DHT22     //What sensor is connected (AM2302) (AM2321) DHT22
  #define ledRedPin    44         //3 Colour LED, which PWM pin connects RED LED
  #define ledGrePin    45       //3 Colour LED, which PWM pin connects GREEN LED
  #define ledBluPin    46        //3 Colour LED, which PWM pin connects BLUE LED
  #define Relay1Pin    34    //220Vac DIO output pin connects WATER KAPOT RELAY1
  #define Relay2Pin    36               //220Vac DIO output pin GROEILED1 RELAY2
  #define Relay3Pin    38     //220Vac DIO output pin connects VERWARMING RELAY3
  #define Relay4Pin    40      //220Vac DIO output pin connects GROEILED2 RELAY4
  #define moistPin     A8        //Analog input pin connects CAPACATIVE MOISTURE
  #define moist2Pin    A9      //Analog input pin connects CAPACATIVE 2 MOISTURE
  #define moist3Pin   A10      //Analog input pin connects CAPACATIVE 3 MOISTURE

  //Define EEPROM variables ----------------------------------------------------
  int    propWaterProg  = 1;    //WATER current program 1=off 2=on 3=auto RELAY1
  int    propWaterON    = 41;    //If capac1 reaches this treshold*10 set RELAY1
  int    propWaterSecs  = 16;           //Seconds*10 water will switch ON RELAY1
  int    propLED1Prog   = 1;        //GROEILED1 program 1=off 2=on 3=auto RELAY2
  int    propLED1hours  = 14;               //Hours around noon groeiled1 RELAY2
  int    propHeatProg   = 1;       //VERWARMING program 1=off 2=on 3=auto RELAY3
  int    propHeatON     = 200;             //Temperature/10 verwarming ON RELAY3
  int    propHeatOFF    = 220;            //Temperature/10 verwarming OFF RELAY3
  int    propLED2prog   = 1;        //GROEILED2 program 1=off 2=on 3=auto RELAY4
  int    propLED2hours  = 10;               //Hours around noon groeiled2 RELAY4
  
  //Define DATABASE VARIABLES --------------------------------------------------
  String propKlok;                                             //DateTime DS1307
  float  propSoilTemp;                     //Soil temperature in Celsius DS18B20
  float  propAirTemp;                     //Air temperature degree Celcius DHT22
  float  propAirHum;                             //Air humidity percentage DHT22
  bool   propRelay1     = HIGH;         //Status HIGH=off or LOW=on WATER RELAY1
  bool   propRelay2     = HIGH;             //Status 1=off, 0=on GROWLED2 RELAY2
  bool   propRelay3     = HIGH;           //Status HI=off, LW=on HEATCOIL RELAY3
  bool   propRelay4     = HIGH;          //Status HI=off, LOW=on GROWLED1 RELAY4
  word   propCapac1;                      //Moisture measured (0-1023) by CAPAC1
  word   propCapac1Min  = 1023;    //Min moisture measured in sequence by CAPAC1
  word   propCapac1Max  =    0;    //Max moisture measured in sequence by CAPAC1
  word   propCapac2;                               //Moisture measured by CAPAC2
  word   propCapac2Min  = 1023;    //Min moisture measured in sequence by CAPAC2
  word   propCapac2Max  =    0;    //Max moisture measured in sequence by CAPAC2
  word   propCapac3;                               //Moisture measured by CAPAC3
  word   propCapac3Min  = 1023;    //Min moisture measured in sequence by CAPAC3
  word   propCapac3Max  =    0;    //Max moisture measured in sequence by CAPAC3

  //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 inStri         = "No answer received";        //Default answer of ESP01
  uint8_t mac[6]        = {0x00,0x01,0x02,0x03,0x04,0x05};                 //LAN
                            // Ethernet MAC address - must be unique on your LAN
  char   buf[100];                //Needed to display the date/time stamp DS1307
  int    starthours1;                                 //Switch ON clock GROWLED1
  int    finishhours1;                               //Switch OFF clock GROWLED1
  int    starthours2;                                 //Switch ON clock GROWLED2
  int    finishhours2;                               //Switch OFF clock GROWLED2
  int    currenthour;      //Compare with starthours and finishhours for GROWLED
  word   readCounter    = 0;      //Read sensors if counted down to zero SENSORS
  word   readTimer      = 9999;   //Fill readCounter after reaching zero SENSORS
  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
  static unsigned long SwitchOFFtimer = millis()+ 300000;             //WATERING
  String tmp            = "";                             //Can be used anywhere
  String tempo          = "";                             //Can be used anywhere
  int    tmp1;                                            //Can be used anywhere
  int    tmp2;                                            //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
  DHT dht(DHTPIN, DHTTYPE);                     //Initialize sensor object DHT22
  DS1307 rtc;                         //Initialize Real Time Clock object DS1307
//END OF PRECOMPILER OPTIONS ---------------------------------------------------



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

  //EEPROMfirstTime();                    //First time use, set values in EEPROM
  propWaterProg  = EEPROM.read(1);      //WATER program 1=off 2=on 3=auto RELAY1
  propWaterON    = EEPROM.read(2);    //If capac1 reaches treshold*10 set RELAY1
  propWaterSecs  = EEPROM.read(3);      //Seconds*10 water will switch ON RELAY1
  propLED1Prog   = EEPROM.read(4);  //GROEILED1 program 1=off 2=on 3=auto RELAY2
  propLED1hours  = EEPROM.read(5);          //Hours around noon groeiled1 RELAY2
  calculateGrowLED1();              //Calculate start and finisch clock GROWLED1
  propHeatProg   = EEPROM.read(6); //VERWARMING program 1=off 2=on 3=auto RELAY3
  propHeatON     = EEPROM.read(7);         //Temperature/10 verwarming ON RELAY3
  propHeatOFF    = EEPROM.read(8);        //Temperature/10 verwarming OFF RELAY3
  propLED2prog   = EEPROM.read(9);  //GROEILED2 program 1=off 2=on 3=auto RELAY4
  propLED2hours  = EEPROM.read(10);         //Hours around noon groeiled2 RELAY4
  calculateGrowLED2();              //Calculate start and finisch clock GROWLED2
  
  pinMode(LED_BUILTIN, OUTPUT);  //Arduino boards contain an onboard LED_BUILTIN
  pinMode(buzActPin, OUTPUT);                 //Set this pin as output to BUZZER
  pinMode(ledRedPin, OUTPUT);                 //Set this pin as output to redLED
  pinMode(ledBluPin, OUTPUT);                //Set this pin as output to blueLED
  pinMode(ledGrePin, OUTPUT);               //Set this pin as output to greenLED
  analogReference(INTERNAL2V56);             //Reduced to measure moisture CAPAC

  pinMode(Relay1Pin, OUTPUT);                 //Set this pin as output to RELAY1
  digitalWrite(Relay1Pin, propRelay1);                 //Switches OFF the RELAY1
  pinMode(Relay2Pin, OUTPUT);                 //Set this pin as output to RELAY2
  digitalWrite(Relay2Pin, propRelay2);                 //Switches OFF the RELAY2
  pinMode(Relay3Pin, OUTPUT);                 //Set this pin as output to RELAY3
  digitalWrite(Relay3Pin, propRelay3);                 //Switches OFF the RELAY3
  pinMode(Relay4Pin, OUTPUT);                 //Set this pin as output to RELAY4
  digitalWrite(Relay4Pin, propRelay4);                 //Switches OFF the RELAY4

  Wire.begin();                 //Start the Two Wire Interface object I2C DS1307
  writeI2CRegister8bit(0x20, 6);     //Reset sensor to tell it is a slave DS1307
  dht.begin();                               //Start sensor object running DHT22
  Serial.begin(57600);        //Nothing more needed for the Serial Monitor RS232


  //Start objects --------------------------------------------------------------
  rtc.begin();    //Initialize Wire.begin first. Start the object running DS1307
  //rtc.adjust(DateTime(__DATE__, __TIME__));      //Set to time compiled DS1307
  Ethernet.begin(mac);              //Create connection  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
  DS1820_init();      //Determins the type of DS1820 and reads properties DS1820
  test_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  *****************************
  DateTime now = rtc.now();  //Read the current time into the object from DS1307
  strncpy(buf,"YYYY-MM-DD hh:mm:ss\0",100);  //Format string for the time DS1307
  propKlok = now.format(buf);       //Format the timestap into a variable DS1307
  strncpy(buf,"hh\0",100);                  //Format string for the time GROWLED
  tempo = now.format(buf);         //Format the timestap into a variable GROWLED
  currenthour = tempo.toInt();          //Convert to value for switching GROWLED
  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
    DS1820_read();               //Reads the temperature in Celsius from DS18B20
    propAirTemp = dht.readTemperature();     //Read temperature as Celsius DHT22
    propAirHum = dht.readHumidity();      //Reading takes 250 milliseconds DHT22

    propCapac1 = analogRead(moistPin);        //Moisture measured by CAPACATIVE1
    if (propCapac1 < propCapac1Min){       //Do some statistics MOISTURE MINIMUM
      propCapac1Min = propCapac1;                         //Set MOISTURE MINIMUM
    }                                      //Do some statistics MOISTURE MINIMUM
    if (propCapac1 > propCapac1Max){       //Compare statistics MOISTURE MAXIMUM
      propCapac1Max = propCapac1;                         //Set MOISTURE MAXIMUM
    } //End of  if (propCapac1 > propCapacMax)  Some statistics MOISTURE MAXIMUM

    propCapac2 = analogRead(moist2Pin);       //Moisture measured by CAPACATIVE2
    if (propCapac2 < propCapac2Min){       //Do some statistics MOISTURE MINIMUM
      propCapac2Min = propCapac2;                         //Set MOISTURE MINIMUM
    }                                      //Do some statistics MOISTURE MINIMUM
    if (propCapac2 > propCapac2Max){       //Compare statistics MOISTURE MAXIMUM
      propCapac2Max = propCapac2;                         //Set MOISTURE MAXIMUM
    } //End of  if (propCapac2 > propCapac2Max) Some statistics MOISTURE MAXIMUM

    propCapac3 = analogRead(moist3Pin);       //Moisture measured by CAPACATIVE3
    if (propCapac3 < propCapac3Min){       //Do some statistics MOISTURE MINIMUM
      propCapac3Min = propCapac3;                         //Set MOISTURE MINIMUM
    }                                      //Do some statistics MOISTURE MINIMUM
    if (propCapac3 > propCapac3Max){       //Compare statistics MOISTURE MAXIMUM
      propCapac3Max = propCapac3;                         //Set MOISTURE MAXIMUM
    } //End of  if (propCapac2 > propCapac2Max) Some statistics MOISTURE MAXIMUM

    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

    if (propRelay1 == LOW){               //Plant needs watering, WATERING IS ON
      beep(1);                    //Create a test beep with KY-012 active BUZZER
    } //End of if (propRelay1 == LOW)       Plant needs watering, WATERING IS ON

    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();                       //WATERING switch, calculate and set RELAY1
  setRelay2();                       //GROWLED2 switch, calculate and set RELAY2
  setRelay3();                    //COIL HEATER switch, calculate and set RELAY3
  setRelay4();                       //GROWLED1 switch, calculate and set RELAY4
} //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 81: //************************** Instructie 81 => GROEILED1 off
              propLED1Prog = 1;        //0=unknown, 1=off, 2=on, 3=auto, set OFF
              EEPROM.write(4, propLED1Prog);          //Write 1 byte into EEPROM
              setRelay2();                    //Switch, calculate and set RELAY4
            break; //case 81:                     Instructie 91 => GROEILED1 off

            case 82: //*************************** Instructie 92 => GROEILED1 on
              propLED1Prog = 2;         //0=unknown, 1=off, 2=on, 3=auto, set ON
              EEPROM.write(4, propLED1Prog);          //Write 1 byte into EEPROM
              setRelay2();                    //Switch, calculate and set RELAY4
            break; //case 82:                      Instructie 92 => GROEILED1 on
            
            case 83: //************************* Instructie 93 => GROEILED1 auto
              propLED1Prog = 3;       //0=unknown, 1=off, 2=on, 3=auto, set AUTO
              EEPROM.write(4, propLED1Prog);          //Write 1 byte into EEPROM
              setRelay2();                    //Switch, calculate and set RELAY4
            break; //case 83:                    Instructie 93 => GROEILED1 auto

            case 84: //******* Instructie 94 => Set Aantal uur per dag GROEILED1
              tempo = commandStr.substring(11, 15);//Extract parameter 0000-0256
              propLED1hours = tempo.toInt();      //Convert to decimal PARAMETER
              EEPROM.write(5, propLED1hours);         //Write 1 byte into EEPROM
              calculateGrowLED1();  //Calculate start and finisch time GROEILED1
              setRelay2();          //GROEILED1 switch, calculate and set RELAY4
            break; //Case 84             Instructie 84 => Set Aantal uur per dag
            




            case 91: //************************ Instructie 91 => VERWARMING1 off
              propHeatProg = 1;        //0=unknown, 1=off, 2=on, 3=auto, set OFF
              EEPROM.write(6, propHeatProg);          //Write 1 byte into EEPROM
              setRelay3();                    //Switch, calculate and set RELAY3
            break; //case 91:                   Instructie 91 => VERWARMING1 off

            case 92: //************************* Instructie 92 => VERWARMING1 on
              propHeatProg = 2;         //0=unknown, 1=off, 2=on, 3=auto, set ON
              EEPROM.write(6, propHeatProg);          //Write 1 byte into EEPROM
              setRelay3();                    //Switch, calculate and set RELAY3
            break; //case 92:                    Instructie 92 => VERWARMING1 on
            
            case 93: //*********************** Instructie 93 => VERWARMING1 auto
              propHeatProg = 3;       //0=unknown, 1=off, 2=on, 3=auto, set AUTO
              EEPROM.write(6, propHeatProg);          //Write 1 byte into EEPROM
              setRelay3();                    //Switch, calculate and set RELAY3
            break; //case 93:                  Instructie 93 => VERWARMING1 auto

            case 94: //** Instructie 94 => Set aanschakeltemperatuur VERWARMING1
              tempo = commandStr.substring(11, 15);//Extract parameter 0000-0256
              propHeatON = tempo.toInt();         //Convert to decimal PARAMETER
              EEPROM.write(7, propHeatON);            //Write 1 byte into EEPROM
              setRelay3();                    //Switch, calculate and set RELAY3
            break; //Case 94          Instructie 94 => Set aanschakeltemperatuur

            case 95: //** Instructie 95 => Set uitschakeltemperatuur VERWARMING1
              tempo = commandStr.substring(11, 15);//Extract parameter 0000-0256
              propHeatOFF = tempo.toInt();        //Convert to decimal PARAMETER
              EEPROM.write(8, propHeatOFF);           //Write 1 byte into EEPROM
              setRelay3();                    //Switch, calculate and set RELAY3
            break; //Case 95          Instructie 95 => Set uitschakeltemperatuur





            case 101: //************************ Instructie 101 => GROEILED2 off
              propLED2prog = 1;        //0=unknown, 1=off, 2=on, 3=auto, set OFF
              EEPROM.write(9, propLED2prog);          //Write 1 byte into EEPROM
              setRelay4();                    //Switch, calculate and set RELAY4
            break; //case 101:                   Instructie 101 => GROEILED1 off

            case 102: //************************* Instructie 102 => GROEILED1 on
              propLED2prog = 2;         //0=unknown, 1=off, 2=on, 3=auto, set ON
              EEPROM.write(9, propLED2prog);          //Write 1 byte into EEPROM
              setRelay4();                    //Switch, calculate and set RELAY4
            break; //case 102:                    Instructie 102 => GROEILED1 on

            case 103: //*********************** Instructie 103 => GROEILED2 auto
              propLED2prog = 3;       //0=unknown, 1=off, 2=on, 3=auto, set AUTO
              EEPROM.write(9, propLED2prog);          //Write 1 byte into EEPROM
              setRelay4();                    //Switch, calculate and set RELAY4
            break; //case 103:                  Instructie 103 => GROEILED2 auto

            case 104: //***** Instructie 104 => Set Aantal uur per dag GROEILED2
              tempo = commandStr.substring(11, 15);//Extract parameter 0000-0256
              propLED2hours = tempo.toInt();      //Convert to decimal PARAMETER
              EEPROM.write(10, propLED2hours);        //Write 1 byte into EEPROM
              calculateGrowLED2();  //Calculate start and finisch time GROEILED2
              setRelay4();          //GROEILED2 switch, calculate and set RELAY4
            break; //Case 104           Instructie 104 => Set Aantal uur per dag





            case 111: //******************* Instructie 111 => BUITEN GEBRUIK off
              propWaterProg = 1;  //WATER propWaterProg 1=off 2=on 3=auto RELAY1
              EEPROM.write(1, propWaterProg);         //Write 1 byte into EEPROM
              setRelay1();                    //Switch, calculate and set RELAY1
            break; //case 111:              Instructie 111 => BUITEN GEBRUIK off

            case 112: //********************* Instructie 112=> BUITEN GEBRUIK on
              propWaterProg = 2;  //WATER propWaterProg 1=off 2=on 3=auto RELAY1
              EEPROM.write(1, propWaterProg);         //Write 1 byte into EEPROM
              setRelay1();                    //Switch, calculate and set RELAY1
            break; //case 112:               Instructie 112 => BUITEN GEBRUIK on

            case 113: //****************** Instructie 113 => BUITEN GEBRUIK auto
              propWaterProg = 3;  //WATER propWaterProg 1=off 2=on 3=auto RELAY1
              EEPROM.write(1, propWaterProg);         //Write 1 byte into EEPROM
              setRelay1();                    //Switch, calculate and set RELAY1
            break; //case 113:             Instructie 113 => BUITEN GEBRUIK auto

            case 114: //* Instructie 114 => Aanschakeltemperatuur BUITEN GEBRUIK
              tempo = commandStr.substring(11, 15);//Extract parameter 0000-0256
              propWaterON = tempo.toInt();        //Convert to decimal PARAMETER
              EEPROM.write(2, propWaterON);           //Write 1 byte into EEPROM
              setRelay1();                    //Switch, calculate and set RELAY1
            break; //Case 114        Instructie 114 => Set aanschakeltemperatuur

            case 115: //* Instructie 115 => Uitschakeltemperatuur BUITEN GEBRUIK
              tempo = commandStr.substring(11, 15);//Extract parameter 0000-0256
              propWaterSecs = tempo.toInt();      //Convert to decimal PARAMETER
              EEPROM.write(3, propWaterSecs);         //Write 1 byte into EEPROM
              setRelay1();                    //Switch, calculate and set RELAY1
            break; //Case 115        Instructie 115 => Set uitschakeltemperatuur

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

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

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

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

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

            rtc.adjust(DateTime(jaar, maand, dag, uur, minuut, seconde));
            // <----------------------SET TIME
         break; //End of case 209:           Adjust clock with given time DS1307

      } //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

    propCapac1Min   = 1023;   //RESET Statistics minimum moisture content CAPAC1
    propCapac1Max   =    0;   //RESET Statistics maximum moisture content CAPAC1
    propCapac2Min  = 1023;    //RESET Statistics minimum moisture content CAPAC2
    propCapac2Max  =    0;    //RESET Statistics maximum moisture content CAPAC2
    propCapac3Min  = 1023;    //RESET Statistics minimum moisture content CAPAC3
    propCapac3Max  =    0;    //RESET Statistics maximum moisture content CAPAC3
    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 refreshAnswer(void) { //Replace the old answer by a new one WIFI **********
  if (String(propAirTemp) == " NAN"){    //Correct answer if not connected DHT22
    propAirTemp = 99.1;      //Both temperature and humidity will affected DHT22
    propAirHum = -1;           //Humidity value gives status not connected DHT22
  }//End of String(propAirTemp) = " NAN" Answer corrected if not connected DHT22

  html =  (propKlok)+ " ";                                     //DateTime DS1307
  html += String(propSoilTemp) + " ";      //Soil temperature in Celsius DS18B20
  html += String(propAirTemp) + " ";      //Air temperature degree Celcius DHT22
  html += String(propAirHum) + " ";              //Air humidity percentage DHT22

  html += String(propRelay1) + " ";       //Status HIGH=off, LOW=on WATER RELAY1
  html += String(propRelay2) + " ";         //Status 1=off, 0=on GROWLED2 RELAY2
  html += String(propRelay3) + " ";       //Status HI=off, LW=on HEATCOIL RELAY3
  html += String(propRelay4) + " ";      //Status HI=off, LOW=on GROWLED1 RELAY4

  html += String(propWaterProg) + " ";      //Watering: 1=off 2=on 3=auto RELAY1
  html += String(propWaterON) + " ";     //If CAPAC reaches this treshold RELAY1
  html += String(propWaterSecs) + " ";      //How many seconds to keep ON RELAY1

  html += String(propLED1Prog) + " ";        //GrowLED1 1=off 2=on 3=auto RELAY2
  html += String(propLED1hours) + " ";      //Number of hours around noon RELAY2

  html += String(propHeatProg)+ " ";       //VERWARMING 1=off 2=on 3=auto RELAY3
  html += String(propHeatON) + " ";         //TTemperature/10 heatcoil ON RELAY3
  html += String(propHeatOFF) + " ";        //Temperature/10 heatcoil OFF RELAY3

  html += String(propLED2prog) + " ";        //GrowLED2 1=off 2=on 3=auto RELAY4
  html += String(propLED2hours) + " ";      //Number of hours around noon RELAY4

  html += String(propCapac1) + " ";                //Moisture measured by CAPAC1
  html += String(propCapac1Min) + " ";  //Minimum moisture in sequence by CAPAC1
  html += String(propCapac1Max) + " ";  //Maximum moisture in sequence by CAPAC1

  html += String(propCapac2) + " ";                //Moisture measured by CAPAC2
  html += String(propCapac2Min) + " ";  //Minimum moisture in sequence by CAPAC2
  html += String(propCapac2Max) + " ";  //Maximum moisture in sequence by CAPAC2

  html += String(propCapac3) + " ";                //Moisture measured by CAPAC3
  html += String(propCapac3Min) + " ";  //Minimum moisture in sequence by CAPAC3
  html += String(propCapac3Max);        //Maximum moisture in sequence by CAPAC3

  bodyLength = html.length();  //Calculate the number of characters to sent WIFI
} //Exit refreshAnswer ---------------------------------------------------------



void setRelay1(){ //WATERING switch, calculate and set RELAY1 ******************
  if (SwitchOFFtimer < millis()) {    //If propWaterSecs SWITCH WATER OFF RELAY1
    propRelay1 = HIGH;              //HIGH=off or LOW=on WATER RELAY1 SWITCH OFF
  } //End of if (SwitchOFFtimer < millis   propWaterSecs SWITCH WATER OFF RELAY1

  switch (propWaterProg) {          //Watering program: 1=off 2=on 3=auto RELAY1
    case 1:                         //Program = 1 = Set program WATERINGPROG OFF
      propRelay1 = HIGH;                //Status HIGH=off or LOW=on WATER RELAY1
    break;                   //End of Program = 1 = Set program WATERINGPROG OFF

    case 2:                          //Program = 2 = Set program WATERINGPROG ON
      propRelay1 = LOW;                 //Status HIGH=off or LOW=on WATER RELAY1
    break;                    //End of Program = 2 = Set program WATERINGPROG ON

    case 3:                        //Program = 3 = Set program WATERINGPROG AUTO
      if (propCapac1 > propWaterON and propRelay1 == HIGH) {  //Treshold then ON
        propRelay1 = LOW;            //Status HIGH=off or LOW=on WATER ON RELAY1
        SwitchOFFtimer = millis() + propWaterSecs*1000L;   //Set SWTICH OFF TIME
        Serial.print("Switch ON ");            //Show activity to the user RS232
        Serial.println(propKlok);              //Show activity to the user RS232
      }  //End of                        If measurement reaches treshold then ON
    break;                  //End of Program = 3 = Set program WATERINGPROG AUTO
  }                                                 //End of switch wateringProg
  digitalWrite(ledRedPin, !propRelay1);              //RELAY1=ON  --> LED RED=ON
  digitalWrite(Relay1Pin, propRelay1);                         //Switches RELAY1
} //Exit setRelay1 -------------------------------------------------------------



void setRelay2(){ //GROWLED1 switch, calculate and set RELAY2 ******************
    switch (propLED1Prog) {         //GROWLED1 program: 1=off 2=on 3=auto RELAY2
    case 1:                             //Program = 1 = Set program GROWLED1 OFF
      propRelay2 = HIGH;             //Status HIGH=off or LOW=on GROWLED2 RELAY2
    break; //Case 1                End of Program = 1 = Set program GROWLED1 OFF

    case 2:                              //Program = 2 = Set program GROWLED1 ON
      propRelay2 = LOW;              //Status HIGH=off or LOW=on GROWLED2 RELAY2
    break; //Case 2                 End of Program = 2 = Set program GROWLED1 ON

    case 3:                            //Program = 3 = Set program GROWLED2 AUTO
      if (currenthour < starthours1){                  //Too early, GROWLED1 OFF
         propRelay2 = HIGH;          //Switch OFF , HIGH=off LOW=on GROWLED1 OFF
      } //End of if (currenthour < starthours){        //Too early, GROWLED1 OFF
      
      if (currenthour >= finishhours1){                 //Too late, GROWLED1 OFF
         propRelay2 = HIGH;          //Switch OFF , HIGH=off LOW=on GROWLED1 OFF
      } //End of if (currenthour > finishhours)           Too late, GROWLED1 OFF
      
      if (currenthour > (starthours1-1) && currenthour <(finishhours1)){    //ON
         propRelay2 = LOW;             //Switch ON , HIGH=off LOW=on GROWLED1 ON
      } //End of  if (currenthour > (starthours-1) && currenthour <(finishhours)
      
    break; //Case 3               End of Program = 3 = Set program GROWLED1 AUTO
  }                                                     //End of switch GROWLED1
  digitalWrite(Relay2Pin, propRelay2);                         //Switches RELAY2
} //Exit setRelay2 -------------------------------------------------------------


void setRelay3(){ //COIL HEATER switch, calculate and set RELAY3 ***************
  switch (propHeatProg) {        //COIL HEATER program: 1=off 2=on 3=auto RELAY3

    case 1:                          //Program = 1 = Set program COIL HEATER OFF
      propRelay3 = HIGH;          //Status HIGH=off or LOW=on COIL HEATER RELAY3
    break;                    //End of Program = 1 = Set program COIL HEATER OFF

    case 2:                           //Program = 2 = Set program COIL HEATER ON
      propRelay3 = LOW;           //Status HIGH=off or LOW=on COIL HEATER RELAY3
    break;                     //End of Program = 2 = Set program COIL HEATER ON


    case 3:                         //Program = 3 = Set program COIL HEATER AUTO
      if (propSoilTemp < propHeatON/10){       //If treshold measurement TURN ON
        propRelay3 = LOW;      //Status HIGH=off or LOW=on COIL HEATER ON RELAY3
      } //End of                                 If treshold measurement TURN ON
      if (propSoilTemp > propHeatOFF/10){     //If treshold measurement TURN OFF
        propRelay3 = HIGH;     //Status HIGH=off or LOW=on COIL HEATER ON RELAY3
      } //End of                                If treshold measurement TURN OFF
    break;                   //End of Program = 3 = Set program COIL HEATER AUTO

  }                                                  //End of switch COIL HEATER
  digitalWrite(Relay3Pin, propRelay3);                         //Switches RELAY3
} //Exit setRelay3 -------------------------------------------------------------



void setRelay4(){ //GROWLED2 switch, calculate and set RELAY4 ******************
  switch (propLED2prog) {           //GROWLED2 program: 1=off 2=on 3=auto RELAY4
    case 1:                              //Program = 1 = Set program GROWLED OFF
      propRelay4 = HIGH;              //Status HIGH=off or LOW=on GROWLED RELAY4
    break; //Case 1                End of Program = 1 = Set program GROWLED2 OFF

    case 2:                              //Program = 2 = Set program GROWLED2 ON
      propRelay4 = LOW;              //Status HIGH=off or LOW=on GROWLED2 RELAY4
    break; //Case 2                 End of Program = 2 = Set program GROWLED2 ON

    case 3:                            //Program = 3 = Set program GROWLED2 AUTO
      calculateGrowLED2();          //Calculate start and finisch clock GROWLED2

      if (currenthour < starthours2){                  //Too early, GROWLED2 OFF
         propRelay4 = HIGH;          //Switch OFF , HIGH=off LOW=on GROWLED2 OFF
      } //End of if (currenthour < starthours){        //Too early, GROWLED2 OFF
      if (currenthour > finishhours2){                  //Too late, GROWLED2 OFF
         propRelay4 = HIGH;          //Switch OFF , HIGH=off LOW=on GROWLED2 OFF
      } //End of if (currenthour > finishhours)           Too late, GROWLED2 OFF
      if (currenthour > (starthours2-1) && currenthour < (finishhours2)){   //ON
         propRelay4 = LOW;             //Switch ON , HIGH=off LOW=on GROWLED2 ON
      } //End of  if (currenthour > (starthours-1) && currenthour <(finishhours)
    break; //Case 3               End of Program = 3 = Set program GROWLED2 AUTO
  }
  digitalWrite(Relay4Pin, propRelay4);                //Switches GROWLED2 RELAY4
} //Exit setRelay4 -------------------------------------------------------------




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();                                  //Read byte by byte
  }                                                       //End of reading bytes
  int16_t raw = (data[1] << 8) | data[0];                      //Rotate the data
  propSoilTemp = (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 is an objest created by ONEWIRE
    term1.reset_search();                  //So if the variables are still empty
    delay(250);          //The variables must be filled and that costs some time
    return;                               //Are you sure any DS1820 is connected
  }                                           //End of if (!term1.search(addr1))
  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
  }
  propSoilTemp = (float)raw / 16.0;
} //Exit DS1820_init -----------------------------------------------------------




unsigned int readI2CRegister16bit(int addr, int reg){ //Read any TWI register **
  Wire.beginTransmission(addr);
  Wire.write(reg);
  Wire.endTransmission();
  delay(20);
  Wire.requestFrom(addr, 2);
  unsigned int t = Wire.read() << 8;
  t = t | Wire.read();
  return t;
} //Exit readI2CRegister16bit --------------------------------------------------



void writeI2CRegister8bit(int addr, int value){  //Reset sensor DHT22 **********
  Wire.beginTransmission(addr);
  Wire.write(value);
  Wire.endTransmission();
} //Exit writeI2CRegister8bit --------------------------------------------------



void calculateGrowLED1() {           //Calculate start and finish clock GROWLED1
  starthours1  = 12 - (propLED1hours / 2);   //Calculate switch ON time GROWLED1
  finishhours1 = 12 + (propLED1hours / 2);  //Calculate switch OFF time GROWLED1
} //Exit calculateGrowLED1 -----------------------------------------------------

void calculateGrowLED2() {           //Calculate start and finish clock GROWLED2
  starthours2  = 12 - (propLED2hours / 2);   //Calculate switch ON time GROWLED2
  finishhours2 = 12 + (propLED2hours / 2);  //Calculate switch OFF time GROWLED2
} //Exit calculateGrowLED2 -----------------------------------------------------



void EEPROMfirstTime() { //First time use, set values in EEPROM ****************
  EEPROM.write(1, 1);           //WATER current program 1=off 2=on 3=auto RELAY1
  EEPROM.write(2, 40);   //If capac1 reaches this treshold*10 then switch RELAY1
  EEPROM.write(3, 15);              //Number seconds*10 water switched on RELAY1
  EEPROM.write(4, 1);       //GROEILED1 current program 1=off 2=on 3=auto RELAY2
  EEPROM.write(5, 14);            //Number of hours around noon groeiled1 RELAY2
  EEPROM.write(6, 1);      //VERWARMING current program 1=off 2=on 3=auto RELAY3
  EEPROM.write(7, 200);   //Temperature/10 (0-25,5) aanschakeltemperatuur RELAY3
  EEPROM.write(8, 220);   //Temperature/10 (0-25,5) uitschakeltemperatuur RELAY3
  EEPROM.write(9, 1);       //GROEILED2 current program 1=off 2=on 3=auto RELAY4
  EEPROM.write(10, 10);           //Number of hours around noon groeiled2 RELAY4
} //Exit EEPROMfirstTime -------------------------------------------------------




void test_LAN(){ //Shows DHCP settings of LAN **********************************
  Serial.print  ("Ethernet.localIP: ");
  Serial.println(Ethernet.localIP());
  Serial.print  ("subnetMask:       ");
  Serial.println(Ethernet.subnetMask());
  Serial.print  ("gatewayIP:        ");
  Serial.println(Ethernet.gatewayIP());
  Serial.print  ("dnsServerIP:      ");
  Serial.println(Ethernet.dnsServerIP());
  Serial.print  ("ACTLOGLEVEL:      ");
  Serial.println(ACTLOGLEVEL);
  Serial.print  ("LOG_NONE:         ");
  Serial.println(LOG_NONE);
} //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 MEGA 2560                                    //
// Board  -Atmel- PIN - Function          - External Connection          FUNC //
//                                                                            //
// CONNECTIONS RAILS RIGHT TOP: DIGITAL PWM<~> ****************************** //
// SCL    -  43 - PD0 - SCL/INT0          - Clock DS1307                  TWI //
// SDA    -  44 - PD1 - SDA/INT1          - Clock DS1307                  TWI //
// AREF   -  98 - REF - AREF              -                               REF //
// 13 PWM -  26 - PB7 - OC0A/OC1C/PCINT17 - LED Arduino LED_BUILTIN       PWM //
// 12 PWM -  25 - PB6 - OC1B/PCINT16      -                               PWM //
// 11 PWM -  24 - PB5 - OC1A/PCINT5       -                               PWM //
// 10 PWM -  23 - PB4 - OC2A/PCINT4       -                               PWM //
//  9 PWM -  18 - PH6 - OC2B              -                               PWM //
//  8 PWM -  17 - PH5 - OC4C              -                               PWM //
//                                                                            //
// CONNECTIONS RAILS RIGHT MIDDLE: DIGITAL PWM<~> *************************** //
//  7 PWM -  16 - PH4 - OC4B              -                               PWM //
//  6 PWM -  15 - PH3 - OC4A              -                               PWM //
//  5 PWM -   5 - PE3 - OC3A/AIN1         -                               PWM //
//  4 PWM -   1 - PG5 - OC0B              - DHT22 room temperature        PWM //
//  3 PWM -   7 - PE5 - OC3C/INT5         -                               INT //
//  2 PWM -   6 - PE4 - OC3B/INT4         -                               INT //
//  1 TX0 -   3 - PE1 - TXD0              - Serial monitor PC             TX0 //
//  0 RX0 -   2 - PE0 - RXD0/PCINT8       - Serial monitor PC             RX0 //
//                                                                            //
// CONNECTIONS RAILS RIGHT BOTTOM: DIGITAL PWM<~> *************************** //
// 14 TX3 -  64 - PJ1 - TXD3/PCINT10      -                               TX3 //
// 15 RX3 -  63 - PJ0 - RXD3/PCINT9       -                               RX3 //
// 16 TX2 -  13 - PH1 - TXD2              -                               TX2 //
// 17 RX2 -  12 - PH0 - RXD2              - DS18B20 Soil temperature      RX2 //
// 18 TX1 -  46 - PD3 - TXD1/INT3         -                               INT //
// 19 RX1 -  45 - PD2 - RXD1/INT2         -                               INT //
// 20 SDA -  44 - PD1 - SDA/INT1          - DS1307 I2C Clock              TWI //
// 21 SCL -  43 - PD0 - SCL/INT0          - DS1307 I2C Clock              TWI //
//                                                                            //
// CONNECTIONS RAILS LEFT TOP: POWER **************************************** //
// NC     -     -     -                   - Not Connected                     //
// IOREF  -     -     - 3.3/5Vdc          - Outputs controller voltage        //
// 5V     -   7 - VCC - VCC               -                               VCC //
// RES    -   1 - RES - PCINT14/RESET     -                               RES //
// 3.3V   -     -     -                   -                                   //
// 5V     -     -     -                   -                                   //
// GND    -     -     -                   -                                   //
// GND    -     -     -                   -                                   //
// Vin    -     -     - 7/9Vdc power in   -                                   //
//                                                                            //
// CONNECTIONS RAILS LEFT MIDDLE : ANALOG IN ******************************** //
// A0     -  97 - PF0 - ADC0              -                               ADC //
// A1     -  96 - PF1 - ADC1              -                               ADC //
// A2     -  95 - PF2 - ADC2              -                               ADC //
// A3     -  94 - PF3 - ADC3              -                               ADC //
// A4     -  93 - PF4 - ADC4/TCK          -                               ADC //
// A5     -  92 - PF5 - ADC5/TMS          -                               ADC //
// A6     -  91 - PF6 - ADC6/TDO          -                               ADC //
// A7     -  90 - PF7 - ADC7/TDI          - Buzzer activ                  ADC //
//                                                                            //
// CONNECTIONS RAILS LEFT BOTTOM: ANALOG IN ********************************* //
// A8     -  89 - PK0 - ADC8/PCINT16      - Moisture Capac 1              ADC //
// A9     -  88 - PK1 - ADC9/PCINT17      - Moisture Capac 2              ADC //
// A10    -  87 - PK2 - ADC10/PCINT18     - Moisture Capac 3              ADC //
// A11    -  86 - PK3 - ADC11/PCINT19     -                               ADC //
// A12    -  85 - PK4 - ADC12/PCINT20     -                               ADC //
// A13    -  84 - PK5 - ADC13/PCINT21     -                               ADC //
// A14    -  83 - PK6 - ADC14/PCINT22     -                               ADC //
// A15    -  82 - PK7 - ADC15/PCINT23     -                               ADC //
//                                                                            //
// CONNECTIONS DOUBLE RAILS BOTTOM ****************************************** //
// Board  -Atmel- PIN - Function          - External Connection          FUNC //
// 5V     -     - 5Vdc- 5Vdc              -                               VCC //
// 5V     -     - 5Vdc- 5Vdc              -                               VCC //
// 22     -  78 - PA0 - AD0               -                               DIO //
// 23     -  77 - PA1 - AD1               -                               DIO //
// 24     -  76 - PA2 - AD2               -                               DIO //
// 25     -  75 - PA3 - AD3               -                               DIO //
// 26     -  74 - PA4 - AD4               -                               DIO //
// 27     -  73 - PA5 - AD5               -                               DIO //
// 28     -  72 - PA6 - AD6               -                               DIO //
// 29     -  71 - PA7 - AD7               -                               DIO //
// 30     -  60 - PC7 - A14               -                               DIO //
// 31     -  59 - PC6 - A15               -                               DIO //
// 32     -  58 - PC5 - A13               -                               DIO //
// 33     -  57 - PC4 - A12               -                               DIO //
// 34     -  56 - PC3 - A11               - Relay1                        DIO //
// 35     -  55 - PC2 - A10               -                               DIO //
// 36     -  54 - PC1 - A9                - Relay2                        DIO //
// 37     -  53 - PC0 - A8                -                               DIO //
// 38     -  50 - PD7 - T0                - Relay3                        DIO //
// 39     -  70 - PG2 - ALE               -                               DIO //
// 40     -  52 - PG1 - RD                - Relay4                        DIO //
// 41     -  51 - PG0 - WR                -                               DIO //
// 42     -  42 - PL7 -                   -                               DIO //
// 43     -  41 - PL6 -                   -                               DIO //
// 44     -  40 - PL5 - OC5C              - 3 Color led Red               PWM //
// 45     -  39 - PL4 - OC5B              - 3 Color led Green             PWM //
// 46     -  38 - PL3 - OC5A              - 3 Color led Blue              PWM //
// 47     -  37 - PL2 - T5                -                               DIO //
// 48     -  36 - PL1 - ICP5              -                               DIO //
// 49     -  35 - PL0 - ICP4              -                               DIO //
// 50     -  22 - PB3 - MISO/PCINT3       - Lan ENC28J60                  SPI //
// 51     -  21 - PB2 - MOSI/PCINT2       - Lan ENC28J60                  SPI //
// 52     -  20 - PB1 - SCK/PCINT1        - Lan ENC28J60                  SPI //
// 53     -  19 - PB1 - SS/PCINT0         - Lan ENC28J60                  SPI //
// GND    -     - GND - GND               -                               GND //
// GND    -     - GND - GND               -                               GND //
////////////////////////////////////////////////////////////////////////////////




////////////////////////////////////////////////////////////////////////////////
// EEPROM MEMORY MAP:                                                         //
// Start End  Number Description                                              //
// 0000  0000      1   Never use this memory location to be AVR compatible    //
// 0001  0001      1 WATER propWaterProg program 1=off 2=on 3=auto     RELAY1 //
// 0002  0002      1   If capac1 reaches this propWaterON*10 then set  RELAY1 //
// 0003  0003      1   Number seconds*10 propWaterSecs water on        RELAY1 //
// 0004  0004      1 GROEILED1 propLED1Prog program 1=off 2=on 3=auto  RELAY2 //
// 0005  0005      1   Number of propLED1hours around noon groeiled1   RELAY2 //
// 0006  0006      1 VERWARMING propHeatProg program 1=off 2=on 3=auto RELAY3 //
// 0007  0007      1   propHeatON/10 (0-25,5) aanschakeltemperatuur    RELAY3 //
// 0008  0008      1   propHeatOFF/10 (0-25,5) uitschakeltemperatuur   RELAY3 //
// 0009  0009      1 GROEILED2 propLED2prog program 1=off 2=on 3=auto  RELAY4 //
// 0010  0010      1   Number of propLED2hours around noon groeiled2   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  //
////////////////////////////////////////////////////////////////////////////////