Version Beta para la FRDM-KL46Z del original de Arduino Uno

Dependencies:   mbed TextLCD

main.cpp

Committer:
RazielLopez
Date:
2018-12-31
Revision:
15:c0bb10aadebc
Parent:
10:fb06357df7d7
Child:
16:15084c17d3b4

File content as of revision 15:c0bb10aadebc:

/*******************************************************************************
*
* ARCHIVO:      main.cpp
*
* PROYECTO:     FRDM-KL46Z_Deshidratador
*
* PLATAFORMA:   FRDM-KL46Z
*
* DISPOSITIVO:  MKL46Z256VLL4
*
* HERRAMIENTA:  Mbed Compiler
*
* DESCRIPCION:  El programa principal lee los datos provenientes del sensor de
*               humedad y temperatura DHT22. Formatea los datos y los despliega
*               por la terminal serial.
*               Posee un menú de Configuración por medio de la Pantalla LCD
*               
*
* VERSION:      Beta
* REV:          A
* RELEASE:      0
*
* AUTOR(ES):    Antulio Morgado Valle, Raziel López Escamilla
*
* FECHA:        10/20/2018
*
* Bugs & Fixes:
* - 30/10/18
*   Se corrigió menu de OTRO (Opera correctamente)
*   Se añadió variable de "error_code" para monitoreo de operación del DHT
*   Se añadió libreria RGB para convertirla a objetos para utilizarse en la 
*   señalización de Alarmas
*   Fallo de control de seguridad al Canceler el Proceso de Deshidratación
*******************************************************************************/

/*
** ===================================================================
**     Librerias del Programa
** ===================================================================
*/
#include "mbed.h"
#include "stdio.h"
#include "TextLCD.h"
#include "I2C.h"
#include "SPI.h"
#include "Serial.h" 
#include "DHT.h"
//#include "Led_RGB.h"

/*
** ===================================================================
**     Definiciones y Constantes del programa.
** ===================================================================
*/

#define LCDFILAS        4
#define LCDCOLUMNAS     20

#define TAPWM           255

#define NOFRUTAS        11
#define CONDALARM       2

#define DHT_TIPO        DHT11
#define DHT_PIN         PTD2
#define  on             0               // Estado para boton presionado
#define off             1               // Estado para boton sin presionar
#define hold            2               // Estado para boton mantenido presionado
#define release         3               // Estado para boton al liberarse 
#define Buzz_On         1               // Buzzer Encendido
#define Buzz_Off        0               // Buzzer Apagado
#define HIGH            1               // 
#define LOW             0               // 
/*
** -------------------------------------------------------------------
**    Inicialización de los Pines de Entrada.
** -------------------------------------------------------------------
*/
DigitalIn   PIN_SWITCH     (PTC4,PullUp);  // Switch de Puerta Abierta
DigitalIn   PIN_BOK        (PTC6,PullUp);  // Botón OK
DigitalIn   PIN_BDERECHO   (PTC7,PullUp);  // Botón DERECHA
DigitalIn   PIN_BARRIBA    (PTC8,PullUp);  // Botón ARRIBA
DigitalIn   PIN_BABAJO     (PTC9,PullUp);  // Botón ABAJO
DigitalIn   PIN_BIZQUIERDO (PTC10,PullUp); // Botón IZQUIERDA
DigitalIn   PIN_BRETURN    (PTC11,PullUp); // Botón RETURN 
/*
** -------------------------------------------------------------------
**    Inicialización de los Pines de Salida.
** -------------------------------------------------------------------
*/
DigitalOut  PIN_BUZZER     (PTB20);  // Buzzer Piezo Eléctrico
DigitalOut  PIN_MOTOR      (PTA12);  // Encendido/Apagado del Elemento de Ventilación 
DigitalOut  Red_Led        (PTE29);  // Led de Actividad del Programa
DigitalOut  Green_Led      (PTD5);   // Led de Actividad del Programa
// Soporte LED RGB
//DigitalOut  Led_Rojo(PTE6);      // Led RGB
//DigitalOut  Led_Verde(PTE3);     // Led RGB
//DigitalOut  Led_Azul (PTE2);     // Led RGB
/*
** -------------------------------------------------------------------
**    Inicialización de las Salidas PWM.
** -------------------------------------------------------------------
*/
PwmOut      PIN_QUEMADOR   (PTE31);  // PWM Control del Elemento Calefactor

/*
** -------------------------------------------------------------------
**    Inicialización de las Entradas Analógicas.
** -------------------------------------------------------------------
*/
//AnalogIn    Temperatura   (PTB0);    // Sensor de Temperatura:       LM35
//AnalogIn    Fotocelda     (PTB1);    // Sensor de Luminosidad:       Fotocelda
//AnalogIn    Ozono         (PTB2);    // Sensor de Ozono:             KS123
/*
** -------------------------------------------------------------------
**    Inicialización de los Pines de Funciones Especiales.
** -------------------------------------------------------------------
*/
/************************************************* 
* Initialize the library with the numbers of the interface pins
* Board Freedom FRDM-KL46Z
* IDE  Mbed On Line Compiler
* LCD  I2C  PCF8574A
* Pin  Board    LCD
*      I2C_SCL  SCL (white) + resistance pull-up 4.7k
*      I2C_SDA  SDA (blue)  + resistance pull-up 4.7k
*      5V       5V  (red)
*      GND      GND (black)
***************************************************/
//LiquidCrystal_I2C lcd(0x7E, LCDCOLUMNAS, LCDFILAS);
//i2c_LCD lcd(0x7E, LCDCOLUMNAS, LCDFILAS);

/************************************************* 
* Initialize the library with the numbers of the interface pins
* Board Freedom FRDM-KL46Z
* IDE  Mbed On Line Compiler
* LCD  SPI  74595
* Pin  Board     LCD
*      SPI_MOSI  SER   (white) 
*      SPI_MISO  none  (blue)  
*      SPI_CLK   SRCLK
*      SPI_PCS   RCLK
*      5V       5V  (red)
*      GND      GND (black)
***************************************************/
// Host PC Communication channels
Serial      Terminal(USBTX, USBRX);         // Tx, Rx
//Serial      Terminal(PTA2,PTA1);          // Terminal Serial
//Serial      Terminal(PTE0, PTE1);         // Tx, Rx Using MAX3232 or BlueTooth

// Bluetooth Communication support
Serial   bluetooth(PTE0, PTE1);             // Tx, Rx

// I2C Communication
I2C         i2c_LCD(PTC2,PTC1);             // SDA, SCL

// SPI Communication
//SPI         spi_LCD(PTD6,PTD7,PTD5,PTD4);   // MOSI, MISO, SCLK, SSEL

// LCD instantiation 
//TextLCD LCD(PTC5, PTC6, PTC8, PTC9, PTC10, PCT11, TextLCD::LCD20x2); // 4bit bus: rs, e, d4-d7
//TextLCD_SPI lcd(&spi_LCD, PTD4, TextLCD::LCD16x4, TextLCD::HD44780);   // SPI bus, SN74595 expander, CS pin, LCD Type 
TextLCD_I2C lcd(&i2c_LCD, 0x7E, TextLCD::LCD20x4);                   // I2C bus, PCF8574A Arduino Shield, LCD Type

//librerias del DHT22  
DHT dht(PTA13, DHT11);              // DHT_PIN, DHT_TIPO (DHT11, DHT22)

/*
** ===================================================================
**     Variables del Programa
** ===================================================================
*/
/* -------------------------------------------------------------------
**   Variables Booleanas.
**
**   Para la Botonera, Checar_Botones()
**   Variables de cada Boton.
**   Posibles Valores:
**    0 - No esta siendo apretado.
**    1 - Esta siendo apretado.
** -------------------------------------------------------------------*/
bool B_Arriba;
bool B_Abajo;
bool B_Izquierdo;
bool B_Derecho;
bool B_Ok;
bool B_Return;

/* -------------------------------------------------------------------
**   Variables Booleanas.
**
**   Para el Motor y Quemador
**     Variables de componentes a controlar.
**   Posibles Valores:
**    0 - Dispositivo apagado.
**    1 - Dispositivo encendido.
** -------------------------------------------------------------------*/
bool Motor;
bool Quemador;

/* -------------------------------------------------------------------
**   Variables Booleanas.
**
**   Para el Control de Interfaz.
**     Variables que ayudan al desplazamiento de cada interfaz.
**   Posibles Valores.
**    0 - Acción Autorizada.
**    1-  Acción No Autorizada.
** -------------------------------------------------------------------*/
bool Bandera;
bool Avanzar;
bool Deshidratando;
bool PuertaAb;
bool Scroll_Cambio;

/* -------------------------------------------------------------------
**   Variables enteras sin signo.
**
**   La variables guardan las opciones disponibles de la interfaz.
** -------------------------------------------------------------------*/

uint16_t Opcion;        //Guarda la opción actual en la que se encuentra la interfaz.
uint16_t Opcion_Ant;    //Guarda la opción Anterior en la que se encontraba la interfaz.
uint16_t Opcion_Max;    //Guarda el número máximo de opciones disponibles en el menú que se encuentra la Interfaz.
uint16_t Scroll;

/* -------------------------------------------------------------------
**   Variables flotantes.
**
**   Variables que guardan datos de los sensores.
** -------------------------------------------------------------------*/

float h;                    //Guarda la Humedad del ambiente.
float t;                    //Guarda la Temperatura del ambiente.
float TF;                   //Variable que guarda la temperatura final.
float HF;                   //Variable que guarda la humedad final.

//Variables de Rangos de control
float Hot_min = 25;
float Hot_max = 35;
float Hum_min = 70;
float Hum_max = 90;

/* -------------------------------------------------------------------
**   Variables de tipo caracter.
**
**   Arreglo de Caracteres
** -------------------------------------------------------------------*/
char     Sensores[CONDALARM][20] = {" TEMPERATURA", " HUMEDAD"};      //Arreglo que guarda el nombre de los sensores
char     Fruta[NOFRUTAS][20] = {"ARANDANO", "AJO", "HIGO", "MELON", "MANZANA", "PLATANO", "PAPA", "JITOMATE", "MANGO", "UVA", "OTRO"};  // Arreglo que guarda el nombre de las frutas disponibles
int16_t  Temp[NOFRUTAS]     = {        55,   55,    65,     60,       50,       70,    55,        65,      65,   55,    55};            // Vector que contiene temperatura de deshidratacion de la fruta.
int16_t  Hume[NOFRUTAS]     = {        15,   10,    16,     18,       14,       15,    12,         8,      16,   15,    15};            //Vector que contiene la humedad de la fruta.
int16_t  Seg;                //Variable que guarda segundos.
int16_t  Min;                //Variable que guarda minuros.
int16_t  Hor;                //Variable que guarda horas.

char     Flecha = 126;       //Tiene el valor en ascii de la flecha.
char     Porcentaje = 37;
char     Celcius = 223;
int16_t  NInterrupciones;
int16_t  DC;
float    DUTYCYCLE=0.7071;  //Valor RMS para el PWM
uint8_t  buf[128];          //Buffer para Transmisión y Recepción Serial
/* -------------------------------------------------------------------
**   Variables para Códigos de Error.
**
**   Variables que guardan el estado de los dispositivos y sensores.
** -------------------------------------------------------------------*/
int16_t  error_code;          //Retorno del Código de Error de las funciones    

/*
** ===================================================================
**   Declaración de Funciones Prototipo
**     Funciones de Usuario.
** ===================================================================
*/
void setup(void);
void Checar_Botones();
bool Deshidratacion(int FrutaD);
void Checar_Calefactor(int TempD);
void Interrupcion();
void Intro();
void Imprime_Menu();
void Imprime_InfoDeshidratacion();
void Imprime_InfoSensores();
void Imprime_Tiempo(int, int);
void Inicio();
void Conf_Otro();
void Alarmas();
void Contacto();
void Acerca();
void Imprime_Flecha();
void Apagar_Calefactor();
void Reporte_Des();
bool inf_fruta(int);
bool Puerta_Abierta();
void Conteo_Cronometro();
void Init_Conometro();
void Init_Var();
void ConfT2_PWM3(int);
void CalefactorON();
void CalefactorOFF();
void MotorON(int);
void MotorOFF();

/*
** ###################################################################
**
**           P R O G R A M A     P R I N C I P A L
**
**     para la operación del microcontrolador MKL46Z256VLL4.
**
** ###################################################################
*/
int main()
{
/*
** ===================================================================
**    InicializaciÓn interna de la Tarjeta FRDM-KL46Z.
** ===================================================================
*/

    setup();            //Inicializa el Hardware Principal
/*
** -------------------------------------------------------------------
**    Inicialización de las Interrupciones.
**    Ticker Inicialzation 
** -------------------------------------------------------------------
*/
Ticker TimerInt;        // Asignación del vector de interrupción para el Ticker
 
  TimerInt.attach(&Interrupcion, 0.250);   // Periodo de Interrupción = 250ms  
  while (true){
      Init_Var();                   //Inicializamos variables iniciales.
      Scroll = 0;                   //Colocamos scroll de pantalla en 0;
      Opcion_Ant = 1;               //Colocamos Opcion anterior en 1
      Opcion_Max = 4;               //Número Máximo de opciones es 4.
    //  interrupts();                 //Autoriza las interrupciones.
      Terminal.printf("Main Menu\n\r"); 
      Imprime_Menu();               //Imprime el Menú.
      while (!Avanzar) {            //Entra al Bucle hasta que el valor de Avanzar no cambie a 1.
        Imprime_Flecha();           //Imprime la Flecha en el display en la posicion de la opcion.
        wait_ms(250);                 //Colocamos un retraso de 250 ms para que no entre a un bucle infinito y tenga tiempo disponible para hacer otras interrupciones.
      }
      switch (Opcion) {            //Dependiendo la opción seleccionada llama a la función correspondiente.
        case 1:
          Inicio();
          break;
        case 2:
          Conf_Otro();
          break;
        case 3:
          Contacto();
          break;
        case 4:
          Acerca();
          break;
      }    
  }
  
}
/*
** ###################################################################
**              FIN DEL PROGRAMA PRINCIPAL
** ###################################################################
*/
/*
** ===================================================================
**     Prototipo   :  setup ()
**     Componente  :  Cpu [MKL46Z256VLL]
**     Descripción :
**         Esta función inicializa el hardware y puertos de comunicación
**         "Serial", "I2C" y "LCD"
**     Argumentos  : Ninguno
**     Retorna     : Nada
** ===================================================================
*/
void setup() {
/* Inicia la comunicación la Terminal */  /* 115200 Bauds, 8 bits, 1 stop, N parity */
  Terminal.baud(115200);                  // Se inicia la comunicación serial.    
  Terminal.printf(" System is Wake Up!.\n\r"); 
/* Inicialización del Bluetooth */      
  bluetooth.baud(115200);                  // Se inicia la comunicación Bluetooth.  
//  bluetooth.scanf("%s", buf);             //Lee un caracter desde el Bluetooth
//  bluetooth.printf("recv: %s", buf);      //Hace eco al Bluetooth
//  Terminal.printf("recv: %s\r\n", buf);   //Imprime en la terminal el caracter recibido
  bluetooth.printf("Bluetooth Starting OK! ... \n\r"); 
  Terminal.printf("Bluetooth Starting OK! ... \n\r");       
/* Prueba del Buzzer */    
  Terminal.printf("Testing Buzzer... \n\r");   
    PIN_BUZZER = Buzz_On;
    wait_ms(750);
    PIN_BUZZER = Buzz_Off;
    wait_ms(125);
    PIN_BUZZER = Buzz_On;
    wait_ms(250);
    PIN_BUZZER = Buzz_Off;   
    wait_ms(125);
    PIN_BUZZER = Buzz_On;
    wait_ms(500);
    PIN_BUZZER = Buzz_Off;
/* Configufración del Display LCD */      /* Mucho OjO !!! */
//  spi_LCD.frequency(1000000);    // Frecuencia de operación para el SPI
//  spi_LCD.format(8,0);              // Modo de Operación para el SPI
  i2c_LCD.frequency(100000);        // Frecuencia de operación para el I2C
  i2c_LCD.start();                  // Inicio de operación para el I2C 
/* Arranque del Display LCD */  
  Terminal.printf("LCD Display is Starting...\n\r"); 
//  lcd.init(TextLCD::LCDDatalength, 4 ); // Enciende la Iluminación de Fondo
  lcd.setBacklight(TextLCD::LightOn); // Enciende la Iluminación de Fondo
  lcd.setCursor(TextLCD::CurOff_BlkOff);
  lcd.cls();                        // Limpia el Display LCD
  lcd.printf("Hello World!\n");     // El LCD saluda al Mundo!
  lcd.printf("Hola Mundo!\n");      // El LCD saluda al Mundo!
  lcd.printf("Ciao Mondo!\n");      // El LCD saluda al Mundo!
  lcd.printf("Bonjour le Monde");   // El LCD saluda al Mundo! 
  wait(2); 
  lcd.cls();                            // Limpia el Display LCD
  lcd.setBacklight(TextLCD::LightOff);  // Apaga la Iluminación de Fondo
  Timer Elpased_Time;                   //Inicialia el Tiempo a Transcurrir
  Elpased_Time.start();
  for (int row=0; row<lcd.rows(); row++)// Prueba toda la Pantalla
  {
   uint16_t col=0; 
    lcd.putc('0' + row);                
    for (col=1; col<lcd.columns()-1; col++) 
    {    
      lcd.putc('*');                    //llena lalinea con el caracter "*"
    }
    lcd.putc('+');                      //Al final pone el caracter "+"
  }  
  Elpased_Time.start();                 //Calcula el tiempo transcurrido
  Terminal.printf("All my hard work took %f sec\r\n", Elpased_Time.read());  
  wait(1);  
  Terminal.printf("LCD Display and TextLCD Enhanced Test Completed.\n\r"); 
  lcd.cls();  
  lcd.setCursor(TextLCD::CurOff_BlkOn); //
// Set and show user defined characters. A maximum of 8 UDCs are supported by the HD44780.
// They are defined by a 5x7 bitpattern. 
  lcd.setUDC(0, (char *) udc_0);        // Show |>
  lcd.putc(0);   
  Terminal.printf("LCD Starting OK! ... \n\r"); 
  wait_ms(500);
  Terminal.printf("\rPrinting Intro \n\r"); 
  Intro();                              // Se ejecuta la Introducción en la LCD.
  uint16_t NInterrupciones = 0;         //Contador de Interrupciones (util para ahorro de energía).
}

/***    Fin de la initialization interna.     ***/


/*
** ===================================================================
**     Prototipo   :  Init_Var (Inicializa variables de estado)
**     Componente  :  Cpu [MKL46Z256VLL]
**     Descripción :
**         Esta función inicializa las banderas de estado para
**         "Bandera", "Avanzar" y "Opción"
**     Argumentos  : Ninguno
**     Retorna     : Nada
** ===================================================================
*/
void Init_Var() {
  Bandera = 0;                  //Bandera en 0.
  Avanzar = 0;                  //Avanzar en 0.
  Opcion  = 1;                  //Colocamos en Opcion 1.
}

/*
** ===================================================================
**     Prototipo   :  Imprime_Flecha() (Imprime la Flecha)
**     Componente  :  Cpu [MKL46Z256VLL]
**     Descripción :
**         Con ayuda de las opciones, imprime la flecha en la opcion
**         seleccionada, moviendola a traves del menú.
**     Argumentos  : Ninguno
**     Retorna     : Nada
** ===================================================================
*/

void Imprime_Flecha() {
  lcd.locate(0, Opcion_Ant - 1 - Scroll); //Coloca cursor de la LCD en la Opcion Anterior.
  lcd.printf(" ");                        //Borra la flecha que previamente impresa.
  lcd.locate(0, Opcion - 1 - Scroll);     //Coloca cursor de la LCD en la Opcion Actual.
  lcd.setUDC(0, (char *) udc_0);          // Show |>
  lcd.putc(0);                            //Imprime la nueva flecha.
}

/*
** ===================================================================
**     Prototipo   :  Checar_Botones() (Verifica el estado de la botonera)
**     Componente  :  Cpu [MKL46Z256VLL]
**     Descripción :
**         Verifica si algún boton está siendo presionado,
**         e indaga su posición y envia por la terminal serial
**         la ubicación del botón seleccionado
**     Argumentos  : Ninguno
**     Retorna     : Nada
** ===================================================================
*/

void Checar_Botones() {

  B_Arriba = !PIN_BARRIBA; //Lee el pin y lo asigna a la variable booleana correspondiente.
  if (B_Arriba) //Si se presionó envia mensaje al serial para mostarlo en la terminal.
    Terminal.printf("Arriba   \r");

  B_Abajo = !PIN_BABAJO;
  if (B_Abajo)
    Terminal.printf("Abajo    \r");

  B_Izquierdo = !PIN_BIZQUIERDO;
  if (B_Izquierdo)
    Terminal.printf("Izquierdo\r");

  B_Derecho = !PIN_BDERECHO;
  if (B_Derecho)
    Terminal.printf("Derecho  \r");

  B_Ok = !PIN_BOK;
  if (B_Ok)
    Terminal.printf("Ok       \r");

  B_Return = !PIN_BRETURN;
  if (B_Return)
    Terminal.printf("Return   \r");

  if (B_Arriba || B_Abajo || B_Izquierdo || B_Derecho || B_Ok || B_Return ) { //Verifica si algun boton fue apretado
    PIN_BUZZER = Buzz_On;                                             //Enciende el buzzer.
  } else
    PIN_BUZZER = Buzz_Off;                                            //Si no se presiono algun boton se apaga el buzzer.
}

/*
** ===================================================================
**     Prototipo   :  Interrupcion() (Verifica el estado de la botonera)
**     Componente  :  Cpu [MKL46Z256VLL]
**     Descripción :
**         Con las interrupciones activadas se manda llamar a esta funcion.
**         Verifica si algun boton esta siendo presionado y habilita o
**         deshabiita banderas para Avanzar dentro del menú de la interfaz.
**     Argumentos  : Ninguno
**     Retorna     : Nada
** ===================================================================
*/

void Interrupcion() {

  if (Deshidratando) {
    Conteo_Cronometro();                                                     //Cronometro Activado.
    PuertaAb = !PIN_SWITCH;                                                  //Checa el estado de la puerta.
    NInterrupciones ++;                                 //Incrementa el numero de interrupciones 
  }
 
  Checar_Botones();                                                           //Lee el estado de los botones.

  if (B_Arriba || B_Abajo || B_Izquierdo || B_Derecho || B_Ok || B_Return ) { //Checa si algun boton fue presionado.
    if (Opcion_Max && (B_Arriba || B_Abajo)) {                                //Checamos si exite opciones disponibles y si se activo el boton de arriba y abajo.

      if (B_Arriba && (Opcion == Scroll + 1) && (Scroll != 0) && (Opcion_Max > 4)) { //Entra al if si se Activa el Boton de arriba, existe un scroll, nos encontramos en la opcion mas alta disponible en el display.
        Scroll_Cambio = 1;                                                  //Indicamos que se debe hacer un cambio de Scroll.
        Scroll--;                                                           //Decrementamos el Scroll.
        Opcion_Ant = Opcion;                                                //Actualizamos valor a la variable que guarda las opciones anteriores.
        Opcion--;                                                           //Decrementa el valor de opción.
      }
      else if (B_Arriba && (Opcion != 1) ) {                                  //Checamos si presionamos Arriba la opcion no es la primera.
        Opcion_Ant = Opcion;                                                  //Actualizamos valor a la variable que guarda las opciones anteriores.
        Opcion--;
        Terminal.printf("%d",Opcion);
      }
      else if (B_Abajo && (Opcion == Scroll + 4) && (Opcion < (Opcion_Max)) && (Opcion_Max > 4)) { //Checamos si presionamos Abajo la opcion es la 4ta de la pantalla, el scroll no es el ultimo posible y nuestras opciones son mayores a 4.
        Scroll_Cambio = 1;                                                   //Indicamos que se debe hacer un cambio de Scroll.
        Scroll++;          //Decrementamos el Scroll.
        Opcion_Ant = Opcion;                                                 //Atualiza opcion anterior.
        Opcion++;
      }
      else if (B_Abajo && (Opcion != Opcion_Max) ) {                         //Checa si se presiona el boton de abajo y la opcion actual no es la ultima opción.
        Opcion_Ant = Opcion;                                                 //Atualiza opcion anterior.
        Opcion++;                                                            //Incrementa la opcion.
      }
    }
    else if (B_Ok) {                                                         //Verifica si presionamos el Boton OK.
      Bandera = 1;                                                           //Cambia bandera a 1 permitiendo el paso a la siguiente acción.
      Avanzar = 1;                                                          //Permite el paso a la siguiente opción.
    }
    else if (B_Return) {                                                     //Checa si se presiono el boton de Regreso.
      Bandera = 1;                                                           //Cambia bandera a 1 permitiendo el paso a la siguiente acción.
//      Avanzar = 0;                                                           //Permite el paso a la opción anterior.
    }
  }
}


/*
** ===================================================================
**     Prototipo   :  Intro() (Envia mensajes a la pantalla LCD)
**     Componente  :  Cpu [MKL46Z256VLL]
**     Descripción :
**         Envia mensajes al inicio del programa a traves del LCD.
**         Limpia la interfaz del LCD
**     Argumentos  : Ninguno
**     Retorna     : Nada
** ===================================================================
*/
void Intro() {
  lcd.setBacklight(TextLCD::LightOn);       // Enciende la Iluminación de Fondo
  lcd.setCursor(TextLCD::CurOff_BlkOff);    // Apaga el Cursor
  lcd.cls();
  lcd.locate(0,0);
  lcd.locate(7, 0);
  lcd.printf("I.P.N.");
  lcd.locate(5, 1);
  lcd.printf("E.S.I.M.E.");
  lcd.locate(3, 2);
  lcd.printf("DESHIDRATADOR");
  wait_ms(2000);
}

/*
** ===================================================================
**     Prototipo   :  Imprime_Menu() (Imprime el Menú en la pantalla LCD)
**     Componente  :  Cpu [MKL46Z256VLL]
**     Descripción :
**         Envia mensajes y coloca mensajes del menú en la LCD.
**         Limpia la interfaz del LCD
**     Argumentos  : Ninguno
**     Retorna     : Nada
** ===================================================================
*/
void Imprime_Menu() {
  lcd.setBacklight(TextLCD::LightOn);       // Enciende la Iluminación de Fondo
  lcd.setCursor(TextLCD::CurOff_BlkOff);    // Apaga el Cursor
  lcd.cls();
  lcd.locate(0,0);
  lcd.locate(1, 0);
  lcd.printf("MENU");
  lcd.locate(1, 1);
  lcd.printf("PERSONALIZAR");
  //lcd.printf("CONFiG OTRO");
  lcd.locate(1, 2);
  lcd.printf("CONTACTO");
  lcd.locate(1, 3);
  lcd.printf("ACERCA DE... ");
}

/*
** ===================================================================
**     Prototipo   :  Imprime_InfoDeshidratacion() (Imprime info en la pantalla LCD)
**     Componente  :  Cpu [MKL46Z256VLL]
**     Descripción :
**         Envia mensajes sobre las variables y el estado de operación
**         del deshidratador y coloca mensajes en la pantalla LCD.
**         Limpia la interfaz del LCD
**     Argumentos  : Ninguno
**     Retorna     : Nada
** ===================================================================
*/
void Imprime_InfoDeshidratacion() {
  lcd.setBacklight(TextLCD::LightOn);       // Enciende la Iluminación de Fondo
  lcd.setCursor(TextLCD::CurOff_BlkOff);    // Apaga el Cursor
  lcd.cls();
  lcd.locate(0, 0);
  lcd.printf("TEMPERATURA: ");
  lcd.locate(0, 1);
  lcd.printf("HUMEDAD:     %");
  lcd.locate(0, 2);
  lcd.printf("VENT:     QUEM: ");
  lcd.locate(0, 3);
  lcd.printf("TIEMPO:");
}
/*
** ===================================================================
**     Prototipo   :  Imprime_InfoSensores() (Imprime info en la pantalla LCD)
**     Componente  :  Cpu [MKL46Z256VLL]
**     Descripción :
**         Imprime las mediciones datos e información obtenida de los
**         sensores y es enviada a la pantalla LCD.
**         Envia los respectivos mensajes y los despliega en la
**         pantalla LCD.
**         Limpia la interfaz del LCD
**     Argumentos  : Ninguno
**     Retorna     : Nada
** ===================================================================
*/
void Imprime_InfoSensores() {
  uint16_t Porcentaje;
  lcd.setBacklight(TextLCD::LightOn);       // Enciende la Iluminación de Fondo
  lcd.setCursor(TextLCD::CurOff_BlkOff);    // Apaga el Cursor
  lcd.locate(12, 0);                //Coloca el cursor en la columna 12 y fila 0.
  lcd.printf("%.2f",t);             //Imprime valores de temperatura.
  lcd.locate(8, 1);                 //Coloca el cursor en la columna 8 fila 1.
  lcd.printf("%.2f",h);             //Imprime valores de humedad.
  lcd.locate(6, 2);                 //Coloca el cursor en columna 6 fila 2.
  Porcentaje = DC * 100 / 255;      // 
  if (Motor) {                      //Vericamos estado del motor.
    lcd.printf("%d",Porcentaje);    //Si - Imprime en LCD ON.
    lcd.printf("%");                //
  } else                            //No.
    lcd.printf("OFF");              //Imprime en LCD OFF.
  lcd.locate(16, 2);                //Colocamos cursor en columna 16 , fila 2.
  if (Quemador)                     //Verificamos estado del quemador.
    lcd.printf("ON ");              //Si - imprime mensaje en LCD de ON.
  else                              //No.
    lcd.printf("OFF");              //Imprime mesaje en LCD de OFF.
}
/*
** ===================================================================
**     Prototipo   :  Imprime_Tiempo() (Imprime info en la pantalla LCD)
**     Componente  :  Cpu [MKL46Z256VLL]
**     Descripción :
**         Imprime en la LCD el tiempo transcurrido.
**         Formatea el mensaje y los despliega en la pantalla LCD.
**         Limpia la interfaz del LCD
**     Argumentos  : Ninguno
**     Retorna     : Nada
**     Variables Globales:
**       uint16_t Columna - Almacena el valor de columna en la que desea imprimir en la LCD.
**       uint16_t Fila    - Almacena el valor de fila en la que desea imprimir en la LCD.
** ===================================================================
*/
void Imprime_Tiempo(int Columna,int Fila) {
  lcd.setBacklight(TextLCD::LightOn);       // Enciende la Iluminación de Fondo
  lcd.setCursor(TextLCD::CurOff_BlkOff);    // Apaga el Cursor
  lcd.locate(Columna, Fila);
  if (Hor < 10)
    lcd.printf("0");
  lcd.printf("%d",Hor);
  lcd.printf(":");
  if (Min < 10)
    lcd.printf("0");
  lcd.printf("%d",Min);
    lcd.printf(":");
  if (Seg < 10)
    lcd.printf("0");
  lcd.printf("%d",Seg);
    lcd.printf(" ");
}
/*
** ===================================================================
**     Prototipo   :  Inicio() (Despliega Menú en la pantalla LCD)
**     Componente  :  Cpu [MKL46Z256VLL]
**     Descripción :
**         Inicia el proceso de deshidratación.
**         Imprime el menú de inicio en la pantalla LCD y permite
**         navegar dentro de él.
**         Envia los respectivos mensajes y los despliega en la
**         pantalla LCD.
**         Limpia la interfaz del LCD
**     Argumentos  : Ninguno
**     Retorna     : Nada
** ===================================================================
*/
void Inicio() {
  bool MenuInicio;              //Variable que permite regresar a esta opción.
  MenuInicio = true;            //Inicializamos variable con verdadero.
  Scroll = 0;                   //Colocamos Scroll de pantalla en 0 (no hay scroll);
  while (MenuInicio) {          //Mientras este en 1 MenuInicio repetira el proceso de esta opción.
    Init_Var();                 //Se inicializan las variables.
    Opcion_Ant = 1;             //Opcion anterior en 1.
    Opcion_Max = NOFRUTAS;      //El máximo número de opciones.
    do {
      Scroll_Cambio = 0;        //Indicamos que no hay cambio de scroll por ahora.
      lcd.cls();                //Limpiamos LCD.
      for (int c = 0; c < 4; c++) {     //FOR que imprime nombres de las frutas en las 4 lineas de la LDC.
        lcd.locate(1, c);               //Coloca el cursor al inicio de la fila.
        lcd.printf(Fruta[c + Scroll]);  //Imprime el nombre de la Fruta dependiendo el valor del scroll.
      }
      while (!Bandera && !Scroll_Cambio) {     //Entra en un bucle de espera hasta que se active la bandera con 1.
        Imprime_Flecha();                      //Imprime la Flecha en el display en la posicion de la opcion.
        wait_ms(250);                          //Aplicamos un retardo para no hacer un bucle infinito.
      }
    } while (Scroll_Cambio);                   //Este ciclo se repite mientras exista cambios en el Scroll.
    if (Avanzar)                               //Si se activa la variable avanzar con 1.
      MenuInicio = Deshidratacion(Opcion - 1); //Comienza Deshidratacion.
    else
      MenuInicio = 0;                          //regresa al menu anterior.
  }
}

/*
** ===================================================================
**     Prototipo   :  Deshidratación() (Despliega Menú en la pantalla LCD)
**     Componente  :  Cpu [MKL46Z256VLL]
**     Descripción :
**         Supervisa el proceso de deshidratación.
**         Imprime el menú de estado en la pantalla LCD y actualiza
**         los datos en tirmpo real.
**         Envia los respectivos mensajes y los despliega en la
**         pantalla LCD.
**         Limpia la interfaz del LCD
**     Llamado por: Inicio()
**     Argumentos  : Ninguno
**     Retorna     : valor BOOLEANO.
**          0 - Deshidratacion cancelada
**          1 - Final de la deshidratación.
** ===================================================================
*/
bool Deshidratacion(int FrutaD) {
  
  //Mostramos informacion de fruta.
  Deshidratando = inf_fruta(FrutaD);
  if (Deshidratando) {
    //Colocamos variables en condiciones iniciales.
    Opcion_Max = 0;                 //0 no existen opciones disponibles.
    Init_Var();                     //Se inicializan las variables.
    Init_Conometro();               //Iniciamos variables del cronometro.
    //ConfT2_PWM3(TAPWM);           //Configuracion de Timer2 PARA MODO FAST PWM EN PIN 3.
    PIN_QUEMADOR = DUTYCYCLE;       //Enciende el Quemador
    while (!Bandera && !Avanzar) {          //Ciclo que se repite hasta que la bandera no sea activada.
      if (PuertaAb)       
      {                                     //Checa si la puerta esta abierta
        Deshidratando = Puerta_Abierta();   //SI - Dependiedo de la decision del usuario puede o no continuar la deshidratación.
        PIN_BUZZER = Buzz_On;               //Enciende el buzzer.
        wait(2);    
        PIN_BUZZER = Buzz_Off;              //Apaga el buzzer 
        wait(1);
      }
      else        {                                //NO...
        Imprime_InfoDeshidratacion();       //Colocamos mensajes en la LCD.
        while (!PuertaAb && Deshidratando && !Bandera) {   //Mientras la puerta este cerrada y la variable Desidratando sea verdadera.
        error_code=dht.readData();          //Lee el Sensor de Humedad y Temperatura
        if (error_code != 0) { 
            Terminal.printf("\rError Reading DHT   ");           //No se puedo leer DHT
            Terminal.printf("\r\nPlease Check Sensor !!! \n\r"); //Envia mensaje de error a la Terminal
            lcd.cls();                      //Limpiamos LCD.
            lcd.locate(1, 0);               //Coloca el cursor al inicio de la fila.
            lcd.printf("Error de Sensores");//Encia mensaje de Error.
            lcd.locate(1, 1);               //Coloca el cursor al inicio de la fila.
            lcd.printf("Revise Equipo ! "); //Encia mensaje de Error.
            PIN_BUZZER = Buzz_On;           //Enciende el buzzer 
            wait(10);                       //Espera 10 seg
          }
          Terminal.printf("\rReading DHT ... ");
          Terminal.printf("\r\nError Code: %d \r\n", error_code);  
          h = dht.ReadHumidity();                          //Se lee la humedad
          Terminal.printf("\rHumedad: %.2f ", h);            
          t = dht.ReadTemperature(CELCIUS);                //Se lee la temperatura: CELCIUS=0,FARENHEIT=1,KELVIN=2
          Terminal.printf("\tTemperatura: %.2f \r\n\v\v\v\v", t);            
          Checar_Calefactor(Temp[FrutaD]);                 //Verifica sesores y enciende componentes.
          Imprime_InfoSensores();                          //Impresion de informacion de sensores,
          Imprime_Tiempo(7, 3);                            //Impresion de Tiempo.
          if (Hor == 5 && Min == 30) {                     //Tiempo Transcurrido es igual a 5:30:XX .
            Bandera = 1;                                   // SI - Termina el proceso.
            Terminal.printf("\rDemasiado Tiempo de Deshidratacion ...\n\r");
            Terminal.printf("\rTiempo Terminado !!! \n\r");  
           }
        }
      }
    }
    //Deshidratacion terminada.
    Terminal.printf("\rDeshidratacion Terminada  \n\r");
    Terminal.printf("\rTiempo Terminado !!! \n\r");      
    TF = t;                                             //Almacenamos el valor final de temperatura.
    HF = h;                                             //Almacenamos el valor final de humedad.
    Terminal.printf("\rHumedad Final: %.2f ", HF);                     //Humedad Final
    Terminal.printf("\tTemperatura Interna: %.2f \r\n\v\v\v\v", TF);     //Temperatura Final
    Deshidratando = 0;                                  //Indica que termina la deshidratacion.
    Apagar_Calefactor();                                //Apaga el calefactor.
    Reporte_Des();                                      //Muestra reporte de deshidratacion.
    return 1;                                           //Indicamos que termino la deshidratación.
  }
  else
    return 0;                                             //Indica que no se inicio el proceso.
}
/*
** ===================================================================
**     Prototipo   :  inf_fruta() (Confugura pramatros de deshidratación)
**     Componente  :  Cpu [MKL46Z256VLL]
**     Descripción :
**         Despliega en la LCD la informacion de la fruta seleccionada.
**         Imprime el menú de estado en la pantalla LCD y actualiza
**         los datos en tirmpo real.
**         Envia los respectivos mensajes y los despliega en la
**         pantalla LCD.
**         Limpia la interfaz del LCD
**     Argumentos  :
**            uint16_t Fruit - recibe el numero de fruta contenido en los arreglos.
**     Retorna     : valor BOOLEANO.
**              0 - Continuar con deshidratacion.
**              1 - Cancelar.
** ===================================================================
*/
bool inf_fruta(int Fruit) {

  //Colocamos variables en condiciones iniciales.
  Opcion_Max = 0;                       //0 no existen opciones disponibles.
  Init_Var();                           //Inicializamos variables
  lcd.setBacklight(TextLCD::LightOn);   // Enciende la Iluminación de Fondo
  lcd.setCursor(TextLCD::CurOff_BlkOff);    // Apaga el Cursor
  lcd.cls();                            //Limpiamos pantalla.
  lcd.locate(0, 0);
  lcd.printf(Fruta[Fruit]);             //Imprimimos nombre de fruta.
  lcd.locate(0, 1);
  lcd.printf("TEMPERATURA MAX: ");
  lcd.printf("%d", Temp[Fruit]);        //Imprimimos temperatura maxima de fruta.
  lcd.locate(0, 2);
  lcd.printf("HUMEDAD MAX: ");
  lcd.printf("%d", Hume[Fruit]);        //Imprimimos humedad maxima de fruta.
  lcd.locate(0, 3);
  lcd.printf("ATRAS             OK");

  while (!Bandera) {                    //Esperamos hasta que se presione algún boton (atras o adelante).
    wait_ms(250);
  }
  if (Avanzar)                          //Verificamos si el Boton fue el de Avanzar.
    return 1;
  else
    return 0;                          //
}
/*
** ===================================================================
**     Prototipo   :  Puerta_Abierta() (Despliega info en la pantalla LCD)
**     Componente  :  Cpu [MKL46Z256VLL]
**     Descripción :
**         Rutina que se ejecuta a la hora de abrir la puerta durante
**         el proceso de deshidratación.
**         Pone en pause el proceso hasta que se cierre nuevamente la
**         puerta.
**         Imprime el estado en la pantalla LCD.
**         Envia los respectivos mensajes y los despliega en la
**         pantalla LCD.
**         Limpia la interfaz del LCD
**     Argumentos  : Ninguno
**     Retorna     : Nada
** ===================================================================
*/
bool Puerta_Abierta() {
  Init_Var();
  Terminal.printf("\r\nPuerta Abierta ");
  Terminal.printf("\r\nProceso Suspendido !!! \r\n");  
  CalefactorOFF();
  lcd.setBacklight(TextLCD::LightOn);       // Enciende la Iluminación de Fondo
  lcd.setCursor(TextLCD::CurOff_BlkOff);    // Apaga el Cursor  
  lcd.cls();
  lcd.locate(0, 0);
  lcd.printf("   PUERTA  ABIERTA");
  lcd.locate(0, 1);
  lcd.printf("      PROCESO");
  lcd.locate(0, 2); 
  lcd.printf("    SUSPENDIDO");
  PIN_BUZZER = Buzz_On;               //Enciende el buzzer.
  wait_ms(5000);                            //Espera 5 segundos
  lcd.cls();
  lcd.locate(0, 0);
  lcd.printf("     POR FAVOR   ");
  lcd.locate(0, 1);
  lcd.printf("      CIERRE");
  lcd.locate(0, 2);
  lcd.printf("     LA PUERTA");
  lcd.locate(0, 3);
  lcd.printf("   PARA CONTINUAR!");  
  PIN_BUZZER = Buzz_Off;              //Apaga el buzzer 
  while (PuertaAb && !Avanzar)  //Mientras la puerta está abierta
    wait_ms(250);
  return !Avanzar;              //Se detiene el proceso
}
/*
** ===================================================================
**     Prototipo   :  Checar_Calefactor() (Verifica estado del calefactor)
**     Componente  :  Cpu [MKL46Z256VLL]
**     Descripción :
**         Enciende o apaga de calefactor con ayuda de las variables de
**         humedad y temperatura.
**         Imprime el menú de estado en la pantalla LCD y actualiza
**         los datos en tirmpo real.
**         Envia los respectivos mensajes y los despliega en la
**         pantalla LCD.
**         Limpia la interfaz del LCD
**     Argumentos  : Ninguno
**     Retorna     : Nada
** ===================================================================
*/
void Checar_Calefactor(int TempD) {
  if ((t > (TempD - 2) && t < (TempD + 1)) || (h > 75))
    MotorON(130);
  else if (t < (TempD - 2) && (h <= 75))
    MotorOFF();
  else if (t >= (TempD + 1))
    MotorON(196);

  if (t <= (TempD - 1)) {           //Checa si el quemador esta apagado y su tempertatura es igual o menor que la temperatura de la fruta.
    wait_ms(1000);                  //Retardo de 1 seg.
    CalefactorON();
  }
  else if (t >= (TempD + 1)) {      //Checa si el motor esta encendido y la si la temperatura es mayor a la maxima permitida
    CalefactorOFF();
    wait_ms(2000);                  //retardo de 2 segundos.
  }
}
/*
** ===================================================================
**     Prototipo   :  Apagar_Calefactor() (Apaga el calefactor)
**     Componente  :  Cpu [MKL46Z256VLL]
**     Descripción :
**         Apaga de calefactor despues de haber terminado el proceso
**         de deshidratacion.
**         Imprime el menú de estado en la pantalla LCD y actualiza
**         los datos en tirmpo real.
**         Envia los respectivos mensajes y los despliega en la
**         pantalla LCD.
**         Limpia la interfaz del LCD
**     Argumentos  : Ninguno
**     Retorna     : Nada
** ===================================================================
*/
void Apagar_Calefactor() {
  lcd.cls();
  lcd.locate(5, 0);
  lcd.printf("ENFRIANDO");
  lcd.locate(6, 1);
  lcd.printf("SISTEMA");
  lcd.locate(2, 2);
  lcd.printf("ESPERE POR FAVOR");
  lcd.locate(0, 3);
  lcd.printf("TEMPERATURA: ");
//Enfriamiento del Sistema  
  CalefactorOFF();                     //Apaga el Elemento Calefactor
  do {
    t = dht.ReadTemperature(CELCIUS);  //Se lee la temperatura: CELCIUS=0, FARENHEIT=1, KELVIN=2
    lcd.locate(13, 3);
    lcd.printf("%.2f",t);              //Temperatura interna del Deshidratador
    Terminal.printf("\rEnfriando, Temperatura: %.2f",t);   //
    wait_ms(1000);                     //Espera 1 segundo
     } 
  while (t > 37);                      //Hasta que la Temperatura Llega a 37°C
    MotorOFF();                        //Apaga el Elemento de Ventilación
  if (t < 25 ){
    printf("\rEs Seguro Abrir Deshidratador !!!   \n\r");    
    lcd.cls();                         //Limpia el LCD
    lcd.locate(3,1);
    lcd.printf("Es Seguro Abrir ");    //Apertura segura del Deshidratador
    lcd.locate(3,2);
    lcd.printf(" Deshidratador ");     //Apertura segura del Deshidratador
    wait(30);                           //Espera 30 segundos   
   }     
}
/*
** ===================================================================
**     Prototipo   :  Reporte_Des() (Reporta el estado del proceso)
**     Componente  :  Cpu [MKL46Z256VLL]
**     Descripción :
**         Despliega en la LCD valores finales de humedad, temperatura
**         y tiempo total del proceso de deshidratación.
**         Imprime el menú de estado en la pantalla LCD y actualiza
**         los datos en tirmpo real.
**         Envia los respectivos mensajes y los despliega en la
**         pantalla LCD.
**         Limpia la interfaz del LCD
**         Limpia la interfaz del LCD
**     Argumentos  : Ninguno
**     Retorna     : Nada
** ===================================================================
*/
void Reporte_Des() {
  //Colocamos variables en condiciones iniciales.
  Opcion_Max = 0;                 //0 no existen opciones disponibles.
  Init_Var();

  lcd.cls();
  lcd.locate(0, 0);
  lcd.printf(" PROCESO TERMINADO");
  lcd.locate(0, 1);
  lcd.printf("TEMP. FINAL: ");
  lcd.printf("%.2f",TF);
  lcd.locate(0, 2);
  lcd.printf("HUM. FINAL: ");
  lcd.printf("%.2f",HF);
  lcd.locate(0, 3);
  lcd.printf("TIEMPO DES:");

  Imprime_Tiempo(12, 3);
  while (!Avanzar) {
    wait_ms(250);
  }

}
/*
** ===================================================================
**     Prototipo   :  Conf_Otro() (Configura parámetros de deshidratación)
**     Componente  :  Cpu [MKL46Z256VLL]
**     Descripción :
**         Configura valores de opcion del menú: OTRO
**         en el cual se puede seleccionar valores para la temperatura
**         y humedad de otro alimento que se desee deshidratar.
**         Imprime el menú de estado en la pantalla LCD y actualiza
**         los datos en tirmpo real.
**         Envia los respectivos mensajes y los despliega en la
**         pantalla LCD.
**         Limpia la interfaz del LCD
**     Argumentos  : Ninguno
**     Retorna     : Nada
** ===================================================================
*/
void Conf_Otro() {
 uint16_t MenuConf;
 uint16_t Temp_Aux;
 uint16_t Hume_Aux;
  MenuConf = 1;
  while (MenuConf) {                    
    Init_Var();                             //se inicializan los valores
    Scroll = 0;                             //No hay scroll.
    Opcion_Ant = 1;                         //Iniciamos Opcion anterior = 1.
    Opcion_Max = CONDALARM;                 //Opciones iguales a las alarmas disponibles.
    lcd.cls();                              //Limpiamos pantalla.
    lcd.locate(1, 0);
    lcd.printf("TEMP. MAX:   ");
    lcd.printf("%d", Temp[NOFRUTAS - 1]);   //Imprimimos temperatura maxima de fruta.
    lcd.locate(1, 1);
    lcd.printf("HUMEDAD MAX: ");
    lcd.printf("%d", Hume[NOFRUTAS - 1]);   //Imprimimos humedad maxima de fruta.
    lcd.locate(0, 3);
    lcd.printf("CANCELAR          OK");
    Temp_Aux = Temp[NOFRUTAS - 1];          //Son guardadas en una variable auxiliar.
    Hume_Aux = Hume[NOFRUTAS - 1];          //Humedad gurdada en una variable auxiliar
    while (!Bandera) {                      //
      Temp[NOFRUTAS - 1] = Temp_Aux;        //Aplica cambio a variable original de temperatura.
      Hume[NOFRUTAS - 1] = Hume_Aux;        //Aplica cambio a variable original de humedad.
      wait_ms(250); 
      Imprime_Flecha();
      if (Opcion == 1 && B_Derecho) {       //Opcion de temperatura DERECHA.
        Temp_Aux++;                         //Incrementa tempertura de variable auxiliar.
      }
      else if (Opcion == 1 && B_Izquierdo) { //Opcion de temperatura IZQUIERDA.
        Temp_Aux--;                         //Decrementa temperatura de la variable auxiliar.
      }
      else if (Opcion == 2 && B_Derecho) {   //Opcion de humedad DERECHA.
        Hume_Aux++;                         //Incrementa humedad de la variable auxiliar.
      }
      else if (Opcion == 2 && B_Izquierdo) { //Opcion de humedad IZQUIERA.
        Hume_Aux--;                         //Decrementa humedad de la variable auxiliar.
      } 
    //Mostramos valores modificados.      
    lcd.locate(1, 0);
    lcd.printf("TEMP. MAX:   ");
    lcd.printf("%d", Temp[NOFRUTAS - 1]);   //Actualizamos Temperatura maxima de fruta.    
    lcd.locate(1, 1);
    lcd.printf("HUMEDAD MAX: ");
    lcd.printf("%d", Hume[NOFRUTAS - 1]);   //Actualizamos Humedad maxima de fruta.
    }                                   
    if (Avanzar) {                          //Si aprieta el boton OK
      lcd.cls();                            //Limpiamos pantalla.  
      lcd.locate(0, 1);
      lcd.printf("      VALORES");
      lcd.locate(1, 2);
      lcd.printf("    ACTUALIZADOS");
      wait_ms(2000);
    }
    MenuConf = 0;
  }
}
/*
** ===================================================================
**     Prototipo   :  Init_Cronometro() (Configura el cronómetro)
**     Componente  :  Cpu [MKL46Z256VLL]
**     Descripción :
**         Configura valores iniciales del cronómetro.
**         Imprime el menú de estado en la pantalla LCD y actualiza
**         los datos en tirmpo real.
**         Envia los respectivos mensajes y los despliega en la
**         pantalla LCD.
**         Limpia la interfaz del LCD
**     Argumentos  : Ninguno
**     Retorna     : Nada
** ===================================================================
*/
void Init_Conometro() {
  Seg = 0;
  Min = 0;
  Hor = 0;
}
/*
** ===================================================================
**     Prototipo   :  Conteo_Cronometro() (incrementa el cronómetro)
**     Componente  :  Cpu [MKL46Z256VLL]
**     Descripción :
**         Incrementa variables que realizan el conteo del tiempo
**         transcurrido del proceso de deshidratación.
**         Imprime el menú de estado en la pantalla LCD y actualiza
**         los datos en tirmpo real.
**         Envia los respectivos mensajes y los despliega en la
**         pantalla LCD.
**         Limpia la interfaz del LCD
**     Argumentos  : Ninguno
**     Retorna     : Nada
** ===================================================================
*/
void Conteo_Cronometro() {
  NInterrupciones++;                        //Incrementa valor de interrupciones (Deacuerdo a la interrupcion se incrementa cada 250 ms).
  if (NInterrupciones >= 4) {               //Al completar al menos 4 interrupciones (4x250ms=1S) tendriamos al menos 1s.
    Seg++;                                  //Incrementamos el valor de la variable que almacena los segundos.
    NInterrupciones = NInterrupciones - 4;  //Decrementamos las 4 interrupciones que representan el segundo.
    if (Seg > 59) {                         //Si tenemos mas de 59 segundos...
      Seg = 0;                              //Reiniciamos variable Seg.
      Min++;                                //Incrementamos los minutos.
      if (Min > 59) {                       //Si tenemos mas de 59 minutos...
        Min = 0;                            //Reiniciams la variable Min.
        Hor++;                              //Incrementamos el valor de las horas.
      }
    }
  }
}
/*
** ===================================================================
**     Prototipo   :  ConfT2_PWM3() (configuración del PWM3)
**     Componente  :  Cpu [MKL46Z256VLL]
**     Descripción :
**         Configuracion de Timer2 PARA MODO FAST PWM EN PIN 3.
**     Argumentos  : Recibe varieble entera
**           uint16_t DUTYCYCLE - Ciclo util del PWM
**                            0.0=0%    1.0=100%
**     Retorna     : Nada
** ===================================================================
*/
void ConfT2_PWM3(int DUTYCYCLE) {
  //TIMER2
  
//  TCCR2A = _BV(COM2B1) | _BV(WGM21) | _BV(WGM20);
//  TCCR2B =  _BV(CS22) | _BV(CS21) | _BV(CS20);
//  OCR2B = DUTYCYCLE;                              //Ancho de pulso.
  //Aqui termina configuración.
}
/*
** ===================================================================
**     Prototipo   :  CalefactorON() (Encendido del elemento Calefactor)
**     Componente  :  Cpu [MKL46Z256VLL]
**     Descripción :
**         Enciende el elemento Calefactor.
**     Argumentos  : Ninguno
**     Retorna     : Nada
** ===================================================================
*/
void CalefactorON() {
  Quemador = 1;                     //Coloca la Bandera de Estado en 1.
  DUTYCYCLE = HIGH;                 //Pone al Máximo el Quemador 
  PIN_QUEMADOR = DUTYCYCLE;         //Actualiza el PWM del Quemador
}
/*
** ===================================================================
**     Prototipo   :  CalefactorOFF() (Apagado del elemento Calefactor)
**     Componente  :  Cpu [MKL46Z256VLL]
**     Descripción :
**         Apaga el elemento Calefactor.
**     Argumentos  : Ninguno
**     Retorna     : Nada
** ===================================================================
*/
void CalefactorOFF() {
  Quemador = 0;                     //Colocamos la Bandera de Estado en 0.
  PIN_QUEMADOR = LOW;               //Pone al Mínimo el Quemador
}
/*
** ===================================================================
**     Prototipo   :  MotorON() (Enciende el Ventilador)
**     Componente  :  Cpu [MKL46Z256VLL]
**     Descripción :
**         Enciende el ventilador del deshidratador.
**     Argumentos  : Ninguno
**     Retorna     : Nada
** ===================================================================
*/
void MotorON(int CicloUtil) {
  Motor = 1;        //Actualiza la Bandera de Estado en 1.      
  DC = CicloUtil;   //
  PIN_MOTOR = DC;   //Encendemos Ventilador.
}
/*
** ===================================================================
**     Prototipo   :  MotorOFF() (Apaga el Ventilador)
**     Componente  :  Cpu [MKL46Z256VLL]
**     Descripción :
**         Apaga el ventilador del deshidratador.
**     Argumentos  : Ninguno
**     Retorna     : Nada
** ===================================================================
*/
void MotorOFF() {
  Motor = 0;        //Colocamos la Bandera de Estado en 0.
  PIN_MOTOR = 0;    //Apagamos Ventilador.
}
/*
** ===================================================================
**     Prototipo   :  Contacto() (Muestra info en la pantalla LCD)
**     Componente  :  Cpu [MKL46Z256VLL]
**     Descripción :
**         Muestra en la pantalla información de contacto con los autores.
**         Envia los respectivos mensajes y los despliega en la
**         pantalla LCD.
**         Limpia la interfaz del LCD
**     Argumentos  : Ninguno
**     Retorna     : Nada
** ===================================================================
*/
void Contacto() {
  Bandera = 0;
  Avanzar = 0;
  lcd.cls();
  lcd.locate(0,0);
  lcd.printf("ATEAM & TEAM-T Unltd");
  lcd.locate(0, 1);
  lcd.printf("Antulio Morgado Valle");
  lcd.locate(0, 2);
  lcd.printf("Raziel Lopez Escamilla");
  lcd.locate(0, 3);
  lcd.printf("IPN ESIME Zacatenco");
  while (!Bandera)
    wait_ms(250);
}
/*
** ===================================================================
**     Prototipo   :  Acerca() (Muestra info en la pantalla LCD)
**     Componente  :  Cpu [MKL46Z256VLL]
**     Descripción :
**         Muestra en la pantalla información del prototipo y de los autores.
**         Envia los respectivos mensajes y los despliega en la
**         pantalla LCD.
**         Limpia la interfaz del LCD
**     Argumentos  : Ninguno
**     Retorna     : Nada
** ===================================================================
*/
void Acerca() {
  Bandera = 0;
  Avanzar = 0;
  lcd.cls();
  lcd.locate(0,0);
  lcd.printf("PROTOTIPO ELABORADO ");
  lcd.locate(0, 1);
  lcd.printf("  POR PROFESORES Y ");
  lcd.locate(0, 2);
  lcd.printf("  ALUMNOS DE ESIME ");
  lcd.locate(0, 3);
  lcd.printf("Version: Beta");
  while (!Bandera)
    wait_ms(250);
}