////////////////////////////////////////////////////////////////////////////////
// Naam:       Couveuse1-07.ino                                               //
//             01 = WIFI test and optimizing.                                 //
//             02 = Data output adapted to PHP an clock handling optimized.   //
//                  Wifimodule present checked.                               //
//             03 = Homecomming. First tests in new casing.                   //
//                  LED, Reset, Relais, DS18B20, Wifi                         //
//             04 = Ethernet. First tests in new casing.                      //
//             05 = LEDdisplay.                                               //
//             06 = Geoptimaliseerd voor Domoticz.                            //
//             07 = MQTT, WiFi uit, Ethernet bibliotheek wissel.              //
//                                                                            //
// LET OP: WERKT ENKEL INDIEN *.h EN CCP WORDEN MEEGEINSTALLEERD IN PROGRAMMA //
//                                                                            //
// http://robotigs.com/robotigs/includes/bots_header.php?idbot=17             //
//             Robot that controls Couveuse1                                  //
// Created by: HARB rboek2@gmail.com August 2020 GPL copyrights               //
// Platform:   Arduino Mega 2560                                              //
////////////////////////////////////////////////////////////////////////////////
// As outputs the following modules are mounted:                              //
// - Standard Arduino Onboard LED (PWM)                                       //
//           http://robotigs.nl/robotigs/includes/parts_header.php?idpart=185 //
// - 3 color LED (PWM)                                                        //
//           http://robotigs.nl/robotigs/includes/parts_header.php?idpart=293 //
// - Activ loudspeaker / buzzer                                               //
//           http://robotigs.nl/robotigs/includes/parts_header.php?idpart=240 //
// - 220 Vac Relay                                                            //
//           http://robotigs.nl/robotigs/includes/parts_header.php?idpart=189 //
//                                                                            //
// As inputs the following modules are mounted:                               //
// - DS1307 Real Time Clock                                                   //
//           http://robotigs.nl/robotigs/includes/parts_header.php?idpart=289 //
// - Temp DS18B20                                                             //
//           http://robotigs.nl/robotigs/includes/parts_header.php?idpart=180 //
//                                                                            //
// For communications and statistics are mounted:                             //
// - Standard Serial Monitor output                                           //
//            http://robotigs.nl/robotigs/includes/parts_header.php?idpart=43 //
// - Lan ENC28J60 unit                                                        //
//           http://robotigs.nl/robotigs/includes/parts_header.php?idpart=313 //
////////////////////////////////////////////////////////////////////////////////


// 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 <RTClib.h>        //Manipulates clock via I2C needs Wire.h lib DS1307
                      // http://robotigs.nl/robots/includes/parts.php?idpart=289
  #include <Wire.h>     //Needed ao by RTClib: Two Wire Interface lib TWI DS1307
                      //  http://robotigs.nl/robots/includes/parts.php?idpart=31
  #include <OneWire.h>    //Library can be installed through Arduino IDE DS18B20
                      // http://robotigs.nl/robots/includes/parts.php?idpart=180
  #include <EEPROM.h>               //Needed to read or write settings in EEPROM
                      // http://robotigs.nl/robots/includes/parts.php?idpart=312
  #include <SPI.h>  //Serial Peripheral Interface requiered by software ENC28J60
                      //  http://robotigs.nl/robots/includes/parts.php?idpart=28
  #include <UIPEthernet.h>                  //Librairy for ethernet Lan ENC28J60
                      // http://robotigs.nl/robots/includes/parts.php?idpart=313
  #include "LEDDisplayDriver.h"                   //Bibliotheek voor LED DISPLAY
                      // http://robotigs.nl/robots/includes/parts.php?idpart=356
  #include <PubSubClient.h>               //Bibliotheek voor een client van MQTT
                      // http://robotigs.nl/robots/includes/parts.php?idpart=114

  //Define PINS ----------------------------------------------------------------
  OneWire term1(38);         //Connects to pin 17, but may be any DIO pin DS1820
  #define heaterPin    40     //220Vac DIO output pin connects VERWARMING RELAY1
  #define lightPin     42    //220Vac DIO output pin connects VERLICHTING RELAY2
  #define ledRedPin    44         //3 Colour LED, which PWM pin connects RED LED
  #define ledGrePin    45       //3 Colour LED, which PWM pin connects GREEN LED
  #define ledBluPin    46        //3 Colour LED, which PWM pin connects BLUE LED
  #define buzActPin    A0          //Define DIO output pin connects ACTIV BUZZER
  const byte dataPin  = 7;               //Functioneert als SDA voor LED DISPLAY
  const byte clockPin = 6;               //Functioneert als SCL voor LED DISPLAY
  
  #define clockChisel  32           //Device select line intended for TWI DS1307
  const int chipSelect = 49;//SPI Chip select LAN pin mut be 53, so SDcard is 49
    //#define SpiMISO  = 50           //PB3 -- MISO/PCINT3  SPI pin LAN ENC28J60
    //#define SpiMOSI  = 51            //PB2 -- MOSI/PCINT2 SPI pin LAN ENC28J60
    //#define SpiSCK   = 52             //PB1 -- SCK/PCINT1 SPI pin LAN ENC28J60
    //#define SpiSS    = 53              //PB0 -- CS/PCINT0 SPI pin LAN ENC28J60

  //Define EEPROM variables ----------------------------------------------------
  int     progHeater = EEPROM.read(1);     //VERWARMING 1=off 2=auto 3=on RELAY1
  int     tempOn     = EEPROM.read(2);       //Temp Celcius verwarming ON RELAY1
  int     tempOff    = EEPROM.read(3);      //Temp Celcius verwarming OFF RELAY1
  int     progLed    = EEPROM.read(4);    //VERLICHTING 1=off 2=auto 3=on RELAY2
  int     hoursLed   = EEPROM.read(5);       //Burning hours around 13:00 RELAY2
  int     ledRedBril = EEPROM.read(6);            //Current brillance of RED LED
  int     ledGreBril = EEPROM.read(7);          //Current brillance of GREEN LED
  int     ledBluBril = EEPROM.read(8);           //Current brillance of BLUE LED
  int     freqMeasSec= EEPROM.read(9);   //Measurement sensors every seconds SYS
  int     versionMaj = EEPROM.read(10);                       //Versie Major SYS
  int     versionMin = EEPROM.read(11);                       //Versie Minor SYS
  int     versionRev = EEPROM.read(12);                    //Versie Revision SYS
  int     serialNum  = EEPROM.read(13);                      //Serial Number SYS

  //Define DATABASE VARIABLES --------------------------------------------------
  int     jaar           = 1991;                   //Read or set the year DS1307
  int     maand          =   12;                  //Read or set the month DS1307
  int     dag            =   31;                    //Read or set the dag DS1307
  int     uur            =   23;                    //Read or set the uur DS1307
  int     minuut         =   59;                 //Read or set the minuut DS1307
  int     seconde        =   59;                //Read or set the seconds DS1307
  bool    heaterStatus   = HIGH;   //Status HIGH=off or LOW=on VERWARMING RELAY1
  bool    lightStatus    = HIGH;         //Status 1=off, 0=on VERLICHTING RELAY2
  bool    wifiPresent    = false;             //Test if a wifi card is installed
  float   tempDS18B20;                   //Sensor temperature in Celsius DS18B20
  float   tempMeting;                    //Sensor temperature in Celsius DS18B20
  
  //Define variables -----------------------------------------------------------
  bool    ledOnBoardVal   = LOW; //You choose HIGH=on or LOW=off for LED_BUILTIN
  byte    mac[] = {0x00,0x01,0x02,0x03,0x04,0x18};            //For PubSupClient
  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  html    = "";                      //Creating response string INTERNET
  word    readCounter    = 0;     //Read sensors if counted down to zero SENSORS
  int     startHour;                                //Switch ON time VERLICHTING
  int     finishHour;                              //Switch OFF time VERLICHTING
  int     panel          =  1;                                //Panel to PERFORM
  char    commando       =  0;                              //Command to PERFORM
  int     value          =  6;          //Set a temperature or hours for PERFORM
  char    char5[5];             //Needed to convert float to string LAN ENC28J60
  String  receiveStr     = "";              //Commands received by html INTERNET
  char    Temperatuur[8] = "34.8";         //Benodigd om data te publiceren MQTT
  float   temperatuurPrev = 0.0;           //Benodigd om data te publiceren MQTT
  String  opdracht       = "aan";           //Benodigd om data te ontvangen MQTT
  int     tmp1;                                           //Can be used anywhere
  String  tmpStr         = " ";                           //Can be used anywhere


  
  //Initialize OBJECTS ---------------------------------------------------------
  EthernetClient ethClient;                                  //Ethernet INTERNET
  PubSubClient mqttClient(ethClient);                                     //MQTT
  DS1307 rtc;                         //Initialize Real Time Clock object DS1307
  LEDDisplayDriver display(dataPin, clockPin);                     //LED DISPLAY
//END OF PRECOMPILER OPTIONS ---------------------------------------------------




void setup() { //Setup runs once ***********************************************
  disable_jtag();       //Disable jtag to free port C, enabled by default SYSTEM
  Serial.begin(115200);       //Nothing more needed for the Serial Monitor RS232
  Serial.println("SETUP start *****************************");
  Serial.println("");
  pinMode(LED_BUILTIN, OUTPUT);  //Arduino boards contain an onboard LED_BUILTIN
  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
  pinMode(heaterPin, OUTPUT);                 //Set this pin as output to RELAY1
  digitalWrite(heaterPin, heaterStatus);               //Switches OFF the RELAY1
  pinMode(lightPin, OUTPUT);                  //Set this pin as output to RELAY2
  digitalWrite(lightPin, lightStatus);                 //Switches OFF the RELAY2
  
  //Start objects --------------------------------------------------------------
  Serial.println("Start ethernet");
  Ethernet.begin(mac);
  Serial.print("  LocalIP: ");
  Serial.println(Ethernet.localIP());
  Serial.print("  SubnetMask: ");
  Serial.println(Ethernet.subnetMask());
  Serial.print("  GatewayIP: ");
  Serial.println(Ethernet.gatewayIP());
  Serial.print("  DnsServerIP: ");
  Serial.println(Ethernet.dnsServerIP());
  Serial.println("");
    
  Serial.println("Start mqttClient");
  mqttClient.setServer("192.168.2.24", 1883);
  mqttClient.setCallback(callback);
  
  if (mqttClient.connect("Couveuse1", "", "")) {                 //Connection ok
  } else {                                                  // connection failed
    Serial.println(" Connection failed ");
    reconnect();                                 // Loop until we're reconnected
  }
  Serial.println("connected");
  boolean r = mqttClient.subscribe("/2802ZS9/kantoor/couveuse1/actuators/#");
  Serial.print("  subscribe ");
  Serial.println(r);
  r=mqttClient.publish("Couveuse1", "Online");  //Voor de statistieken op broker
  freqMeasSec = 4000;     //Enkel nodig tijdens testen, anders loopt het te snel
  Wire.begin();                 //Start the Two Wire Interface object I2C DS1307
  rtc.begin();    //Initialize Wire.begin first. Start the object running DS1307
  DS1820_init();      //Determins the type of DS1820 and reads properties DS1820
  initVerlichting();              //Calculate start and finisch time VERLICHTING
  //rtc.adjust(DateTime(__DATE__, __TIME__));      //Set to time compiled DS1307
  //EEPROMfirstTime();                    //First time use, set values in EEPROM

  //Test hardware and software -------------------------------------------------
  testLEDs();                 //PWM fade in and fade out for 3in1 + on board LED
  //testRelay();                           //Switches ON for 2 seconds the RELAY
  Serial.println(" ");                   //Show the user the setup is done RS232
  Serial.println("Setup completed");     //Show the user the setup is done RS232
  Serial.println(" ");                   //Show the user the setup is done RS232
} //End of setup ---------------------------------------------------------------





void loop() { //KEEP ON RUNNING THIS LOOP FOREVER  *****************************
  mqttClient.loop(); //This is needed at the top of the loop so its often called
  readSensors();         //Read sensors at timed intervals only and publish data
  readClock();          //Read timestamp and write results into variables DS1307
} //End of void loop() ----------------------- KEEP ON RUNNING THIS LOOP FOREVER






void readSensors() { //Read sensors at timed intervals only ********************
  if (readCounter == 0){       //Only perform measurements if counted down TIMER
    readCounter  =  freqMeasSec;                       //RESET the counter TIMER
    analogWrite(ledGrePin, ledGreBril);     //Green HIGH=on, LOW=off activityLED
    
    DS1820_read();               //Reads the temperature in Celsius from DS18B20
    if (tempDS18B20 != temperatuurPrev){
      if (!mqttClient.publish("/2802ZS9/kantoor/couveuse1/sensors/ds1820/celcius/", Temperatuur)) {
        Serial.println("geen MQTT data verzonden");          //Show activity RS232
      }else{
        temperatuurPrev = tempDS18B20;
      }
    }
    setRelay1();                   //VERWARMING switch, calculate and set RELAY1
    setRelay2();                  //VERLICHTING switch, calculate and set RELAY2
    refreshLEDdisplay();                       //Show data at module LED display
    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 callback(char* topic, byte* payload, unsigned int length) {
  opdracht = "";
  String onderwerp = String(topic);
  //Serial.print("Boodschap ontvangen [");
  //Serial.print(onderwerp);
 // Serial.print("] ");
  for (int i=0;i<length;i++) {
    opdracht += (char)payload[i];
    //Serial.print((char)payload[i]);
  }
  //Serial.println(""); 

  if (onderwerp == "/2802ZS9/kantoor/couveuse1/actuators/verwarming/opdracht/"){
    if (opdracht == "aan"){                                 //1 = VERWARMING AAN
      progHeater = 1;                          //0=unknown, 1=aan, 2=uit, 3=auto
      EEPROM.write(1, 1);                             //Write 1 byte into eeprom
      Serial.println("Opdracht: verwarming aan");
    }
    if (opdracht=="uit"){                                   //2 = VERWARMING UIT
      progHeater = 2;                          //0=unknown, 1=aan, 2=uit, 3=auto
      EEPROM.write(1, 2);                             //Write 1 byte into eeprom
      Serial.println("Opdracht: verwarming uit");
    }
    if (opdracht=="auto"){                                 //3 = VERWARMING AUTO
      progHeater = 3;                          //0=unknown, 1=aan, 2=uit, 3=auto
      EEPROM.write(1, 3);                             //Write 1 byte into eeprom
      Serial.println("Opdracht: verwarming automatisch");
    }
    setRelay1();                           //Calculate and set relay1 VERWARMING
  }



  if (onderwerp=="/2802ZS9/kantoor/couveuse1/actuators/verlichting/opdracht/"){
    if (opdracht == "aan"){                                //1 = VERLICHTING AAN
      progLed = 1;                             //0=unknown, 1=aan, 2=uit, 3=auto
      EEPROM.write(4, 1);                             //Write 1 byte into eeprom
      Serial.println("Opdracht: verlichting aan");
    }
    if (opdracht=="uit"){                                  //2 = VERLICHTING UIT
      progLed = 2;                             //0=unknown, 1=aan, 2=uit, 3=auto
      EEPROM.write(4, 2);                             //Write 1 byte into eeprom
      Serial.println("Opdracht: verlichting uit");
    }
    if (opdracht=="auto"){                                //3 = VERLICHTING AUTO
      progLed = 3;                             //0=unknown, 1=aan, 2=uit, 3=auto
      EEPROM.write(4, 3);                             //Write 1 byte into eeprom
      Serial.println("Opdracht: verlichting automatisch");
    }
    setRelay2();                          //Calculate and set relay1 VERLICHTING
  }
} //Exit callback --------------------------------------------------------------







void reconnect() {   // Loop until we're reconnected
  while (!mqttClient.connected()) {
    Serial.println("Attempting MQTT connection...");
    //String clientId = "Dit is niet echt random";     // Create a random client ID
    if (mqttClient.connect("Couveuse1", "", "")) {
    } else {
      delay(1000);
      Serial.print("failed, rc=");
      Serial.print(mqttClient.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}











void readClock(){ //Read timestamp and write results into variables DS1307 *****
  DateTime now = rtc.now();                           //Read clock object DS1307
  jaar = now.year();            //Needed to http respond the right date and time
  maand = now.month();          //Needed to http respond the right date and time
  dag = now.day();              //Needed to http respond the right date and time
  uur = now.hour();             //Needed to http respond the right date and time
  minuut = now.minute();            //Needed to http respond and watering switch
  seconde = now.second();       //Needed to http respond the right date and time
} //Exit readClock -------------------------------------------------------------





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
  tempDS18B20 = (float)raw / 16.0;      //Until they are in the correct position
  tempDS18B20 = round(tempDS18B20 * 10);       //For correct testing in senddata
  tempDS18B20 = (float)tempDS18B20 / 10;
  Serial.print(tempDS18B20);
  Serial.print(" ");
  dtostrf(tempDS18B20, 6, 1, Temperatuur);    //Leave room for too large numbers
} //Exit DS1820_read -----------------------------------------------------------




void refreshLEDdisplay() { //Show data at module LED display *******************
   display.showNum1decimal(tempDS18B20,0,4);
   display.update();
} //Exit refreshLEDdisplay -----------------------------------------------------





void refreshAnswer(void) { //Replace the old answer by a fresh one INTERNET ****
  html  = String(jaar) + " ";                                        //Timestamp
  html += String(maand) + " ";                                       //Timestamp
  html += String(dag) + " ";                                         //Timestamp
  html += String(uur) + " ";                                         //Timestamp
  html += String(minuut) + " ";                                      //Timestamp
  html += String(seconde) + " ";                                     //Timestamp
  html += String(tempDS18B20) + " ";            //Temperature in Celcius DS18B20
  html += String(heaterStatus) + " "; //Status HIGH=off LOW=on VERWARMING RELAY1
  html += String(progHeater) + " ";        //VERWARMING 1=off 2=auto 3=on RELAY1
  html += String(tempOn) + " ";       //Temperature Celcius verwarming ON RELAY1
  html += String(tempOff) + " ";     //Temperature Celcius verwarming OFF RELAY1
  html += String(lightStatus) + " "; //Status HIGH=off LOW=on VERLICHTING RELAY2
  html += String(progLed) + " ";          //VERLICHTING 1=off 2=aut 3=off RELAY2
  html += String(hoursLed) + " ";       //Hours around 13:00h VERLICHTING RELAY2
  html += String(freqMeasSec);              //How often will the sensors be read
} //Exit refreshAnswer ---------------------------------------------------------



void performCommand() { //Check if any command has been raised *****************
  tmpStr = receiveStr.substring(7, 8);                   //Extract command 01-99
  panel = tmpStr.toInt();               //Translate the function to a executable
  Serial.println(panel);                    //Showing we handeld a request RS232
  tmpStr = receiveStr.substring(9, 10);                  //Extract command 01-99
  commando = tmpStr.toInt();            //Translate the function to a executable
  tmpStr = receiveStr.substring(11,15);                   //Extract value 01-255
  value = tmpStr.toInt();         //Translate into a temerature or hours setting

  Serial.print("-");                        //Showing we handeld a request RS232
  Serial.print(receiveStr);                 //Showing we handeld a request RS232
  Serial.print("-");                        //Showing we handeld a request RS232
  Serial.print(panel);                      //Showing we handeld a request RS232
  Serial.print("-");                        //Showing we handeld a request RS232
  Serial.print(commando + 48);              //Showing we handeld a request RS232
  Serial.println("-");                      //Showing we handeld a request RS232
  switch (panel) {      //Go to the according panel /flora/includes/florabot.php

    case 1: //==================================== Command panel 1 = DS1307 KLOK
      switch (commando) {                        //Go to the according procedure

        case 1:                            //Adjust clock with given time DS1307
          tmpStr = receiveStr.substring(11, 15);             //Extract 0000-9999
          jaar = tmpStr.toInt();                //Translate the data into a year
          tmpStr = receiveStr.substring(16, 18);                 //Extract 01-12
          maand = tmpStr.toInt();              //Translate the data into a month
          tmpStr = receiveStr.substring(19, 21);                 //Extract 01-31
          dag = tmpStr.toInt();                  //Translate the data into a day
          tmpStr = receiveStr.substring(22, 24);                 //Extract 00-23
          uur = tmpStr.toInt();                 //Translate the data into a hour
          tmpStr = receiveStr.substring(25, 27);                 //Extract 00-59
          minuut = tmpStr.toInt();            //Translate the data into a minute
          tmpStr = receiveStr.substring(28, 30);                 //Extract 00-59
          seconde = tmpStr.toInt();          //Translate the data into a seconds
          Serial.println("YES");            //Showing we handeld a request RS232
          Serial.println(uur);                           //Showing data at RS232
          Serial.println(minuut);                        //Showing data at RS232
          Serial.println(seconde);                       //Showing data at RS232
          rtc.adjust(DateTime(jaar, maand, dag, uur, minuut, seconde)); //DS1307
          setRelay2();            //VERLICHTING switch, calculate and set RELAY2
          break;                   //case 1: Adjust clock with given time DS1307

      } //End of switch (commando)                 Go to the according procedure
    break;                                       //Command panel 1 = DS1307 KLOK

    case 2: //===================================== Command panel 2 = VERWARMING
      switch (commando) {                        //Go to the according procedure

        case 1:                                //Set program 1 => VERWARMING OFF
          progHeater = 1;                       //0=unknown, 1=off, 2=on, 3=auto
          EEPROM.write(1, 1);                         //Write 1 byte into eeprom
          setRelay1();                                //Calculate and set relay1
        break;
        case 2:                               //Set program 2 => VERWARMING AUTO
          progHeater = 2;                       //0=unknown, 1=off, 2=on, 3=auto
          EEPROM.write(1, 2);                         //Write 1 byte into eeprom
          setRelay1();                                //Calculate and set relay1
        break;
        case 3:                                 //Set program 3 => VERWARMING ON
          progHeater = 3;                       //0=unknown, 1=off, 2=on, 3=auto
          EEPROM.write(1, 3);                         //Write 1 byte into eeprom
          setRelay1();                                //Calculate and set relay1
        break; 

        case 4:                           //Set aanschakeltemperatuur VERWARMING
          tempOn = value;                                       //Set to reading
          EEPROM.write(2, tempOn);                    //Write 1 byte into eeprom
          setRelay1();                                //Calculate and set relay1
        break;

        case 5:                           //Set uitschakeltemperatuur VERWARMING
          tempOff = value;                                      //Set to reading
          EEPROM.write(3, tempOff);                   //Write 1 byte into eeprom
          setRelay1();                                //Calculate and set relay1
        break;
      } //End of switch (commando)
    break;                                        //Command panel 2 = VERWARMING


    case 3: //==================================== Command panel 3 = VERLICHTING
      switch (commando) {                        //Go to the according procedure

        case 1:                               //Set program 1 => VERLICHTING OFF
          progLed = 1;                          //0=unknown, 1=off, 2=on, 3=auto
          EEPROM.write(4, 1);                         //Write 1 byte into eeprom
          setRelay2();                                //Calculate and set relay2
        break;
        case 2:                              //Set program 2 => VERLICHTING AUTO
          progLed = 2;                          //0=unknown, 1=off, 2=on, 3=auto
          EEPROM.write(4, 2);                         //Write 1 byte into eeprom
          setRelay2();                                //Calculate and set relay2
        break;
        case 3:                                //Set program 3 => VERLICHTING ON
          progLed = 3;                          //0=unknown, 1=off, 2=on, 3=auto
          EEPROM.write(4, 3);                         //Write 1 byte into eeprom
          setRelay2();                                //Calculate and set relay2
        break; 

        case 4:                          //Set aanschakeltemperatuur VERLICHTING
          hoursLed = value;                                     //Set to reading
          EEPROM.write(5, hoursLed);                  //Write 1 byte into eeprom
          initVerlichting();      //Calculate start and finisch time verlichting
          setRelay2();                                //Calculate and set relay2
        break;
      } //End of switch (commando)

   break;                                        //Command panel 3 = VERLICHTING
  } //End of switch (panel)     the according panel /flora/includes/florabot.php
  refreshAnswer();                    //Replace the old answer by a new one WIFI
} //Exit performCommand --------------------------------------------------------




void setRelay1(){ //HEATER switch, calculate and set RELAY1 ********************
  switch (progHeater) {               //HEATER program: 1=off 2=auto 3=on RELAY1
    case 1:                      //Program = 1 = Set program  VERWARMINGSMAT AAN
      heaterStatus = LOW;       //Status HIGH=off, LOW=on VERWARMINGSMAT RELAIS1
    break;                //End of Program = 1 = Set program  VERWARMINGSMAT AAN
    case 2:                      //Program = 2 = Set program  VERWARMINGSMAT UIT
      heaterStatus = HIGH;    //Status HIGH=off or LOW=on  VERWARMINGSMAT RELAY1
    break;                //End of Program = 2 = Set program  VERWARMINGSMAT UIT
    case 3:                      //Program = 2 = Set program VERWARMINGSMAT AUTO
      if (tempDS18B20 < tempOn){               //If treshold measurement TURN ON
        heaterStatus = LOW;         //Status HIGH=off or LOW=on HEATER ON RELAY1
      } //End of                                 If treshold measurement TURN ON
      if (tempDS18B20 > tempOff){             //If treshold measurement TURN OFF
        heaterStatus = HIGH;        //Status HIGH=off or LOW=on HEATER ON RELAY1
      } //End of                                If treshold measurement TURN OFF
    break;                   //End of Program = 3 = Set program COIL HEATER AUTO
  }                                                       //End of switch HEATER
  digitalWrite(heaterPin, heaterStatus);                       //Switches RELAY1
} //Exit setRelay1 -------------------------------------------------------------



void setRelay2(){ //VERLICHTING switch, calculate and set RELAY2 ***************
  switch (progLed) {             //VERLICHTING program: 1=off 2=auto 3=on RELAY2
    case 1:                           //Program = 3 = Set program VERLICHTING ON
      lightStatus = LOW;          //Status HIGH=off or LOW=on VERLICHTING RELAY2
    break; //Case 1              End of Program = 3 = Set program VERLICHTING ON
    case 2:                     //Program = 1 = Set program GROEIVERLICHTING OFF
      lightStatus = HIGH;    //Status HIGH=off or LOW=on GROEIVERLICHTING RELAY4
    break; //Case 2        End of Program = 1 = Set program GROEIVERLICHTING OFF
    case 3:                         //Program = 2 = Set program VERLICHTING AUTO
      if (uur < startHour){                         //Too early, VERLICHTING OFF
         lightStatus = HIGH;      //Switch OFF , HIGH=off LOW=on VERLICHTING OFF
      } //End of if (currenthour < starthours){     //Too early, VERLICHTING OFF
      if (uur > finishHour){                         //Too late, VERLICHTING OFF
         lightStatus = HIGH;      //Switch OFF , HIGH=off LOW=on VERLICHTING OFF
      } //End of if (currenthour > finishhours)        Too late, VERLICHTING OFF
      if (uur > (startHour-1) && uur < (finishHour)){                       //ON
         lightStatus = LOW;         //Switch ON , HIGH=off LOW=on VERLICHTING ON
      } //End of  if (currenthour > (starthours-1) && currenthour <(finishhours)
    break; //Case 3            End of Program = 2 = Set program VERLICHTING AUTO
  } //End of switch (progLed)      VERLICHTING program: 1=off 2=auto 3=on RELAY2
  digitalWrite(lightPin, lightStatus);               //Switch VERLICHTING RELAY2
} //Exit setRelay2 -------------------------------------------------------------





void initVerlichting() { //Calculate start and finisch time VERLICHTING ********
  startHour  = 13 - (hoursLed / 2);       //Calculate switch ON time VERLICHTING
  finishHour = 13 + (hoursLed / 2);      //Calculate switch OFF time VERLICHTING
} //Exit initVerlichting -------------------------------------------------------







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
  }
  tempDS18B20 = (float)raw / 16.0;
} //Exit DS1820_init -----------------------------------------------------------


void EEPROMfirstTime() { //First time use, set values in EEPROM ****************
  EEPROM.write(1,   2);            //progHeater program 1=off 2=auto 3=on RELAY1
  EEPROM.write(2,  15);        //tempOn Temperature Celcius verwarming ON RELAY1
  EEPROM.write(3,  20);      //tempOff Temperature Celcius verwarming OFF RELAY1
  EEPROM.write(4,   2);               //progLed program 1=off 2=auto 3=on RELAY2
  EEPROM.write(5,  14);     //hoursLed Burning hours around noon groeiled RELAY2
  EEPROM.write(6,  10);                //ledRedBril Current brillance of RED LED
  EEPROM.write(7,   5);              //ledGreBril Current brillance of GREEN LED
  EEPROM.write(8,  10);               //ledBluBril Current brillance of BLUE LED
  EEPROM.write(9, 255);  //freqMeasSec Measurement every freqMeasSec seconds SYS
  EEPROM.write(10,  0);                                       //Versie Major SYS
  EEPROM.write(11,  1);                                       //Versie Minor SYS
  EEPROM.write(12,  1);                                    //Versie Revision SYS
  EEPROM.write(13,  4);                                      //Serial Number SYS
  //char    ssid[]       = "*********";               //Network SSID (name) WIFI
  //char    pass[]       = "********";                   //Network password WIFI
} //Exit EEPROMfirstTime -------------------------------------------------------





void testLEDs(void){ //PWM fade in and fade out for 3in1 + on board LED ********
  tmp1 = 0;                      //Brightness of any color, just to test PWM LED

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

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

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

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



void testRelay(){ //Switches ON for 2 seconds all RELAY ************************
  digitalWrite(heaterPin, LOW);                         //Switches ON the RELAY1
  delay (2000);                                             //Wait for 2 seconds
  digitalWrite(heaterPin, HIGH);                       //Switches OFF the RELAY1
  digitalWrite(lightPin, LOW);                          //Switches ON the RELAY2
  delay (2000);                                             //Wait for 2 seconds
  digitalWrite(lightPin, HIGH);                        //Switches OFF the RELAY2
} //End of testRelay(){ Switches ON for 2 seconds the RELAY --------------------



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




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




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



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






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




//345678911234567892123456789312345678941234567895123456789612345678971234567898
////////////////////////////////////////////////////////////////////////////////
// FUSES (can always be altered by using the STK500)                          //
// On-Chip Debug Enabled: off                            (OCDEN=0)            //
// JTAG Interface Enabled: off                           (JTAGEN=0)           //
// Preserve EEPROM mem through the Chip Erase cycle: On  (EESAVE = 0)         //
// Boot Flash section = 2048 words, Boot startaddr=$3800 (BOOTSZ=00)          //
// Boot Reset vector Enabled, default address=$0000      (BOOTSTR=0)          //
// CKOPT fuse (operation dependent of CKSEL fuses        (CKOPT=0)            //
// Brown-out detection level at VCC=2,7V;                (BODLEVEL=0)         //
// Ext. Cr/Res High Freq.; Start-up time: 16K CK + 64 ms (CKSEL=1111 SUT=11)  //
//                                                                            //
// LOCKBITS (are dangerous to change, since they cannot be reset)             //
// Mode 1: No memory lock features enabled                                    //
// Application Protect Mode 1: No lock on SPM and LPM in Application Section  //
// Boot Loader Protect Mode 1: No lock on SPM and LPM in Boot Loader Section  //
////////////////////////////////////////////////////////////////////////////////