////////////////////////////////////////////////////////////////////////////////
// Name:       FloraPropagator2560-02 2018 WIFI 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 september 2018 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                                           //
// - ESP-01 Wifi unit                                                         //
//                                                                            //
// Connect ESP-01 to your Arduino:                                            //
// Yellow = Arduino RX1 19 = ESP-01 TX                                        //
// Blue   = Arduino TX1 18 = ESP-01 RX                                        //
// Connect your Arduino to your PC and open the serial monitor.               //
// AT commands AT version:1.1.0.0(May 11 2016 18:09:56)                       //
////////////////////////////////////////////////////////////////////////////////





////////////////////////////////////////////////////////////////////////////////
//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 <WiFiEsp.h>                   //https://github.com/bportaluri/WiFiEsp
  #include <Wire.h>                                         //Two Wire Interface

  // 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 ledBluPin    45        //3 Colour LED, which PWM pin connects BLUE LED
  #define ledGrePin    46       //3 Colour LED, which PWM pin connects GREEN LED
  #define DHTPIN       47                   //Which DIO input pin connects DHT22
  #define DHTTYPE   DHT22     //What sensor is connected (AM2302) (AM2321) DHT22
  #define Relay1Pin    48       //220Vac DIO output pin connects WATERING RELAY1
  #define Relay2Pin    49     //220Vac DIO output pin connects AIR HEATER RELAY2
  #define Relay3Pin    50    //220Vac DIO output pin connects COIL HEATER RELAY3
  #define Relay4Pin    51        //220Vac DIO output pin ILLUMINATION LED RELAY4
  #define buzAct       52          //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   A15      //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         = 1;            //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 html           = "";                    //HTML Response preapaired WIFI
  int    bodyLength;                                   //HTML answer length WIFI
  int    status         = WL_IDLE_STATUS;             //Status of the ESP01 WIFI
  char   ssid[]         = "Ranonkel9_EXT";            //Network SSID (name) WIFI
  char   pass[]         = "Kat14_-5";                    //Network password WIFI
  String commandStr     = "";               //Commands received by html INTERNET
  int    command        = 0;                //Which user command to perform WIFI
  int    value          = 0;             //Value that comes with the object WIFI

  String tempo          = "";                             //Can be used anywhere 
  int    tmp1;                                            //Can be used anywhere 
  int    tmp2;                                            //Can be used anywhere 

  static unsigned long SwitchOFFtimer = millis()+ 300000;             //WATERING

    
  // Initialize OBJECTS --------------------------------------------------------
  DHT dht(DHTPIN, DHTTYPE);                     //Initialize sensor object DHT22
  DS1307 rtc;                         //Initialize Real Time Clock object DS1307
  WiFiEspServer server(80);                           //Start the webserver WIFI
  RingBuffer buf2(8);       //Ringbuffer increases speed and reduces memory WIFI
//END OF PRECOMPILER OPTIONS ---------------------------------------------------



void setup() { // **************************************************************
  ESP01setSpeed();                   //Initializes the modem to 57600 WIFI ESP01
  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(buzAct, 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
  dht.begin();                               //Start sensor object running DHT22
  writeI2CRegister8bit(0x20, 6);      //Reset sensor to tell it is a slave DHT22

  Serial.begin(9600);        //Nothing more needed for the Serial Monitor RSR232
  Serial1.begin(57600);      //RS232 Speed is preset to 57600 or 115200 at ESP01
  
  //Start objects --------------------------------------------------------------
  rtc.begin();    //Initialize Wire.begin first. Start the object running DS1307
  //rtc.adjust(DateTime(__DATE__, __TIME__));      //Set to time compiled DS1307

  //Test hardware and software -------------------------------------------------
  beep(10);                       //Create a test beep with KY-012 active BUZZER
  initializeWiFI();                   //Initializes and connects to network WIFI
  DS1820_init();      //Determins the type of DS1820 and reads properties DS1820
  test_LEDs();            //PWM fade in and fade out for all 4 LEDs on board LED
  //test_RELAY();                          //Switches ON for 2 seconds the RELAY
  Serial.println("Setup completed");     //Show the user the setup is done RS232
  beep(10);                       //Create a test beep with KY-012 active BUZZER
} //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
  checkWifi();      //Check if any request available and if so then respond WIFI
  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
  checkWifi();      //Check if any request available and if so then respond WIFI
  readSensors();          //Read several sensors at timed intervals only SENSORS
  checkWifi();      //Check if any request available and if so then respond WIFI
} //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
    digitalWrite(ledGrePin, HIGH);           //Blue 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 checkWifi(){   //Check if any request available and if so then respond WIFI
  WiFiEspClient client = server.available();  //Listen for incoming clients WIFI
  if (client) {                               //If you get a client then do WIFI
    digitalWrite(ledBluPin, HIGH);           //Blue HIGH=on, LOW=off activityLED
    handleClient(client);                //Answers a client request made by WIFI
    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)                      //If you get a client then do WIFI
} //Exit checkWifi -------------------------------------------------------------




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




void handleClient(WiFiEspClient client){  //Proces a client request made by WIFI
  commandStr = "";                                //Reset the commands line WIFI
  //Serial.println("New client");              //Show activity to the user RS232
  buf2.init();                                  //Initialize the circular buffer
  while (client.connected()) {              //Loop while the client is connected
    if (client.available()) {           //If there are bytes to read from client
      char c = client.read();                                      //Read a byte
      buf2.push(c);                         //Push the byte into the ring buffer
      commandStr += c;                       //Add received character to command
      if (buf2.endsWith("\r\n\r\n")) {   //Check for 2 newline characters in row
        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
        sendHttpResponse(client);          //Meaning the end of the HTTP request
        break;                     //After the response is sent we are done here
      } //End of if (buf2.endsWith("\r\n\r\n")) {    //Check for 2 newline chars
    } //End of if (client.available()) {  If there are bytes to read from client
  } //End of  while (client.connected()) {    Loop while the client is connected
  client.stop();                                //Close the Wifi connection WIFI
  Serial.println("Client disconnected");    //Showing we handeld a request RS232
  Serial.println(" ");                     //Just to start a new paragraph RS232
} //End of handleClient Proces a client request made by WIFI -------------------



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 =  String(wateringProg) + " ";       //Watering: 1=off 2=on 3=auto RELAY1
  html += String(propRelay1) + " ";       //Status HIGH=off, LOW=on WATER RELAY1
  html += String(propCapac) + " ";                  //Moisture measured by CAPAC
  html += String(propCapacMin) + " ";    //Minimum moisture in sequence by CAPAC
  html += String(propCapacMax) + " ";    //Maximum moisture in sequence by CAPAC
  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(propRelay2) + " ";        //Status 1=off, 0=on AIRHEATER RELAY2
  html += String(propAirTemp) + " ";      //Air temperature degree Celcius DHT22
  html += String(propAirHum) + " ";              //Air humidity percentage DHT22
  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(propRelay3)+ " ";        //Status HI=off, LW=on HEATCOIL RELAY3
  html += String(propSoilTemp)+ " ";       //Soil temperature in Celsius DS18B20
  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(propRelay4)+ " ";        //Status HI=off, LOW=on GROWLED RELAY4
  html += (propKlok)+ " ";                                     //DateTime DS1307
  html += String(propLEDhours) + " ";       //Number of hours around noon RELAY4

  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 showMonitor(){ //Shows all values at the serial monitor RS232 *************
  Serial.println(html);                              //Print the answer to RS232
} //ExitshowMonitor(){ Shows all values at the serial monitor RS232 ------------


void printWifiStatus() { //Show relevant network settings to the user RS232 ****
  Serial.println("You're connected to the network");    //Used at initialisation
  Serial.print("SSID: ");     //Print the SSID of the network you're attached to
  Serial.println(WiFi.SSID());                               //Print Router name 
  IPAddress ip = WiFi.localIP();                         //Print your IP address
  Serial.print("IP Address: ");                   //Print text for understanding
  Serial.println(ip);                                               //IP address
} //Exit printWifiStatus -------------------------------------------------------



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 initializeWiFI(){ //Initializes and connects to network *******************
  WiFi.init(&Serial1);                            //Initialize ESP01 module WIFI
  if (WiFi.status() == WL_NO_SHIELD) {   //Check the presence of the module WIFI
    Serial.println("WiFi module not present");    //Show error to the user RS232
    while (true);                  //Don't continue by looping here forever WIFI
  } //End of if (WiFi.status() == WL_NO_SHIELD) {        Check the presence WIFI
  while (status != WL_CONNECTED) {     //Attempt connecting to WiFi network WIFI
    Serial.print("Attempting to connect to WPA SSID: "); //Show connecting RS232
    Serial.println(ssid);            //Show fixed network name to the user RS232
    status = WiFi.begin(ssid, pass);             //Connected to WPA/WPA2 network
  } //End of while (status != WL_CONNECTED)  Keep on trying until connected WIFI
  printWifiStatus();          //Show relevant network settings to the user RS232
  server.begin();                         //Start the web server on port 80 WIFI
} //End of initializeWiFI(){ Initializes and connects to network ---------------




void ESP01setSpeed(){ //Initializes the modem to 57600 WIFI ESP01 **************
  Serial1.begin(115200);                     //Can be 115200 or 57600 WIFI ESP01
  Serial1.setTimeout(5000);                      //1000 = default for WIFI ESP01
  readESP01();                                            //Empty serial buffers

  Serial.println("Test if AT system works correctly: ");    //General test ESP01
  Serial1.println("AT");                      //Send the AT command to the ESP01
  readESP01();                                     //Receive data from the ESP01
  Serial.println(inStri);                    //Show answer at the SERIAL MONITOR

  Serial.println("Restart ESP01: ");                   //Reset to defaults ESP01
  Serial1.println("AT+RST");                  //Send the AT command to the ESP01
  readESP01();                                     //Receive data from the ESP01
  Serial.println(inStri);                    //Show answer at the SERIAL MONITOR

  Serial.println("Print firmware version: ");            //Firmware of the ESP01
  Serial1.println("AT+GMR");                  //Send the AT command to the ESP01
  readESP01();                                     //Receive data from the ESP01
  Serial.println(inStri);                    //Show answer at the SERIAL MONITOR

  Serial.println("Lists all valid modes: ");        //Modes of Wifi on the ESP01
  Serial1.println("AT+CWMODE?");              //Send the AT command to the ESP01
  readESP01();                                     //Receive data from the ESP01
  Serial.println(inStri);                    //Show answer at the SERIAL MONITOR

  Serial.println("Lists available Access Points: ");        //Networks for ESP01
  Serial1.println("AT+CWLAP");                //Send the AT command to the ESP01
  readESP01();                                     //Receive data from the ESP01
  Serial.println(inStri);                    //Show answer at the SERIAL MONITOR

  Serial.println("Test if AT system works correctly: ");    //General test ESP01
  Serial1.println("AT");                      //Send the AT command to the ESP01
  readESP01();                                     //Receive data from the ESP01
  Serial.println(inStri);                    //Show answer at the SERIAL MONITOR
  
  Serial.println("Set to slower communication rate: ");      //General set ESP01
  Serial1.println("AT+UART_DEF=57600,8,1,0,0");      //Send command to the ESP01
  readESP01();                                     //Receive data from the ESP01
  Serial.println(inStri);                    //Show answer at the SERIAL MONITOR
  
  Serial.println("Test if AT system works correctly: ");    //General test ESP01
  Serial1.println("AT");                      //Send the AT command to the ESP01
  readESP01();                                     //Receive data from the ESP01
  Serial.println(inStri);                    //Show answer at the SERIAL MONITOR
} //Exit ESP01setSpeed ---------------------------------------------------------





void readESP01(void){ //Receive and proces AT data from the ESP01 **************
  delay(10);                                    //Give some time to answer ESP01
  inStri = "";                                       //Reset receive string WIFI
  while (Serial1.available() > 0) {        //Check if any request available WIFI
    inStri = inStri + Serial1.readString();     //Read incoming characters ESP01
    delay(500);             //Give some time to retreive data from the net ESP01 
  } //End of while (Serial1.available() > 0)    Entire block has been read ESP01
  if (inStri == "") {                          //Check if any error is made WIFI
    inStri = "No answer received";     //Default answer if nothing received WIFI
  } //End of if (inStri <> "")                   Check if any error is made WIFI
} //Exit readESP01 -------------------------------------------------------------








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_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 *******
  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
  
  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
} //Exit test_LEDs -------------------------------------------------------------





void beep(uint8_t ms) { //Create a beep with KY-012 active buzzer **************
  digitalWrite(buzAct,HIGH);                                    //Turn buzzer on
  while (ms > 0){                            //Timer of the duration of the beep
    delay(5);                                                //Wait milliseconds
    ms--;                                     //Countdown untill we reached zero
  }            //Timer of the duration of the beep has been counted down to zero
  digitalWrite(buzAct,LOW);        //Turn annoying buzzer off as fast as you can
} //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 - IDE - Function          - External Connection    FUNC //
//                                                                            //
// CONNECTIONS RAILS TOP LEFT: DIGITAL PWM<~> ******************************* //
// SCL    -  28 - PC5 -19/A5- ADC5/SCL/PCINT13  - DS1307 SCL orange       TWI //
// SDA    -  27 - PC4 -18/A4- ADC4/SDA/PCINT12  - DS1307 SDA white        TWI //
// AREF   -  31 - REF -     - AREF              -                         REF //

// 13 PWM -  26 - PB7 -  13 - OC0A/OC1C/PCINT17 - LED Arduino LED_BUILTIN PWM //
// 12 PWM -  18 - PB6 -  12 - OC1B/PCINT16      -                         PWM //
// 11 PWM -  17 - PB3 -  11 - MOSI/OC2A/PCINT3  -                         PWM //
// 10 PWM -  16 - PB2 -  10 - SS/OC1B/PCINT2    -                         PWM //
//  9 PWM -  15 - PB1 -   9 - OC1A/PCINT1       -                         PWM //
//  8 PWM -  14 - PB0 -   8 - PCINT0/CLK0/ICP1  -                         DIO //
//                                                                            //
// CONNECTIONS RAILS TOP MIDDLE: DIGITAL PWM<~> ***************************** //
//  7 PWM -  13 - PD7 -   7 - PCINT23/AIN1      -                         PWM //
//  6 PWM -  12 - PD6 -   6 - PCINT22/OCA0/AIN0 -                         PWM //
//  5 PWM -  11 - PD5 -   5 - PCINT21/OC0B/T1   -                         PWM //
//  4 PWM -   6 - PD4 -   4 - PCINT20/XCK/T0    -                         PWM //
//  3 PWM -   5 - PD3 -   3 - PCINT19/OC2B/INT1 -                         PWM //
//  2 PWM -   4 - PD2 -   2 - PCINT18/INT0      -                         INT //
//  1 TX0 -   3 - PD1 -   1 - PCINT17/TXD       - Serial monitor          TX0 //
//  0 RX0 -   2 - PD0 -   0 - PCINT16/RCD       - Serial Monitor          RC0 //
//                                                                            //
// CONNECTIONS RAILS TOP RIGHT: DIGITAL PWM<~> ****************************** //
// 14 TX3 -  13 - PD7 -   7 - PCINT23/AIN1      -                         DIO //
// 15 RX3 -  12 - PD6 -   6 - PCINT22/OCA0/AIN0 -                         PWM //
// 16 TX2 -  11 - PD5 -   5 - PCINT21/OC0B/T1   -                         TX2 //
// 17 RX2 -   6 - PD4 -   4 - PCINT20/XCK/T0    - DS18B20 green           RX2 //
// 18 TX1 -   5 - PD3 -   3 - PCINT19/OC2B/INT1 - Transmit to ESP01 blue  INT //
// 19 RX1 -   4 - PD2 -   2 - PCINT18/INT0      - Rec from ESP01 yellow   INT //
// 20 SDA -   3 - PD1 -   1 - PCINT17/TXD       - DS1307 white            TWI //
// 21 SCL -   2 - PD0 -   0 - PCINT16/RCD       - DS1307 orange           TWI //
//                                                                            //
// CONNECTIONS RAILS BOTTOM LEFT: POWER ************************************* //
// 5V     -   7 - VCC -     - VCC               -                         VCC //
// RES    -   1 - RES -     - PCINT14/RESET     -                         RES //
// 3.3V   -     -     -     -                   -                             //
// 5V     -     -     -     -                   -                             //
// GND    -     -     -     -                   -                             //
// GND    -     -     -     -                   -                             //
// Vin    -     -     -     -                   -                             //
//                                                                            //
// CONNECTIONS RAILS BOTTOM CENTER: ANALOG IN ******************************* //
// A0     -  23 - PC0 -A0/14- ADC0/PCINT8       -                         ADC //
// A1     -  24 - PC1 -A1/15- ADC1/PCINT9       -                         ADC //
// A2     -  25 - PC2 -A2/16- ADC2/PCINT10      -                         ADC //
// A3     -  26 - PC3 -A3/17- ADC3/PCINT12      -                         ADC //
// A4     -  27 - PC4 -A4/18- ADC4/SDA/PCINT12  -                         TWI //
// A5     -  28 - PC5 -A5/19- ADC5/SCL/PCINT13  -                         TWI //
//                                                                            //
// CONNECTIONS RAILS BOTTOM RIGHT: ANALOG IN ******************************** //
// A08    -  89 - PK0 -     - ADC1 4/PCINT?     - Moisture Capac yellow   ADC //
// A09    -  88 - PK1 -     - ADC15/PCINT?      -                         ADC //
// A10    -  87 - PK2 -     - ADC14/PCINT?      -                         ADC //
// A11    -  86 - PK3 -     - ADC15/PCINT?      -                         ADC //
// A12    -  85 - PK4 -     - ADC14/PCINT?      -                         ADC //
// A13    -  84 - PK5 -     - ADC15/PCINT?      -                         ADC //
// A14    -  83 - PK6 -     - ADC14/PCINT22     -                         ADC //
// A15    -  82 - PK7 -     - ADC15/PCINT23     -                         ADC //
//                                                                            //
// CONNECTIONS RAILS QUER RIGHT ********************************************* //
// Board  -Atmel- PIN - IDE - Function          - External Connection    FUNC //
// 32     -  58 - PC5 -     - DIO               -                         DIO //
// 44     -  40 - PL5 -     - OC5C              - 3 Color led Red         PWM //
// 45     -  39 - PL4 -     - OC5B              - 3 Color led Blue        PWM //
// 46     -  38 - PL3 -     - OC5A              - 3 Color led Green       PWM //
// 47     -  37 - PL2 -     - T5                - DHT22 one-wire white    DIO //
// 48     -  36 - PL1 -     - ICP5              - Relais 1 brown          DIO //
// 49     -  35 - PL0 -     - ICP4              - Relais 2 brown          DIO //
// 50     -  22 - PB3 -     - MISO/PCINT3       - Relais 3 brown          SPI //
// 51     -  21 - PB2 -     - MOSI/PCINT2       - Relais 4 brown          SPI //
// 52     -  20 - PB1 -     - SCK/PCINT1        - Activ buzzer blue       SPI //
// 53     -  19 - PB1 -     - SS/PCINT0         -                         SPI //
// 54     -     - GND -     - GND               -                         GND //
// 55     -     - GND -     - GND               -                         GND //
////////////////////////////////////////////////////////////////////////////////


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


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