01 · Punto de partida
El sensor de un bit
Empezamos los sensores concretos por el más sencillo: un contacto que se abre o se cierra. Como vimos en el tema 3, es una salida de todo o nada que se lee con un pin digital, sin ADC ni protocolo. Parece un caso trivial, y por eso mismo es el que más se subestima. Un botón mal leído hace que una pantalla salte tres opciones con una sola pulsación, que un contador sume diez cuando debía sumar uno o que una máquina no frene cuando un cable se corta.
Este tema ordena el problema en cuatro preguntas que se repiten con cualquier contacto: ¿cómo lo conecto? (pull-up o pull-down), ¿qué hago con los rebotes? (antirrebote), ¿qué evento quiero detectar? (flanco, pulsación larga, doble clic) y ¿qué pasa si falla? (seguridad). En el curso de Microcontroladores (temas 15 a 18) viste la mecánica del pin y de los registros; aquí nos ocupamos del contacto y del comportamiento del programa.
02 · Clasificación
Tipos de contacto
Los dispositivos de contacto se distinguen por tres criterios independientes:
- Mecanismo: un pulsador (push button) vuelve a su posición al soltarlo (acción momentánea); un interruptor (switch) mantiene su posición hasta que se lo cambia (acción mantenida). Un final de carrera es un interruptor de acción momentánea accionado por una pieza móvil, no por una persona.
- Reposo: normalmente abierto (NO, normally open) o normalmente cerrado (NC, normally closed). El «normalmente» se refiere al estado sin accionar.
- Polos y tiros: cuántos circuitos independientes conmuta (polos) y entre cuántas posiciones (tiros).
| Sigla | Nombre | Qué hace | Ejemplo |
|---|---|---|---|
| SPST | Un polo, un tiro | Abre o cierra un circuito (NO o NC) | Pulsador de placa de 2 patas, interruptor simple |
| SPDT | Un polo, dos tiros | Conecta un común a una de dos salidas (NO y NC a la vez) | Microswitch de 3 terminales, interruptor de dos posiciones |
| DPST | Dos polos, un tiro | Dos circuitos aislados que se abren y cierran juntos | Interruptor de alimentación bipolar |
| DPDT | Dos polos, dos tiros | Dos conmutadores SPDT accionados a la vez | Inversor de sentido de giro de un motor |
Los pulsadores de montaje en placa (tactile switch) de 4 patas son un SPST con las patas unidas de a pares internamente: se miden con un multímetro en modo continuidad antes de soldarlos, para no equivocarse de par. Otras variantes: interruptores de lengüeta o reed (accionados por un imán, tema 24), de inclinación, de flotador, de presión y teclados de membrana. Para el programa son todos iguales: un contacto que cambia de estado.
03 · Conexión eléctrica
Cómo conectarlos: pull-up y pull-down
Un contacto solo puede conectar el pin a algún sitio o dejarlo desconectado. Si el pin queda sin conectar, está flotante: su nivel es indeterminado y capta ruido eléctrico de los alrededores, de modo que el programa lee valores al azar. Para evitarlo se agrega una resistencia que fija el nivel en reposo:
Pull-up
Una resistencia lleva el pin a Vcc. El contacto va del pin a masa. En reposo se lee 1; al accionar el contacto, el pin se conecta a masa y se lee 0. La lógica queda invertida: «activo = nivel bajo».
Pull-down
Una resistencia lleva el pin a masa. El contacto va del pin a Vcc. En reposo se lee 0; al accionar, 1. La lógica es directa, pero hace falta cablear Vcc hasta el contacto.
| Configuración | Contacto sin accionar | Contacto accionado | Ventaja |
|---|---|---|---|
| Pull-up (a masa) | 1 (alto) | 0 (bajo) | Casi todos los microcontroladores tienen pull-up interna: no hace falta resistencia externa |
| Pull-down (a Vcc) | 0 (bajo) | 1 (alto) | Lógica intuitiva; requiere resistencia externa |
| Sin resistencia | Indeterminado: el pin flota cuando el contacto está abierto | Ninguna: es un error de diseño | |
La opción habitual es el pull-up interno del microcontrolador, que se activa por software (en Arduino, pinMode(pin, INPUT_PULLUP)) y vale entre 20 y 50 kΩ en un ATmega328P. Si se usa una resistencia externa, 10 kΩ es el valor tradicional: con 5 V circulan 5 V / 10 kΩ = 0,5 mA cuando el contacto está cerrado, un consumo pequeño pero no nulo. Resistencias mayores consumen menos y son más sensibles al ruido; menores consumen más y resisten mejor las interferencias.
Con pull-up, la inversión se resuelve de una sola vez en el programa y no se vuelve a pensar en ella:
const uint8_t PIN_BOTON = 2;
void setup() {
pinMode(PIN_BOTON, INPUT_PULLUP); // el contacto va del pin a masa
}
bool pulsado() {
return digitalRead(PIN_BOTON) == LOW; // activo en bajo: se traduce una sola vez
}
Esa función encapsula la lógica invertida. El resto del código habla en términos de «pulsado» y «no pulsado», sin recordar si el hardware usa pull-up o pull-down. Es el mismo criterio de abstracción que aplicamos a los drivers en el tema 40.
04 · El problema
Los rebotes
Al cerrarse, los contactos metálicos no se unen limpiamente: chocan, rebotan elásticamente y vuelven a chocar varias veces antes de quedar firmes. Durante ese tiempo el contacto se abre y se cierra de forma irregular, y el pin ve una ráfaga de pulsos en lugar de un único flanco. Lo mismo ocurre, aunque con menor amplitud, al abrir.
La duración de los rebotes depende del contacto: de unos pocos milisegundos en un pulsador pequeño y nuevo a veinte o más en un interruptor grande o desgastado. El microcontrolador, que consulta la entrada cada microsegundo, los ve todos. Las consecuencias son:
- Un contador de pulsaciones suma varias veces con un solo toque.
- Un interruptor de «alternar» (cada pulsación cambia el estado) queda en un estado aleatorio.
- Una interrupción por flanco se dispara varias veces, y la rutina de servicio se ejecuta de más.
- Un menú pasa dos o tres opciones de una sola vez.
05 · Primera solución
Antirrebote por hardware
La solución más simple es un filtro RC en paralelo con el contacto, seguido de un buffer con histéresis. El capacitor tarda un tiempo en cargarse y descargarse, y suaviza los pulsos rápidos de los rebotes para que el pin solo vea una transición lenta. El problema es que una rampa lenta, aplicada a una entrada digital común, puede cruzar el umbral varias veces por ruido; por eso conviene un disparador Schmitt (por ejemplo, un 74HC14), que tiene dos umbrales distintos para subir y para bajar y entrega flancos limpios.
Con un pull-up de 10 kΩ y un capacitor de 1 µF, la constante de tiempo es τ = R × C = 10 ms. Al soltar el pulsador, la tensión sube hacia Vcc con la curva de carga del capacitor y cruza el umbral del 70 % de Vcc a los τ × ln(1 / 0,3) ≈ 1,2 τ ≈ 12 ms. Eso suele cubrir el rebote. Cuanto mayor es el RC, más tarda en responder el sistema.
| Método | Cómo funciona | Cuándo conviene |
|---|---|---|
| RC + Schmitt trigger | Filtra con un capacitor; el Schmitt regenera el flanco | Pulsadores simples; pocos componentes |
| Biestable SR con contacto SPDT | El primer contacto con el polo opuesto fija el estado y los rebotes no lo cambian | Circuitos digitales sin microcontrolador; muy robusto |
| Circuito integrado dedicado (MAX6816 y similares) | Filtra y entrega la señal limpia internamente | Productos con muchos pulsadores o requisitos de ESD |
Su ventaja es que no consume tiempo de CPU y sirve incluso con interrupciones. El costo: componentes, espacio en la placa y un tiempo de respuesta fijo que no se puede ajustar con el código.
06 · Segunda solución
Antirrebote por software
En un microcontrolador, el método usual es resolverlo por programa: se acepta un cambio de estado solo si permanece estable durante un tiempo mínimo (típicamente 20 a 50 ms). Si la señal cambia antes, se descarta y se reinicia la espera.
Lo que no hay que hacer
La solución del principiante es detectar el flanco y llamar a delay(50). Funciona, pero bloquea todo el programa durante 50 ms: no se leen otros sensores, no se actualizan las pantallas ni se atienden comunicaciones. En un sistema que hace varias cosas, es inaceptable. Además, un solo delay sigue sin filtrar los rebotes al soltar.
Un antirrebote sin bloqueo
La alternativa es consultar el pin en cada vuelta del bucle principal, anotar cuándo cambió y aceptar el cambio recién cuando pasó el tiempo requerido. No hay esperas: cada llamada es instantánea y recuerda su estado interno.
const uint8_t PIN_BOTON = 2;
const uint16_t TIEMPO_REBOTE = 20; // ms
bool estable = HIGH; // estado aceptado (pull-up: HIGH = suelto)
bool candidato = HIGH; // última lectura cruda
uint32_t tCambio = 0; // instante del último cambio crudo
// Devuelve true una sola vez por cada pulsación aceptada.
bool botonPresionado() {
bool lectura = digitalRead(PIN_BOTON);
if (lectura != candidato) { // la señal se movió: reiniciar la espera
candidato = lectura;
tCambio = millis();
}
if (candidato != estable && millis() - tCambio >= TIEMPO_REBOTE) {
estable = candidato; // el nuevo estado duró lo suficiente
return estable == LOW; // solo el flanco de pulsación
}
return false;
}
void loop() {
if (botonPresionado()) {
cuenta++; // exactamente una vez por pulsación
}
// ... el resto del programa sigue corriendo sin esperas
}
Otra forma común es el integrador: un contador que sube cuando el contacto está cerrado y baja cuando está abierto, con límites, y se cambia de estado al llegar a un extremo. Ambas dan el mismo resultado; la de arriba es más fácil de leer y ajustar. Lo importante es lo que tienen en común: el tiempo de filtrado es un parámetro, y la decisión se toma con información de varios instantes, no de uno solo.
Una elección de diseño: el tiempo de filtrado agrega latencia. Con 20 ms de filtrado, el sistema reconoce la pulsación unos 20 ms después de producirse. Para una interfaz humana es imperceptible (el umbral de percepción ronda los 100 ms); para un final de carrera de seguridad o un encoder, no (tema 25).
07 · Interpretar al usuario
De niveles a eventos
Un contacto limpio sigue entregando un nivel. Lo que el programa suele necesitar son eventos: «se acaba de pulsar», «se mantuvo pulsado», «se pulsó dos veces». Se obtienen comparando el estado actual con el anterior y midiendo tiempos:
| Evento | Cómo se detecta | Uso típico |
|---|---|---|
| Flanco de pulsación | El estado pasó de suelto a pulsado | Contar, alternar, avanzar en un menú |
| Flanco de liberación | El estado pasó de pulsado a suelto | Detener un movimiento al soltar |
| Pulsación larga | Pulsado durante más que un tiempo umbral (por ejemplo 1 s) | Encender o apagar el equipo, entrar a configuración |
| Repetición automática | Mantenido: un evento cada cierto intervalo, tras una espera inicial | Subir o bajar un valor rápidamente |
| Doble clic | Dos pulsaciones con una separación menor que una ventana (por ejemplo 300 ms) | Segunda función de un botón |
Combinar eventos sobre un solo botón obliga a una decisión de interfaz: la pulsación corta solo puede conocerse al soltar, porque hasta entonces no se sabe si será larga. Eso retrasa la reacción corta hasta el flanco de liberación. Con doble clic ocurre lo mismo: tras la primera pulsación hay que esperar la ventana para saber si viene otra.
El modo natural de organizar estos eventos es una máquina de estados. Los estados típicos son suelto, pulsado (aún no es larga), pulsación larga emitida y esperando segunda pulsación. Cada transición se dispara por un cambio del contacto o por un temporizador. Este patrón se retoma en el tema 41, cuando veamos tareas sin bloqueo.
08 · Sensores de posición y seguridad
Finales de carrera y seguridad
Un final de carrera (limit switch) es un contacto que se acciona cuando una pieza llega a una posición. Se usa para detectar el extremo de un recorrido (una puerta cerrada, el tope de un carro), para referenciar una posición conocida (homing en una impresora 3D) y como protección: cortar el movimiento antes de un choque.
En aplicaciones de seguridad hay una regla de oro: la falla debe llevar al estado seguro. Compará las dos conexiones de un final de carrera que detiene un motor al llegar al tope, con pull-up y el contacto a masa:
| Situación | Contacto NO (con pull-up) | Contacto NC (con pull-up) |
|---|---|---|
| Funcionamiento normal (sin llegar al tope) | Pin en 1 | Pin en 0 (contacto cerrado a masa) |
| Tope accionado | Pin en 0: se detecta el tope | Pin en 1: se detecta el tope |
| Cable cortado o conector flojo | Pin en 1: parece normal y el motor sigue hasta chocar | Pin en 1: parece el tope y el motor se detiene |
Con el contacto NC, una falla de cableado produce la misma señal que una activación legítima: el sistema se detiene y alguien investiga. Con NO, la falla pasa inadvertida hasta que ocurre el accidente. Por eso los circuitos de seguridad y las paradas de emergencia usan contactos normalmente cerrados (y un pulsador de emergencia es siempre NC). El programa agrega una desconfianza adicional: un final de carrera que nunca cambia de estado en un recorrido completo es sospechoso, y el sistema debería detectarlo.
Otras cuestiones prácticas: elegir la palanca o el rodillo adecuados para la pieza que acciona; dejar un sobrerrecorrido (el contacto debe poder seguir cediendo después de conmutar para no romperse); y, en ambientes con polvo, humedad o aceite, usar finales de carrera con grado de protección IP adecuado o sensores sin contacto (inductivos, magnéticos, ópticos), que no tienen desgaste mecánico ni rebotes.
09 · Más allá de la placa de pruebas
Cables largos y ambientes hostiles
Un cable largo de un pulsador a la entrada del microcontrolador funciona como antena: capta interferencia de motores, relés y la red. Con un pull-up de 50 kΩ, la entrada tiene una impedancia alta y es muy sensible. Algunas prácticas:
- Pull-up externo más fuerte (1 a 4,7 kΩ) en cables de más de un metro. Consume más corriente cuando el contacto está cerrado, pero reduce la sensibilidad al ruido.
- Capacitor de 10 a 100 nF cerca del pin, que hace de filtro RC junto con la resistencia.
- Resistencia en serie de 100 Ω a 1 kΩ y diodos de protección, para limitar la corriente de picos y descargas electrostáticas (ESD) que recibe un pulsador tocado por una persona.
- Optoacoplador o entrada aislada en la industria, donde los contactos trabajan a 12 o 24 V y las masas están lejos: la señal se aísla galvánicamente y se adapta a los 3,3 V o 5 V del microcontrolador.
- Cable trenzado o blindado para distancias largas, con la malla conectada a masa en un solo extremo.
También hay que prever la revisión de los contactos: se oxidan, se ensucian, se desgastan. Un contacto con rebotes cada vez mayores es un síntoma de fin de vida, y el filtro por software puede ocultarlo hasta el día en que la falla es total.
10 · Analogía con programación
Contar flancos con y sin antirrebote
Podemos estudiar el problema con una simulación sencilla: un contacto cuya señal, durante los milisegundos del rebote, cambia al azar entre 0 y 1. Se pulsa en t = 50 ms y se suelta en t = 200 ms. Contamos cuántos flancos de subida ve un programa ingenuo y cuántos ve uno con antirrebote de 20 ms. Es una prueba automática: se repite con rebotes de 0, 5, 10 y 15 ms. El generador usa una semilla fija para que el resultado sea reproducible.
Python en tu navegador. Los bloques son editables: cambiá los valores y presioná «Ejecutar Python». La primera vez tarda unos segundos en cargar.
def azar(semilla):
estado = semilla
while True:
estado = (1103515245 * estado + 12345) % 2**31
yield estado / 2**31
def contacto(t_pulso, t_suelta, rebote, generador):
"""Valor del contacto en cada milisegundo (0 a 399). En el rebote cambia al azar."""
senal = []
for t in range(400):
if t_pulso <= t < t_pulso + rebote or t_suelta <= t < t_suelta + rebote:
senal.append(1 if next(generador) < 0.5 else 0)
elif t_pulso + rebote <= t < t_suelta:
senal.append(1)
else:
senal.append(0)
return senal
def flancos_subida(x):
return sum(1 for anterior, actual in zip(x, x[1:]) if actual and not anterior)
def antirrebote(x, ms):
"""Acepta un cambio solo si la señal se mantiene estable durante `ms` milisegundos."""
aceptado = candidato = 0
desde = 0
salida = []
for t, valor in enumerate(x):
if valor != candidato:
candidato, desde = valor, t
if candidato != aceptado and t - desde >= ms:
aceptado = candidato
salida.append(aceptado)
return salida
print("rebote cambios flancos sin filtro flancos con filtro latencia")
for rebote in (0, 5, 10, 15):
x = contacto(50, 200, rebote, azar(3))
y = antirrebote(x, 20)
cambios = sum(1 for a, b in zip(x, x[1:]) if a != b)
latencia = y.index(1) - 50
print(f"{rebote:4d} ms {cambios:7d} {flancos_subida(x):14d} {flancos_subida(y):19d} {latencia:9d} ms")
Resultado: con rebote de 0 ms hay 2 cambios y 1 pulsación. Con 5 ms aparecen 4 cambios y el programa ingenuo cuenta 2 pulsaciones; con 10 ms, 10 cambios y 5 pulsaciones; con 15 ms, 14 cambios y 7 pulsaciones. El antirrebote cuenta 1 pulsación en todos los casos, a cambio de una latencia de 20 a 35 ms. Probá bajar el filtro a 5 ms con el rebote de 15 ms y comprobá que ya no alcanza.
La lección es doble: el filtro debe ser más largo que el rebote y todo filtro suma latencia. El modelo supone rebotes completamente aleatorios y sin ruido de otro tipo; el comportamiento real de un contacto dado conviene medirlo con instrumentos.
11 · Exploración interactiva
Un pulsador con rebotes, un filtro y un contador
Este laboratorio simula una pulsación: se aprieta el botón a los 20 ms y se suelta tras el tiempo que elijas, y en ambos momentos aparece una ráfaga de rebotes aleatorios. Ajustá la duración de los rebotes, el tiempo de filtrado y la frecuencia con que el programa consulta el pin. El gráfico muestra la señal cruda (tenue) y la que ve el programa después del filtro (color).
Banco de pruebas de un pulsador
La «señal cruda» se evalúa cada milisegundo; el programa solo conoce las muestras que toma cada período de consulta. Una pulsación se cuenta correctamente cuando el contador marca 1: un toque, una pulsación.
Recorrido guiado
- Poné el filtrado en 0 ms, la consulta en 1 ms y los rebotes en 8 ms. El contador sin filtro marca varias pulsaciones por un solo toque. Pulsá «Pulsar de nuevo» y comprobá que el número cambia: los rebotes son aleatorios.
- Subí el filtrado a 20 ms: el contador con filtro marca 1 en cada pulsación. Observá la latencia, que ronda el filtrado más la duración de los rebotes.
- Con rebotes de 20 ms, bajá el filtrado a 5 ms: ya no alcanza y aparecen pulsaciones de más. El filtro debe superar al rebote.
- Con 8 ms de rebote y 0 ms de filtro, subí el período de consulta a 10 ms o 20 ms: el programa «ve» menos rebotes, pero a veces ve exactamente uno de más o de menos. Consultar menos seguido no es antirrebote: reduce los síntomas sin garantizar nada.
- Cambiá el tiempo de pulsación a 40 ms y poné el filtrado en 50 ms: el toque desaparece. El filtro descarta pulsaciones más cortas que él, que puede ser aceptable o no según la aplicación.
- Con consulta cada 20 ms y filtrado de 20 ms, el cambio se acepta después de solo dos lecturas iguales: el filtro apenas supera el período de consulta. Mirá cuántas lecturas estables indica la nota del veredicto en cada combinación.
Desafío: el valor de filtrado para un teclado
Un teclado de oficina tiene pulsadores con rebotes de hasta 6 ms, y el usuario más rápido puede tocar una tecla durante unos 40 ms. Usá el laboratorio para encontrar un tiempo de filtrado que (a) supere el peor rebote con un margen del 100 % y (b) no descarte los toques de 40 ms. Con 15 ms se cumple: duplica el rebote de 6 ms y es menor que los 40 ms del toque corto. Con 50 ms se pierden los toques rápidos.
12 · Método de trabajo
Cómo integrar un contacto en un proyecto
- Elegí el tipo de contacto según el uso: pulsador o interruptor para el usuario, final de carrera para posición, NC para seguridad.
- Definí el nivel en reposo. Con pull-up interno y contacto a masa se resuelve casi siempre; en cables largos o ambientes ruidosos, pull-up externo y filtro.
- Encapsulá la lectura en una función que traduzca el nivel eléctrico a «pulsado» o «no pulsado».
- Medí el rebote con un osciloscopio o analizador lógico y fijá el tiempo de filtrado con un margen.
- Eliminá los rebotes sin bloquear: algoritmo temporal con
millis()o hardware. Nuncadelay()en un programa que hace más de una cosa. - Pasá de niveles a eventos: flancos, pulsación larga, repetición, doble clic. Documentá los tiempos usados.
- Pensá en la falla: cable cortado, contacto pegado o no accionado. Si hay riesgo, un contacto NC y un corte por hardware.
- Probá con un usuario real. Los tiempos que parecen razonables en el banco de pruebas pueden resultar torpes en la práctica.
Si un botón «hace cosas raras», revisá en este orden: la conexión (¿hay resistencia de pull-up o pull-down?), el nivel lógico que lee el programa (¿está invertido?) y, por último, los rebotes. La mayoría de los problemas con pulsadores son de las dos primeras categorías.
13 · Comprensión
Confusiones frecuentes
«Un pulsador es tan simple que no necesita cuidado»
Es el origen de muchos errores: pines flotantes, lógica invertida, rebotes y fallas sin detectar. Los de un bit son sensores, y requieren el mismo rigor que los demás.
«Con delay(50) después de detectar el botón alcanza»
Funciona en un programa de una sola tarea, pero bloquea todo lo demás durante ese tiempo y no filtra los rebotes que llegan después. El algoritmo basado en millis() hace lo mismo sin bloquear.
«El pull-up interno consume mucha corriente»
Con 20 a 50 kΩ y 5 V circulan entre 0,1 y 0,25 mA solo mientras el contacto está cerrado. Es un consumo despreciable salvo en dispositivos con batería que pasan mucho tiempo con el botón accionado.
«Normalmente abierto es siempre la mejor opción»
Para señales de usuario sí es la común, pero en funciones de seguridad conviene el contacto normalmente cerrado, porque una falla del cableado se parece a una activación y lleva al estado seguro.
«Los rebotes solo ocurren al pulsar»
También al soltar, y a veces con mayor duración si el resorte es débil. Un antirrebote que solo trata un flanco deja pasar el otro.
«Si usé una interrupción no hay rebotes»
La interrupción reacciona a cada uno de los flancos del rebote. Sin hardware antirrebote o sin una estrategia por software, se dispara muchas veces por pulsación.
14 · Práctica guiada
Predecí antes de comprobar
1. Lógica invertida
Un pulsador va del pin a masa y el pin usa el pull-up interno. ¿Qué devuelve digitalRead sin pulsar y pulsado? ¿Cómo se escribe la función pulsado()?
Ver solución
Sin pulsar: HIGH (el pull-up lleva el pin a Vcc). Pulsado: LOW. La función es return digitalRead(pin) == LOW;. Todo el resto del código usa «pulsado» sin pensar en la inversión.
2. Corriente del pull-up
Un pull-up externo de 10 kΩ a 5 V y un pulsador a masa. ¿Cuánta corriente y potencia se consumen con el botón apretado? ¿Y con el pull-up interno de 30 kΩ?
Ver solución
Con 10 kΩ: I = 5 / 10 000 = 0,5 mA, P = 5 V × 0,5 mA = 2,5 mW. Con 30 kΩ: I ≈ 0,17 mA y P ≈ 0,83 mW. En ambos casos, solo mientras se mantiene apretado.
3. Muestras estables
Se mide un rebote de hasta 12 ms y se quiere filtrar con un margen del 100 %. El programa consulta el pin cada 5 ms. ¿Cuántas lecturas iguales seguidas debe exigir (contando la primera) y cuál será la latencia mínima?
Ver solución
El filtro debe cubrir 24 ms. Con consulta cada 5 ms, el estado debe verificarse tras 24 / 5 = 4,8, es decir, 5 períodos (25 ms): 6 lecturas iguales seguidas, contando la primera. La latencia es de unos 25 ms más el tiempo del rebote en sí, del orden de 30 a 40 ms. Imperceptible para una persona.
4. Filtro RC
Un antirrebote con R = 10 kΩ y C = 1 µF alimentado a 5 V. ¿Cuánto tarda el capacitor en subir de 0 V a 3,5 V (el 70 % de Vcc), cuando se suelta el botón?
Ver solución
τ = RC = 10 kΩ × 1 µF = 10 ms. t = −τ × ln(1 − 0,7) = 10 ms × 1,204 ≈ 12 ms. Es el retardo que agrega el filtro, y debería superar la duración del rebote al soltar. Con un Schmitt trigger, el flanco de salida es limpio.
5. Parada de seguridad
Un carro se mueve entre dos topes y un final de carrera debe detenerlo. Con pull-up interno, ¿qué contacto elegirías, NO o NC, y qué pasa si se corta el cable?
Ver solución
NC. En marcha normal el contacto está cerrado y el pin lee 0. Al llegar al tope se abre y el pin pasa a 1 (parada). Si el cable se corta, el pin también pasa a 1: el sistema interpreta una parada y se detiene en lugar de seguir sin protección. Con un contacto NO, el corte pasaría inadvertido.
6. Doble clic
Un pulsador tiene una ventana de doble clic de 250 ms medida entre la liberación de la primera pulsación y el comienzo de la segunda. Primera pulsación entre 0 y 80 ms. Si la segunda empieza a los 220 ms, ¿es doble clic? ¿Y si empieza a los 400 ms?
Ver solución
Con 220 ms: la separación es 220 − 80 = 140 ms, menor que 250 ms: doble clic. Con 400 ms: la separación es 320 ms, mayor que la ventana: son dos clics simples. Fijate que el primer clic simple solo puede emitirse cuando la ventana vence (a los 330 ms), no antes.
15 · Síntesis
Ideas para recordar
- Un contacto entrega un bit; se clasifica por su mecanismo (pulsador o interruptor), su reposo (NO o NC) y sus polos y tiros.
- Un pin sin resistencia flota; hay que fijarlo con pull-up o pull-down. El pull-up interno con el contacto a masa es la opción habitual y deja la lógica invertida.
- La inversión se encapsula en una función («pulsado») para que el resto del programa no dependa de la conexión.
- Los contactos rebotan al cerrarse y al abrirse durante unos pocos milisegundos; el microcontrolador ve todos los rebotes.
- El antirrebote se hace por hardware (RC con Schmitt trigger, biestable SR) o por software: aceptar un cambio solo si dura un tiempo mínimo.
- Nunca se debe usar
delay()para filtrar: el algoritmo conmillis()no bloquea. - El filtro debe superar el rebote medido con un margen y agrega latencia; descarta toques más cortos que él.
- Con los niveles limpios se detectan eventos: flancos, pulsación larga, repetición y doble clic, normalmente con una máquina de estados.
- En seguridad se usan contactos normalmente cerrados, porque un cable cortado se interpreta como una activación; y el corte de potencia no debe depender solo del software.
- En cables largos y ambientes hostiles se refuerza la entrada con pull-up externo, capacitor, resistencia serie, protección o aislamiento.
¿Listo para el tema 7?
Antes de avanzar, dibujá cómo conectarías un pulsador con pull-up interno y escribí la función que devuelve «pulsado», explicá con un ejemplo por qué un final de carrera de parada debe ser normalmente cerrado y calculá el tiempo de filtrado y el número de muestras estables para un rebote de 10 ms con consulta cada 5 ms. Si podés justificar las tres respuestas, ya sabés leer un contacto con confianza.
En el próximo tema pasamos a los sensores de umbral y los optointerruptores: módulos con comparador y salida de colector abierto, histéresis y sensores ópticos de barrera y reflexión, que dan una salida digital a partir de una magnitud analógica.