////////////////////////////////////////////////////////////////////////////////
// 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  11            //3 Colour LED, which PWM pin connects redLED
  #define ledGrePin  10       //3 Colour LED, to which PWM pin connects greenLED
  #define ledBluPin   9        //3 Colour LED, to which PWM pin connects blueLED
  #define kCePin      8                           //Chip Enable, blue RST DS1302
  #define kIoPin      7                        //Input/Output, yellow DAT DS1302
  #define kSclkPin    6                         //Serial Clock, white CLK DS1302
  #define Relay1Pin   5                //Define to which DIO pin connects RELAY1
  #define Relay2Pin   4                //Define to which DIO pin connects RELAY2
  #define Relay3Pin   3                //Define to which DIO pin connects RELAY3
  #define Relay4Pin   2                //Define to which DIO pin connects RELAY4
  #define ldrPin     A3          //Define to which DA converter pin connects LDR
      
  //Define VARIABLES -----------------------------------------------------------
  bool ledOnBoardVal = LOW;      //You choose HIGH-on or LOW-off for LED_BUILTIN
  bool moistSwitch1 = HIGH;  //HIGH=L>R or LOW=R<L Needed for measurement RELAY1
  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

  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

  float propahours = 14.0; //Number of hours around noon to switch relay1 DS1302
  int starthours = 12 - (propahours / 2);       //Used to switch clock ON DS1302
  int finishhours = 12 + (propahours / 2);     //Used to switch clock OFF DS1302
  int currenthour;           //To compare with starthours and finishhours DS1302
  char buf[50];                                          //Needed to read DS1302
  String propaclock1;        //Timestamp format PgSql yyyy-mm-dd hh:mm:ss DS1302
  DS1302 rtc(kCePin, kIoPin, kSclkPin);    //Create object by name of rtc DS1302


  
//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
//END OF PRECOMPILER OPTIONS ---------------------------------------------------



void setup() { //Setup runs once ***********************************************
  disable_jtag();         //Disable jtag to free port C, enabled by default JTAG
  Serial.begin(9600);        //Nothing more needed for the Serial Monitor RSR232
  pinMode(LED_BUILTIN, OUTPUT);  //Arduino boards contain an onboard LED_BUILTIN
  pinMode(Relay1Pin, OUTPUT);         //Arduino boards contain an onboard RELAY1
  digitalWrite(Relay1Pin, HIGH);                        //Switches OFF the RELAY
  pinMode(Relay2Pin, OUTPUT);         //Arduino boards contain an onboard RELAY2
  digitalWrite(Relay2Pin, HIGH);                        //Switches OFF the RELAY
  pinMode(Relay3Pin, OUTPUT);         //Arduino boards contain an onboard RELAY3
  digitalWrite(Relay3Pin, HIGH);                        //Switches OFF the RELAY
  pinMode(Relay4Pin, OUTPUT);         //Arduino boards contain an onboard RELAY4
  digitalWrite(Relay4Pin, HIGH);                        //Switches OFF the RELAY
    
  DS1820_init();      //Determins the type of DS1820 and reads properties DS1820
  rtc.writeProtect(false);                                              //DS1302
  rtc.halt(false);                                                      //DS1302
  Time t(2018, 06, 20, 16, 03, 00, Time::kFriday);     //UNCOMMENT TO SET TIME
  rtc.time(t); //Set the time and date on the chip   UNCOMMENT TO SET THE TIME

  //test_RELAY();                    //Switches ON for 2 seconds for all 4 RELAY
  test_LEDs();            //PWM fade in and fade out for all 4 LEDs on board LED

  Serial.println("SETUP DS1302 DONE");
  Serial.println(" ");
}//--(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
  ldrVal = analogRead(ldrPin);                     //Read voltage on pin A15 LDR
  DS1820_read();                  //Reads the temperature in Celsius from DS1802
  readTime();        //Reading the time and format results into variables DS1302
  toggle_ledOnBoard();           //Toggles the LED_BUILTIN  ON or OFF onboardLED
  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
  delay(5000);                                      //Just to test your patience
} //End of void loop()                       //KEEP ON RUNNING THIS LOOP FOREVER




void test_RELAY(){ //Switches ON for 2 seconds all RELAY ***********************
  digitalWrite(Relay1Pin, LOW);                          //Switches ON the RELAY
  delay (2000);                                             //Wait for 2 seconds
  digitalWrite(Relay1Pin, HIGH);                        //Switches OFF the RELAY

  digitalWrite(Relay2Pin, LOW);                          //Switches ON the RELAY
  delay (2000);                                             //Wait for 2 seconds
  digitalWrite(Relay2Pin, HIGH);                        //Switches OFF the RELAY
  
  digitalWrite(Relay3Pin, LOW);                          //Switches ON the RELAY
  delay (2000);                                             //Wait for 2 seconds
  digitalWrite(Relay3Pin, HIGH);                        //Switches OFF the RELAY
  
  digitalWrite(Relay4Pin, LOW);                          //Switches ON the RELAY
  delay (2000);                                             //Wait for 2 seconds
  digitalWrite(Relay4Pin, HIGH);                        //Switches OFF the RELAY
} //End of test_Relay(){ Switches ON for 2 seconds the RELAY -------------------




void readTime(){ //DS1302 Reading the time and format results into variables ***
   Time t = rtc.time();            //Get the current time and date from the chip
   snprintf(buf, sizeof(buf), "%04d-%02d-%02d %02d:%02d:%02d",       //Format as
           t.yr, t.mon, t.date,       //Desired by the Pgsql timestamp data type
           t.hr, t.min, t.sec);
   currenthour = t.hr;            //Used to calculate the grow light time switch
   propaclock1 = buf ;                          //Used to export to the database
} //End of DS1302 Reading the time and format results into variables -----------


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





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



void http_check(void) { //See if we received a http request and reply if so ****
  String Request = "";                                    //Reset receive string
  while (Serial.available() > 0) {   //Check if any request is made by a browser
    Request = String(Request + Serial.readString());   //Read incoming character
  } //End of if (Serial.available() > 0)              Entire block has been read
  if (Request != "") {                         //Did I really receive a request?
    //Serial.println(Request);                                //Show the request
    html = "";                              //Always start answer with this line
    html += "<html><head><title>Greenhouse</title></head><body>";   
    html += "gardsoimoi1=";
    html += "</body></html>";

    bodyLength = html.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
    Serial.println(html);                                         //Entire tekst
  } //End of if (inStri <> "")
} //Exit http_check, end of See if we received a http request and reply if so---



////////////////////////////////////////////////////////////////////////////////
// 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 all 4 LEDs on board *******
  /*
  while (brillance<255){
    analogWrite(LED_BUILTIN, brillance);  //Set to desired PWM value LED_BUILTIN
    brillance++;
    delay (msWait);
  }
  while (brillance>0){
    analogWrite(LED_BUILTIN, brillance);  //Set to desired PWM value LED_BUILTIN
    brillance--;
    delay (msWait);
  }
  analogWrite(LED_BUILTIN, 0);  //Set LED to desired PWM value = off LED_BUILTIN


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