Pregunta sobre la eliminación de rebotes: retraso del cambio de estado

Tengo un proyecto muy simple en el que necesitaba eliminar el rebote de un botón (en el software). Lógicamente, mi proceso de pensamiento es:

  • Si el estado ha sido estable durante un tiempo y cambia, señale inmediatamente un evento.

  • Asegúrese de que el siguiente estado sea estable antes de permitir otro cambio de estado.

Entonces, si no se presiona un botón y ha estado así durante un tiempo, pero de repente leo una entrada modificada, no creo que deba esperar para confirmar que la entrada modificada ha sido estable (lo sé que ha habido un cambio físico real en el estado del botón). Simplemente puedo señalar un evento, pero no permitir nuevos eventos durante un período de tiempo determinado para evitar que los rebotes de botones falsos señalen eventos.

Aquí está el código arduino para una función getAction() hecha de esta manera:

static int buttonBounceState = BUTTON_STATE_UP; // "Bouncing" state
static int buttonState = BUTTON_STATE_UP; // Debounced state
static unsigned long lastChangeMillis = 0; // Time of last state transition
unsigned long currentMillis;

buttonBounceState = digitalRead(BUTTON_PIN);

if (buttonBounceState != buttonState) {
   // Only allow state change if it's been 20 millis since last
   currentMillis = millis()
   if (currentMillis >= lastChangeMillis + 20) {
       buttonState = buttonBounceState; // Change state
       lastChangeMillis = currentMillis; // Only update timings at state transition
       // Button state has changed, so return an action
       if (buttonState == BUTTON_STATE_DOWN) return ACT_PRESS;
       else return ACT_RELEASE;
   }
}
// No button state change. Return no action.
return ACT_NONE;

Sin embargo, parece que dondequiera que miro, la forma en que se realiza el antirrebote es que la transición de estado inicial debe estabilizarse antes de realizar una señalización de evento/cambio de estado de software. Por ejemplo, la imagen inferior aquí: https://www.baldengineer.com/arduino-de-bounce-a-button-with-micros.html

Mi pregunta: ¿es mejor hacer el antirrebote de esta manera? ¿Hay algo en mi método que podría fallar en lo que no estoy pensando, es decir, algún tipo de ruido mientras el botón está abierto o cerrado? Si no, parece que mi método daría tiempos más precisos; y no me pierdo los toques de botón muy rápidos (pero lo retrasaría hasta que se estable). Además, ¿cómo se relacionan estos dos métodos de software con la eliminación de rebotes de hardware? ¿Cómo se implementaría un antirrebote de hardware que pueda cronometrar cosas similares a mi método?

¿Qué sucede si obtiene un ruido que cambia la entrada por solo un ciclo o dos mientras lee la entrada? Ahora vuelve la prensa y luego después de 20 ms de supresión, la liberación.
Hay muchas justificaciones diferentes, ninguna anula a las demás. Depende de las circunstancias. En algunos instrumentos en los que he trabajado, es muy posible que alguien "roce" accidentalmente el equipo sin intención de nada. Y también es muy posible, dado que los interruptores a veces no están en la tarjeta de circuito en sí, sino que se extraen de ella y se instalan en un chasis, tener un ruido que en algunas circunstancias puede ser lo suficientemente grande como para desencadenar un evento que debe ignorarse. Entonces, tomas decisiones basadas en otros conocimientos y experiencias. Existen pocas líneas brillantes.

Respuestas (4)

Si elimina el rebote reaccionando de inmediato y dejando el botón en blanco (ignorando los cambios de etapa subsiguientes durante un tiempo predeterminado), el beneficio es una latencia baja. El inconveniente es la vulnerabilidad al ruido inducido que puede hacer o deshacer algunos sistemas.

Las personas no reaccionan lo suficientemente rápido como para notar una latencia de 10 ms, por lo que creo que, por lo general, es mejor eliminar el rebote verificando que un cambio de estado sea estable durante unos pocos ms antes de reaccionar. De esa manera, puede evitar problemas inesperados de ruido.

La razón principal por la que a veces reboto con "reaccionar inmediatamente y luego en blanco" es cuando estoy escribiendo un código de prueba rápido y sucio que finalmente se eliminará. Por lo general, encuentro que es más simple y menos invasivo codificar el rebote de esta manera, por lo que es más rápido de escribir y más fácil de eliminar del código final.

Algunos dispositivos antirrebote de hardware como el MAX6816 usan temporizadores y contadores cableados. El MAX6816, en particular, espera a que el estado sea estable durante un cierto período de tiempo antes de pasar.

En un FPGA también está cableado en el sentido de que se utilizan temporizadores, contadores y registro de muestreo. Puede hacer que reaccione inmediatamente y luego en blanco, o esperar hasta que el interruptor se estabilice antes de pasar la señal.

Los dispositivos antirrebote JK-flip flop cambian de estado inmediatamente y luego "en blanco". Pongo en blanco entre comillas porque no usan un intervalo de tiempo para ignorar los cambios posteriores. Más bien, se basa en algo más parecido a la histéresis mecánica. Inmediatamente cambia de estado si y solo si se hace un contacto eléctrico positivo. No reacciona si simplemente se pierde el contacto. Por lo tanto, si se pierde el contacto dentro del interruptor (como debido a un rebote) pero no se hace un nuevo contacto positivo, no cambian de estado. El interruptor nunca debe poder rebotar tan fuerte que vuele lo suficientemente lejos en la dirección opuesta para golpear el otro contacto. Esto es similar a la conservación de la energía en la que una pelota que se deja caer nunca debe rebotar hasta la altura desde la que se dejó caer.

También existen otros métodos de eliminación de rebotes, como el uso de filtros de paso bajo y comparadores, que dependen de que el interruptor sea estable durante el tiempo suficiente, pero también pueden activarse falsamente si el interruptor rebota demasiadas veces y la constante de tiempo se elige para ser demasiado corto ya que el capacitor continuará cargándose o descargándose a medida que el interruptor haga contacto con cada rebote.

Bueno, los antirrebote JK flip flop no se pueden usar con un interruptor SPST de todos modos. Requieren un interruptor SPDT.
Ah, lo siento, leí lo que decías un poco fuera de contexto, ¡ups!
Bueno, es un buen punto para mencionar de todos modos. Descarta los dispositivos antirrebote JK-FF en la mayoría de los casos.
Realmente me pregunto por qué los teclados para juegos que se esfuerzan por lograr la latencia más baja posible no reaccionan de inmediato cuando se eliminan los rebotes. Su marketing en torno a los interruptores ópticos sugiere que no hay forma de eliminar el retraso de rebote en los interruptores eléctricos: razer.com/eu-en/razer-optical-switch
@JoshHaberman Puedes. Pero técnicamente se llama en blanco. En lugar de esperar a que la señal sea estable antes de reaccionar, reacciona de inmediato e ignora las activaciones posteriores durante el siguiente período de tiempo. Pero ese método no hace nada por la vulnerabilidad al ruido, lo que supongo que no es un problema para los teclados para juegos. No he oído hablar de lo óptico antes, pero debería durar mucho más que el contacto mecánico (a menos que las teclas mecánicas todavía usen una membrana para captar la señal, en cuyo caso el aumento es intrascendente). Por otra parte, el retardo antirrebote es intrascendente. Marketing

No hay absolutamente nada de malo en hacer un antirrebote de "vanguardia" como lo describe; de ​​hecho, es el método que prefiero en mis propios proyectos.

Como dices, tan pronto como ves el primer borde, sabes que el usuario ha iniciado una acción, por lo que no hay razón para retrasar la acción. El sistema se "sentirá" más sensible al usuario.

La única razón para usar el antirrebote de "borde posterior" (el tipo que ha estado encontrando) sería si hay alguna razón (EMI, ESD, etc.) por la que una entrada podría fallar que en realidad no es causada por la acción del usuario.

Gracias por esto. Sé mucho sobre software, pero al aventurarme en la electrónica, encuentro que a veces es difícil encontrar información simplemente por falta de vocabulario, por ejemplo, "vanguardia" y "vanguardia" (aunque estoy seguro de que estos conceptos surgen en términos puramente dominios de software también)
Como mencioné en un comentario anterior, realmente me pregunto por qué los teclados para juegos que se esfuerzan por lograr la latencia más baja posible no reaccionan de inmediato cuando se eliminan los rebotes. Su marketing en torno a los interruptores ópticos sugiere que no hay forma de eliminar el retraso de rebote en los interruptores eléctricos: razer.com/eu-en/razer-optical-switch

No hay mejor manera ya que cada caso puede tener diferentes interruptores, diferentes entornos o diferentes requisitos. Su solución funcionará bien, si no hay pulsos falsos por alguna razón. Un ejemplo sería una conexión normalmente cerrada, pero bajo vibraciones mecánicas podría abrirse y provocar activaciones falsas ocasionales, y reaccionar a cada borde solo amplificaría el problema. Es un delicado equilibrio entre eliminar el rebote lo suficiente como para mantener alejado el ruido no deseado y no gastar demasiado tiempo, como sondear en un bucle cerrado durante 10 milisegundos que el pin IO realmente permanece activo durante ese tiempo antes de creer que está presionado.

Si busca lo suficiente, puede encontrar muchos sistemas complicados para eliminar rebotes.

Pocos de ellos superan a los muy simples, solo espera .

Su sistema tendrá un requisito de tiempo de respuesta, tiene que funcionar más rápido que, o reaccionar a pulsos más cortos que un tiempo de umbral, llamado t metro i norte . El algoritmo de espera sondea el interruptor un poco más rápido que esto y lo ignora por completo entre tiempos.

Si su conmutador realmente rebota durante más tiempo que este tiempo, entonces su conmutador no es lo suficientemente bueno para cumplir con los requisitos de su sistema. Ningún esquema de rebote arbitrariamente complicado puede eliminar la ambigüedad de un pulso corto al que el sistema debería responder de un rebote largo.

En la versión más simple, solo sondeamos el interruptor cada t metro i norte . Habrá una latencia variable según el momento exacto en que se presionó el interruptor, lo que podría ser perceptible y molesto si t metro i norte era más grande que 100mS más o menos.

En una versión más receptiva y un poco más complicada, sondeamos con mucha más frecuencia y actuamos en un cambio de estado del interruptor. Una vez que el estado ha cambiado, esperamos a que t metro i norte antes de sondear el interruptor de nuevo.