Inicio » Electrónica para Arduino » Cómo eliminar rebotes con Arduino

Es posible que te haya ocurrido esto: has conectado un pulsador en un pin digital de Arduino esperando que entrase un valor al pulsarlo y otro valor diferente al soltarlo, pero el resultado final ha sido un poco diferente. Es posible que te hayas llevado una pequeña sorpresa al ver que cada pulsación ha sido interpretada por tu Arduino como muchas pulsaciones consecutivas, o simplemente no ha ocurrido nada. No, no se ha roto tu Arduino, ni se ha vuelto loco, es por culpa de los rebotes.

En este artículo te voy a mostrar varios escenarios para que entiendas qué está pasando y sepas cómo solucionarlo.

Vamos a conectar un pulsador a un Arduino y vamos a hacer un sketch que cuente las pulsaciones que se realizan sobre el mismo, pero vamos a implementar diferentes soluciones para ver qué ocurre en cada caso y decidir cuál es la mejor forma de hacerlo.

Solución 1: Pulsador e instrucción if

En este escenario, vamos a conectar el pulsador a Arduino directamente, sin ningún elemento hardware adicional. Es decir, un pin del pulsador a un pin digital (en este caso al 2) y el otro pin a 5V.

En la siguiente imagen puedes ver las conexiones:

Arduino y pulsador

Los pines digitales de Arduino soportan 5V, por lo que, puede parecer lógico que entrarán 5V cuando presionemos el pulsador y 0V cuando lo soltemos. Como el pin es digital, Arduino debería interpretar esos valores como un pulso alto (HIGH) y un pulso bajo (LOW) respectivamente. Algo así:

pulso digital Arduino sin rebotes

El sketch que usaremos para este circuito es el siguiente:

const int PULSADOR = 2;
int contador = 0;

void setup()
{
  Serial.begin(9600);
  pinMode(PULSADOR, INPUT);
}

void loop()
{
  if(digitalRead(PULSADOR)==HIGH){
    contador ++;
    Serial.println(contador);
  }
}

Como el pulsador está conectado al pin digital 2 tenemos que configurar dicho pin como entrada (función setup): pinMode(PULSADOR, INPUT).

Dentro de la función loop comprobamos el valor del pin digital 2 con un if y la función digitalRead: if(digitalRead(PULSADOR)==HIGH). La idea es que cuando el pulsador se presiona entran los 5V y digitalRead nos devolverá valor HIGH. Cuando esto ocurra incrementamos el contador (contador++) y mostramos su valor en el monitor serie (Serial.println(contador)).

Como la función loop se repite indefinidamente, la instrucción if estará comprobando de forma constante si el pulsador se ha presionado.

Bueno, pues parece que todo tiene sentido, ¿no? Vamos a ejecutarlo para ver si es verdad.

¡Oops! Parece que algo no ha ido como esperábamos, porque la salida en el monitor serie es esta, pulsemos el pulsador o no. Parece que se ha vuelto loco y no paran de aparecer números sin parar:

monitor serie Arduino primer escenario

Está claro que esta solución no nos sirve, así que tendremos que buscar otra.

Solución 2: Pulsador, resistencia e instrucción if

Vamos a añadir una resistencia al pulsador para asegurar que entre valor HIGH cuando se presione y valor LOW cuando no. Para eso vamos a utilizar una configuración de resistencia llamada pull-down. (Puedes saber más sobre esto aquí).

En la siguiente imagen puedes ver cómo quedaría el circuito:

pulsador con resistencia de pull down Arduino

La resistencia es de 10kOhms y va conectada al pin del pulsador que se conecta con el pin digital 2. Además, el otro extremo de la resistencia va conectado a tierra (GND).

No vamos a modificar nada más, ni siquiera el sketch. Vamos a ejecutar ahora a ver qué ocurre.

Hemos conseguido un pequeño cambio. Ahora, cuando no presiones el pulsador no verás nada en el monitor serie, pero al presionarlo se volverá loco de nuevo:

Salida monitor serie

Gracias a la resistencia hemos logrado que reconozca la pulsación, cosa que antes no ocurría.

Ya hemos avanzado un poco, pero todavía no hace lo que esperamos. Tenemos que seguir probando cosas.

Solución 3: Pulsador, resistencia y bucles while

En este caso vamos a realizar una modificación a nivel de software. En cuanto al circuito usaremos el mismo que en la solución 2.

El nuevo sketch será este:

const int PULSADOR = 2;
int contador = 0;

void setup()
{
  Serial.begin(9600);
  pinMode(PULSADOR, INPUT);
}

void loop()
{
  while(digitalRead(PULSADOR)==LOW);
  contador ++;
  Serial.println(contador);
  while(digitalRead(PULSADOR)==HIGH);
}

El cambio se encuentra dentro de la función loop. He quitado la instrucción if y he añadido 2 bucles while sin cuerpo (terminan en punto y coma).

El primer while está justo al inicio de la función loop y el segundo justo al final. Con el primero comprobamos cuándo se presiona el pulsador. Mientras no se presione, es decir, mientras entre valor LOW por el pin digital 2 (digitalRead(PULSADOR)==LOW) el bucle while se repite, lo que evita que se avance a la siguiente instrucción. Cuando el pulsador se presione, la condición del while dejará de cumplirse y se ejecutarán las instrucciones contador++ y Serial.println(contador).

Llega el turno del segundo while. ¿Para qué sirve? Pues muy sencillo. Este while se repite mientras entre valor HIGH por el pin digital 2, es decir, mientras esté el pulsador presionado, o mientras se produzcan los rebotes consecuencia de la pulsación anterior. Con este while conseguimos que no se repita la función loop hasta que no esté el pulsador en reposo y entre un valor LOW estable por el pin digital 2.

señal digital de un pulsador con rebotes en Arduino

Suena bien, ¿verdad? Pues es aun mejor. Ejecútalo y verás que en el monitor serie solo aparecerá un número cuando presiones el pulsador (puede que en algún caso se cuele alguna pulsación no esperada). El número es el valor de la variable contador que se va incrementando en cada pulsación.

En la siguiente imagen puedes ver la prueba que he hecho. Lo he presionado 10 veces y las ha contado perfectamente:

monitor serie con salida sin rebotes

Parece que por fin hemos encontrado la solución, ¿verdad? Pues siento decirte que no al 100%. Es verdad que esta solución es muy efectiva y reduce considerablemente los rebotes (de vez en cuando se escapa alguno y cuenta dos pulsaciones de golpe aunque se presione solo una vez). La puedes aplicar sin problema, pero aun la podemos mejorar un poquito más.

Solución 4: Pulsador, resistencia, condensador y bucles while

Ahora si, la solución definitiva que combina tanto técnicas software como hardware.

Vamos a añadir un nuevo componente hardware al circuito y vamos a utilizar la solución software del escenario anterior.

El circuito quedará de esta forma:

pulsador con resistencia y condensador Arduino

El circuito es exactamente el mismo, pero he conectado un condensador de 0.1uF al pulsador.

El ánodo (positivo, pata larga) del condensador va conectado al pin positivo del pulsador, es decir, el que va conectado a los 5V. El cátodo (negativo, pata corta, marcado con una línea gris) va conectado al pin opuesto del pulsador, es decir, el que va conectado al pin digital y lleva la resistencia.

Este cambio, que puede parecer insignificante, te garantizo que elimina al 100% los rebotes en combinación con la técnica software de los bucles que vimos antes.

Ejecuta de nuevo el sketch anterior con este nuevo circuito y verás lo que ocurre. Los rebotes han desaparecido por completo. El conteo de las pulsaciones es preciso y puedes presionar el pulsador de forma constante sin que lo cuente como más de una pulsación.

¡Hemos encontrado la solución optima!


Te avisaré cuando publique nuevo contenido en paraarduino.com y en mi canal de YouTube (@ParaArduino).

No hemos podido validar tu suscripción.
¡Se ha realizado tu suscripción!

Newsletter

Suscríbete para que te avise cuando publique nuevo contenido.

Usamos Brevo como plataforma de marketing. Al hacer clic a continuación para enviar este formulario, consiente que la información proporcionada sea transferida a Brevo para su procesamiento de acuerdo con sus términos de uso