////////////////////////////////////////////////////////////////////////////////
// Name:       FloraPropagator2560-03Old 2019 ETHERNET version                //
// http://robotigs.com/robotigs/includes/bots_header.php?idbot=17             //
//             Robot that controls propagator                                 //
// Platform:   Arduino Mega 2560                                              //
// Created by: HARB rboek2@gmail.com januari 2019 GPL copyrights              //
// Thanks to:  Library DHT 2011 by Limor Frie, modified 2012 by Tom Igoe      //
//             https://github.com/PaulStoffregen/OneWire                      //
//             <DS1302.h> Copyright (c) 2009, Matt Sparks                     //
// As outputs the following modules are mounted:                              //
// - Standard Arduino Onboard LED (PWM)                                       //
// - 3 color LED (PWM)                                                        //
// - Activ loudspeaker                                                        //
// - 220 Vac Relay                                                            //
// As inputs the following modules are mounted:                               //
// - DS1307 Real Time Clock                                                   //
// - DHT22 air temperature and air humidity sensor                            //
// - LED                                                                      //
// - CJMCU soil huidity sensor (TWI)                                          //
// For communications are mounted:                                            //
// - Standard Serial Monitor output                                           //
// - Lan ENC28J60 unit                                                        //
////////////////////////////////////////////////////////////////////////////////





////////////////////////////////////////////////////////////////////////////////
//3456789112345678921234567893123456789412345678951234567896123456789712345678//
// EEPROM MEMORY MAP:                                                         //
// Start End  Number Description                                              //
// 0000  0000      1 Never use this memory location to be AVR compatible      //
// 0001  0001      1 wateringProg Usr choice: 1=off 2=on 3=auto RELAY1        //
// 0002  0003      2 wateringON If CAPAC reaches this 2byte treshold RELAY1   //
// 0004  0005      2 wateringSecs How many seconds to keep ON RELAY1          //
// 0006  0006      1 Temperature/10 airheater Switch ON RELAY2 (0-25,5)       //
// 0007  0007      1 Temperature/10 airheater Switch OFF RELAY2 (0-25,5)      //
// 0008  0008      1 Usr choice: airheater 1=off 2=on 3=auto RELAY2           //
// 0009  0009      1 Temperature/10 heat coil Switch ON RELAY3 (0-25,5)       //
// 0010  0010      1 Temperature/10 heat coil Switch OFF RELAY3 (0-25,5)      //
// 0011  0011      1 Usr choice: heatcoil 1=off 2=on 3=auto RELAY3            //
// 0012  0012      1 Number of hours around noon GROWLED RELAY4               //
// 0013  0013      1 /Usr choice: growled 1=off 2=on 3=auto 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
  #include <EEPROM.h>                       //Needed for read or write in EEPROM
  #include <OneWire.h>    //Library can be installed through Arduino IDE DS18B20
  #include <RTClib.h>                           //connected via I2C and Wire lib
  #include <Wire.h>                                         //Two Wire Interface
  #include <UIPEthernet.h>       //ENC28J60 by https://github.com/ntruchsess LAN

  // 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 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 DHTPIN        4                   //Which DIO input pin connects DHT22
  #define DHTTYPE   DHT22     //What sensor is connected (AM2302) (AM2321) DHT22
  #define Relay1Pin    34 //220Vac DIO output pin connects WATERING RELAY1 KAPOT
  #define Relay2Pin    36     //220Vac DIO output pin connects AIR HEATER RELAY2
  #define Relay3Pin    38    //220Vac DIO output pin connects COIL HEATER RELAY3
  #define Relay4Pin    40        //220Vac DIO output pin ILLUMINATION LED RELAY4
  #define buzActPin    A7          //Define DIO output pin connects ACTIV BUZZER
  #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    wateringProg   = 1;                //Watering: 1=off 2=on 3=auto RELAY1
  word   propWaterON    = 435;    //If sensor CAPAC reaches this treshold RELAY1
  word   propWaterSecs  = 300;   //Number seconds watering will switch ON RELAY1
  int    airheatProg    = 1;    //Usr choice: airheater 1=off 2=on 3=auto RELAY2
  int    propAirheatON  = 100;       //Temperature/10 airheater Switch ON RELAY2
  int    propAirheatOFF = 130;      //Temperature/10 airheater Switch OFF RELAY2
  int    heatCoilProg   = 1;                 //Heatcoil 1=off 2=on 3=auto RELAY3
  int    propCoilON     = 150;               //Temperature/10 heatcoil ON RELAY3
  int    propCoilOFF    = 160;             //Temperature/10 airheater OFF RELAY2
  int    growLEDProg    = 1;                  //GrowLED 1=off 2=on 3=auto RELAY4
  int    propLEDhours   = 14;               //Number of hours around noon RELAY4

  //Define DATABASE VARIABLES --------------------------------------------------
  bool   propRelay1     = HIGH;         //Status HIGH=off or LOW=on WATER RELAY1
  bool   propRelay2     = HIGH;            //Status 1=off, 0=on AIRHEATER RELAY2
  bool   propRelay3     = HIGH;           //Status HI=off, LW=on HEATCOIL RELAY3
  bool   propRelay4     = HIGH;           //Status HI=off, LOW=on GROWLED RELAY4
  word   propCapac;                                 //Moisture measured by CAPAC
  word   propCapacMin   = 1023; //Minimum moisture measured in sequence by CAPAC
  word   propCapacMax   =    0; //Maximum moisture measured in sequence by CAPAC
  float  propAirTemp;                     //Air temperature degree Celcius DHT22
  float  propAirHum;                             //Air humidity percentage DHT22
  float  propSoilTemp;                     //Soil temperature in Celsius DS18B20
  String propKlok;                                             //DateTime DS1307
  word   propCapac2;                                //Moisture measured by CAPAC
  word   propCapac2Min  = 1023; //Minimum moisture measured in sequence by CAPAC
  word   propCapac2Max  =    0; //Maximum moisture measured in sequence by CAPAC
  word   propCapac3;                                //Moisture measured by CAPAC
  word   propCapac3Min  = 1023; //Minimum moisture measured in sequence by CAPAC
  word   propCapac3Max  =    0; //Maximum moisture measured in sequence by CAPAC


  //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
  char   buf[100];                //Needed to display the date/time stamp DS1307
  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
  int    starthours     = 12 - (propLEDhours / 2);     //Switch ON clock GROWLED
  int    finishhours    = 12 + (propLEDhours / 2);    //Switch OFF clock GROWLED
  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

  String tempo          = "";                             //Can be used anywhere 
  int    tmp1;                                            //Can be used anywhere 
  int    tmp2;                                            //Can be used anywhere 
  uint8_t mac[6]        = {0x00,0x01,0x02,0x03,0x04,0x05};                 //LAN
                            // Ethernet MAC address - must be unique on your LAN
  static unsigned long SwitchOFFtimer = millis()+ 300000;             //WATERING


  // Initialize 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
  wateringProg   = EEPROM.read(1);          //Watering: 1=off 2=on 3=auto RELAY1
  propWaterON    = promReadWord(2);      //If CAPAC reaches this treshold RELAY1
  propWaterSecs  = promReadWord(4);         //How many seconds to keep ON RELAY1

  airheatProg    = EEPROM.read(6);        //Usr choice: 1=off 2=on 3=auto RELAY2
  propAirheatON  = EEPROM.read(7);          //Temperature/10 airheater ON RELAY2
  propAirheatOFF = EEPROM.read(8);         //Temperature/10 airheater OFF RELAY2

  heatCoilProg   = EEPROM.read(9);           //Heatcoil 1=off 2=on 3=auto RELAY3
  propCoilON     = EEPROM.read(10);          //Temperature/10 heatcoil ON RELAY3
  propCoilOFF    = EEPROM.read(11);         //Temperature/10 heatcoil OFF RELAY3

  growLEDProg    = EEPROM.read(12);           //GrowLED 1=off 2=on 3=auto RELAY4
  propLEDhours   = EEPROM.read(13);         //Number of hours around noon RELAY4
  starthours  = 12 - (propLEDhours / 2);               //Switch ON clock GROWLED
  finishhours = 12 + (propLEDhours / 2);              //Switch OFF clock GROWLED

  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(9600);         //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

    propCapac = analogRead(moistPin);         //Moisture measured by CAPACATIVE1
    if (propCapac < propCapacMin){         //Do some statistics MOISTURE MINIMUM
      propCapacMin = propCapac;                           //Set MOISTURE MINIMUM
    }                                      //Do some statistics MOISTURE MINIMUM
    if (propCapac > propCapacMax){         //Compare statistics MOISTURE MAXIMUM
      propCapacMax = propCapac;                           //Set MOISTURE MAXIMUM
    } //End of  if (propCapac > 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();                     //AIR HEATER switch, calculate and set RELAY2
  setRelay3();                    //COIL HEATER switch, calculate and set RELAY3
  setRelay4();                        //GROWLED 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
          if (isDigit(commandStr[5])){        //Check if we received any command
          tempo = commandStr.substring(5, 7);            //Extract command 01-99
          command = tempo.toInt();      //Translate the function to a executable
          switch (command) {                     //Go to the according procedure

            case 1: //Command = 1 = Set program WATERINGPROG *******************
              tempo = commandStr[8];       //Extract parameter 1=off 2=on 3=auto
              wateringProg = tempo.toInt();    //Set actual program for WATERING
              setRelay1();           //WATERING switch, calculate and set RELAY1
              eepromWriteByte(1, wateringProg);              //Set 1 byte EEPROM
            break; //End of command == 1  translates to command is 1=Set program

            case 2: //If CAPAC reaches treshold CAPAC switch WATERING ON *******
              tempo = commandStr.substring(8, 12); //Extract parameter 0000-9999
              propWaterON = tempo.toInt();        //Convert to decimal PARAMETER
              setRelay1();           //WATERING switch, calculate and set RELAY1
              eepromWriteWord (2, propWaterON);             //Set 2 bytes EEPROM
            break; ///End of if (command == 2) Set switch ON WATERING ----------

            case 3: //How many seconds to keep ON RELAY1  b4 switch WATERING OFF
              tempo = commandStr.substring(8, 12); //Extract parameter 0000-9999
              propWaterSecs = tempo.toInt();      //Convert to decimal PARAMETER
              setRelay1();           //WATERING switch, calculate and set RELAY1
              eepromWriteWord(4, propWaterSecs);            //Set 2 bytes EEPROM
            break; //End of if (command == 3) Set switch OFF WATERING ----------

            case 11: //Command = 11 = Set program AIR HEATER *******************
              tempo = commandStr[8];       //Extract parameter 1=off 2=on 3=auto
              airheatProg = tempo.toInt();        //Convert to decimal PARAMETER
              setRelay2();         //AIR HEATER switch, calculate and set RELAY2
              eepromWriteByte(6, airheatProg);               //Set 1 byte EEPROM
            break; //End of command == 1  translates to command is 1=Set program

            case 12: //If Temperature reaches treshold switch AIR HEATER ON ****
              tempo = commandStr.substring(8, 12); //Extract parameter 0000-0256
              propAirheatON = tempo.toInt();      //Convert to decimal PARAMETER
              setRelay2();         //AIR HEATER switch, calculate and set RELAY2
              eepromWriteByte(7, propAirheatON);             //Set 1 byte EEPROM
            break; //End of if (command == 2) Set switch ON AIR HEATER ---------

            case 13: //If Temperature reaches treshold switch AIR HEATER OFF ***
              tempo = commandStr.substring(8, 12); //Extract parameter 0000-0256
              propAirheatOFF = tempo.toInt();     //Convert to decimal PARAMETER
              setRelay2();         //AIR HEATER switch, calculate and set RELAY2
              eepromWriteByte(8, propAirheatOFF);            //Set 1 byte EEPROM
            break; //End of if (command == 3) Set switch OFF AIR HEATER --------

            case 21: //Command = 21 = Set program COIL HEATER ******************
              tempo = commandStr[8];       //Extract parameter 1=off 2=on 3=auto
              heatCoilProg = tempo.toInt();       //Convert to decimal PARAMETER
              setRelay3();        //COIL HEATER switch, calculate and set RELAY3
              eepromWriteByte(9, heatCoilProg);              //Set 1 byte EEPROM
            break; //Case 21              Command = 21 = Set program COIL HEATER

            case 22: //If Temperature reaches treshold switch COIL HEATER ON ***
              tempo = commandStr.substring(8, 12); //Extract parameter 0000-0256
              propCoilON = tempo.toInt();         //Convert to decimal PARAMETER
              setRelay3();        //COIL HEATER switch, calculate and set RELAY3
              eepromWriteByte(10, propCoilON);               //Set 1 byte EEPROM
            break; //Case 22          Temperature treshold switch COIL HEATER ON

            case 23: //If Temperature reaches treshold switch COIL HEATER OFF **
              tempo = commandStr.substring(8, 12); //Extract parameter 0000-0256
              propCoilOFF = tempo.toInt();        //Convert to decimal PARAMETER
              setRelay3();        //COIL HEATER switch, calculate and set RELAY3
              eepromWriteByte(11, propCoilOFF);              //Set 1 byte EEPROM
            break; //Case 23         Temperature treshold switch COIL HEATER OFF

            case 31: //Command = 31 = Set program GROWLED **********************
              tempo = commandStr[8];       //Extract parameter 1=off 2=on 3=auto
              growLEDProg = tempo.toInt();        //Convert to decimal PARAMETER
              setRelay4();            //GROWLED switch, calculate and set RELAY4
              eepromWriteByte(12, growLEDProg);              //Set 1 byte EEPROM
            break; //Case 31                  Command = 31 = Set program GROWLED

            case 32: //Number of hours around noon RELAY4 GROWLED ON ***********
              tempo = commandStr.substring(8, 12); //Extract parameter 0000-0023
              propLEDhours = tempo.toInt();       //Convert to decimal PARAMETER
              starthours  = 12 - (propLEDhours / 2);   //Switch ON clock GROWLED
              finishhours = 12 + (propLEDhours / 2);  //Switch OFF clock GROWLED
              setRelay4();            //GROWLED switch, calculate and set RELAY4
              eepromWriteByte(13, propLEDhours);             //Set 1 byte EEPROM
            break; //Case 32       Number of hours around noon RELAY4 GROWLED ON

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

    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
    propCapacMin   = 1023;  //RESET Statistics minimum moisture content MOISTURE
    propCapacMax   =    0;  //RESET Statistics maximum moisture content MOISTURE
    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 AIRHEATER RELAY2
  html += String(propRelay3)+ " ";        //Status HI=off, LW=on HEATCOIL RELAY3
  html += String(propRelay4)+ " ";        //Status HI=off, LOW=on GROWLED RELAY4      
  
  html += String(wateringProg) + " ";       //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(airheatProg) + " ";       //Air heater 1=off 2=on 3=auto RELAY2
  html += String(propAirheatON) + " ";      //Temperature/10 airheater ON RELAY2
  html += String(propAirheatOFF) + " ";    //Temperature/10 airheater OFF RELAY2

  html += String(heatCoilProg)+ " ";         //Heatcoil 1=off 2=on 3=auto RELAY3
  html += String(propCoilON)+ " ";          //TTemperature/10 heatcoil ON RELAY3
  html += String(propCoilOFF)+ " ";         //Temperature/10 heatcoil OFF RELAY3

  html += String(growLEDProg)+ " ";           //GrowLED 1=off 2=on 3=auto RELAY4
  html += String(propLEDhours) + " ";       //Number of hours around noon RELAY4

  html += String(propCapac) + " ";                 //Moisture measured by CAPAC1
  html += String(propCapacMin) + " ";   //Minimum moisture in sequence by CAPAC1
  html += String(propCapacMax) + " ";   //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 (wateringProg) {           //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 (propCapac > 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(){ //AIR HEATER switch, calculate and set RELAY2 ****************
  switch (airheatProg) {          //AIR HEATER program: 1=off 2=on 3=auto RELAY2

    case 1:                           //Program = 1 = Set program AIR HEATER OFF
      propRelay2 = HIGH;           //Status HIGH=off or LOW=on AIR HEATER RELAY2
    break;                     //End of Program = 1 = Set program AIR HEATER OFF

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

    case 3:                          //Program = 3 = Set program AIR HEATER AUTO
      if (propAirTemp < propAirheatON/10){     //If treshold measurement TURN ON
        propRelay2 = LOW;       //Status HIGH=off or LOW=on AIR HEATER ON RELAY2
      } //End of                                 If treshold measurement TURN ON
      if (propAirTemp > propAirheatOFF/10){   //If treshold measurement TURN OFF
        propRelay2 = HIGH;      //Status HIGH=off or LOW=on AIR HEATER ON RELAY2
      } //End of                                If treshold measurement TURN OFF
    break;                    //End of Program = 3 = Set program AIR HEATER AUTO

  }                                                   //End of switch AIR HEATER
  digitalWrite(Relay2Pin, propRelay2);                         //Switches RELAY2
} //Exit setRelay2 -------------------------------------------------------------


void setRelay3(){ //COIL HEATER switch, calculate and set RELAY3 ***************
  switch (heatCoilProg) {        //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 < propCoilON/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 > propCoilOFF/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(){ //GROWLED switch, calculate and set RELAY4 *******************
  switch (growLEDProg) {             //GROWLED 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 GROWLED OFF

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

    case 3:                             //Program = 3 = Set program GROWLED AUTO
      if (currenthour < starthours){                    //Too early, GROWLED OFF
         propRelay4 = HIGH;           //Switch OFF , HIGH=off LOW=on GROWLED OFF
      } //End of if (currenthour < starthours){         //Too early, GROWLED OFF
      if (currenthour > finishhours){                    //Too late, GROWLED OFF
         propRelay4 = HIGH;           //Switch OFF , HIGH=off LOW=on GROWLED OFF
      } //End of if (currenthour > finishhours)            Too late, GROWLED OFF
      if (currenthour > (starthours-1) && currenthour <(finishhours)){      //ON
         propRelay4 = LOW;              //Switch ON , HIGH=off LOW=on GROWLED ON
      } //End of  if (currenthour > (starthours-1) && currenthour <(finishhours)
    break; //Case 3                End of Program = 3 = Set program GROWLED AUTO
  }                                                      //End of switch GROWLED
  digitalWrite(Relay4Pin, propRelay4);                         //Switches 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 eepromWriteByte(word place, int parameter){ //Set EEPROM 1 byte and REFRESH
  EEPROM.write(place , parameter);            //Setting must be an integer WRITE
} //Exit eepromWriteByte -------------------------------------------------------



void eepromWriteWord(word place, word parameter){ //EEPROM 2 bytes and REFRESH*
  tmp1 = parameter/255;                           //Tmp1 contains the HIGH BYTE
  EEPROM.write(place, tmp1);                          //Setting HIGH byte WRITE
  tmp2 = parameter -(tmp1 * 255)   ;                       //Calculate LOW BYTE
  EEPROM.write(place + 1, tmp2);                      //Setting HIGH byte WRITE
} //Exit eepromWriteWord ------------------------------------------------------



word promReadWord(word address) { //EEPROM read a 2 byte word ******************
  tmp1 = EEPROM.read(address);             //Read the HIGH part of the word HIGH
  tmp2 = EEPROM.read(address+1);             //Read the LOW part of the word LOW
  return tmp1*255 + tmp2;                               // Return the word value
} //Exit promReadWord ----------------------------------------------------------




void EEPROMfirstTime() { //First time use, set values in EEPROM ****************
  EEPROM.write(1, 1);                       //Watering: 1=off 2=on 3=auto RELAY1
  EEPROM.write(2, 1);               //If CAPAC reaches this treshold HIGH RELAY1
  EEPROM.write(3, 11);               //If CAPAC reaches this treshold LOW RELAY1
  EEPROM.write(4, 1)  ;                //How many seconds to keep ON HIGH RELAY1
  EEPROM.write(5, 55);                  //How many seconds to keep ON LOW RELAY1
  EEPROM.write(6, 1);                      //Air heater 1=off 2=on 3=auto RELAY2
  EEPROM.write(7, 100);                     //Temperature/10 airheater ON RELAY2
  EEPROM.write(8, 130);                    //Temperature/10 airheater OFF RELAY2
  EEPROM.write(9, 1);                        //Heatcoil 1=off 2=on 3=auto RELAY3
  EEPROM.write(10, 150);                     //Temperature/10 heatcoil ON RELAY3
  EEPROM.write(11, 160);                    //Temperature/10 heatcoil OFF RELAY3
  EEPROM.write(12, 1);                        //GrowLED 1=off 2=on 3=auto RELAY4
  EEPROM.write(13, 14);                     //Number of hours around noon 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          -                               TWI //
// SDA    -  44 - PD1 - SDA/INT1          -                               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              -                               RX2 //
// 18 TX1 -  46 - PD3 - TXD1/INT3         -                               INT //
// 19 RX1 -  45 - PD2 - RXD1/INT2         - DS18B20 Soil temperature      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 //
////////////////////////////////////////////////////////////////////////////////




////////////////////////////////////////////////////////////////////////////////
//3456789112345678921234567893123456789412345678951234567896123456789712345678//
// EEPROM MEMORY MAP:                                          Max 4096 bytes //
// Start End  Number Description                                              //
// 0000  0000      1 Never use this memory location to be AVR compatible      //
////////////////////////////////////////////////////////////////////////////////




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