#include <16F88.h>
#device ADC=10
#use delay(internal=4000000)
#fuses nowdt,intrc_io,nomclr,nocpd,nobrownout,nolvp,noput,nodebug,nowrt,noprotect
#use fast_io(A)
#use fast_io(B)
#define BAJAR PIN_B7
#define SUBIR PIN_B5
#define ENTER PIN_B6
#define RELE PIN_B1
#define LCD_DATA_PORT getenv("SFR:PORTA")
#define LCD_ENABLE_PIN PIN_A6
#define LCD_RS_PIN PIN_A7
#define LCD_RW_PIN PIN_B3
#define LCD_DATA4 PIN_A1
#define LCD_DATA5 PIN_A2
#define LCD_DATA6 PIN_A3
#define LCD_DATA7 PIN_A4
#include <lcd.c>
// Variables globales
long mem_temp_set;
long sierra = 0;
signed long error2_ant,error2;
long long SumaLectura;
long PromLectura;
long error;
long Temp_actual_ant,Temp_actual;
long Temp_set_ant,Temp_set=50;
int i = 0;
char sys_estado[2][4]={"OFF","ON "};
enum
{
   OFF = 0,
   ON,
};
typedef struct {
   unsigned int estado;
   unsigned int estado_ant;
} SYSInfo;
SYSInfo Sys;
#Int_timer1
void Calculos (void)
{
   set_timer1(45536);
   if (sierra < 400)
   {
      sierra = sierra + 1;
   }
   else
   {
      sierra = 0;
   }
   if (sierra < error2)
   {
      output_high(rele);
   }
   else
   {
      output_low(rele);
   }
}
signed long mapeo (long x, long ent_min, long ent_max, long sal_min, long sal_max)
{
   return (x - ent_min)*(sal_max - sal_min)/(ent_max - ent_min) + sal_min;
}
void sensado_temperatura (void)
{
   if (i < 200)
   {
      SumaLectura = (SumaLectura + read_adc());
      i++;
   }
   else
   {
      PromLectura = SumaLectura/i;
      Temp_actual = (320*PromLectura)/1023;
      i = 0;
      SumaLectura = 0;
   }
}
void main()
{
   set_tris_a (0b00100001) ; // Entradas:A0,A5 - Salidas:A1,A2,A3,A4,A6,A7
   output_a (0);
   set_tris_b (0b11110000); // Entradas:B4,B5,B6,B7 - Salidas:B0,B1,B2,B3
   output_b (0);
   setup_adc_ports(sAN0|VSS_VDD);
   setup_adc(ADC_CLOCK_INTERNAL);
   set_adc_channel(0);
   lcd_init();
   lcd_gotoxy (1,1);
   printf(lcd_putc,"Control de");
   lcd_gotoxy (1,0);
   printf(lcd_putc,"temperatura");
   setup_timer_1 (T1_INTERNAL|T1_DIV_BY_1);
   mem_temp_set = make16(read_eeprom (0),read_eeprom (1));
   if (mem_temp_set < 50)
      mem_temp_set = 50;
   if (mem_temp_set > 350)
      mem_temp_set = 50;
   Temp_set = (float)mem_temp_set;
   enable_interrupts (global);
   Sys.estado_ant = ON;
   Sys.estado = OFF;
   Temp_actual = (320*read_adc())/1023;
   error = Temp_set - Temp_actual;
   error2 = mapeo(error,0,10,0,400);
   delay_ms (1000);
   for(;;)
   {
      sensado_temperatura ();
      if (Temp_set_ant != Temp_set)
      {
         Temp_set_ant = Temp_set;
         lcd_gotoxy (1,1);
         printf(lcd_putc,"TS:%3.0LuC  ",Temp_set);
      }
      if (Temp_actual_ant != Temp_actual)
      {
         Temp_actual_ant = Temp_actual;
         lcd_gotoxy (10,1);
         printf(lcd_putc,"TM:%3.0LuC",Temp_actual);
      }
      if (error2_ant != error2)
      {
         error2_ant = error2;
         lcd_gotoxy (1,0);
         printf(lcd_putc,"ERR:%4.0Ld",error2);
      }
      if (Sys.estado_ant != Sys.estado)
      {
         Sys.estado_ant = Sys.estado;
         lcd_gotoxy (9,0);
         printf(lcd_putc," SIS:%s",sys_estado[Sys.estado]);
      }
      error = Temp_set - Temp_actual;
      error2 = mapeo(error,0,10,0,400);
      if (Sys.estado == ON)
      {
         if (error < 10)
         {
            enable_interrupts (Int_timer1);
         }
         else
         {
            disable_interrupts (Int_timer1);
         }
      }
      if (input(bajar) == 0)
      {
         while(input(bajar) == 0);
         if (Temp_set > 50)
         {
            Temp_set = Temp_set - 1;
            mem_temp_set = (long)Temp_set;
            write_eeprom (0,make8(mem_temp_set,1));
            write_eeprom (1,make8(mem_temp_set,0));
         }
      }
      if (input(subir) == 0)
      {
         while(input(subir) == 0);
         if (Temp_set < 320)
         {
            Temp_set = Temp_set + 1;
            mem_temp_set = (long)Temp_set;
            write_eeprom (0,make8(mem_temp_set,1));
            write_eeprom (1,make8(mem_temp_set,0));
         }
      }
      if (input(enter) == 0)
      {
         while(input(enter) == 0);
         if (Sys.estado == ON)
         {
            disable_interrupts (Int_timer1);
            output_low (rele);
            Sys.estado = OFF;       
         }
         else
         {
            Sys.estado = ON;
            output_high (rele);
         }
      }
   }
}