////////////////////////////////////////////////////////////////////////////////
// Name:       Kasrobot-Uno-01                                                //
// Platform:   Arduino UNO R3                                                 //
// Created by: HARB rboek2@gmail.com March 2019 GPL copyrights                //
// http://robotigs.com/robotigs/includes/bots_header.php?idbot=9              //
// This program is made to:                                                   //
// - Relais 1: It will automatically switch on the working light if it        //
//   detects any movement in the dark.                                        //
// - Relais 2: Maintain a set temperature in the greenhouse. This is mainly   //
//   ment to prevent the plants from freezing.                                //
// - Relais 3: Furthermore it can switch the growleds on for any set period   //
//   per day.                                                                 //
// - Relais 4: Will switch the watering system.                               //
// - Relais 5: Will switch an audio bluetooth amplifier.                      //
//           http://robotigs.nl/robotigs/includes/parts_header.php?idpart=189 //
// The settings can be adjusted with any browser from any device and will be  //
// communicated to this robot by WiFi.                                        //
// !! When uploading program do not forget to set BOTH dip-switches to off !! //
////////////////////////////////////////////////////////////////////////////////




////////////////////////////////////////////////////////////////////////////////
// EEPROM MEMORY MAP:                                                         //
// Start End  Number Description                                              //
// 0000  0000    1        Never use this memory location to be AVR compatible //
// 0001  0001    1   WERKVERLICHTING kasLightProg: 1=off 2=on 3=auto   RELAY1 //
// 0002  0002    1     If LDR reaches this kasLightON*10 switch        RELAY1 //
// 0003  0003    1     kasLightSecs*10 werkverlichting on              RELAY1 //
// 0004  0004    1   VERWARMING kasAirHeatProg: 1=off 2=on 3=auto      RELAY2 //
// 0005  0005    1     Celsius kasAirHeatON/10 verwarming switch on    RELAY2 //
// 0006  0006    1     Celsius kasAirHeatOFF/10 verwarming switch off  RELAY2 //
// 0007  0007    1   GROEILED kasLedProg: 1=off 2=on 3=auto            RELAY3 //
// 0008  0008    1     Hours kasLedHours around noon to switch on      RELAY3 //
// 0009  0009    1   WATER kasWaterProg: 1=off 2=on 3=auto             RELAY4 //
// 0010  0010    1     kasWaterSecs*10 to keep watering                RELAY4 //
// 0011  0011    1   AUDIO kasAudioProg: 1=off 2=on 3=auto             RELAY5 //
// 0012  0012    1     kasAudioMins*10 to keep audio playing           RELAY5 //
////////////////////////////////////////////////////////////////////////////////




// SET PRECOMPILER OPTIONS *****************************************************
  //Initialse conditional compiling, uncomment to include, comment to exclude --
  // Do comment for runtime versions
  //#define RS232                 //Uncomment to include Serial Monitor sections

  //Define the needed header files for the precompiler, no charge if not used --
  #include <DHT.h> //Needed for DHT22 and DHT11 Temperature and humidity sensors
             // http://robotigs.nl/robotigs/includes/parts_header.php?idpart=252
  #include <EEPROM.h>                       //Needed for read or write in EEPROM
             // http://robotigs.nl/robotigs/includes/parts_header.php?idpart=312
  #include <RTClib.h>        //Manipulates clock DS1307 via I2C needs Wire.h lib
             // http://robotigs.nl/robotigs/includes/parts_header.php?idpart=289
  #include <Wire.h>                //Needed ao by RTClib: Two Wire Interface lib
              // http://robotigs.nl/robotigs/includes/parts_header.php?idpart=31

  //Define PINS ----------------------------------------------------------------
  #define DHTPIN       10                   //Which DIO input pin connects DHT22
  #define DHTTYPE   DHT22     //What sensor is connected (AM2302) (AM2321) DHT22
  #define ldrPin       A0     //Define to which I/O pin the LDR is connected LDR
  #define ledRedPin     3         //3 Colour LED, which PWM pin connects RED LED
  #define ledGrePin     5       //3 Colour LED, which PWM pin connects GREEN LED
  #define ledBluPin     6        //3 Colour LED, which PWM pin connects BLUE LED
  #define pirPin       11                     //Which DIO input pin connects PIR
  #define Relay1Pin     8         //220Vac switch DIO pin WERKVERLICHTING RELAY1
  #define Relay2Pin    A3              //220Vac switch DIO pin VERWARMING RELAY2
  #define Relay3Pin     9                //220Vac switch DIO pin GROEILED RELAY3
  #define Relay4Pin     7                   //220Vac switch DIO pin WATER RELAY4
  #define Relay5Pin    12                   //220Vac switch DIO pin AUDIO RELAY5

  //Define DATABASE VARIABLES --------------------------------------------------
  String hobbyKlok      = "2019-02-01 23:59:59";               //DateTime DS1307
  int    hobbyPIR       = LOW;             //On=1=high or off=0=low movement PIR
  word   hobbyLDR       = 0;  //Light Depending Resistor measurement, 0-1023 LDR
  float  hobbyAirTemp   = 0;              //Air temperature degree Celsius DHT22
  float  hobbyAirHum    = 0;                     //Air humidity percentage DHT22
  int    hobbyRelay1    = HIGH;  //WERKVERLICHTING status high=off low=on RELAY1
  int    hobbyRelay2    = HIGH;       //VERWARMING status high=off low=on RELAY2
  int    hobbyRelay3    = HIGH;         //GROEILED status high=off low=on RELAY3
  int    hobbyRelay4    = HIGH;            //WATER status high=off low=on RELAY4
  int    hobbyRelay5    = HIGH;            //AUDIO status high=off low=on RELAY5

  //Define DATABASE & EEPROM variables -----------------------------------------
  int    hobbyLightProg = 1; //WERKVERLICHTING program: 1=off 2=on 3=auto RELAY1
  int    hobbyLightON   = 43;           //If LDR reaches this treshold*10 RELAY1
  int    hobbyLightSecs = 30;             //Seconds*10 werkverlichting on RELAY1
  int    hobbyHeatProg  = 1;      //VERWARMING program: 1=off 2=on 3=auto RELAY2
  int    hobbyHeatON    = 10;           //Celsius/10 verwarming switch on RELAY2
  int    hobbyHeatOFF   = 30;          //Celsius/10 verwarming switch off RELAY2
  int    hobbyLEDProg   = 1;        //GROEILED program: 1=off 2=on 3=auto RELAY3
  int    hobbyLEDHours  = 14;            //Hours around noon to switch on RELAY3
  int    hobbyWaterProg = 1;           //WATER program: 1=off 2=on 3=auto RELAY4
  int    hobbyWaterSecs = 6;                //Seconds*10 to keep watering RELAY4
  int    hobbyAudioProg = 1;          //AUDIO programm: 1=off 2=on 3=auto RELAY5
  int    hobbyAudioMins = 6;           //Minutes*10 to keep audio playing RELAY5

  // Define variables ----------------------------------------------------------
  int    ledOnBoardVal  = LOW;   //You choose HIGH-on or LOW-off for LED_BUILTIN
  int    ledbrillance   = 50;        //Brightness of all LED colors PWM TEST LED
  byte   ledmsWait      = 5;            //Test your patience during the TEST LED
  
  byte   ledRedPWM      = 4;         //Current brightness 1-4 PWM TOGGLE RED LED
  byte   ledGrePWM      = 20;     //Current brightness 1-20 PWM TOGGLE GREEN LED
  byte   ledBluPWM      = 1;        //Current brightness 1-3 PWM TOGGLE BLUE LED
  
  word   readCounter    = 0;      //Read sensors if counted down to zero SENSORS
  word   readTimer      = 999;    //Fill readCounter after reaching zero SENSORS
  char   ssid[]         = "Ranonkel9";                //Network SSID (name) WIFI
  char   pass[]         = "Kat14_-5";                    //Network password WIFI
  String html           = "";                //HTML Response preapaired INTERNET
  int    command        = 0;            //Which user command to perform INTERNET
  String commandStr     = "";                   //Create receive string INTERNET
  int    bodyLength     = 0;                       //HTML answer length INTERNET
  char   buf[100];                //Needed to display the date/time stamp DS1307
  int    currenthour;      //Compare with starthours and finishhours for GROWLED
  int    starthours;                                   //Switch ON clock GROWLED
  int    finishhours;                                 //Switch OFF clock GROWLED
  static unsigned long wateringOFFtimer = millis()+ 300000;           //WATERING
  static unsigned long LightOFFtimer = millis()+ 300000;         //WORKING LIGHT
  String tmp            = "";                             //Can be used anywhere
  int    tmp1;                                            //Can be used anywhere
  int    tmp2;                                            //Can be used anywhere

  //Initialize OBJECTS ---------------------------------------------------------
  DHT dht(DHTPIN, DHTTYPE);                            //Initialize DHT22 sensor
  DS1307 rtc;                         //Initialize Real Time Clock object DS1307
//END OF PRECOMPILER OPTIONS ---------------------------------------------------


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

  //EEPROMfirstTime();   //First time use only, write factory settings to EEPROM
  hobbyLightProg = EEPROM.read(1);    //WERKVERLICHTING 1=off 2=on 3=auto RELAY1
  hobbyLightON   = EEPROM.read(2);      //If LDR reaches this treshold*10 RELAY1
  hobbyLightSecs = EEPROM.read(3);        //Seconds*10 werkverlichting on RELAY1
  hobbyHeatProg  = EEPROM.read(4); //VERWARMING program 1=off 2=on 3=auto RELAY2
  hobbyHeatON    = EEPROM.read(5);      //Celsius/10 verwarming switch on RELAY2
  hobbyHeatOFF   = EEPROM.read(6);     //Celsius/10 verwarming switch off RELAY2
  hobbyLEDProg   = EEPROM.read(7);  //GROEILED program: 1=off 2=on 3=auto RELAY3
  hobbyLEDHours  = EEPROM.read(8);       //Hours around noon to switch on RELAY3
  hobbyWaterProg = EEPROM.read(9);     //WATER program: 1=off 2=on 3=auto RELAY4
  hobbyWaterSecs = EEPROM.read(10);         //Seconds*10 to keep watering RELAY4
  hobbyAudioProg = EEPROM.read(11);   //AUDIO programm: 1=off 2=on 3=auto RELAY5
  hobbyAudioMins = EEPROM.read(12);    //Minutes*10 to keep audio playing RELAY5
  calculateGrowLED();               //Calculate start and finisch clock GROEILED

  Serial.begin(57600);         //Nothing more needed for the Serial Monitor WIFI
  pinMode(LED_BUILTIN, OUTPUT);  //Arduino boards contain an onboard LED_BUILTIN
  pinMode(ledRedPin, OUTPUT);           //Make the LED connection output RED LED
  pinMode(ledGrePin, OUTPUT);         //Make the LED connection output GREEN LED
  pinMode(ledBluPin, OUTPUT);          //Make the LED connection output BLUE LED
  pinMode(Relay1Pin, OUTPUT);                //Make the switch output pin RELAY1
  pinMode(Relay2Pin, OUTPUT);                //Make the switch output pin RELAY2
  pinMode(Relay3Pin, OUTPUT);                //Make the switch output pin RELAY3
  pinMode(Relay4Pin, OUTPUT);                //Make the switch output pin RELAY4
  pinMode(Relay5Pin, OUTPUT);                //Make the switch output pin RELAY5
  analogWrite(ledRedPin, 0);             //Set the initial brightness of RED LED
  analogWrite(ledGrePin, 0);           //Set the initial brightness of GREEN LED
  analogWrite(ledBluPin, 0);            //Set the initial brightness of BLUE LED

  //Start objects --------------------------------------------------------------
  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 DHT sensor DHT11
  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 -------------------------------------------------
  test_RELAY();                            //Switches ON for 2 seconds all RELAY
  test_LEDs();       //PWM fade in and fade out for 3 colorLEDs on board ALL LED
} //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
  hobbyKlok = now.format(buf);      //Format the timestap into a variable DS1307
  strncpy(buf,"hh\0",100);                  //Format string for the time GROWLED
  tmp = now.format(buf);           //Format the timestap into a variable GROWLED
  currenthour = tmp.toInt();            //Convert to value for switching GROWLED
  readSensors();          //Read several sensors at timed intervals only SENSORS
  setActuators();                                //Calculate and set all OUTPUTS
  http_check();     //See if we received a http request and reply if so INTERNET
} //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
    hobbyPIR = digitalRead(pirPin); //Read the status of the movement sensor PIR
    hobbyLDR = analogRead(ldrPin);              //Reads light intensity from LDR
    hobbyAirTemp = dht.readTemperature();    //Read temperature as Celsius DHT22
    hobbyAirHum = dht.readHumidity();     //Reading takes 250 milliseconds DHT22
    readCounter  =  readTimer;                         //RESET the counter TIMER
    refreshAnswer();                  //Replace the old answer by a new one DATA
    toggleGreenLed();                          //Toggles ON or OFF the GREEN LED
    setActuators();                              //Calculate and set all OUTPUTS
  }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();                //WERKVERLICHTING switch, calculate and set RELAY1
  setRelay2();                     //VERWARMING switch, calculate and set RELAY2
  setRelay3();                       //GROEILED switch, calculate and set RELAY3
  setRelay4();                          //WATER switch, calculate and set RELAY4
  setRelay5();                          //AUDIO switch, calculate and set RELAY5
} //Exit setActuators ----------------------------------------------------------




void http_check(void) { //See if we received a http request and reply if so ****
  
  commandStr = "";                                        //Reset receive string
  while (Serial.available() > 0) {   //Check if any request is made by a browser
    commandStr = String(commandStr + Serial.readString());       //Read incoming
  } //End of if (Serial.available() > 0)              Entire block has been read

  if (commandStr != "") {                     //Did we really receive a request?
    if (isDigit(commandStr[6])){              //Check if we received any command
      tmp = commandStr.substring(6, 10);             //Extract command 0001-9999
      command = tmp.toInt();            //Translate the function to a executable
      switch (command) {                         //Go to the according procedure


        case 11: //************************ Instructie 11 => WERKVERLICHTING off
          hobbyLightProg = 1;          //0=unknown, 1=off, 2=on, 3=auto, set OFF
          EEPROM.write(1, 1);                         //Write 1 byte into EEPROM
          setRelay1();                        //Switch, calculate and set RELAY1
        break; //End of case 11:            Instructie 11 => WERKVERLICHTING off

        case 12: //************************* Instructie 12 => WERKVERLICHTING on
          hobbyLightProg = 2;           //0=unknown, 1=off, 2=on, 3=auto, set ON
          EEPROM.write(1, 2);                         //Write 1 byte into EEPROM
          setRelay1();                        //Switch, calculate and set RELAY1
        break; //End of case 12:             Instructie 12 => WERKVERLICHTING on

        case 13: //*********************** Instructie 13 => WERKVERLICHTING auto
          hobbyLightProg = 3;         //0=unknown, 1=off, 2=on, 3=auto, set AUTO
          EEPROM.write(1, 3);                         //Write 1 byte into EEPROM
          setRelay1();                        //Switch, calculate and set RELAY1
        break; //End of case 13:           Instructie 13 => WERKVERLICHTING auto



        case 21: //***************************** Instructie 21 => VERWARMING off
           hobbyHeatProg = 1;          //0=unknown, 1=off, 2=on, 3=auto, set OFF
           EEPROM.write(4, 1);                        //Write 1 byte into EEPROM
           setRelay2();                       //Switch, calculate and set RELAY2
         break; //End of case 21:                Instructie 21 => VERWARMING off

        case 22: //****************************** Instructie 22 => VERWARMING on
           hobbyHeatProg = 2;           //0=unknown, 1=off, 2=on, 3=auto, set ON
           EEPROM.write(4, 2);                        //Write 1 byte into EEPROM
           setRelay2();                       //Switch, calculate and set RELAY2
         break; //End of case 22:                 Instructie 22 => VERWARMING on

        case 23: //**************************** Instructie 23 => VERWARMING auto
           hobbyHeatProg = 3;         //0=unknown, 1=off, 2=on, 3=auto, set AUTO
           EEPROM.write(4, 3);                        //Write 1 byte into EEPROM
           setRelay2();                       //Switch, calculate and set RELAY2
         break; //End of case 23:               Instructie 23 => VERWARMING auto



        case 31: //******************************* Instructie 31 => GROEILED off
           hobbyLEDProg = 1;           //0=unknown, 1=off, 2=on, 3=auto, set OFF
           EEPROM.write(7, 1);                        //Write 1 byte into EEPROM
           setRelay3();                       //Switch, calculate and set RELAY3
         break; //End of case 31:                  Instructie 31 => GROEILED off

        case 32: //******************************** Instructie 32 => GROEILED on
           hobbyLEDProg = 2;            //0=unknown, 1=off, 2=on, 3=auto, set ON
           EEPROM.write(7, 2);                        //Write 1 byte into EEPROM
           setRelay3();                       //Switch, calculate and set RELAY3
         break; //End of case 32:                   Instructie 32 => GROEILED on

        case 33: //****************************** Instructie 33 => GROEILED auto
           hobbyLEDProg = 3;          //0=unknown, 1=off, 2=on, 3=auto, set AUTO
           EEPROM.write(7, 3);                        //Write 1 byte into EEPROM
           setRelay3();                       //Switch, calculate and set RELAY3
         break; //End of case 33:                 Instructie 33 => GROEILED auto

/*
            case 84: //******* Instructie 94 => Set Aantal uur per dag GROEILED1
              tempo = commandStr.substring(11, 15);//Extract parameter 0000-0256
              propLED1hours = tempo.toInt();      //Convert to decimal PARAMETER
              EEPROM.write(5, propLED1hours);         //Write 1 byte into EEPROM
              calculateGrowLED1();  //Calculate start and finisch time GROEILED1
              setRelay2();          //GROEILED1 switch, calculate and set RELAY4
            break; //Case 84             Instructie 84 => Set Aantal uur per dag
      
*/
        case 41: //********************************** Instructie 41 => WATER off
           hobbyWaterProg = 1;         //0=unknown, 1=off, 2=on, 3=auto, set OFF
           EEPROM.write(9, 1);                        //Write 1 byte into EEPROM
           setRelay4();                       //Switch, calculate and set RELAY4
         break; //End of case 41:                     Instructie 41 => WATER off

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

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



        case 51: //********************************** Instructie 51 => AUDIO off
           hobbyAudioProg = 1;         //0=unknown, 1=off, 2=on, 3=auto, set OFF
           EEPROM.write(11, 1);                       //Write 1 byte into EEPROM
           setRelay5();                       //Switch, calculate and set RELAY5
         break; //End of case 51:                     Instructie 51 => AUDIO off

        case 52: //*********************************** Instructie 52 => AUDIO on
           hobbyAudioProg = 2;          //0=unknown, 1=off, 2=on, 3=auto, set ON
           EEPROM.write(11, 2);                       //Write 1 byte into EEPROM
           setRelay5();                       //Switch, calculate and set RELAY5
         break; //End of case 52:                      Instructie 52 => AUDIO on

        case 53: //********************************* Instructie 53 => AUDIO auto
           hobbyAudioProg = 3;        //0=unknown, 1=off, 2=on, 3=auto, set AUTO
           EEPROM.write(11, 3);                       //Write 1 byte into EEPROM
           setRelay5();                       //Switch, calculate and set RELAY5
         break; //End of case 53:                    Instructie 53 => AUDIO auto
      } //End of switch (command) the list with possible precedures ------------
    } //End of if (isDigit(Request[6])         /Check if we received any command

    sendHttpResponse();                               //Send a HTTP respnse WIFI
  } //End of if (Request != "") {              //Did we really receive a request
} //Exit http_check, end of See if we received a http request and reply if so---




void setRelay1(){ //WERKVERLICHTING switch, calculate and set RELAY1 **********
  if (LightOFFtimer < millis()) { //If LightOFFtimer SWITCH OFF WERKVERLICHTING
    hobbyRelay1 = HIGH;    //HIGH=off or LOW=on WORKING LIGHT RELAY1 SWITCH OFF
  } //End of if SwitchOFFtimer < millis          kasLightSecs SWITCH OFF RELAY1
  
  switch (hobbyLightProg) {       //Frontlight program: 1=off 2=on 3=auto RELAY1

    case 1:                              //Program = 1 = Set WERKVERLICHTING OFF
      hobbyRelay1 = HIGH;     //Status HIGH=off or LOW=on WERKVERLICHTING RELAY1
    break;                     //End of Program = 1 = Set program FRONTLIGHT OFF
    
    case 2:                               //Program = 2 = Set WERKVERLICHTING ON
      hobbyRelay1 = LOW;        //Status HIGH=off or LOW=on WORKING LIGHT RELAY1
    break;                           //End of Program = 2 = Set WORKING LIGHT ON
    
    case 3:                             //Program = 3 = Set WERKVERLICHTING AUTO
      if (hobbyLDR > hobbyLightON and hobbyPIR == HIGH) {     //Treshold then ON
        hobbyRelay1 = LOW;   //Status HIGH=off or LOW=on WORKING LIGHT ON RELAY1
        LightOFFtimer = millis() + hobbyLightSecs*1000L;   //Set SWTICH OFF TIME
      }  //End of                        If measurement reaches treshold then ON
    break;                            //End of Program = 3 = Set FRONTLIGHT AUTO
    
  }                                               //End of switch frontLightProg
  digitalWrite(Relay1Pin, hobbyRelay1);         //Switches WORKING LIGHTS RELAY1
} //Exit setRelay1 -------------------------------------------------------------




void setRelay2(){ //AIR HEATER switch, calculate and set RELAY2 ****************
  switch (hobbyHeatProg) {        //AIR HEATER program: 1=off 2=on 3=auto RELAY2

    case 1:                           //Program = 1 = Set program AIR HEATER OFF
      hobbyRelay2 = 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
      hobbyRelay2 = 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 (hobbyAirTemp < hobbyHeatON/10){      //If treshold measurement TURN ON
        hobbyRelay2 = LOW;      //Status HIGH=off or LOW=on AIR HEATER ON RELAY2
      } //End of                                 If treshold measurement TURN ON
      if (hobbyAirTemp > hobbyHeatOFF/10){    //If treshold measurement TURN OFF
        hobbyRelay2 = 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, hobbyRelay2);                        //Switches RELAY2
} //Exit setRelay2 -------------------------------------------------------------






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

    case 1:                              //Program = 1 = Set program GROWLED OFF
      hobbyRelay3 = HIGH;               //Status HIGH=off or LOW=on GROWLED RELAY3
    break; //Case 1                 End of Program = 1 = Set program GROWLED OFF

    case 2:                               //Program = 2 = Set program GROWLED ON
      hobbyRelay3 = LOW;                //Status HIGH=off or LOW=on GROWLED RELAY3
    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
         hobbyRelay3 = HIGH;            //Switch OFF, 3HIGH=off LOW=on GROWLED OFF
      } //End of if (currenthour < starthours){         //Too early, GROWLED OFF
      if (currenthour > finishhours){                    //Too late, GROWLED OFF
         hobbyRelay3 = 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
         hobbyRelay3 = 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(Relay3Pin, hobbyRelay3);                        //Switches RELAY3
} //Exit setRelay3 -------------------------------------------------------------




void setRelay4(){ //Aplifier switch, calculate and set RELAY4 ******************
  switch (hobbyWaterProg) {               //AMPLIFIER program: 1=off 2=on RELAY4

    case 1:                            //Program = 1 = Set program AMPLIFIER OFF
      hobbyRelay4 = HIGH;             //Status HIGH=off or LOW=on AMPLIFIER RELAY4
    break; //Case 1               End of Program = 1 = Set program AMPLIFIER OFF

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

  } //End of switch (kasAudioProg)     
  digitalWrite(Relay4Pin, hobbyRelay4);                          //Switches RELAY4

} //Exit setRelay4 -------------------------------------------------------------



void setRelay5(){ //Aplifier switch, calculate and set RELAY4 ******************
  switch (hobbyAudioProg) {                 //AMPLIFIER program: 1=off 2=on RELAY5

    case 1:                            //Program = 1 = Set program AMPLIFIER OFF
      hobbyRelay5 = HIGH;             //Status HIGH=off or LOW=on AMPLIFIER RELAY4
    break; //Case 1               End of Program = 1 = Set program AMPLIFIER OFF

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

  } //End of switch (kasAudioProg)     
  digitalWrite(Relay5Pin, hobbyRelay5);                          //Switches RELAY5
} //Exit setRelay5 -------------------------------------------------------------




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




void refreshAnswer(void) { //Replace the old answer by a new one WIFI **********
  if (String(hobbyAirTemp) == " NAN"){  //Replace answers if not connected DHT22
    hobbyAirTemp = 99.1;     //Both temperature and humidity will affected DHT22
    hobbyAirHum = -1;          //Humidity value gives status not connected DHT22
  } //End of String(kasAirTemp) =  "NAN" Answer corrected if not connected DHT22

  //First but not least tell the client our current sensor values
  html = String(hobbyKlok) + " ";          //DateTime 2019-02-01 23:59:59 DS1307
  html += String(hobbyPIR) + " ";          //ON=1=HIGH or OFF=0=LOW movement PIR
  html += String(hobbyLDR) + " ";                //Light measurement, 0-1023 LDR
  html += String(hobbyAirTemp) + " ";     //Air temperature degree Celsius DHT22
  html += String(hobbyAirHum) + " ";             //Air humidity percentage DHT22

  //Next tell the client about the status of all relay
  html += String(hobbyRelay1) + " ";    //WERKVERLICHTING high=off low=on RELAY1
  html += String(hobbyRelay2) + " ";         //VERWARMING high=off low=on RELAY2
  html += String(hobbyRelay3) + " ";           //GROEILED high=off low=on RELAY3
  html += String(hobbyRelay4) + " ";              //WATER high=off low=on RELAY4
  html += String(hobbyRelay5) + " ";              //AUDIO high=off low=on RELAY5

  //Now tell the current EEPROM values
  html += String(hobbyLightProg) + " ";//WERKVERLICHTNG 1=off 2=on 3=auto RELAY1
  html += String(hobbyLightON) + " ";   //If LDR reaches this treshold*10 RELAY1
  html += String(hobbyLightSecs) + " ";//Seconds*10 werkverlichting burns RELAY1
  html += String(hobbyHeatProg) + " ";    //VERWARMING: 1=off 2=on 3=auto RELAY2
  html += String(hobbyHeatON) + " ";     //Celsius kasHeatON/10 switch on RELAY2
  html += String(hobbyHeatOFF) + " ";  //Celsius kasHeatOFF/10 switch off RELAY2
  html += String(hobbyLEDProg) + " ";         //GrowLED 1=off 2=on 3=auto RELAY3
  html += String(hobbyLEDHours) + " ";  ///Hours around noon to switch on RELAY3
  html += String(hobbyWaterProg) + " ";         //WATER 1=off 2=on 3=auto RELAY4
  html += String(hobbyWaterSecs) + " ";     //Seconds*10 to keep watering RELAY4
  html += String(hobbyAudioProg) + " ";         //AUDIO 1=off 2=on 3=auto RELAY5
  html += String(hobbyAudioMins) + " ";//Minutes*10 to keep audio playing RELAY5
  //Eventually here can follow some current counters              if interesting

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




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




void calculateGrowLED() {             //Calculate start and finish clock GROWLED
  starthours  = 12 - (hobbyLEDHours / 2);     //Calculate switch ON time GROWLED
  finishhours = 12 + (hobbyLEDHours / 2);    //Calculate switch OFF time GROWLED
} //Exit calculateGrowLED ------------------------------------------------------




void EEPROMfirstTime() { //First time use only, write factory settings to EEPROM
  EEPROM.write( 1, 1);  //WERKVERLICHTING kasLightProg: 1=off 2=on 3=auto RELAY1
  EEPROM.write( 2, 10);        //If LDR reaches this kasLightON*10 switch RELAY1
  EEPROM.write( 3, 11);              //kasLightSecs*10 werkverlichting on RELAY1
  EEPROM.write( 4, 1);        //VERWARMING kasHeatProg: 1=off 2=on 3=auto RELAY2
  EEPROM.write( 5, 50);       //Celsius kasHeatON/10 verwarming switch on RELAY2
  EEPROM.write( 6, 70);     //Celsius kasHeatOFF/10 verwarming switch off RELAY2
  EEPROM.write( 7, 1);           //GROEILED kasLedProg: 1=off 2=on 3=auto RELAY3
  EEPROM.write( 8, 10);      //Hours kasLedHours around noon to switch on RELAY3
  EEPROM.write( 9, 1);            //WATER kasWaterProg: 1=off 2=on 3=auto RELAY4
  EEPROM.write(10, 6);                 //kasWaterSecs*10 to keep watering RELAY4
  EEPROM.write(11, 1);            //AUDIO kasAudioProg: 1=off 2=on 3=auto RELAY5
  EEPROM.write(12, 6);            //kasAudioMins*10 to keep audio playing RELAY5
} //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
  digitalWrite(Relay5Pin, LOW);                         //Switches ON the RELAY5
  delay (2000);                                             //Wait for 2 seconds
  digitalWrite(Relay5Pin, HIGH);                       //Switches OFF the RELAY5
} //End of test_Relay(){ Switches ON for 2 seconds the RELAY -------------------




void test_LEDs(void){ //PWM fade in and fade out for 4 LEDs on board ***********
  tmp1 = 0;                           //Reset the counter to set PWM up and down
  
  while (tmp1 < ledbrillance){    //Show LED until maximum brillance reached RED
    analogWrite(ledRedPin, tmp1);             //Set LED to desired PWM value RED
    tmp1++;                                //Increase the brightness by one step
    delay (ledmsWait);                //Built in a pause to make changes visible
  } //End of while (tmp1 < brillance)           Show LED until maximum brillance
  while (tmp1 > 0){      //Show LED until minimum brillance has been reached RED
    analogWrite(ledRedPin, tmp1);             //Set LED to desired PWM value RED
    tmp1--;                                //Decrease the brightness by one step
    delay (ledmsWait);                //Built in a pause to make changes visible
  }//End of while (tmp1 > 0)                    Show LED until minimum brillance
  analogWrite(ledRedPin, 0);                   //Red LED off PWM value = off RED

  while (tmp1 < ledbrillance){  //Show LED until maximum brillance reached GREEN
    analogWrite(ledGrePin, tmp1);           //Set LED to desired PWM value GREEN
    tmp1++;                                //Increase the brightness by one step
    delay (ledmsWait);                //Built in a pause to make changes visible
  } //End of while (tmp1 < brillance)           Show LED until maximum brillance
  while (tmp1 > 0){    //Show LED until minimum brillance has been reached GREEN
    analogWrite(ledGrePin, tmp1);           //Set LED to desired PWM value GREEN
    tmp1--;                                //Decrease the brightness by one step
    delay (ledmsWait);                //Built in a pause to make changes visible
  }//End of while (tmp1 > 0)                    Show LED until minimum brillance
  analogWrite(ledGrePin, 0);               //Green LED off PWM value = off GREEN

  while (tmp1 < ledbrillance){   //Show LED until maximum brillance reached BLUE
    analogWrite(ledBluPin, tmp1);            //Set LED to desired PWM value BLUE
    tmp1++;                                //Increase the brightness by one step
    delay (ledmsWait);                //Built in a pause to make changes visible
  } //End of while (tmp1 < brillance)           Show LED until maximum brillance
  while (tmp1 > 0){     //Show LED until minimum brillance has been reached BLUE
    analogWrite(ledBluPin, tmp1);            //Set LED to desired PWM value BLUE
    tmp1--;                                //Decrease the brightness by one step
    delay (ledmsWait);                //Built in a pause to make changes visible
  }//End of while (tmp1 > 0)                    Show LED until minimum brillance
  analogWrite(ledBluPin, 0);           //Set LED to desired PWM value = off BLUE

  while (tmp1 < ledbrillance){    //Show LED until maximum brillance LED_BUILTIN
    analogWrite(LED_BUILTIN, tmp1);       //Set to desired PWM value LED_BUILTIN
    tmp1++;                                //Increase the brightness by one step
    delay (ledmsWait);                //Built in a pause to make changes visible
  } //End of while (tmp1 < brillance)           Show LED until maximum brillance
  while (tmp1 > 0){       //Show LED until minimum brillance reached LED_BUILTIN
    analogWrite(LED_BUILTIN, tmp1);       //Set to desired PWM value LED_BUILTIN
    tmp1--;                                //Decrease the brightness by one step
    delay (ledmsWait);                //Built in a pause to make changes visible
  }//End of while (tmp1 > 0)                    Show LED until minimum brillance
  analogWrite(LED_BUILTIN, 0);  //Set LED to desired PWM value = off LED_BUILTIN
} //Exit test_LEDs -------------------------------------------------------------




void toggleGreenLed(void){ //Toggles ON or OFF the green LED *******************
  if (ledGrePWM > 0) {                        //Test if the led is on>0 or off=0
    analogWrite(ledGrePin, 0);                 //Set the brightness of LED GREEN
    ledGrePWM = 0;                        //Store the brightness set to this led
  }else{                                  //The led is off so we will turn it on
    analogWrite(ledGrePin,ledbrillance);       //Set the brightness of LED GREEN
    ledGrePWM = ledbrillance;             //Store the brightness set to this led
  } //End of if (ledGrePWM > 0)                 Test if the led is on>0 or off=0
} //Exit toggleGreenLed --------------------------------------------------------




void toggleBlueLed(void){ //Toggles ON or OFF the blue LED *********************
  if (ledBluPWM > 0) {                        //Test if the led is on>0 or off=0
    analogWrite(ledBluPin, 0);                  //Set the brightness of LED BLUE
    ledBluPWM = 0;                        //Store the brightness set to this led
  }else{                                  //The led is off so we will turn it on
    analogWrite(ledBluPin, ledbrillance);       //Set the brightness of LED BLUE
    ledBluPWM = ledbrillance;             //Store the brightness set to this led
  } //End of if (ledBluPWM > 0)                 Test if the led is on>0 or off=0
} //Exit toggleBlueLed ---------------------------------------------------------




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




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





////////////////////////////////////////////////////////////////////////////////
// PIN ALLOCATIONS TABLE ARDUINO UNO                                          //
// Board -Atmel- PIN - IDE - Function          - Connection               ALT //
//                                                                            //
// CONNECTIONS RAILS TOP LEFT: DIGITAL PWM<~> ******************************* //
// SCL   -  28 - PC5 -19/A5- ADC5/SCL/PCINT13  - Clock DS1307             TWI //
// SDA   -  27 - PC4 -18/A4- ADC4/SDA/PCINT12  - Clock DS1307             TWI //
// AREF  -  21 - REF -     - AREF              -                              //
// GND   -  22 - GND -     - GND               -                              //
// 13    -  19 - PB5 -  13 - SCK/PCINT5        - LED Arduino LED_BUILTIN  SPI //
// 12    -  18 - PB4 -  12 - MISO/PCINT4       - Relay5 AUDIO             SPI //
// ~11   -  17 - PB3 -  11 - MOSI/OC2A/PCINT3  - PIR sensor               PWM //
// ~10   -  16 - PB2 -  10 - SS/OC1B/PCINT2    - DHT22                    PWM //
// ~9    -  15 - PB1 -   9 - OC1A/PCINT1       - Relay3 GROEILED          PWM //
// 8     -  14 - PB0 -   8 - PCINT0/CLK0/ICP1  - Relay1 WERKVERLICHTING   DIO //
//                                                                            //
// CONNECTIONS RAILS TOP RIGHT: DIGITAL PWM<~> ****************************** //
// 7     -  13 - PD7 -   7 - PCINT23/AIN1      - Relay4 WATER             DIO //
// ~6    -  12 - PD6 -   6 - PCINT22/OCA0/AIN0 - LED blue                 PWM //
// ~5    -  11 - PD5 -   5 - PCINT21/OC0B/T1   - LED green                PWM //
// 4     -   6 - PD4 -   4 - PCINT20/XCK/T0    -                         INT //
// ~3    -   5 - PD3 -   3 - PCINT19/OC2B/INT1 - LED red                  PWM //
// ~2    -   4 - PD2 -   2 - PCINT18/INT0      -                          INT //
// TX->1 -   3 - PD1 -   1 - PCINT17/TXD       - Serial monitor / WIFI    TXD //
// RX<-0 -   2 - PD0 -   0 - PCINT16/RCD       - Serial Monitor / WIFI    RCD //
//                                                                            //
// 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 RIGHT: ANALOG IN ******************************** //
// A0    -  23 - PC0 -A0/14- ADC0/PCINT8       - LDR                      ADC //
// A1    -  24 - PC1 -A1/15- ADC1/PCINT9       -                          ADC //
// A2    -  25 - PC2 -A2/16- ADC2/PCINT10      -                          ADC //
// A3    -  26 - PC3 -A3/17- ADC3/PCINT12      - Relay2 VERWARMING        ADC //
// A4    -  27 - PC4 -A4/18- ADC4/SDA/PCINT12  - Clock DS1307             TWI //
// A5    -  28 - PC5 -A5/19- ADC5/SCL/PCINT13  - Clock DS1307             TWI //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////




////////////////////////////////////////////////////////////////////////////////
// EEPROM MEMORY MAP:                                                         //
// Start End  Number Description                                              //
// 0000  0000    1        Never use this memory location to be AVR compatible //
// 0001  0001    1   WERKVERLICHTING kasLightProg: 1=off 2=on 3=auto   RELAY1 //
// 0002  0002    1     If LDR reaches this kasLightON*10 switch        RELAY1 //
// 0003  0003    1     kasLightSecs*10 werkverlichting on              RELAY1 //
// 0004  0004    1   VERWARMING kasAirHeatProg: 1=off 2=on 3=auto      RELAY2 //
// 0005  0005    1     Celsius kasAirHeatON/10 verwarming switch on    RELAY2 //
// 0006  0006    1     Celsius kasAirHeatOFF/10 verwarming switch off  RELAY2 //
// 0007  0007    1   GROEILED kasLedProg: 1=off 2=on 3=auto            RELAY3 //
// 0008  0008    1     Hours kasLedHours around noon to switch on      RELAY3 //
// 0009  0009    1   WATER kasWaterProg: 1=off 2=on 3=auto             RELAY4 //
// 0010  0010    1     kasWaterSecs*10 to keep watering                RELAY4 //
// 0011  0011    1   AUDIO kasAudioProg: 1=off 2=on 3=auto             RELAY5 //
// 0012  0012    1     kasAudioMins*10 to keep audio playing           RELAY5 //
////////////////////////////////////////////////////////////////////////////////




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