////////////////////////////////////////////////////////////////////////////////
// Name:       FloraGardenUno-02                                              //
// Platform:   Arduino UNO Rev3                                               //
// Created by: HARB, july 2018, GPL copyrights                                //
// http://robotigs.com/robotigs/includes/bots_header.php?idbot=18             //
// An Arduino Uno is used to switch waterswitch                               //
////////////////////////////////////////////////////////////////////////////////
// /robotigs/includes/parts_header.php?idpart=293

// SET PRECOMPILER OPTIONS *****************************************************
  // Initialse conditional compiling, uncomment to include, comment to exclude -
  // Do comment the next line for runtime versions -----------------------------
  #define RS232             //Uncomment to include Serial Monitor sections RS232
  //#ifdef RS232   //Only include these lines if variable has been defined RS232

  // Define the needed header files for the precompiler, no charge if not used -
  #include <stdio.h>       //http://quadpoint.org/projects/arduino-ds1302 DS1302
  #include <DS1302.h>                   //Copyright (c) 2009, Matt Sparks DS1302
  #include <OneWire.h>    //Library can be installed through Arduino IDE DS18B20

  // Define precompiler variables, runs faster & doesn`t use RAM ---------------
  // Define PINS ---------------------------------------------------------------
  OneWire term1(12);         //Connects to pin 12, but may be any DIO pin DS1820

  #define ledRedPin  44            //3 Colour LED, which PWM pin connects redLED
  #define ledBluPin  45        //3 Colour LED, to which PWM pin connects blueLED
  #define ledGrePin  46       //3 Colour LED, to which PWM pin connects greenLED
  #define DHTPIN     47                            //What DIO pin connects DHT22
  #define DHTTYPE DHT22       //What sensor is connected (AM2302) (AM2321) DHT22

      
  //Define VARIABLES -----------------------------------------------------------
  bool ledOnBoardVal = LOW;      //You choose HIGH-on or LOW-off for LED_BUILTIN
  word ldrVal =   0;                    //Contains last measurement (0-1023) LDR
  byte msWait = 3;                      //Test your patience during the test LED
  byte brillance = 10;           //Brightness of any color, just to test PWM LED

  bool Relay1val = HIGH;         //HIGH=OFF or LOW=ON Needed for settings RELAY1
  bool Relay2val = HIGH;         //HIGH=OFF or LOW=ON Needed for settings RELAY2
  bool Relay3val = HIGH;         //HIGH=OFF or LOW=ON Needed for settings RELAY3
  bool Relay4val = HIGH;         //HIGH=OFF or LOW=ON Needed for settings RELAY4
  
  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;   //0=ok, except old DS1820=1, triggers other calc DS18B20
  byte   addr1[8];  //Array with first 8 bytes of ROM, including address DS18B20
  float  tmp1;        //Used for oneWire to store calculated temperature DS18B20

  char   buf2[100];                             //Needed to receive request WIFI
  String requestCommand;              //Last complete read request sentence WIFI
  String answerCurrent;                //Last complete read answer sentence WIFI
  String answerBuild;      //Answer that is being constructed at the moment WIFI
  
//String record;                   //Needed to store all data to print and write
String html;              //HTML Response preapaired and counted into bodylength
unsigned int bodyLength;                                    //HTML answer length
byte addr[8];    //Array with the first 8 bytes of DS1820 ROM, including address
byte type_s = 0; //0 always ok, except old DS1820 = 1, results in different calc
float  propboxtmp1;      //Switchbox soil temperature in Celsius by DS18B20 99.9
  
  // Initialize OBJECTS --------------------------------------------------------
//END OF PRECOMPILER OPTIONS ---------------------------------------------------



void setup() { //Setup runs once ***********************************************
  disable_jtag();         //Disable jtag to free port C, enabled by default JTAG
  
  Serial.begin(57600);       //Nothing more needed for the Serial Monitor RSR232


  
  pinMode(LED_BUILTIN, OUTPUT);  //Arduino boards contain an onboard LED_BUILTIN
  test_LEDs();            //PWM fade in and fade out for all 4 LEDs on board LED
}//--(end setup )---------------------------------------------------------------



void loop() { //KEEP ON RUNNING THIS LOOP FOREVER ******************************
  //test_LEDs();          //PWM fade in and fade out for all 4 LEDs on board LED
  http_check();         //See if we received a http request and reply if so WIFI
  toggle_ledOnBoard();           //Toggles the LED_BUILTIN  ON or OFF onboardLED
  refreshAnswer();                    //Replace the old answer by a new one WIFI
  http_check();         //See if we received a http request and reply if so WIFI

  Serial.println(answerCurrent);                                //Entire tekst
  delay(5000);                                    //Just to test your patience
} //End of void loop()                       //KEEP ON RUNNING THIS LOOP FOREVER




void http_check(void) { //See if we received a http request and reply if so ****
  String Request = "";                                    //Reset receive string
  String requestCommand = "";                             //Reset command string
  
  if (Serial.available() > 0) {      //Check if any request is made by a browser
    Request = (Request + Serial.readStringUntil('/'));      //Read until command
    requestCommand = (requestCommand + Serial.readStringUntil('K'));   //Command
    while (Serial.available() > 0) {         //Check if any more data by request
      Request = (Request + Serial.readStringUntil('/'));      //Read until empty
    } //End of if (Serial.available() > 0)            Entire block has been read

    Serial.println();    //The content of the HTTP response follows the header:
    Serial.println("HTTP/1.1 200 OK");
    Serial.println("Content-type:text/html");
    Serial.println();    //The content of the HTTP response follows the header:
    //Serial.println(Request);                                    //Entire tekst
    //Serial.println(requestCommand);                             //Entire tekst
    Serial.println(answerCurrent);                                //Entire tekst
    Serial.println();           //Any HTTP response ends with another blank line
    Serial.println();           //Any HTTP response ends with another blank line


    
  } //End of if (Serial.available() > 0)            Entire request has been read

  if (requestCommand != "") {                  //Did I really receive a request?
    test_LEDs();          //PWM fade in and fade out for all 4 LEDs on board LED
      //if (buf2.endsWith("\r\n\r\n")) {   //Check for 2 newline characters in row
      //  sendHttpResponse(client);          //Meaning the end of the HTTP request
      //  break;                     //After the response is sent we are done here
      //} //End of if (buf2.endsWith("\r\n\r\n")) {    //Check for 2 newline chars

      
    //bodyLength = answerCurrent.length();  //Calculate the number of characters to be sent
    //bodyLength = bodyLength + 17;                           //Add the basic text
    //Serial.println("HTTP/1.1 200 OK");                   //Answer to the request
    //Serial.println("Connection: close");          //Close after html is finished
    //Serial.print("Content-Length: ");        //Finish html after amount of chars
    //Serial.println (bodyLength);
    //Serial.println("Content-Type: text/html");         //Needed to be compatible
    //Serial.println(" /n \n");                //Needed to end the headers somehow
    //Serial.println("<!DOCTYPE HTML>");    //Tell the browser what we are sending

  } //End of if (inStri <> "")
} //Exit http_check, end of See if we received a http request and reply if so---



void refreshAnswer(void) {            //Replace the old answer by a new one WIFI
  /*
  answerBuild = (propaclock1);           //Add desired data in fixed length WIFI
  answerBuild = (answerBuild) + (" ") + (tmp1);          //Add desired data WIFI
  answerBuild = (answerBuild) + (" ") + (ldrVal);        //Add desired data WIFI
  answerBuild = (answerBuild) + (" ") + (Relay1val);     //Add desired data WIFI
  answerCurrent = answerBuild + (" ");       //Add a space for the later explode
*/
} //Exit refreshAnswer replace the old answer by a new one WIFI ----------------


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();
  }
  int16_t raw = (data[1] << 8) | data[0];                      //Rotate the data
  tmp1 = (float)raw / 16.0;            //Untill they are in the correct position
} //Exit DS1820_read -----------------------------------------------------------



void DS1820_init(void) { //Determins the type of DS1820 thermometer1 ***********
  if (!term1.search(addr1)) {
    term1.reset_search();
    delay(250);
    return;
  }
  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
  }
  tmp1 = (float)raw / 16.0;
} //Exit DS1820_init -----------------------------------------------------------




///////////////////////////////////////////////////////////////////////////////
// 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  -                          TWI //
// SDA   -  27 - PC4 -18/A4- ADC4/SDA/PCINT12  -                          TWI //
// AREF  -  21 - REF -     - AREF              -                              //
// GND   -  22 - GND -     - GND               -                              //
// 13    -  19 - PB5 -  13 - SCK/PCINT5        - LED_BUILTIN Arduino      SPI //
// 12    -  18 - PB4 -  12 - MISO/PCINT4       - DS1820                   SPI //
// ~11   -  17 - PB3 -  11 - MOSI/OC2A/PCINT3  - LED 3-color red          PWM //
// ~10   -  16 - PB2 -  10 - SS/OC1B/PCINT2    - LED 3-color blue         PWM //
// ~9    -  15 - PB1 -   9 - OC1A/PCINT1       - LED 3-color green        PWM //
// 8     -  14 - PB0 -   8 - PCINT0/CLK0/ICP1  - DS1302 RST blue          DIO //
//                                                                            //
// CONNECTIONS RAILS TOP RIGHT: DIGITAL PWM<~> ****************************** //
// 7     -  13 - PD7 -   7 - PCINT23/AIN1      - DS1302 DAT yellow        DIO //
// ~6    -  12 - PD6 -   6 - PCINT22/OCA0/AIN0 - DS1302 CLK white         PWM //
// ~5    -  11 - PD5 -   5 - PCINT21/OC0B/T1   - Relay1                   PWM //
// ~4    -   6 - PD4 -   4 - PCINT20/XCK/T0    - Relay2                   PWM //
// ~3    -   5 - PD3 -   3 - PCINT19/OC2B/INT1 - Relay3                   INT //
// ~2    -   4 - PD2 -   2 - PCINT18/INT0      - Relay4                   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              - Output to breadboard     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       -                          ADC //
// A1    -  24 - PC1 -A1/15- ADC1/PCINT9       -                          ADC //
// A2    -  25 - PC2 -A2/16- ADC2/PCINT10      -                          ADC //
// A3    -  26 - PC3 -A3/17- ADC3/PCINT12      - LDR purple               ADC //
// A4    -  27 - PC4 -A4/18- ADC4/SDA/PCINT12  -                          TWI //
// A5    -  28 - PC5 -A5/19- ADC5/SCL/PCINT13  -                          TWI //
////////////////////////////////////////////////////////////////////////////////
// EEPROM MEMORY MAP:                                                         //
// Start End  Number Description                                              //
// 0000  0000      1 Never use this memory location to be AVR compatible      //
////////////////////////////////////////////////////////////////////////////////
//345678911234567892123456789312345678941234567895123456789612345678971234567898



void test_LEDs(void){ //PWM fade in and fade out for 3 colorLEDs on board ******
  brillance = 0;
  while (brillance<50){
    analogWrite(ledRedPin, brillance);        //Set LED to desired PWM value RED
    brillance++;
    delay (msWait);
  }
  while (brillance>0){
    analogWrite(ledRedPin, brillance);        //Set LED to desired PWM value RED
    brillance--;
    delay (msWait);
  }
  analogWrite(ledRedPin, 0);            //Set LED to desired PWM value = off RED

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

  while (brillance<50){
    analogWrite(ledBluPin, brillance);       //Set LED to desired PWM value BLUE
    brillance++;
    delay (msWait);
  }
  while (brillance>0){
    analogWrite(ledBluPin, brillance);       //Set LED to desired PWM value BLUE
    brillance--;
    delay (msWait);
  }
  analogWrite(ledBluPin, 0);           //Set LED to desired PWM value = off BLUE
} //Exit test_LEDs -------------------------------------------------------------




void toggle_ledOnBoard(void){ //Toggles the LED_BUILTIN on-board LED on or off *
  //Serial.print(tmp1);                        //Show activity to the user RS232
  //Serial.print(" ");                         //Show activity to the user RS232
  //Serial.print(ldrVal);                      //Show activity to the user RS232
  //Serial.print(" ");                         //Show activity to the user RS232
  //Serial.println(propaclock1);               //Show activity to the user RS232
  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 ----------------------------------------------------------







/*
void writeI2CRegister8bit(int addr, int value) {
  Wire.beginTransmission(addr);
  Wire.write(value);
  Wire.endTransmission();
}
unsigned int readI2CRegister16bit(int addr, int reg) {
  Wire.beginTransmission(addr);
  Wire.write(reg);
  Wire.endTransmission();
  delay(20);
  Wire.requestFrom(addr, 2);
  unsigned int t = Wire.read() << 8;
  t = t | Wire.read();
  return t;
}
*/