// CODIGO PARA EL MODULO GENERADOR PWM CON PULSADORES Y PANTALLA LCD 
#include <LiquidCrystal_I2C.h>  
#include <LiquidCrystal.h>                  /*INICIALIZAMOS LIBRERIA PARA LA LCD 16X2*/
#include <PWMMotorControl.h>                            /*INICIALIZAMOS LIBRERIA PWM*/
//LiquidCrystal lcd(8, 9, 4, 5, 6, 7);        /*ESTABLECEMOS LOS PINES PARA LA COMUNICACION CON LA LCD*/
LiquidCrystal_I2C lcd(0x27,16,2); 
/*Declarando las variables de tipo entero*/
int inc_freq;                               /*BOTON PARA INCREMENTO DE FRECUENCIA*/
int dec_freq=1;                             /*BOTON PARA DECREMENTO DE FRECUENCIA*/

int inc_duty;                               /*BOTON PARA INCREMENTO DEL CICLO DE TRABAJO*/
int dec_duty=1;                             /*BOTON PARA DECREMENTO DEL CICLO DE TRABAJO*/

int freq=100;                               /*VARIABLE ASIGNADA PARA LA FRECUENCIA*/
int duty=10;                                /*VARIABLE ASIGNADA PARA EL CICLO DE TRABAJO*/

int ant_freq=1;                             /*VALOR DEL ESTADO ANTERIOR DE LA FRECUENCIA*/
int ant_duty=1;                             /*VALOR DEL ESTADO ANTERIOR DEL CICLO DE TRABAJO*/

int time_push = 0;                          /*TIEMPO EN QUE SE PRESIONA EL BOTON*/
int time_free  = 0;                         /*TIEMPO EN QUE SE LIBERA EL BOTON*/

int time_press = 0;                         /*TIEMPO QUE SE MANTUVO PRESIONADO EL BOTON +FREQ*/
int time_press2 = 0;                        /*TIEMPO QUE SE MANTUVO PRESIONADO EL BOTON -FREQ*/

int ref_1 = 0;                              /*VARIABLE PARA CONDICION INICIAL DE +FREQ*/
int ref_2 = 0;                              /*VARIABLE PARA CONDICION INICIAL DE -FREQ*/

float factor= 1;                            /*FACTOR DE MULTIPLICACION PARA OBTENER UN RANGO DE FRECUENCIA*/
                                            /*CON factor=1 SE TIENE DE 33 A 30,000 HZ*/

/*_________________________________________*/                            
void setup()
{
  lcd.begin(16,2);                          /*ESTABLECIENDO EL TIPO DE DISPLAY*/
  Serial.begin(9600);                       /*INICIALIZANDO EL PUERTO SERIE*/
  pinMode(12,INPUT);
  pinMode(10,INPUT);
  InitTimersSafe();                                  
}
/*_________________________________________*/ 
void loop()
{    
  /*CODIGO PARA INCREMENTAR EL VALOR DEL CICLO DE TRABAJO AL OPRIMIR PUSH-BOTON EN EL PIN 12 */
  inc_duty = digitalRead(12); 
  if (ant_duty != inc_duty && dec_duty!=inc_duty){
    if (inc_duty ==HIGH){
      digitalWrite(12,HIGH);
      duty++;
      Serial.println(duty);
      delay(50);}
      }
      ant_duty=inc_duty;

  /*CODIGO PARA DECREMENTAR EL VALOR DEL CICLO DE TRABAJO AL OPRIMIR PUSH-BOTON EN EL PIN 13 */
  dec_duty = digitalRead(13); 
   if (dec_duty ==HIGH){
    if(ant_duty!=dec_duty);{
      digitalWrite(13,HIGH);
      duty--;
      Serial.println(duty);
      delay(50);}
      }
      ant_duty=dec_duty;

   /*ESTABLECIENDO LOS VALORES LIMITE PARA EL CICLO DE TRABAJO DE 0 A 99%*/
   if (duty<0){
      duty=0;}
      if (duty>99){
      duty =99;
      Serial.println(duty);
      delay(100);}                          
      pwmWrite(3, duty*2.56);     
      delay(50); 
     
   /*CODIGO PARA INCREMENTAR EL VALOR DE LA FRECUENCIA AL OPRIMIR PUSH-BOTON EN EL PIN 10 */     
   inc_freq = digitalRead(10);   
   if (ant_freq != inc_freq && dec_freq!=inc_freq){
      if (inc_freq ==HIGH){
      digitalWrite(10,HIGH);
      freq++;
      Serial.println(freq);
      delay(5);}
      }
      ant_freq=inc_freq;

    /*CODIGO PARA DECREMENTAR EL VALOR DE LA FRECUENCIA AL OPRIMIR PUSH-BOTON EN EL PIN 11 */
    dec_freq = digitalRead(11);  
    if (dec_freq ==HIGH){
      if(ant_freq!=dec_freq);{
      digitalWrite(11,HIGH);
      freq--;
      Serial.println(freq);
      delay(5);}
      }
      ant_freq=dec_freq;

    /*CODIGO PARA CONTAR EL TIEMPO QUE SE MANTIENE OPRIMIDO +Freq */
    if (!digitalRead(inc_freq) && ref_1 == 0){
      ref_1 = 1;
      time_push = millis();}
    if (digitalRead(inc_freq) && ref_1 == 1){
      time_free = millis();
      time_press = time_free - time_push;
      ref_1 = 0; 
      Serial.print("Tiempo que se mantuvo presionado +Freq: ");
      Serial.println(time_press);
      } 

    /*CODIGO PARA CONTAR EL TIEMPO QUE SE MANTIENE OPRIMIDO -Freq */  
    if (!digitalRead(dec_freq) && ref_2 == 0){
      ref_2 = 1;
      time_push = millis();}
    if (digitalRead(dec_freq) && ref_2 == 1){
      time_free = millis();
      time_press2 = time_free - time_push;
      ref_2 = 0; 
      Serial.print("Tiempo que se mantuvo presionado -Freq: ");
      Serial.println(time_press2);
      }

    /*ESTABLECIENDO LOS VALORES LIMITE PARA LA FRECUENCIA DE 33 A 30,000 HZ*/
    if (freq<33){
     freq=33;
     Serial.println(freq);
     delay(5);}
   if (freq>30000){
     freq=30000;
     Serial.println(freq);
     delay(5);}
     //Serial.println(freq);
     //delay(50);

    /*CODIGO PARA AUMENTAR RAPIDAMENTE LA FRECUENCIA SI SE DEJA PRESIONADO  +Freq POR 3 Y 5 SEG*/ 
    if (time_press>=3000 && digitalRead(inc_freq)){
     freq= freq+10;}                                /*AUMENTA CON MAS DE 3 SEGUNDOS*/
    if (time_press>=5000 && digitalRead(inc_freq)){
     freq= freq+100;                                /*AUMENTA CON MAS DE 5 SEGUNDOS*/
     Serial.println(freq);
     delay(5);}
     
    /*CODIGO PARA DISMINUIR RAPIDAMENTE LA FRECUENCIA SI SE DEJA PRESIONADO -Freq POR 3 Y 5 SEG*/ 
    if (time_press2>=3000 && digitalRead(dec_freq)){
     freq= freq-10;}                                 /*DISMINUYE CON MAS DE 3 SEGUNDOS*/
    if (time_press2>=5000 && digitalRead(dec_freq)){
     freq= freq-100;                                 /*DISMINUYE CON MAS DE 5 SEGUNDOS*/
     Serial.println(freq);
     delay(5);}

   /*ASIGNANDO LA SEÑAL DE SALIDA PWM AL PIN DIGITAL "3" */
   /*El "factor" se utiliza para modificar el rango de frecuencia requerido*/
     SetPinFrequencySafe (3,freq*factor); 
     delay(5);

   /*COMANDOS PARA MOSTRAR TEXTO EN PANTALLA LCD: 
     ESCRITURA Y LOCALIZACION DE TEXTO EN LCD EN LA PRIMERA FILA*/
     lcd.setCursor(0,0);
     lcd.print("Freq: ");
     lcd.print(freq*factor);
     lcd.setCursor(14,0);
     lcd.print("Hz");
     delay(10);
  
   /*ESCRITURA Y LOCALIZACION DE TEXTO EN LCD EN 
     LA SEGUNDA FILA*/
     lcd.setCursor(0,1);
     lcd.print("Duty cicle: ");
     lcd.print(duty);
     lcd.print(" %");
     delay(10);
  
} //FIN DE LA CODIFICACION........