Temporizador con pulsadores

Buenas noches! Estoy haciendo un proyecto escolar con Arduino mega, una pantalla lcd y 4 pulsadores para horas, minutos, segundos e iniciar (respectivamente). El problema es que los botones no funcional al presionarlos sino que el tiempo se pone en la pantalla hasta que conecto los cables que van de los botones a la entrada analógica del Arduino, es decir, si mi botón de horas es la A5 en vez de ponerse las horas en la pantalla e ir aumentando de uno en uno cada que presiono el botón las horas aumentan cada que conecto el cable a la entrada A5 y si dejo el cable metido en la entrada se van aumentando las horas sin parar. Espero me puedan ayudar. Les dejo el código que estoy utilizando.

//TEMPORIZADOR ARDUINO + LCD 

#include <LiquidCrystal.h> //Libreria del display LCD

LiquidCrystal lcd(12, 11, 5, 4, 3, 2); //Inicializamos la libreria con el numero de los pines a utilizar

int buzzer = 9;           //Alarma
int ahoras = 0;            //Variable a mostrar por LCD de las horas
int aminutos = 0;          //Variable a mostrar por LCD de los minutos
int asegundos = 0;         //Variable a mostrar por LCD de los segundos
int segundostotal = 0;     //Tiempo total
int msg= 0;                //Barrera para el mensaje de bienvenida

int start = A1;            //Pulsador de arranque
int empieza = 1024;        // Variable para almacenaje del pulsador de arranque

int buth = A5;             //Pulsador de Horas
int butm = A4;             //Pulsador de Minutos
int buts = A3;             //Pulsador de segundos

int varbuth = 0;           //Variable para almacenar el valor del pulsador de horas
int varbutm = 0;           //Variable para almacenar el valor del pulsador de minutos
int varbuts = 0;           //Variable para almacenar el valor del pulsador de segundos

void setup() 
{
   lcd.begin(20, 4);         // Configuramos el numero de columnas y filas del LCD.  
      pinMode(buzzer, OUTPUT);  //Pin de alarma --> Salida
   pinMode(buth, INPUT);     //Pin de pulsador de horas --> Entrada
   pinMode(butm, INPUT);     //Pin de pulsador de minutos --> Entrada
   pinMode(buts, INPUT);     //Pin de pulsador de segundos --> Entrada
   pinMode(start, INPUT);    //Pin de pulsador de arranque --> Entrada
   
   msg = 0;                  //Barrera del mensaje de bienvenida
   empieza = 1024;           //Barrera de arranque
   
   varbuth = 1;              //Barrera de horas
   varbutm = 1;              //Barrera de minutos
   varbuts = 1;              //Barrera de segundos
}

void loop() 
{
     if(msg==0)             //Mostramos el mensaje de bienvenida solo una vez
     {
       lcd.setCursor(0,0);
       lcd.print("Temporizador con");
       lcd.setCursor(1,1);
       lcd.print("Arduino + LCD");
       delay(2500); 
       msg = 1;
       lcd.clear();
     }
     
     //-------------------------------------------------------------------------------------------------     
     // LECTURA DE LOS BOTONES Y ELECCIÓN DEL TIEMPO, NO SALE DEL BUCLE HASTA PULSAR 
     // EL BOTON DE ARRANQUE
     //-------------------------------------------------------------------------------------------------
     
     do                   
     {
       
       varbuth = analogRead(buth);   //Leemos boton de horas
       varbutm = analogRead(butm);   //Leemos boton de minutos
       varbuts = analogRead(buts);   //Leemos boton de segundos
       
       if(varbuth == 0)              //Si el boton ha sido pulsado, aumentamos las horas en una unidad
       {
        ahoras = ahoras + 1 ;
        delay(250);
       }  
       
        if(varbutm == 0)            //Si el boton ha sido pulsado, aumentamos los minutos en una unidad
       {
         aminutos = aminutos + 1;
         delay(250);
       }  
       
        if(varbuts == 0)            //Si el boton ha sido pulsado, aumentamos los segundos en una unidad
       {
         asegundos = asegundos + 1; 
         delay(250);
       }  
             
       lcd.setCursor(0,0);
       lcd.print("Elige el tiempo");  //Muestra mensaje y las HH:MM:SS que vayamos aumentando
       
       lcd.setCursor(4,1);     

      if (ahoras < 10) lcd.print("0");    // Si las horas son menor que 10, pone un "0" delante.
       lcd.print(ahoras);                 // Sin este codigo, se muestra asi: H:M:S  (1:M:S)
       lcd.print(":");

      if (aminutos < 10) lcd.print("0");  // Si los minutos son menor que 10, pone un "0" delante.
       lcd.print(aminutos);               // Sin este codigo, se muestra asi: H:M:S  (H:1:S)

       lcd.print(":");
      if (asegundos < 10) lcd.print("0"); // Si los segundos son menor que 10, pone un "0" delante.
       lcd.print(asegundos);              // Sin este codigo, se muestra asi: H:M:S  (H:M:1)
       
       empieza = analogRead(start);   //Lee el boton de arranque
       
       if (empieza == 0)              //Si el boton de arranque, fue pulsado...
       {
        segundostotal = asegundos + (aminutos * 60) + (ahoras * 60 * 60);  //Convierte el tiempo elegido en segundos!!
       }
             
     } while(empieza != 0);  // Se repite el menu de elegir tiempo hasta que pulsemos el boton de arranque.
       
      //-------------------------------------------------------------------------------------------------
      // UNA VEZ PULSADO EL BOTON DE ARRANQUE Y ACUMULADO EL TIEMPO, ENTRA EN EL SIGUIENTE WHILE
      // Y NO FINALIZA HASTA TERMINAR LA CUENTA.
      //-------------------------------------------------------------------------------------------------

      while (segundostotal > 0) 
      {
        delay (1000);          //Descontamos en periodos de 1 segundo
        segundostotal--;     
   
        ahoras = ((segundostotal / 60)/ 60);   //Convertimos los segundos totales en horas
        aminutos = (segundostotal / 60) % 60;  //Convertimos los segundos totales en minutos
        asegundos = segundostotal % 60;        //Convertimos los segundos totales en periodos de 60 segundos

        lcd.setCursor(0,0);
        lcd.print("Tiempo restante");        //Mostramos mensaje de tiempo restante
  
        lcd.setCursor(4,1);
        if (ahoras < 10) lcd.print("0");     // Si las horas son menor que 10, pone un "0" delante.
        lcd.print(ahoras);                   // Sin este codigo, se muestra asi: H:M:S  (1:M:S)
        lcd.print(":");

        if (aminutos < 10) lcd.print("0");   // Si los minutos son menor que 10, pone un "0" delante.
        lcd.print(aminutos);                 // Sin este codigo, se muestra asi: H:M:S  (H:1:S)

        lcd.print(":");
        if (asegundos < 10) lcd.print("0");  // si el valor de segundo esta por debajo de 9 (unidad) antepone un cero
        lcd.print(asegundos);                // Sin este codigo, se muestra asi: H:M:S  (H:M:1)
        
          if (segundostotal == 0)            //Si finaliza el tiempo
          {           
             while(1)                        //Bucle infinito mostrando mensaje y haciendo parpadear un led
             {               
                  lcd.clear();
                  lcd.setCursor(5,0);
                  lcd.print("Tiempo");
                  lcd.setCursor(3,1);
                  lcd.print("Finalizado");
               
                 digitalWrite(buzzer, HIGH);
                 delay(200);
                 digitalWrite(buzzer, LOW);
                 delay(200);
             }      
          }
     }
      
}

¿Por qué lees el estado de los botones con analogRead()?

Define las entradas como INPUT_PULLUP y luego lee su estado con digitalRead().

Saludos

PD: Edita tu post e inserta el código según las Normas del Foro, punto 7. Es para tu beneficio.

1 Like

El msg de bienvenida deberías mostrarlo en el setup que se ejecuta solo cuando el arduino se energiza, aunque esta igualmente bien que lo hagas como lo has hecho, las cosas que se presentan 1 vez justamente son para el setup().
No se para que planteas un do {} while para leer los pulsadores o luego un while(1)
Un while(1) no sale jamás de esa parte de código. Tal vez sea tu intención porque se alcanzó el tiempo pero si se trata de una alarma la misma de poder rearmarse.
Entiendo que estas aprendiendo asi que por eso te damos ciertos consejos que mejoren tu programación.
Otra cosa. Ya que empiezas olvida el uso de delay() si estas haciendo algo que cuenta tiempos, cada delay() te genera distorsiones además de que por ese lapso no responde a nada. Micro haciendo absolutamente nada.
Ve a Documentación y lee sobre millis()

Moderador:
Por favor, lee las Normas del foro y edita tu código/error usando etiquetas de código.
Ve a edición, luego selecciona todo el código que has publicado, lo cortas y click en </>


1 Like

Hola!! Hice las correcciones que me indicaste y ya funciona muy bien mi temporizador, muchas gracias!! pero ahora necesito agregarle un relevador que encienda al iniciar el tiempo y se apague al finalizar. Agregué la instrucción para el relé a mi código pero no funciona bien, se enciende el relé inmediatamente al conectar a la corriente y se apaga al iniciar el tiempo.

//TEMPORIZADOR ARDUINO + LCD 

#include <LiquidCrystal.h> //Libreria del display LCD

LiquidCrystal lcd(12, 11, 5, 4, 3, 2); //Inicializamos la libreria con el numero de los pines a utilizar

int buzzer = 10;           //Alarma
int rele = 13;             //Relé
int ahoras = 0;            //Variable a mostrar por LCD de las horas
int aminutos = 0;          //Variable a mostrar por LCD de los minutos
int asegundos = 0;         //Variable a mostrar por LCD de los segundos
int segundostotal = 0;     //Tiempo total
int msg= 0;                //Barrera para el mensaje de bienvenida

int start = 6;            //Pulsador de arranque
int empieza = 1024;        // Variable para almacenaje del pulsador de arranque

int buth = 7;             //Pulsador de Horas
int butm = 8;             //Pulsador de Minutos
int buts = 9;             //Pulsador de segundos

int varbuth = 0;           //Variable para almacenar el valor del pulsador de horas
int varbutm = 0;           //Variable para almacenar el valor del pulsador de minutos
int varbuts = 0;           //Variable para almacenar el valor del pulsador de segundos

void setup() 
{
   lcd.begin(20, 4);         // Configuramos el numero de columnas y filas del LCD.  
      pinMode(buzzer, OUTPUT);  //Pin de alarma --> Salida
      pinMode(rele, OUTPUT);    //Pin de relevador --> Salida
   pinMode(buth, INPUT_PULLUP);     //Pin de pulsador de horas --> Entrada
   pinMode(butm, INPUT_PULLUP);     //Pin de pulsador de minutos --> Entrada
   pinMode(buts, INPUT_PULLUP);     //Pin de pulsador de segundos --> Entrada
   pinMode(start, INPUT_PULLUP);    //Pin de pulsador de arranque --> Entrada
   
   msg = 0;                  //Barrera del mensaje de bienvenida
   empieza = 1024;           //Barrera de arranque
   
   varbuth = 1;              //Barrera de horas
   varbutm = 1;              //Barrera de minutos
   varbuts = 1;              //Barrera de segundos
}

void loop() 
{
     if(msg==0)             //Mostramos el mensaje de bienvenida solo una vez
     {
      digitalWrite(buzzer,HIGH);
      delay(500);
      digitalWrite(buzzer,LOW);
      delay(500);
       lcd.setCursor(3,0);
       lcd.print("Temporizador");
       lcd.setCursor(4,1);
       lcd.print("Electroiman");
       lcd.setCursor(7,2);
       lcd.print("UPIIG");
       delay(3000); 
       msg = 1;
       lcd.clear();
     }
     
     //-------------------------------------------------------------------------------------------------     
     // LECTURA DE LOS BOTONES Y ELECCIÓN DEL TIEMPO, NO SALE DEL BUCLE HASTA PULSAR 
     // EL BOTON DE ARRANQUE
     //-------------------------------------------------------------------------------------------------
     
     do                   
     {
       
       varbuth = digitalRead(buth);   //Leemos boton de horas
       varbutm = digitalRead(butm);   //Leemos boton de minutos
       varbuts = digitalRead(buts);   //Leemos boton de segundos
       
       if( ! varbuth == 0)              //Si el boton ha sido pulsado, aumentamos las horas en una unidad
       {
        ahoras = ahoras + 1 ;
        delay(250);
       }  
       
        if( ! varbutm == 0)            //Si el boton ha sido pulsado, aumentamos los minutos en una unidad
       {
         aminutos = aminutos + 1;
         delay(250);
       }  
       
        if( ! varbuts == 0)            //Si el boton ha sido pulsado, aumentamos los segundos en una unidad
       {
         asegundos = asegundos + 1; 
         delay(250);
       }  
             
       lcd.setCursor(0,0);
       lcd.print("Elige el tiempo");  //Muestra mensaje y las HH:MM:SS que vayamos aumentando
       
       lcd.setCursor(4,1);     

      if (ahoras < 10) lcd.print("0");    // Si las horas son menor que 10, pone un "0" delante.
       lcd.print(ahoras);                 // Sin este codigo, se muestra asi: H:M:S  (1:M:S)
       lcd.print(":");

      if (aminutos < 10) lcd.print("0");  // Si los minutos son menor que 10, pone un "0" delante.
       lcd.print(aminutos);               // Sin este codigo, se muestra asi: H:M:S  (H:1:S)

       lcd.print(":");
      if (asegundos < 10) lcd.print("0"); // Si los segundos son menor que 10, pone un "0" delante.
       lcd.print(asegundos);              // Sin este codigo, se muestra asi: H:M:S  (H:M:1)
       
       empieza = digitalRead(start);   //Lee el boton de arranque
       
       if ( ! empieza == 0)              //Si el boton de arranque, fue pulsado...
       {
        segundostotal = asegundos + (aminutos * 60) + (ahoras * 60 * 60);  //Convierte el tiempo elegido en segundos!!
       }
             
     } while(empieza != 0);  // Se repite el menu de elegir tiempo hasta que pulsemos el boton de arranque.

      digitalWrite (rele, HIGH);
       
      //-------------------------------------------------------------------------------------------------
      // UNA VEZ PULSADO EL BOTON DE ARRANQUE Y ACUMULADO EL TIEMPO, ENTRA EN EL SIGUIENTE WHILE
      // Y NO FINALIZA HASTA TERMINAR LA CUENTA.
      //-------------------------------------------------------------------------------------------------

      while (segundostotal > 0) 
      {
        delay (1000);          //Descontamos en periodos de 1 segundo
        segundostotal--;     
   
        ahoras = ((segundostotal / 60)/ 60);   //Convertimos los segundos totales en horas
        aminutos = (segundostotal / 60) % 60;  //Convertimos los segundos totales en minutos
        asegundos = segundostotal % 60;        //Convertimos los segundos totales en periodos de 60 segundos

        lcd.setCursor(0,0);
        lcd.print("Tiempo restante");        //Mostramos mensaje de tiempo restante
  
        lcd.setCursor(4,1);
        if (ahoras < 10) lcd.print("0");     // Si las horas son menor que 10, pone un "0" delante.
        lcd.print(ahoras);                   // Sin este codigo, se muestra asi: H:M:S  (1:M:S)
        lcd.print(":");

        if (aminutos < 10) lcd.print("0");   // Si los minutos son menor que 10, pone un "0" delante.
        lcd.print(aminutos);                 // Sin este codigo, se muestra asi: H:M:S  (H:1:S)

        lcd.print(":");
        if (asegundos < 10) lcd.print("0");  // si el valor de segundo esta por debajo de 9 (unidad) antepone un cero
        lcd.print(asegundos);                // Sin este codigo, se muestra asi: H:M:S  (H:M:1)
        
          if (segundostotal == 0)            //Si finaliza el tiempo
          {           
             while(1)                        //Bucle infinito mostrando mensaje y haciendo parpadear un led
             {               
                  lcd.clear();
                  lcd.setCursor(5,0);
                  lcd.print("Tiempo");
                  lcd.setCursor(3,1);
                  lcd.print("Finalizado");

        digitalWrite (rele, LOW);
                 digitalWrite(buzzer,HIGH);
                 delay(1000);
                 digitalWrite(buzzer,LOW);
                 delay(4000); 
                 
             
             }      
          }
     }
      
}`Texto preformateado`

La mayoría de los módulos de relevadores se activan (se encienden) con LOW y se apagan con HIGH. Estudia el diagrama para que veas por qué.

Si es este tu caso debes invertir las instrucciones de encendido y apagado.

1 Like

Algunas aclaraciones a este afirmación.

image
Esta es la forma de conexión mas repetida en internet y coincido que es la mas natural si se permite el término y claramente coincide con tu afirmación @mancera1979
Un LOW hace que el led conduzca y un ALTO o HIGH no.

Pero ahora si quitas el jumper, alimentas con 5V en JDVcc.
Luego el pin Arduino se conecta a Vcc (Repito sin JUMPER).
Y el IN1 va a GND.
Entonces un HIGH enciende el rele y un LOW lo apagará.
Esta conexión es la que debe usarse si o si con dispositivos 3.3V que usen reles de 5V de lo contario el rele vibra en muchos de los caso y en otros no funciona.

@seaandsun
Ahora agrega esto en tu setup

digitalWrite(rele, HIGH); // para que arranque apagado 

y luego ya te lo han dicho pero trabaja con lógica invertida.
Prende con LOW, apaga con HIGH
una cómoda es esta, defines ON y OFF al comienzo de este modo

#define ON      LOW
#define OFF     HIGH
// y en tu código usas 
digitalWrite(rele, ON);  // para encender
// o
digitalWrite(rele, OFF);  // para apagar
1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.