Autor Tema: Pulsador encienda led por un tiempo  (Leído 1642 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado osmangutierrez

  • PIC10
  • *
  • Mensajes: 13
Pulsador encienda led por un tiempo
« en: 07 de Enero de 2022, 14:02:46 »
Hola a todos..
estoy empezando a usar arduino para cosas sencillas por ahora.
El motivo de mi post es que necesito presionar un pulsador y se encienda un led por 2 segundos y luego se apague, "sin importar el tiempo que este presionado el pulsador".
Hice el sieguiente:

Código: [Seleccionar]
int salida = 8;
int entrada = 7;

void setup(){
  pinMode(salida, OUTPUT);            // led
  pinMode(entrada, INPUT_PULLUP);     // pulsador
  Serial.begin( 9600 );
}

void loop(){
  int boton = digitalRead(entrada);
  if (boton == 0){
    digitalWrite(salida, HIGH);       //enciende led
    Serial.println("led encendido");
    delay(2000);
  } else {
    digitalWrite(salida, LOW);        //apaga led
    Serial.println("led apagado");
  }
}

Pero el led se mantiene encendido y se apaga 2 segundos despues de soltar el pulsador.
les agradeceria mucho la ayuda.

Desconectado DominusDRR

  • PIC24H
  • ******
  • Mensajes: 1937
    • Sicoy
Re:Pulsador encienda led por un tiempo
« Respuesta #1 en: 07 de Enero de 2022, 14:16:02 »
Hola a todos..
estoy empezando a usar arduino para cosas sencillas por ahora.
El motivo de mi post es que necesito presionar un pulsador y se encienda un led por 2 segundos y luego se apague, "sin importar el tiempo que este presionado el pulsador".
Hice el sieguiente:

Hola, no soy experto en Arduino, pero tal vez debas hacerlo en estados de máquina

Código: C
  1. int estado = 0;
  2. void loop(){
  3.   int boton = digitalRead(entrada);
  4.   swicth (estado)
  5.   {
  6.          case 0x00: //espero al botón sea presionado
  7.         {
  8.             if (0 == boton)
  9.             {
  10.                 estado = 0x01;  
  11.             }
  12.             break;
  13.         }
  14.         case 0x01: // activo el led y espero 1 segundo
  15.         {
  16.                 digitalWrite(salida, HIGH);       //enciende led
  17.                 Serial.println("led encendido");
  18.                 delay(2000);
  19.                 digitalWrite(salida, LOW);        //apaga led
  20.                 Serial.println("led apagado");
  21.                 estado = 0x02;
  22.                 break;
  23.           }
  24.           default: // equivale a case 0x02:
  25.           {
  26.                   if (1== boton) //si el botón sigue presionado, espero hasta que lo suelte el usuario
  27.                   {
  28.                           estado = 0x00;
  29.                   }
  30.                   break;
  31.           }
  32.   }
  33. }

Obviamente esto considerando que no existe rebotes por parte del pulsante.
« Última modificación: 07 de Enero de 2022, 14:19:21 por DominusDRR »
Tengo una idea algo difusa sobre MPLAB Harmony, XC32 con PIC32

Desconectado osmangutierrez

  • PIC10
  • *
  • Mensajes: 13
Re:Pulsador encienda led por un tiempo
« Respuesta #2 en: 07 de Enero de 2022, 15:46:36 »
Muchisimas gracias DominusDRR
Funciona perfectamente

Desconectado osmangutierrez

  • PIC10
  • *
  • Mensajes: 13
Re:Pulsador encienda led por un tiempo
« Respuesta #3 en: 31 de Enero de 2022, 07:50:49 »
Obviamente esto considerando que no existe rebotes por parte del pulsante.

Hola de nuevo a todos, estoy atascado con lo del antirrebote, lo he intentado por hardware, no me fue bien  :(
Como quedaria el codigo con antirrebote y los estados de máquina?
gracias de antemano

Desconectado DominusDRR

  • PIC24H
  • ******
  • Mensajes: 1937
    • Sicoy
Re:Pulsador encienda led por un tiempo
« Respuesta #4 en: 31 de Enero de 2022, 09:03:20 »
Obviamente esto considerando que no existe rebotes por parte del pulsante.

Hola de nuevo a todos, estoy atascado con lo del antirrebote, lo he intentado por hardware, no me fue bien  :(
Como quedaria el codigo con antirrebote y los estados de máquina?
gracias de antemano

Sería interesante conocer como lo estás haciendo por hardware.

Por software simplemente debes colocar un retardo cuando hay cambios en el pulsador. En el orden de 100 a 200 ms.

Puedes empezar por el valor máximo, e ir decrementando hasta conseguir un valor adecuado.

Código: C++
  1. int estado = 0;
  2. void loop(){
  3.   int boton = digitalRead(entrada);
  4.   swicth (estado)
  5.   {
  6.           case 0x00: //espero al boton sea presionado
  7.                 if (0 == boton)
  8.                 {
  9.                         delay(150); //<--- para elimnar rebote
  10.                         estado = 0x01;  
  11.                 }
  12.           break;
  13.           case 0x01: // activo el led y espero 1 segundo
  14.           {
  15.                 digitalWrite(salida, HIGH);       //enciende led
  16.                 Serial.println("led encendido");
  17.                 delay(2000);
  18.                 digitalWrite(salida, LOW);        //apaga led
  19.         Serial.println("led apagado");
  20.                 estado = 0x02;
  21.                 break;
  22.           }
  23.           default: // equivale a case 0x02:
  24.           {
  25.                   if (1== boton) //si el bot?n sigue presionado, espero hasta que lo suelte el usuario
  26.                   {
  27.                           delay(150); //<--- para elimnar rebote
  28.                           estado = 0x00;
  29.                   }
  30.                   break;
  31.           }
  32.   }
  33. }
Tengo una idea algo difusa sobre MPLAB Harmony, XC32 con PIC32

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5883
    • Picuino
Re:Pulsador encienda led por un tiempo
« Respuesta #5 en: 31 de Enero de 2022, 11:28:12 »
Con este otro programa no se utiliza delay() sino millis() y tiene la ventaja de no quedarse parado en el delay() por lo que puede hacer otras tareas mientras espera.


Código: C
  1. #define PIN_LED   13
  2. #define PIN_INPUT  2
  3.  
  4. int estado_pulsador;
  5. unsigned long delay_antirrebote, delay_led;
  6.  
  7. void setup() {
  8.   pinMode(PIN_LED, OUTPUT);
  9.   pinMode(PIN_INPUT, INPUT_PULLUP);
  10.   estado_pulsador = 0;
  11.   estado_led = 0;
  12. }
  13.  
  14. void loop() {
  15.   int boton = digitalRead(PIN_INPUT);
  16.  
  17.   switch (estado_pulsador) {
  18.     case 0:  // Reposo
  19.       digitalWrite(PIN_LED, LOW);
  20.       if (boton == 0) {
  21.         delay_antirrebote = millis() + 100L;
  22.         estado_pulsador = 1;
  23.       }
  24.       break;
  25.  
  26.     case 1:  // Delay antirrebote
  27.       if (boton == 1) {
  28.         estado_pulsador = 0;
  29.       }
  30.       if (millis() - delay_antirrebote < 0x80000000L) {
  31.         delay_led = millis() + 2000L;
  32.         estado_pulsador = 2;
  33.       }
  34.       break;
  35.  
  36.     case 2:  // LED encendido
  37.       digitalWrite(PIN_LED, HIGH);
  38.       if (millis() - delay_led < 0x80000000L) {
  39.         estado_pulsador = 0;
  40.       }
  41.       break;
  42.   }
  43.  
  44. }

Desconectado DominusDRR

  • PIC24H
  • ******
  • Mensajes: 1937
    • Sicoy
Re:Pulsador encienda led por un tiempo
« Respuesta #6 en: 31 de Enero de 2022, 11:34:14 »
Con este otro programa no se utiliza delay() sino millis() y tiene la ventaja de no quedarse parado en el delay() por lo que puede hacer otras tareas mientras espera.


Código: C
  1. #define PIN_LED   13
  2. #define PIN_INPUT  2
  3.  
  4. int estado_pulsador;
  5. unsigned long delay_antirrebote, delay_led;
  6.  
  7. void setup() {
  8.   pinMode(PIN_LED, OUTPUT);
  9.   pinMode(PIN_INPUT, INPUT_PULLUP);
  10.   estado_pulsador = 0;
  11.   estado_led = 0;
  12. }
  13.  
  14. void loop() {
  15.   int boton = digitalRead(PIN_INPUT);
  16.  
  17.   switch (estado_pulsador) {
  18.     case 0:  // Reposo
  19.       digitalWrite(PIN_LED, LOW);
  20.       if (boton == 0) {
  21.         delay_antirrebote = millis() + 100L;
  22.         estado_pulsador = 1;
  23.       }
  24.       break;
  25.  
  26.     case 1:  // Delay antirrebote
  27.       if (boton == 1) {
  28.         estado_pulsador = 0;
  29.       }
  30.       if (millis() - delay_antirrebote < 0x80000000L) {
  31.         delay_led = millis() + 2000L;
  32.         estado_pulsador = 2;
  33.       }
  34.       break;
  35.  
  36.     case 2:  // LED encendido
  37.       digitalWrite(PIN_LED, HIGH);
  38.       if (millis() - delay_led < 0x80000000L) {
  39.         estado_pulsador = 0;
  40.       }
  41.       break;
  42.   }
  43.  
  44. }

Inteserante que se pueda hacer eso similar a Harmony 3 (cofunciones y multitareas), lo que no entiendo es porqué incrementas en 100L (delay_antirrebote = millis() + 100L;) cuando capturas el valor inicial para generar un retardo.

Porque en Harmony es más o menos así:

Código: C
  1. valorCapturado = CoreTimer();  //Capturo el valor del Core TImer
  2.  
  3. ...
  4.  
  5. if ((CoreTimer() - valorCapturado) > UnaConstante)
  6. {
  7.     //el retardo deseado (UnaConstante) ha ocurrido
  8. }

« Última modificación: 31 de Enero de 2022, 11:37:42 por DominusDRR »
Tengo una idea algo difusa sobre MPLAB Harmony, XC32 con PIC32

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5883
    • Picuino
Re:Pulsador encienda led por un tiempo
« Respuesta #7 en: 31 de Enero de 2022, 12:43:37 »
Las dos funcionan igual. Yo estaba acostumbrado a la forma que he posteado, pero la forma de Harmony también me ha gustado. De hecho creo que es mejor, pero tendría que probarlo.



Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5883
    • Picuino
Re:Pulsador encienda led por un tiempo
« Respuesta #8 en: 31 de Enero de 2022, 13:04:30 »
Parece que funciona bien.
Falta comprobar el funcionamiento justo en el momento en el que se desborda millis() al cabo de 49.7 días.
Por lo que he podido simular, funcionará correctamente durante el desbordamiento aunque las cantidades a temporizar sean muy grandes y parecidas al tiempo de desbordamiento.

Código: C
  1. #define PIN_LED   13
  2. #define PIN_INPUT  2
  3.  
  4. #define TIEMPO_ANTIRREBOTE      100L
  5. #define TIEMPO_LED_ENCENDIDO   2000L
  6.  
  7. int estado_pulsador, estado_led;
  8. unsigned long old_millis;
  9.  
  10. void setup() {
  11.   pinMode(PIN_LED, OUTPUT);
  12.   pinMode(PIN_INPUT, INPUT_PULLUP);
  13.   estado_pulsador = 0;
  14.   estado_led = 0;
  15. }
  16.  
  17. void loop() {
  18.   int boton = digitalRead(PIN_INPUT);
  19.  
  20.   switch (estado_pulsador) {
  21.     case 0:  // Reposo
  22.       digitalWrite(PIN_LED, LOW);
  23.       if (boton == 0) {
  24.         old_millis = millis();
  25.         estado_pulsador = 1;
  26.       }
  27.       break;
  28.  
  29.     case 1:  // Delay antirrebote
  30.       if (boton == 1) {
  31.         estado_pulsador = 0;
  32.       }
  33.       if ((millis() - old_millis) > TIEMPO_ANTIRREBOTE) {
  34.         old_millis = millis();
  35.         estado_pulsador = 2;
  36.       }
  37.       break;
  38.  
  39.     case 2:  // LED encendido
  40.       digitalWrite(PIN_LED, HIGH);
  41.       if ((millis() - old_millis) > TIEMPO_LED_ENCENDIDO) {
  42.         estado_pulsador = 0;
  43.       }
  44.       break;
  45.   }
  46. }
« Última modificación: 31 de Enero de 2022, 13:07:27 por Picuino »

Desconectado osmangutierrez

  • PIC10
  • *
  • Mensajes: 13
Re:Pulsador encienda led por un tiempo
« Respuesta #9 en: 31 de Enero de 2022, 19:02:58 »
Buenas tardes a todos
Muchas gracias por sus respuestas, mi proyecto ha cambiado en el tiempo de encendido del led, yo no son 2 segundos, sinó 70 milisegundos, y el tiempo máximo que el arduino estará encendió son 6 horas

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5883
    • Picuino
Re:Pulsador encienda led por un tiempo
« Respuesta #10 en: 01 de Febrero de 2022, 13:02:54 »
He hecho una modificación para añadir una máquina de estados más.
La primera máquina de estados detecta flancos del pulsador después de un tiempo de delay para evitar detectar rebotes.
La segunda máquina de estados enciende el led durante 2 segundos cuando está apagado y le llega una señal de flanco del pulsador.
Es un programa más complejo, pero mucho más flexible al separar el manejo del pulsador del comportamiento del led.

Además ahora el led solo se enciende cada vez que presionamos el pulsador y se apaga si el pulsador permanece todo el tiempo presionado.

Código: C
  1. #define PIN_LED   13
  2. #define PIN_INPUT  2
  3.  
  4. #define TIEMPO_ANTIRREBOTE      50L
  5. #define TIEMPO_LED_ENCENDIDO   2000L
  6.  
  7. byte estado_pulsador, estado_led;
  8. byte flanco_pulsador;
  9. unsigned long millis_pulsador, millis_led;
  10.  
  11. void setup() {
  12.   pinMode(PIN_LED, OUTPUT);
  13.   pinMode(PIN_INPUT, INPUT_PULLUP);
  14.  
  15.   estado_pulsador = 0;
  16.   estado_led = 0;
  17.  
  18.   flanco_pulsador = 0;
  19. }
  20.  
  21. void loop() {
  22.   int boton = digitalRead(PIN_INPUT);
  23.  
  24.   switch (estado_pulsador) {
  25.     case 0:  // Reposo
  26.       if (boton == LOW) {
  27.         millis_pulsador = millis();
  28.         estado_pulsador = 1;
  29.       }
  30.       break;
  31.  
  32.     case 1:  // Delay antirrebote
  33.       if (boton == HIGH) {
  34.         estado_pulsador = 0;
  35.       }
  36.       if ((millis() - millis_pulsador) > TIEMPO_ANTIRREBOTE) {
  37.         estado_pulsador = 2;
  38.         flanco_pulsador = 1;
  39.       }
  40.       break;
  41.     case 2:
  42.       if (boton == HIGH) {
  43.         estado_pulsador = 0;
  44.       }
  45.       break;
  46.   }
  47.  
  48.   switch (estado_led) {
  49.     case 0:
  50.       digitalWrite(PIN_LED, LOW);
  51.       if (flanco_pulsador == 1) {
  52.         flanco_pulsador = 0;
  53.         estado_led = 1;
  54.         millis_led = millis();
  55.       }
  56.       break;
  57.     case 1:
  58.       digitalWrite(PIN_LED, HIGH);
  59.       if ((millis() - millis_led) > TIEMPO_LED_ENCENDIDO) {
  60.         estado_led = 0;
  61.       }
  62.       break;
  63.   }
  64.  
  65. }
« Última modificación: 01 de Febrero de 2022, 13:05:55 por Picuino »

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5883
    • Picuino
Re:Pulsador encienda led por un tiempo
« Respuesta #11 en: 01 de Febrero de 2022, 13:07:47 »
Una pequeña modificación para que el temporizador del led se reinicie cada vez que volvemos a presionar el pulsador.

Código: C
  1. #define PIN_LED   13
  2. #define PIN_INPUT  2
  3.  
  4. #define TIEMPO_ANTIRREBOTE      50L
  5. #define TIEMPO_LED_ENCENDIDO   2000L
  6.  
  7. byte estado_pulsador, estado_led;
  8. byte flanco_pulsador;
  9. unsigned long millis_pulsador, millis_led;
  10.  
  11. void setup() {
  12.   pinMode(PIN_LED, OUTPUT);
  13.   pinMode(PIN_INPUT, INPUT_PULLUP);
  14.  
  15.   estado_pulsador = 0;
  16.   estado_led = 0;
  17.  
  18.   flanco_pulsador = 0;
  19. }
  20.  
  21. void loop() {
  22.   int boton = digitalRead(PIN_INPUT);
  23.  
  24.   switch (estado_pulsador) {
  25.     case 0:  // Reposo
  26.       if (boton == LOW) {
  27.         millis_pulsador = millis();
  28.         estado_pulsador = 1;
  29.       }
  30.       break;
  31.  
  32.     case 1:  // Delay antirrebote
  33.       if (boton == HIGH) {
  34.         estado_pulsador = 0;
  35.       }
  36.       if ((millis() - millis_pulsador) > TIEMPO_ANTIRREBOTE) {
  37.         estado_pulsador = 2;
  38.         flanco_pulsador = 1;
  39.       }
  40.       break;
  41.     case 2:
  42.       if (boton == HIGH) {
  43.         estado_pulsador = 0;
  44.       }
  45.       break;
  46.   }
  47.  
  48.   switch (estado_led) {
  49.     case 0:
  50.       digitalWrite(PIN_LED, LOW);
  51.       if (flanco_pulsador == 1) {
  52.         flanco_pulsador = 0;
  53.         estado_led = 1;
  54.         millis_led = millis();
  55.       }
  56.       break;
  57.     case 1:
  58.       digitalWrite(PIN_LED, HIGH);
  59.       if (flanco_pulsador == 1) {
  60.         flanco_pulsador = 0;
  61.         millis_led = millis();
  62.       }
  63.       if ((millis() - millis_led) > TIEMPO_LED_ENCENDIDO) {
  64.         estado_led = 0;
  65.       }
  66.       break;
  67.   }
  68.  
  69. }

Desconectado osmangutierrez

  • PIC10
  • *
  • Mensajes: 13
Re:Pulsador encienda led por un tiempo
« Respuesta #12 en: 08 de Mayo de 2023, 23:35:22 »
Una pequeña modificación para que el temporizador del led se reinicie cada vez que volvemos a presionar el pulsador.
Buenaa.. Con eso queda mas que solucionado mi problema, quedo muy agradecido.
PD. mil disculpas por la tardanza  :oops: