Debounce

De Proyectos
Saltar a: navegación, buscar

Que es?

Debounce significa anti-rebote. Cuando pulsamos un botón tenemos un efecto de rebote debido a que las partes metálicas del botón no conexionan idealmente entre ellas y causa un error de lectura para el microcontrolador.
Si tenemos un botón que enciende o apaga un led, si no implementamos un filtro anti-rebote (por software o por hardware) las pulsaciones no serán precisas. A veces apretarás y no actuará el led.


Solución software, en que se basa?

La solución por software se basa en implementar un código que filtre las pulsaciones que no se mantienen estables un mínimo de x milisegundos, así sabemos que esa pulsación es la que es correcta y las demás no se tienen en cuenta.


Código para un solo botón

Después de buscar por la red un código anti-rebote me decanté por el de la web a trastear un poco. Encuentro que es sencillo y claro. Este código lo modificado un poco (he cambiado el nombre de algunas varaibles, funciona con las resistencias pull-up integradas en arduino y he modificado alguna tonteria mas, pero la esencia de cómo hacerlo es del sitio a trastear un poco

//Esta programado tienendo en cuena que se usan las PULL UP integradas en Arduino. Por lo tanto
//la logica esta cambiada. Es decir, cuando aprieto el boton la entrada lee LOW y cuando esta sin
//apretar lee HIGH. Para cambiar la logica se tiene que cambiar:
//-El flanco - si se usa PULL DOWN para el flanco de subida es HIGH y el de bajada es LOW
//           - si se usa PULL UP (este caso) el flanco de subida es LOW y el de bajada es HIGH
//-Las variables inicializadas en HIGH deben pasar a LOW
//  -Aunque realmente lo importante es que botonFiltadoAnt sea inicializada con el mismo valor que botonFiltrado
//   y el valor de inicializado de botonSinFiltrarAnt no es relevante

//Se utilizad una pareja de variables para el estado del boton actual y anterior sin filtrar y otra igual pero filtrada.
//Las filtradas se usan para saber si ha habido un cambio de estado voluntario y entonces cambiar el led según el flanco
//Las sin filtrar se usan para empezar a contar cuando se detecta un cambio de estado

int buttonPin = 8;
int ledPin = 13;

byte botonSinFiltrar;
byte botonSinFiltrarAnt = HIGH;
byte botonFiltrado = HIGH;
byte botonFiltradoAnt = HIGH;
boolean estadoLed = false;
long tiempo = 0;
long debounceTime = 50;

void setup() {
  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(ledPin, OUTPUT);
}

void loop() {
  botonSinFiltrar = digitalRead(buttonPin);
  
  if(botonSinFiltrar != botonSinFiltrarAnt){
    tiempo = millis();
  }
  
  botonSinFiltrarAnt = botonSinFiltrar;
  
  if(millis()-tiempo > debounceTime){
    botonFiltrado = botonSinFiltrar;
  }
  
  if(botonFiltrado != botonFiltradoAnt){
    if(botonFiltrado == LOW){ //Solo se cambia el led en el flanco de subida
      estadoLed = !estadoLed;
      digitalWrite(ledPin, estadoLed);
    }
    botonFiltradoAnt = botonFiltrado;
  }
}


Código para mas de un botón

Hay una librería llamada Bounce en Arduino Playground - Bounce. Esta librería es muy útil para cuando tienes más de un botón en el circuito porqué crea un objeto para cada botón.

He usado esta libreria para el proyecto Cronometro y he podido implementar las pull-up del arduino sin tener que modificar nada. La manera en la que he usado la librería es:

//Declaración del objeto
Bounce nombreBoton = Bounce(NumeroPin, DebounceTimeMillis);

//En setup
void setup(){
  pinMode(NumeroPin, INPUT_PULLUP);
}

//Para leer el estado de un botón
if(nombreBoton.update() && nombreBoton.read() == LOW){ //Se pone en LOW porque estoy trabajando con ressitencias pull up, sino seria HIGH
  //hacer lo que sea
}

Documentación

a traestear un poco - Solución que me ha gustado más de las que encontré.
Arduino for Absolute Beginners - Otro código Debounce explicado
Arduino Playground - Bounce - Libreria de Arduino para filtrar el anti-rebote de un botón. Es muy útil para cuando tienes más de un botón en el circuito