Arduino - Botón - Antirrebote

Cuando se pulsa o se suelta un botón o cuando se cambia un interruptor, los novatos suelen pensar simplemente que su estado cambia de bajo a alto o de alto a bajo. En la práctica, no es exactamente así. Debido a las características mecánicas y físicas, el estado del botón (o interruptor) puede cambiar entre bajo y alto varias veces. Este fenómeno se llama rebote. El fenómeno de rebote hace que una pulsación única pueda leerse como varias pulsaciones, lo que provoca un mal funcionamiento en algunos tipos de aplicaciones. Este tutorial muestra cómo eliminar este fenómeno (llamado anti-rebote de la entrada).

Fenómeno de chattering en Arduino

Acerca de Botón

Si no sabes sobre los botones (disposición de pines, cómo funcionan, cómo programarlos...), aprende sobre ellos en los siguientes tutoriales:

Diagrama de Cableado

Diagrama de cableado de un botón de Arduino

This image is created using Fritzing. Click to enlarge image

Veamos y comparemos el código de Arduino entre las versiones sin anti-rebote y con anti-rebote, y sus comportamientos.

Lectura de botón sin antirrebote

Antes de aprender sobre el debouncing, solo mira el código sin debouncing y su comportamiento.

Pasos R\u00e1pidos

  • Conecta Arduino al PC mediante un cable USB
  • Abre Arduino IDE, selecciona la placa y el puerto correctos
  • Copia el código de abajo y ábrelo con Arduino IDE
/* * Este código de Arduino fue desarrollado por es.newbiely.com * Este código de Arduino se proporciona al público sin ninguna restricción. * Para tutoriales completos y diagramas de cableado, visite: * https://es.newbiely.com/tutorials/arduino/arduino-button-debounce */ // constants won't change. They're used here to set pin numbers: const int BUTTON_PIN = 7; // the number of the pushbutton pin // Variables will change: int lastState = LOW; // the previous state from the input pin int currentState; // the current reading from the input pin void setup() { // initialize serial communication at 9600 bits per second: Serial.begin(9600); // initialize the pushbutton pin as an pull-up input // the pull-up input pin will be HIGH when the switch is open and LOW when the switch is closed. pinMode(BUTTON_PIN, INPUT_PULLUP); } void loop() { // read the state of the switch/button: currentState = digitalRead(BUTTON_PIN); if(lastState == HIGH && currentState == LOW) Serial.println("The button is pressed"); else if(lastState == LOW && currentState == HIGH) Serial.println("The button is released"); // save the the last state lastState = currentState; }
  • Haz clic en el botón Subir en el IDE de Arduino para subir el código al Arduino
Subir código al IDE de Arduino
  • Abre el Monitor Serial
  • Mantén pulsado el botón durante varios segundos y luego suéltalo.
  • Ver el resultado en el Monitor Serial
COM6
Send
The button is pressed The button is pressed The button is pressed The button is released The button is released
Autoscroll Show timestamp
Clear output
9600 baud  
Newline  

⇒ Como puedes ver, presionaste y soltaste el botón solo una vez. Sin embargo, Arduino lo reconoce como múltiples pulsaciones y liberaciones.

Lectura de un botón con antirrebote

Pasos R\u00e1pidos

  • Copie el código a continuación y ábralo con Arduino IDE
/* * Este código de Arduino fue desarrollado por es.newbiely.com * Este código de Arduino se proporciona al público sin ninguna restricción. * Para tutoriales completos y diagramas de cableado, visite: * https://es.newbiely.com/tutorials/arduino/arduino-button-debounce */ // constants won't change. They're used here to set pin numbers: const int BUTTON_PIN = 7; // the number of the pushbutton pin const int DEBOUNCE_DELAY = 50; // the debounce time; increase if the output flickers // Variables will change: int lastSteadyState = LOW; // the previous steady state from the input pin int lastFlickerableState = LOW; // the previous flickerable state from the input pin int currentState; // the current reading from the input pin // the following variables are unsigned longs because the time, measured in // milliseconds, will quickly become a bigger number than can be stored in an int. unsigned long lastDebounceTime = 0; // the last time the output pin was toggled void setup() { // initialize serial communication at 9600 bits per second: Serial.begin(9600); // initialize the pushbutton pin as an pull-up input // the pull-up input pin will be HIGH when the switch is open and LOW when the switch is closed. pinMode(BUTTON_PIN, INPUT_PULLUP); } void loop() { // read the state of the switch/button: currentState = digitalRead(BUTTON_PIN); // check to see if you just pressed the button // (i.e. the input went from LOW to HIGH), and you've waited long enough // since the last press to ignore any noise: // If the switch/button changed, due to noise or pressing: if (currentState != lastFlickerableState) { // reset the debouncing timer lastDebounceTime = millis(); // save the the last flickerable state lastFlickerableState = currentState; } if ((millis() - lastDebounceTime) > DEBOUNCE_DELAY) { // whatever the reading is at, it's been there for longer than the debounce // delay, so take it as the actual current state: // if the button state has changed: if (lastSteadyState == HIGH && currentState == LOW) Serial.println("The button is pressed"); else if (lastSteadyState == LOW && currentState == HIGH) Serial.println("The button is released"); // save the the last steady state lastSteadyState = currentState; } }
  • Haz clic en el botón Subir en el IDE de Arduino para subir el código al Arduino
  • Abre el Monitor Serial
  • Mantén pulsado el botón durante varios segundos y luego suéltalo.
  • Ver el resultado en el Monitor Serial
COM6
Send
The button is pressed The button is released
Autoscroll Show timestamp
Clear output
9600 baud  
Newline  

⇒ Como puedes ver, presionaste y soltaste el botón solo una vez. Arduino lo reconoce como la única pulsación y liberación. El rebote se elimina.

Lo Hicimos Fácil - Código de Antirrebote de Botón en Arduino con Biblioteca

Para facilitarlo a los principiantes, especialmente cuando se usan varios botones, creamos una biblioteca llamada ezButton. Puedes informarte sobre la biblioteca ezButton aquí.

Código de antirrebote de Arduino para un único botón

/* * Created by ArduinoGetStarted.com * * This example code is in the public domain * * Tutorial page: https://arduinogetstarted.com/tutorials/arduino-button-library * * This example reads the state of a button with debounce and print it to Serial Monitor. */ #include <ezButton.h> ezButton button(7); // create ezButton object that attach to pin 7; void setup() { Serial.begin(9600); button.setDebounceTime(50); // set debounce time to 50 milliseconds } void loop() { button.loop(); // MUST call the loop() function first if(button.isPressed()) Serial.println("The button is pressed"); if(button.isReleased()) Serial.println("The button is released"); }

Código de antirrebote de Arduino para múltiples botones

/* * Este código de Arduino fue desarrollado por es.newbiely.com * Este código de Arduino se proporciona al público sin ninguna restricción. * Para tutoriales completos y diagramas de cableado, visite: * https://es.newbiely.com/tutorials/arduino/arduino-button-debounce */ #include <ezButton.h> ezButton button1(6); // create ezButton object that attach to pin 6; ezButton button2(7); // create ezButton object that attach to pin 7; ezButton button3(8); // create ezButton object that attach to pin 8; void setup() { Serial.begin(9600); button1.setDebounceTime(50); // set debounce time to 50 milliseconds button2.setDebounceTime(50); // set debounce time to 50 milliseconds button3.setDebounceTime(50); // set debounce time to 50 milliseconds } void loop() { button1.loop(); // MUST call the loop() function first button2.loop(); // MUST call the loop() function first button3.loop(); // MUST call the loop() function first if(button1.isPressed()) Serial.println("The button 1 is pressed"); if(button1.isReleased()) Serial.println("The button 1 is released"); if(button2.isPressed()) Serial.println("The button 2 is pressed"); if(button2.isReleased()) Serial.println("The button 2 is released"); if(button3.isPressed()) Serial.println("The button 3 is pressed"); if(button3.isReleased()) Serial.println("The button 3 is released"); }

El diagrama de cableado para el código anterior:

Diagrama de cableado de la biblioteca de botones de Arduino

This image is created using Fritzing. Click to enlarge image

Video Tutorial

Estamos considerando crear tutoriales en video. Si considera que los tutoriales en video son importantes, suscríbase a nuestro canal de YouTube para motivarnos a crear los videos.

Conocimiento adicional

  • DEBOUNCE_DELAY El valor depende de las aplicaciones. Diferentes aplicaciones pueden usar diferentes valores.

Extensibilidad

El método de anti-rebote puede aplicarse a interruptores, sensores táctiles ...

※ NUESTROS MENSAJES

  • No dude en compartir el enlace de este tutorial. Sin embargo, por favor no use nuestro contenido en otros sitios web. Hemos invertido mucho esfuerzo y tiempo en crear el contenido, ¡por favor respete nuestro trabajo!