#include <TimerOne.h>
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>     // if you don´t have I2C version of the display, use LiquidCrystal.h library instead

LiquidCrystal_I2C lcd(0x27,16,2);  // set the LCD address to 0x27 for a 16 chars and 2 line display

//Declaracion variables de aplicacion
int Tiempo_Coccion = 0;
int Modo_Coccion = 0;
int Estado_Aplicacion = 0;
int cuentas = 0;
int temperatura = 0;
#define RESISTENCIA_TERMICA   9

//Codigos del teclado matricial 
#define CODIGO_TECLA_0        0
#define CODIGO_TECLA_1        1
#define CODIGO_TECLA_2        2
#define CODIGO_TECLA_3        3
#define CODIGO_TECLA_4        4
#define CODIGO_TECLA_5        5
#define CODIGO_TECLA_6        6
#define CODIGO_TECLA_7        7
#define CODIGO_TECLA_8        8
#define CODIGO_TECLA_9        9
#define CODIGO_TECLA_INICIO       10 // *
#define CODIGO_TECLA_FIN          11 // #
#define CODIGO_TECLA_COC_BAJO     12 //Letra A
#define CODIGO_TECLA_COC_MEDIO    13 //Letra B
#define CODIGO_TECLA_COC_ALTO     14 //Letra C
#define CODIGO_TECLA_ACEPTAR    15 //Letra D
#define NO_TECLA_PRESIONADA   256


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

  // Teclado
  TECLADO_HW_Inicializacion();

  // LCD
  lcd.begin(16, 2);
  // Enciende la retroiluminación
  lcd.backlight();
  // Coloca el cursor en la segunda línea
  lcd.setCursor(0, 1);

  // Timer
  Timer1.initialize(1000);  // 1ms
  Timer1.attachInterrupt( Systick_Handler );

  // Inicializamos la resistencia
  pinMode(RESISTENCIA_TERMICA, OUTPUT);
  digitalWrite(RESISTENCIA_TERMICA, LOW);

  // Inicializamos la maquina de estados
  Aplicacion_Init();

}

void Systick_Handler(void)
{
  static int divisor = 0;
  static int TiempoEnvio = 0;
  // Aca vamos a entrar cada 1mseg
  //GPIO_Antirebote();

  TECLADO_Antirebote();

  TiempoEnvio++;

  divisor++;
  if(divisor >= 1000)
  {
    divisor = 0;
    // 1 seg

   if(Tiempo_Coccion > 0)
      Tiempo_Coccion--;
  }

  if(TiempoEnvio >= 6000) //Tiempo de envio configurado cada 6 segundos para poder visualizarlo mas rapido
  {
    if(Tiempo_Coccion > 0)
    {
    TiempoEnvio = 0;
    // 1 seg
    PSerial_Enviar();
    }


  }


}


void loop() {
  //En el loop llamamos a la funcion que carga el tiempo y la temperatura en el display 
  Tiempo_Display();
  //Llamamos para que se ejecute la maquina de estado de la aplicacion desde el loop 
  Aplicacion_MdE();
}