//Reloj mediante interrupciones con registro de temperatura.
// SETA43
// Programa hecho por JUAN GALAZ
//05/02/2013
#include <avr/io.h>
#include <avr/interrupt.h>

#include <LiquidCrystal.h>

#include <OneWire.h>

#include <EEPROM.h>

byte LedPin=8;
byte e1Pin=9;
byte e2Pin=10;

byte horas,minutos,segundos,dias;
byte bandera=0;

char time[15];

OneWire ds(11); // pin utilizado para el bus Onewire
float ftempe;
float sensor1;
float sensor2;

float maxsensor1;
float maxsensor2;
float minsensor1;
float minsensor2;


char titulo[]="Reloj-REC";

int menu1=0;
char* smenu1[]={"-","-","Horas","Minutos","TX registro","Borra registro","Tipo REC","Salir"};
char* mensajes[]={"Transmitiendo ","Clear EEPROM","Mensaje3"};
int menu2=0;
char* smenu2[]={"No REC","10 Seg.","30 Seg.","1 Min.","10 Min.","30 Min.","1 Hora","6 Horas","Dia.MAX.MIN."};

int address = 0;
byte value;
int tem;
int contador;

int z;

LiquidCrystal lcd(2,3,4,5,6,7);


void setup(){
  Serial.begin(9600);
  lcd.begin(16, 2);
  Serial.println(titulo);
  lcd.setCursor(0, 0);
  lcd.print(titulo);
  pinMode(LedPin, OUTPUT);
  pinMode(e1Pin, INPUT);
  pinMode(e2Pin, INPUT);
  cli();
  TCCR1A=0;
  TCCR1B=0;
  OCR1A=15624;
  TCCR1B |= (1<<WGM12);
  TCCR1B |= (1<<CS10);
  TCCR1B |= (1<<CS12);
  TIMSK1=(1<<OCIE1A);
  sei();
}

void loop()
{
  
  
    
  if(bandera==1)
   {
     bandera=0;
     digitalWrite(LedPin, !digitalRead(LedPin));    
     printTime();
   
     if(menu2==0)
       {
        if(segundos==5  || segundos==35)
          {
           LeerSensores();
           printSensor();
          }
       }
     else
       {
         lcd.setCursor(12, 1);
         lcd.print("REC");
         switch (menu2)
           {
            case 1:
              if(segundos==10  || segundos==20 || segundos==30  || segundos==40 ||segundos==50  || segundos==0 )
               {
                Grabar();    
                }            
            break;
            
            case 2:
              if(segundos==0  || segundos==40 )
               {
                Grabar();    
                }   
            break;
            
            case 3:
              if(segundos==10)
               {
                Grabar();    
               }   
            break;
            
            case 4:
              if(segundos==10)
               {
                if(minutos==00 ||minutos==10 ||minutos==20 ||minutos==30 ||minutos==40 ||minutos==50)
                  {
                    Grabar();    
                  }
                }  
            break;
            
            case 5:
              if(segundos==10)
               {
                if(minutos==00 ||minutos==30)
                  {
                    Grabar();    
                  }
                }              
            break;
            
            case 6:
              if(segundos==10 && minutos==00)
                {                
                    Grabar();    
                }  
            break;
            
            case 7:
              if(segundos==10 && minutos==00)
                {                
                 if(horas==0 || horas==6 || horas==12 || horas==18)
                  {
                    Grabar();    
                  }    
                }  
            break;
            
            case 8:
                if(segundos==10 && minutos==00 && horas==00)
                  {
                    Grabar();
                    maxsensor1=-100;
                    maxsensor2=-100;
                    minsensor1=100;
                    minsensor2=100;
                  }
            break;

           }
         if(menu2>2  && segundos==30)
           {
            LeerSensores();
            printSensor();
            if(menu2==8)
              {
               if(sensor1>maxsensor1)maxsensor1=sensor1;
               if(sensor2>maxsensor2)maxsensor2=sensor2;
               if(sensor1<minsensor1)minsensor1=sensor1;
               if(sensor2<minsensor2)minsensor2=sensor2;
              }
           }
        }
   }
  if(!digitalRead(e1Pin))menu1=1;
      
  while(menu1!=0)
    {
      if(!digitalRead(e1Pin)||menu1==1)
       {
        menu1++;
        lcd.clear();
        lcd.print(smenu1[menu1]);
        while(!digitalRead(e1Pin));
        delay(300);
       }
      if(menu1==7)menu1=0;
      switch (menu1)
       {
        case 2:
          if(!digitalRead(e2Pin))
           {
            horas++;
            if(horas==24)horas=0;
            printTime();
            while(!digitalRead(e2Pin));
           }
        break;
        case 3:
          if(!digitalRead(e2Pin))
           {
            minutos++;
            segundos=0;
            if(minutos==60)minutos=0;
            printTime();
            while(!digitalRead(e2Pin));
           }
        break;
        case 4:  //TX registro
          if(!digitalRead(e2Pin))
           {
            Serial.println(mensajes[0]);
            Serial.println(smenu2[menu2]);
            lcd.setCursor(0,1);
            lcd.print(mensajes[0]);
            
            for(address=0;address<510;address++)
              {                
                tem = EEPROM.read(address);
                if(tem>128)tem-=256;
                Serial.print(tem); Serial.print(" ");
                
                tem = EEPROM.read(address+1);
                Serial.print(tem); Serial.print(" ");
                                
                tem = EEPROM.read(address+2);
                if(tem>128)tem-=256;
                Serial.print(tem); Serial.print(" ");
                
                tem = EEPROM.read(address+3);
                Serial.print(tem); Serial.print(" ");
                
                tem = EEPROM.read(address+4);
                Serial.print(tem); Serial.println(" ");                               
              }
            Serial.println(" ")           ;
            while(!digitalRead(e2Pin));
            delay(1000);
            lcd.clear();
            menu1=0;
           }
        break;
        case 5:  //Clear EEPROM
          if(!digitalRead(e2Pin))
           {
            Serial.println(mensajes[1]);
            lcd.setCursor(0,1);
            lcd.print(mensajes[1]);    
             for(address=0;address<512;address++)
              {
               EEPROM.write(address, 255);
              }       
            while(!digitalRead(e2Pin));
            delay(1000);
            lcd.clear();
            menu1=0;
           }
        break;
        case 6:  //Tipo de REC
          if(!digitalRead(e2Pin))
           {
            menu2++;
            if(menu2>8)menu2=0;
            lcd.setCursor(0,1);
            lcd.print("            ");  
            lcd.setCursor(0,1);
            lcd.print(smenu2[menu2]);
            delay(300);        
            while(!digitalRead(e2Pin));
            if(menu2==8)
              {
               maxsensor1=-100;
               maxsensor2=-100;
               minsensor1=100;
               minsensor2=100;
              }          
           }
        break;
       }
      if(menu1==0)printSensor();
    }

 if(!digitalRead(e2Pin))
       {        
         lcd.clear();
         lcd.setCursor(0,1);
         lcd.print(smenu2[menu2]);
         lcd.print("  N.");
         lcd.print(contador);
      
         LeerSensores();
         
         while(!digitalRead(e2Pin));
         sendSensor();
         printSensor();
         lcd.setCursor(0, 1);
         lcd.print("            ");
       }       
}


void Grabar()
{
      LeerSensores();
      sendSensor();
      printSensor();
      contador=0;
      for(address=0;address<505;address+=5)
        {
         contador++;
         if(255==EEPROM.read(address) && 255==EEPROM.read(address+1) && 255==EEPROM.read(address+2) && 255==EEPROM.read(address+3) && 255==EEPROM.read(address+4) )
            {
             if(menu2>0 && menu2<8)
              {               
               value=sensor1;  EEPROM.write(address,value);
               value=sensor2;  EEPROM.write(address+2,value);
               z=sensor1;   ftempe=z;
               if(ftempe==sensor1)
                   EEPROM.write(address+1,0);
                 else
                   EEPROM.write(address+1,50);               
               z=sensor2;   ftempe=z;    
               if(ftempe==sensor2)
                   EEPROM.write(address+3,0);
                 else
                   EEPROM.write(address+3,50);
                   
               if(menu2<4)
                   EEPROM.write(address+4,minutos);
                 else
                   EEPROM.write(address+4,horas);
              }
              
            if(menu2==8)
              {
               value=maxsensor1;  EEPROM.write(address,value);
               value=minsensor1;  EEPROM.write(address+1,value);
               value=maxsensor2;  EEPROM.write(address+2,value);
               value=minsensor2;  EEPROM.write(address+3,value);
               EEPROM.write(address+4,dias);  

              }
             break;
            }
        }
}

void printTime()
{
     sprintf(time,"%02d:%02d:%02d",horas,minutos,segundos);
//     Serial.println(time);
     lcd.setCursor(0, 1);
     lcd.print(time);  
}

void printSensor()
{
    lcd.setCursor(0, 0);
    lcd.print("A>");
    lcd.print(sensor1);
    lcd.print(" B>");
    lcd.print(sensor2);
    lcd.print("  ");   
}

void sendSensor()
{
     Serial.print(sensor1);
     Serial.print(",");
     Serial.print(sensor2);
     Serial.print(" ");
     Serial.println(time);
}

ISR(TIMER1_COMPA_vect)
{
  bandera=1;
  segundos++;
  if(segundos>59)
    {
     segundos=0;
     minutos++;
     if(minutos>59)
         {
          minutos=0;
          horas++;
            if(horas>23)
              {               
               segundos=0;
               minutos=0;
               horas=0;
               dias++;
              }
         }
    }     
}



int LeerSensores()
{
         getTemp(1);
         sensor1=ftempe;
         getTemp(1);
         sensor2=ftempe;
         getTemp(0);

}

int getTemp(char x)
{

byte data[12];
byte addr[8];
char i;
byte MSB;
byte LSB;

  if ( x==0 || !ds.search(addr))
    {
      ds.reset_search();
      return 0;
    }

  if ( OneWire::crc8( addr, 7) != addr[7])
    {
      Serial.println("CRC is not valid!");
      return -1;
    }

  if ( addr[0] != 0x10 && addr[0] != 0x28)
    {
      Serial.print("Device is not recognized");
      return -1;
    }

  ds.reset();
  ds.select(addr);
  ds.write(0x44,1); // start conversion, with parasite power on at the end
  delay(750);  // espera para que carge la tension el IC

  byte present = ds.reset();
  ds.select(addr);
  ds.write(0xBE); // Read Scratchpad

  for ( i = 0; i < 9; i++) data[i] = ds.read();

    MSB = data[1];
    LSB = data[0];

   float tempRead = ((MSB << 8) | LSB); //using two's compliment
   ftempe = tempRead / 2;
  return 1;
}