27 votos

¿Es posible usar solo un capacitor para eliminar el rebote de un botón?

He estado pensando: ¿por qué no se puede simplemente conectar un capacitor a un botón para eliminar el rebote? He estado buscando la forma de reducir el trabajo que mi microprocesador tiene que hacer, pero tengo un espacio muy limitado en un PCB que estoy diseñando, así que no quiero hacer un circuito de rebote completo que complicaría el diseño.


esquemático

simula este circuito – Esquemático creado usando CircuitLab


Ese es un ejemplo de circuito; perdón por cualquier error (no soy bueno diseñando circuitos con capacitores). ¿Funcionaría esto? Para el interruptor táctil, no pude encontrar uno que coincida con lo que es en la vida real, pero funciona en esta situación. El botón es como el que se encuentra aquí. D10 representa el Pin Digital 10, pero no importa; solo significa la entrada de Arduino. Tampoco sé qué tamaño de capacitor necesitaría, así que si este circuito funciona, ¿qué tamaño necesito?


Nuevamente, solo estoy tratando de simplificar esto para que sea más fácil de construir sin tener que hacer el rebote de software. Al observar cómo funcionan los capacitores, parece que esto funcionaría, pero también podría hacer que el botón se presione más tiempo / con un retraso si la capacitancia es demasiado grande. Se utilizan comúnmente para "suavizar" el ruido en las fuentes de alimentación, entonces, ¿no es esto algo similar donde "suaviza" el rebote? Cualquier modificación de circuito para hacer que funcione (si es necesario) también sería apreciada.

12voto

Depende de cuál sea el estado predeterminado del interruptor. Un capacitor solo se cargará cuando le dé un voltaje positivo. Por lo general, en un entorno integrado, usamos una resistencia de pull-up para darle a un pin un estado alto predeterminado, y conectamos el interruptor a tierra. Agregar un capacitor aquí no ayudará, porque no "almacenará" el estado de tierra.

Sin embargo, también puedes usar una resistencia de pull-down. Esto significaría que el pin es bajo por defecto. Hacerlo alto al presionar el interruptor cargará el capacitor. Después de soltarlo, el capacitor mantendrá el pin alto por un tiempo, por lo que sí, esto funcionaría. No estoy seguro si 1uF es suficiente, demasiado poco o demasiado, te recomendaría que lo revises con un osciloscopio y lo pruebes un poco.

10voto

karfai Puntos 18

Creo que la respuesta aceptada dijo que solo puedes usar un truco RC para eliminar los rebotes de un interruptor atado a bajo, pero creo que eso no es cierto. También puedes hacerlo para alto. Aquí está el esquema. Hay una verdadera Biblia del de-bouncing que recomienda el siguiente esquema:

RC de-bouncing, R1 atado a alto, actuando el interruptor lo conecta a tierra. Sin embargo, hay un capacitor en paralelo al interruptor a tierra y una R2 conectando el interruptor al capacitor y a la compuerta lógica que deseas alimentar. Aquí se muestra un inversor, pero podría ser un buffer o cualquier entrada de compuerta lógica.

RC de-bouncing, R1 atado a alto, actuando el interruptor lo conecta a tierra. Sin embargo, hay un capacitor en paralelo al interruptor a tierra y una R2 conectando el interruptor al capacitor y a la compuerta lógica que deseas alimentar. Aquí se muestra un inversor, pero podría ser un buffer o cualquier entrada de compuerta lógica.

Cuando C está completamente cargado y activas el interruptor, la carga se drenará a través de R2, con suerte hasta que el interruptor se haya establecido antes de que alcances el nivel bajo lógico en la entrada.

Cuando C está completamente descargado, y abres el interruptor, entonces C se cargará a través de R1+R2 hasta que se alcance el nivel alto lógico.

Dado que el nivel alto lógico normal en la lógica TTL a 2V es relativamente bajo en comparación con el nivel bajo lógico de 0.8V, tiene sentido que R1+R2 haga que el tiempo de carga sea más largo que el tiempo de descarga solo a través de R2.

Usar una entrada de disparador de Schmitt elevaría el nivel lógico alto a 4V (que algunas fuentes ni siquiera golpearían de manera confiable, pero un interruptor sí).

Voy a probar esto ahora en mi protoboard y osciloscopio (analógico). Espero poder ver los rebotes en el canal 1 para activar, y espero poder verlo sin que sea un osciloscopio de almacenamiento. Pero también puedo usar un contador de 4 bits 74LS161 para atrapar los rebotes. Y he aquí que tengo el 74LS04 inversor hex TTL y el 74LS14 disparador de Schmitt inversor hex a mano para jugar.

Actualización: Resultados Experimentales

Dado que no tengo un osciloscopio de almacenamiento digital no pude usarlo en absoluto. En su lugar, utilicé un contador 74LS161 con 4 LEDs y me aseguré de que cada activación del interruptor cuente exactamente un incremento.

Puedo ver claramente la inestabilidad del interruptor. Así que, la línea de base es positiva, lo que significa que podré decir cuándo mis contra-medidas serán efectivas.

No pude encontrar una combinación de R1, R2 y C que funcionara cuando tengo una entrada de TTL normal en el 74LS04. Sin embargo, con una entrada de disparador de Schmitt del 74LS14 tengo una configuración bastante buena cuando R1 y R2 son ambos de 1 kΩ y C = 1 μF o mejor aún 4.7 μF. Obviamente depende también del interruptor.

Encontré algunos interruptores de botón de goma que tenían una resistencia interna demasiado alta para que no redujeran el voltaje de entrada lo suficiente. Con dos interruptores de calidad moderada conté varias corridas de 16 y tuve solo unos pocos fallos con 100 nF, 1 μF, y ninguno con 4.7 μF.

Con la entrada de TTL normal no pude hacer que funcionara.

Sin embargo, si tu entrada es un Arduino, es posible que desees volver a comprobar que de hecho sus entradas digitales puedan ser disparadores de Schmitt, y así podrías estar bien con R1 y R2 ambos de 1 kΩ y C = 1 μF y posiblemente incluso 100 nF.

Finalmente, después de más experimentación e investigación frustrante, concluyo que en niveles de TTL normales es simplemente imposible usar el método de RC para eliminar rebotes. Y no importa si conectas tu interruptor alto o bajo.

Necesitas un disparador de Schmitt para hacer esto. Dudo que incluso funcione con CMOS.

Aquí está un corto video de TI (ellos deberían saber) diciendo que necesitas el inversor de disparo de Schmitt aquí.

Y aquí hay un circuito alternativo con un disparador de Schmitt, que es aún más interesante ya que no requiere ningún condensador.

introducir descripción de la imagen aquí

Sin embargo, lo intenté, y descubrí que no funciona. Simplemente no funciona.

El mismo documento técnico también ofrece una solución con dos inversores y sin resistor ni capacitor de ningún tipo, solo requiere un botón de dos posiciones.

introducir descripción de la imagen aquí

Lo intenté y tampoco funciona de esta forma mágica. Casi funciona, pero aún obtengo doble activación con mucha más frecuencia que con el RC 1k/1k/100nF y el disparador de Schmitt. Además, si uso esta configuración de doble inversor con el inversor de disparo de Schmitt 74LS14, no funciona mejor. Así que simplemente no funciona, punto.

0voto

user88784 Puntos 16

"así que no quiero hacer un circuito de rebote completo que complicaría el diseño".

Realmente no entiendo por qué lo hiciste tan complicado. No mencionas qué tipo de MCU estás usando, sin embargo puedo ver que es un Arduino. Puedes hacerlo por software input( pin, INPUT_PULLUP ); (así que no necesitas componentes externos) o puedes usar una resistencia pullup o pulldown (SMD es realmente pequeño) de 10K a GND o 5V, lo que prefieras usar.

Lo único que tienes que hacer es leer un valor de la entrada con una tasa de rebote en ms, usa millis() para esto (¡no uses delay()!) y úsalo en la función loop(). Esto es pan comido para cualquier Arduino.

Por ejemplo:

circuito

#define BTM_PIN_BTN_BT_POWER               10 // Botón táctil para encender/apagar
#define BTM_POW_BTN_DEBOUNCE               200 // en ms
//#define BTM_POW_BTN_NO_WAIT              // descomenta si no quieres esperar a que se suelte   

bool getPowerButtonPressed() // No sé si tu botón es de encendido, este es solo un ejemplo
{
  static uint32_t iDebounceTime = millis();
  bool bResult = false;

  if( millis()-iDebounceTime >= BTM_POW_BTN_DEBOUNCE )
  {
    #ifndef BTM_POW_BTN_NO_WAIT 
    while( digitalRead( BTM_PIN_BTN_BT_POWER ) == HIGH )
    {
      bResult = true;
    }
    #else
      bResult = ( digitalRead( BTM_PIN_BTN_BT_POWER ) == HIGH ); 
    #endif

    iDebounceTime = millis();

}  

  return bResult;
}

void loop()
{
  if( getPowerButtonPressed() )
  {
    // haz algo

  } 

  // otro código
  .....
  .....
}

¡Eso es todo!

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X