/*
 * Temprature & Humidity using DHT22 and 0.96 OLED Display
 * 
 * Sergei Bellagamba January 2018
 * 
 */
 
#include <Arduino.h>
#include <U8g2lib.h>
#include "DHT.h"

enum state {
  button, topHYST, bottomHYST    // 
};
state current_state;

#define DHTPIN 2     // what pin we're connected to
#define DHTTYPE DHT22   // DHT 22  (AM2302)
DHT dht(DHTPIN, DHTTYPE);

#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif

const int  ledpin = 4;
int sensorValue = digitalRead(4);
const int  buttonPinPlus = 6;    // the pin that the pushbutton is attached to
const int  buttonPinMinus = 7;      
const int  buttonPinPause = 5; 
float HYST;      
// Variables will change:
float SEL = 16;   // counter for the number of button presses


int buttonState = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button
int buttonState2 = 0;         // current state of the button
int lastButtonState2 = 0;     // previous state of the button
int buttonState3 = 0;         // current state of the button Pause
int lastButtonState3 = 0;     // previous state of the button Pause



U8G2_SSD1306_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);

long previousMillisOLED = 0;
long intervalOLED = 50; //a
long previousMillisBUTTON = 0;
long intervalBUTTON = 1000;
unsigned long currentMillisBUTTON;  // 


long readVcc() {
  // Read 1.1V reference against AVcc
  // set the reference to Vcc and the measurement to the internal 1.1V reference
  #if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
    ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
  #elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
    ADMUX = _BV(MUX5) | _BV(MUX0);
  #elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
    ADMUX = _BV(MUX3) | _BV(MUX2);
  #else
    ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
  #endif  

  delay(2); // Wait for Vref to settle
  ADCSRA |= _BV(ADSC); // Start conversion
  while (bit_is_set(ADCSRA,ADSC)); // measuring

  uint8_t low  = ADCL; // must read ADCL first - it then locks ADCH  
  uint8_t high = ADCH; // unlocks both

  long result = (high<<8) | low;

  result = 1125300L / result; // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000
  return result; // Vcc in millivolts
}


void draw(void) {
  //  // graphic commands to redraw the complete screen should be placed here
  float h = dht.readHumidity();
  // Read temperature as Celsius
  float t = dht.readTemperature();
  // Read temperature as Fahrenheit
  float f = dht.readTemperature(true);
  //u8g2.drawBox(76,0,2,44);
  float s = SEL;
  
  u8g2.setFont(u8g2_font_t0_11_tr);
  u8g2.setCursor(70, 10);
  u8g2.print("NOW");
  u8g2.setCursor(43, 62);
  u8g2.print("SET");
  u8g2.setCursor(4, 62);
  u8g2.print("H "); u8g2.print(HYST,1);
  u8g2.setFont(u8g2_font_maniac_tn);
  u8g2.setCursor(4, 25);
  u8g2.print(t,1);  // 1 means 1 decimals
  u8g2.setCursor(64, 62);
  u8g2.print(s,1);  // 1 means 1 decimals
  u8g2.setFont(u8g2_font_bubble_tr);     
  u8g2.setCursor(5, 48);
  u8g2.print("on");
  u8g2.drawFrame(1,29,49,22);

  
  if ( readVcc()/100 > 33  ) { 
  u8g2.setFont(u8g2_font_t0_11_tr);
  u8g2.setCursor(106, 9);
  u8g2.print(h,0); u8g2.print("%"); // 0 means 0 decimals
}
else {
  u8g2.drawFrame(69,12,54,15);
  u8g2.setCursor(72, 23);
  u8g2.setFont(u8g2_font_t0_11_tr);
  u8g2.print("RECHARGE");
} //
 
}

void setup(void) {
  
   // initialize the button pin as a input:
  pinMode(buttonPinPlus, INPUT);
  pinMode(buttonPinMinus, INPUT);
  pinMode( ledpin,OUTPUT);
  // initialize the LED as an output:

  // initialize serial communication:
  Serial.begin(9600);
  dht.begin();

  u8g2.begin();  
  digitalWrite(ledpin, HIGH);
  delay (1000);
  digitalWrite(ledpin, LOW);

}

void loop(void) {


SEL = constrain(SEL, 10, 22);  
HYST = constrain(HYST, 0.5, 1.5);  


Serial.print(current_state);
Serial.print(" LED PIN: ");
Serial.print( sensorValue);
Serial.print(" ");
Serial.print( SEL);
Serial.print(" ");
Serial.print( previousMillisBUTTON);
Serial.println(" "); 

uint16_t Vcc = readVcc(); // Vcc in mV
  // read the pushbutton input pin:
  buttonState = digitalRead(buttonPinPlus);
  buttonState2 = digitalRead(buttonPinMinus);
  buttonState3 = digitalRead(buttonPinPause);


   if (buttonState3 != lastButtonState3) {
    // if the state has changed, increment the counter
    if (buttonState3 == HIGH) {
      // if the current state is HIGH then the button went from off to on:
      HYST+= 0.5;
      //Serial.println("on");
      //Serial.print("number of button pushes: ");
      //Serial.println(SEL);
    } //else {
      // if the current state is LOW then the button went from on to off:
      //Serial.println("off");
      //}
    // Delay a little bit to avoid bouncing 50ms
    delay(20);
  }
  // save the current state as the last state, for next time through the loop
  lastButtonState3 = buttonState3;


  // compare the buttonState to its previous state
  if (buttonState != lastButtonState) {
      currentMillisBUTTON = millis();
    // if the state has changed, increment the counter
    if (buttonState == HIGH) {
      // if the current state is HIGH then the button went from off to on:
      SEL+=0.5;
      //Serial.println("on");
      //Serial.print("number of button pushes: ");
      //Serial.println(SEL);
    } //else {
      // if the current state is LOW then the button went from on to off:
      //Serial.println("off");
      //}
    // Delay a little bit to avoid bouncing 50ms
    delay(20);
  }
  // save the current state as the last state, for next time through the loop
  lastButtonState = buttonState;

  if (buttonState2 != lastButtonState2) {
      currentMillisBUTTON = millis();
    // if the state has changed, increment the counter
    if (buttonState2 == HIGH) {
      // if the current state is HIGH then the button went from off to on:
      SEL-=2;
      //Serial.println("on");
      //Serial.print("number of button pushes: ");
      //Serial.println(SEL);
    } //else {
      // if the current state is LOW then the button went from on to off:
      //Serial.println("off");
      //}
    // Delay a little bit to avoid bouncing 50ms
    delay(20);
  }

  // save the current state as the last state, for next time through the loop
  lastButtonState2 = buttonState2;



  
  
   switch (current_state) {                
    case button:  
                          
      if ((SEL > dht.readTemperature())   ) {
      //&& ((currentMillisBUTTON - previousMillisBUTTON > intervalBUTTON)) 
      //digitalWrite(ledpin, LOW);
      current_state = topHYST;  
      }
      break;

    case topHYST:
      digitalWrite(ledpin, HIGH);
      if ( (dht.readTemperature()) >= (SEL + HYST)   ) {
        current_state = bottomHYST;
      }
      
      break;

    case bottomHYST:
      digitalWrite(ledpin, LOW);
      
      if ( (( millis() - currentMillisBUTTON ) < intervalBUTTON)   ) {
        current_state = button;
      }
      else if ((dht.readTemperature()) <= (SEL -1) ) { 
        current_state = topHYST;
      }
            
      break;
     }
   



    // Wait a few seconds between measurements.
  //delay(10);

  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  float h = dht.readHumidity();
  // Read temperature as Celsius
  float t = dht.readTemperature();
  
//  u8g2.firstPage();
//  do {
//   draw();
//  } while ( u8g2.nextPage() );
//  //delay(10);
unsigned long currentMillisOLED = millis();
  if (currentMillisOLED - previousMillisOLED > intervalOLED) {
    previousMillisOLED = currentMillisOLED;
    u8g2.firstPage();
  do {
    draw();
  } while ( u8g2.nextPage() );
  //delay(10);
    
  }

if (HYST > 1)  HYST = 0.5 ;

}