#include <LiquidCrystal.h>
#include <DHT.h>
#include <avr/io.h>
#include <avr/eeprom.h>
#include <avr/delay.h>
#include <math.h>

#define DHTPIN 24 //Define sensor pin
#define DHTTYPE DHT22 //Define sensor type (DHT11 for prototype)
#define coldBIT 4
#define hotBIT 5
#define inputPin0 PD0
#define inputPin1 PD1
#define inputPin2 PD2
#define inputReg PORTD
#define ledReg PORTA //Define register that controls led

//MACROS 
#define set_bit(y,bit_x) (y|=(1<<bit_x))  
#define clr_bit(y,bit_x) (y&=~(1<<bit_x)) 
#define cpl_bit(y,bit_x) (y^=(1<<bit_x))   
#define tst_bit(y,bit_x) (y&(1<<bit_x))
#define getHigh(bit_x) (1&&bit_x)

int cel_fah = 0; //Variable to indicate which scale to show (0=celsius/1=fahrenheit)
int buz_led = 0; //Variable to indicate which way to alert (0=led/1=buzzer)
int smp_frq = 0; //Variable to indicate what is the sample period (0=4s/1=2s)

uint8_t samplePH[2] = { 0b11110100,
                        0b01111010};

uint8_t samplePL[2] = { 0b00100011,
                        0b00010001};

float t; //Declare the temperature variable

float addr[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; //Declare eeprom address count
float *p = addr;

bool pressed0 = false;

//Array for degree symbol
byte grau[8] ={ B00001100,
                B00010010,
                B00010010,
                B00001100,
                B00000000,
                B00000000,
                B00000000,
                B00000000,};

//initialize the lcd
LiquidCrystal lcd(23, 22, 37, 36, 35, 34);
//initialize the sensor
DHT dht(DHTPIN, DHTTYPE);

void setup() {
  Serial.begin(9600);

  sei();

  //Seting up the 16 bit timer
  TCCR1A = 0b01000000;
  TCCR1B = 0b00001101;
  OCR1AH = samplePH[smp_frq];
  OCR1AL = samplePL[smp_frq];
  TIMSK1 = 0b00000010;

  lcd.begin(16, 2); //Initialize the lcd
  lcd.clear();
  lcd.createChar(0, grau); //Creates the char with the degree symbol

  dht.begin(); //Initialize the sensor

  EICRA = 0b00101010; //Set the interupt 0, 1, 2, 3 to activate on rising edge
  EIMSK = 0x07; //Enable interupt 0, 1, 2

  set_bit(DDRA, coldBIT);
  set_bit(DDRA, hotBIT);
 
}

void loop() {
  printTemp();
  alert();
}

void printTemp(){
  lcd.setCursor(0,0);
  t = dht.readTemperature();

  if(cel_fah){
    float tf = (t*9/5)+32; //Temperature in fahrenheit
    lcd.print(tf);
  }else{
    lcd.print(t);
  }

  lcd.write((byte)0);

  if(cel_fah){
    lcd.print("F");
  }else{
    lcd.print("C");
  }

  if(buz_led){
    lcd.setCursor(8,0);
    lcd.print("sound");
  }else{
    lcd.setCursor(8,0);
    lcd.print("light");
  }

  float sum = 0;
  for(int j=0; j<10; j++){
    float *med_addr = addr;
    if(isnan(eeprom_read_float(med_addr))){
      sum += 0.0;
    }else{
      sum += eeprom_read_float(med_addr);
    }
    med_addr++;
  }

  lcd.setCursor(0, 1);
  lcd.print("med:");

  if(cel_fah){
    float tf_med = sum/10.0;
    tf_med = (tf_med*9/5)+32;
    lcd.print(tf_med);
    lcd.write((byte)0);
    lcd.print("F");
  }else{
    float t_med = sum/10.0;
    lcd.print(t_med);
    lcd.write((byte)0);
    lcd.print("C");
  }
  
  lcd.setCursor(14,0);

  if(smp_frq){
    lcd.print(2);
    lcd.print("s");
  }else{
    lcd.print(4);
    lcd.print("s");
  }
  lcd.setCursor(0,0);
  
  //delay(4000);
}

ISR(INT0_vect){
  _delay_ms(100);
  if(cel_fah){
    cel_fah = 0;
  }else{
    cel_fah = 1;
  }

}

ISR(INT1_vect){
  if(buz_led){
    buz_led = 0;
  }else{
    buz_led = 1;
  }

  delay(125);
}

ISR(INT2_vect){
  if(smp_frq){
    smp_frq = 0;
  }else{
    smp_frq = 1;
  }
  OCR1AH = samplePH[smp_frq];
  OCR1AL = samplePL[smp_frq];

  delay(125);
}

ISR(TIMER1_COMPA_vect){
  eeprom_write_float(p, t);
  if(*p == 9.0){
    p = addr;
  }else{
    p++;
  }

  delay(200);
}

void ledAlert(){
  if(t<24){
      clr_bit(ledReg, hotBIT);
      set_bit(ledReg, coldBIT);
  }
  if(t>32){
    clr_bit(ledReg, coldBIT);
    set_bit(ledReg, hotBIT);
  }
  if(t>24 && t<32){
    clr_bit(ledReg, hotBIT);
    clr_bit(ledReg, coldBIT);
  }
}

void buzAlert(){
  if(t<24 || t>32){
    tone(13, 262);
  }else{
    noTone(13);
  }
}

void alert(){
  if(buz_led){
    clr_bit(ledReg, hotBIT);
    clr_bit(ledReg, coldBIT);
    buzAlert();
  }else{
    noTone(13);
    ledAlert();
  }
}
$abcdeabcde151015202530354045505560fghijfghij