Maneras inteligentes de detectar un botón (menos consumo de energía)

Durante una reunión para un proyecto en particular, me pidieron que pensara en la forma de detectar la pulsación de un botón con una MCU. La detección debe consumir la menor cantidad de energía posible. A primera vista, pensé en el típico circuito con un pull-up o un pull-down:

esquemático

simular este circuito : esquema creado con CircuitLab

No tengo en cuenta algunas funciones anti-rebote aquí, ya que eso está más allá del alcance de esta pregunta. En cualquier caso, cuando se presiona el botón, el valor de corriente total que fluye depende del valor de la resistencia. Para minimizarla (la corriente), podría aumentar el valor de la resistencia pero no tanto ya que, si no me equivoco, también depende del valor de fuga del pin de entrada. Además, una resistencia grande se recuperaría lentamente.

Mi pregunta es la siguiente: ¿cuáles son las formas inteligentes de detectar un botón presionado que no consume energía (típicamente para una aplicación que consume mucha energía)? ¿Hay algún método que apenas consuma energía cuando se presiona el botón?

Un menú desplegable de 10k casi no consume energía. 3.3V da 330uA. Y en la mayoría de los MCU modernos, tiene la opción de configurar uno internamente, que tendrá una resistencia aún mayor. Dicho esto, puede activar el suministro del botón desde un pin MCU a través de un BJT o MOSFET. Solo actívelo durante la lectura y lea con sondeo.
@Lundin En términos "modernos", 330 m A puede ser una corriente alta...
de hecho, muchos microcontroladores pueden obtener corrientes de sueño tan bajas como 2-10 μA. Desperdiciar 30 veces eso en un solo menú desplegable es un poco triste, especialmente en una situación con batería.
El tamaño de la resistencia que puede usar en un pull down depende de la impedancia del pin y del voltaje que cambian. Digamos que tiene un pin de 3.3v en un estado de alta impedancia que cambia a 2.4v, todo lo que realmente necesita es una impedancia ligeramente más baja que la entrada. Le recomendaría que conecte un potenciómetro y mida el valor alto de una resistencia que puede usar para que el pin siga funcionando de manera confiable, y luego reduzca el valor un 20% para mantener un margen.

Respuestas (7)

Un método de baja corriente que usé una vez fue conectar un interruptor entre dos pines de E/S del microcontrolador.

Una E/S se configuró como salida (SWO). El segundo se configuró como entrada (SWI) con su pull-up interno programable habilitado.

El estado del interruptor se muestreaba con poca frecuencia (cada 10 ms) mediante una rutina de interrupción de software. La secuencia de lectura fue: conducir SWO bajo, leer SWI, conducir SWO alto.

Esto significaba que un interruptor presionado solo atraía la corriente desplegable SWI a través de sí mismo y SWO por menos de 1 us durante el escaneo, mientras que un interruptor no presionado no consumía corriente. Este consumo de corriente para <1 us cada 10 ms dio como resultado un consumo de corriente promedio pequeño.

Es cuestionable por qué necesita el pull-up con esta técnica. La secuencia SWO Low, Read SWI, SWO High, SWI Read podría ser suficiente para saber si los pines están conectados entre sí. También puede compartir el SWO entre numerosos interruptores.
@Trevor Dejar la entrada flotando cuando el interruptor está abierto no es una idea particularmente buena. Dependiendo de la tecnología, puede hacer que el búfer de entrada consuma energía si su entrada está en un estado intermedio.
Sin embargo, @RoyC hay formas de evitar eso.
@RoyC mira mi respuesta.
@Trevor Multiplicando efectivamente la resistencia pull up por el ciclo de trabajo sw1 sw2. Todavía un pull-up que nos lleva de vuelta al esquema 1 del OP. Puede funcionar en un entorno de bajo ruido.
@RoyC no realmente, ya que la carga solo está activa muy brevemente. El ruido es solo un problema de que la longitud de la línea hasta el interruptor es larga, no recomendaría usar la técnica de retención de carga en un interruptor remoto apagado en el panel frontal en alguna parte.
ESD es otro problema con esto. Los botones tienden a ponerse en contacto con los humanos, que tienden a emitir cargas de ESD. No desea obtener eso directamente en los pines de MCU.
¿El hecho de que la MCU tenga que permanecer despierta para hacer el sondeo en lugar de depender de una interrupción cancela por completo cualquier ahorro de los ciclos de trabajo más cortos del interruptor?
Hola, @Lundin, parece que estás defendiendo el caso de no conectar nunca los interruptores a los pines de MCU, que es una discusión separada. Ese algo para comenzar una nueva pregunta si es algo de lo que no está seguro y necesita respuestas.
Hola, @AndreKR, teníamos una aplicación de microcontrolador alimentada por batería y necesitaba varios interruptores conectados, así que usamos esta técnica, ya que era bastante sencilla. No habíamos puesto una MCU solo para la detección de interruptores. La MCU extrajo algo así como 900 nA en modo de suspensión entre sus interrupciones de 10 ms, por lo que los ahorros de pull-up valieron la pena.
@TonyM Es relevante, ya que la contramedida más común es una resistencia en serie en el pin de entrada. Lo que a su vez da un divisor de voltaje junto con el pull-up interno. Tendremos que elegir un valor de resistencia para que la caída de voltaje sea despreciable.
@Lundin, nunca he visto eso, con mucho, el más común es un terminal de interruptor directamente a la lógica, con protección estática ofrecida por el propio interruptor. Sin embargo, no sigamos con esto en la discusión de comentarios, vaya al chat o plantéelo como una pregunta separada.

Un botón SPDT ( Single P ole D ouble Throw ) sería su botón ultra eficiente.

ingrese la descripción de la imagen aquí

Fuente: http://www.ni.com/white-paper/3960/en/

En tu caso el 1P iría a la MCU, el 1T a VCC, el 2T a GND.

+1... Siempre me ha molestado que los SPDT subminiatura sean muy difíciles de encontrar o cuesten demasiado...
@Trevor Sí... lamentablemente, algunas cosas son muy caras. Mientras que otros artículos tienen un precio bajo (MCU, por ejemplo). No puedes tenerlo todo.
Esta es una gran idea. Lamentablemente, no logré encontrar un botón SPDT CMS que se ajustara a mis necesidades. Sin embargo, tendré en cuenta este circuito.

Un método que he usado aprovecha la naturaleza capacitiva de las entradas CMOS.

esquemático

simular este circuito : esquema creado con CircuitLab

En el circuito sobre el interruptor, cuando está cerrado, permite que la resistencia desplegable cargue/descargue las capacitancias de entrada del GPIO hasta el nivel del suelo.

El truco con este circuito es usar la naturaleza bidireccional de un GPIO para mantener la entrada cargada a un nivel lógico alto cuando el interruptor está abierto.

La rutina de control apaga periódicamente el pin como un nivel alto, o habilita brevemente el pull-up, el tiempo suficiente para mantener las tapas cargadas. El pin de entrada actúa como un bit de memoria dinámica y, con la mayoría de los dispositivos, mantendrá esa carga durante una cantidad de tiempo considerable y utilizable.

Cuando se configura correctamente, si se presiona el botón, la carga en el pin se descargará más rápido que la frecuencia de actualización. Esa condición se puede detectar como parte del algoritmo de actualización como una operación de lectura antes de actualizar, o se puede usar para generar una interrupción.

La energía se usa brevemente durante el pulso de actualización, tanto para recargar los capacitores como a través de la resistencia y el interruptor si está cerrado. Sin embargo, la duración del pulso de actualización es corta y la frecuencia de consulta hace que la corriente de actualización sea relativamente insignificante.

Obviamente, este método es activo. Si el micro se pone a dormir, el estado del interruptor será indeterminado al despertar. El primer ciclo de actualización después de la activación debe ignorar la lectura del pin. Además, este método no debe usarse para activar el micro. Antes de acostarse, también es aconsejable habilitar el pin como salida baja para estacionarlo en un estado de corriente cero.

Para leer más interruptores estáticos, como interruptores DIP de configuración, se puede usar una rutina dedicada en lugar de un ciclo de actualización continua. Después de la lectura, los pines GPIO deben "estacionarse" en un estado activo de salida baja (corriente cero) para evitar el problema de las entradas flotantes.

NOTA: Esta técnica sufre un poco de sensibilidad al ruido si las longitudes de los trazos son largas y viajan a través de un área ruidosa. Como tal, R1 debe estar cerca del pin de entrada. Sin embargo, no lo recomendaría para conectar un interruptor a cierta distancia en un panel frontal en algún lugar a menos que agregue capacitancia adicional cerca del pin.

Esto parece muy vulnerable a EMI de hecho. Si alguna forma de energía de radio ingresa a ese circuito y creo que todas las apuestas están canceladas. Menos mal que las cosas inalámbricas no son tan comunes hoy en día :)
@Lundin no es tan malo como podrías pensar. 30pF y un mega hacen un filtro bastante bueno.

¿Cuánto tiempo se presionará el botón? Si no es un interruptor de palanca (que mantiene su estado) sino un interruptor momentáneo, entonces la corriente que fluye cuando se presiona el botón es en gran medida irrelevante debido al poco tiempo que el botón está realmente cerrado.

Cualquiera de los dos circuitos que muestra está bien, no importa.

Puede suponer que la fuga de entrada y/o la corriente en una entrada de MCU es insignificante . Todos los MCU están en tecnología CMOS en estos días y tienen una corriente de entrada prácticamente nula. Así que deja de considerarlo, no está ahí.

En lugar de usar una resistencia externa, también puede usar la resistencia pull-up interna integrada en muchas entradas de MCU. Esta resistencia puede tener un valor relativamente bajo (quizás 50 kohm), por lo que fluirá una pequeña corriente cuando se presione el botón.

Puede usar con seguridad incluso una resistencia de 1 Mohm para un pull-up/pull-down. Solo en entornos muy "sucios" (eléctricamente hablando) es posible que necesite un valor más bajo. También puede colocar un capacitor de 100 nF en paralelo con el interruptor para suprimir la interferencia de otros circuitos cercanos.

Consejo profesional: reserve un lugar para dicho condensador en la PCB, pero no monte una tapa. aún. En caso de problemas: colóquelo y vea si eso ayuda.

Para detectar el estado del interruptor, use el sondeo (como en la respuesta de TonyM) o use una interrupción . Depende de la aplicación cuál es mejor para el consumo de energía (de la MCU).

En realidad, el botón será momentáneo, pero el tiempo que se presionará puede ser suficiente (minutos)
Si el dispositivo está encendido las 24 horas, los 7 días de la semana, es posible que un par de minutos no sumen mucho. Lo importante es el ciclo de trabajo, 5 minutos cada hora es 5 x 60 / 3600 = 8,3 %. Entonces, incluso con una corriente de 100 uA, el interruptor consumiría 8.3 uA en promedio en mi escenario. Mi mensaje es: no se concentre demasiado en la corriente que usa el interruptor cuando se presiona sin compararlo con el consumo de corriente del sistema completo. Solo cuando las contribuciones son las mismas, entonces tiene sentido mejorar el consumo de corriente del interruptor. No sirve de nada hacer un cambio de 0.1 uA cuando la MCU usa 1uA continuamente.
"No sirve de nada hacer un cambio de 0.1 uA cuando la MCU usa 1uA continuamente". eso suena mal Creo que te refieres a un pico de 1uA. 10% solo por el cambio sería excesivo ;)
@Trevor No es pico, me refiero a una corriente promedio de 1uA para la MCU pero a 0.1uA cuando se presiona el interruptor. Combinado con un interruptor de 0,1 A que se presionará solo durante períodos (relativamente) cortos, el interruptor no contribuye casi en nada al consumo de energía promedio total, ya que la corriente promedio será: 100 % x 1 uA + 8,3 % * 0,1 uA = 1,0083 uA (8,3 % reutilizado del comentario anterior).
Sí, solo se lee como si quisieras decir un promedio de 0.1uA en el interruptor. Lo cual no sería irrazonable como un interruptor DIP.
@Bimpelrekkie Un botón mecánico en una interrupción está buscando problemas a menos que se rebote con mucho cuidado...

Si su botón es un interruptor piezoeléctrico, entonces la única energía requerida es la energía generada al presionar el botón.

Por ejemplo: R2/C1 recolecta la energía producida al presionar el piezoeléctrico. D1 evita que el voltaje de C1 suba demasiado. R1 drena C1 cuando se suelta el botón. El MCU GPIO debe estar en entrada, sin modo pull. Voilà, botón de detección con cero consumo de corriente del suministro.

esquemático

simular este circuito : esquema creado con CircuitLab

Hmm, ¿puede hacer/diseñar un prototipo funcional de eso y mostrar el beneficio de las soluciones con un interruptor normal que hemos estado usando durante los últimos 30 años?
Seguro. He agregado un esquema de ejemplo. Simplemente construye eso. El beneficio es que no hay consumo de corriente del suministro en estado cerrado o abierto. Las desventajas incluyen un control deficiente del esfuerzo requerido para activar el interruptor (un circuito activo sería mejor, pero eso frustra el beneficio marginal del circuito), y es un diseño novedoso en comparación con el diseño de interruptor normal de 30 (¿300?) años.
Aún así, mi calculadora tiene muchos botones y funciona al menos 5 años en una celda de moneda. Todavía no veo cómo su solución traería algún beneficio a eso. Sigo pensando que es una "solución" a un problema inexistente. Y más costoso también.
¡Ay estoy de acuerdo! Cumple con el criterio original de "consumir la menor cantidad de energía posible", pero es difícil imaginar por qué ahorrar menos de un milijulio es realmente útil.
¿La impedancia de entrada de la MCU no hace cosas desagradables debido a la alta impedancia de salida del piezoeléctrico?
@ScottSeidman De hecho, sin protección adicional, podría obtener voltajes bastante altos en la entrada de la MCU. Sin embargo, estas entradas están protegidas contra ESD (mediante diodos ESD en el chip), por lo que, por encima de un par de voltios, la entrada ya no es de alta impedancia. Depende de cuánta energía provenga del elemento piezoeléctrico si la protección ESD puede manejar eso. Para estar seguro, se necesita el circuito como se muestra arriba. Con los valores correctos de los componentes, será bastante difícil dañar la entrada de la MCU con esta protección.

Si el dispositivo debe poder permanecer en cualquiera de los estados indefinidamente, usar un interruptor SPDT será el enfoque de menor potencia, ya que se puede hacer que un circuito estático no consuma corriente más allá de su propia fuga interna y la del interruptor. Una ventaja adicional de los interruptores SPDT es que se pueden eliminar casi perfectamente, sin importar qué tan rápido se operen o qué tan malos sean los contactos, siempre que un contacto deje de rebotar antes de que el otro se lea por primera vez como cerrado.

Hay dos buenos enfoques para cablear tales interruptores:

esquemático

simular este circuito : esquema creado con CircuitLab

El primer enfoque requiere una resistencia menos que el segundo, pero el segundo será más tolerante a la superposición entre los dos polos (consumirá una corriente más alta que la habitual, pero no provocará un cortocircuito en el suministro). Tenga en cuenta que si el interruptor puede entrar en un estado que es moderadamente resistivo durante un período de tiempo prolongado, eso podría quemar una corriente significativamente mayor que la habitual, pero durante el uso normal ninguna de las resistencias llevará una corriente significativa excepto durante el breve momento entre el vez que el interruptor cambia de estado y la salida responde.

Utilice el pull-up interno del microcontrolador y, cuando se detecte la pulsación, deshabilite el pull-up. Luego, ocasionalmente, vuelva a habilitarlo brevemente para verificar el estado del botón.