Una pulsación que cuenta dos veces
Un botón conectado a un microcontrolador parece fácil: lo pulsas y llega un 1. Pero un botón real no sube una vez, sino que tiembla unos instantes, y el programa puede contar dos pulsaciones donde hubo una.
El chip tiene dos formas de enterarse: preguntar sin parar, que se llama sondeo, o recibir un aviso, que es una interrupción.
Al final de esta lección
Nota
Puedo explicar en qué se diferencian el sondeo y una interrupción, y cómo se filtra un rebote.
Palabras clave
| Palabra | Qué significa |
|---|---|
| Sondeo | leer la patilla una y otra vez para ver si cambió |
| Interrupción | un aviso que hace parar al chip y atender un suceso |
| Manejador | la función que el chip llama cuando hay una interrupción |
| Flanco ascendente | el paso de 0 a 1 en una patilla |
| Rebote | los saltos rápidos entre 0 y 1 al pulsar un botón |
| Estado | lo que el programa recuerda entre un tic y el siguiente |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Recuerda: es un simulador
Importante
El chip del laboratorio es un simulador de un chip inventado, no una placa real. Los scripts escriben en inglés, como tick, pin y handler.
El sondeo pregunta en cada vuelta
Con sondeo, el programa lee la patilla del botón en cada tic y guarda lo que leyó la vez anterior. Ese recuerdo es su estado.
Si antes leyó 0 y ahora lee 1, ha visto un flanco ascendente y cuenta una pulsación. Un botón real, sin embargo, no sube limpio: sube, baja y vuelve a subir en unos pocos tics. Eso es el rebote.
Ejemplo resuelto: una pulsación con rebote
| Tic | Lectura | ¿Flanco ascendente? |
|---|---|---|
| 0 y 1 | 0 | No |
| 2 | 1 | Sí, el primero |
| 3 | 0 | No, bajó |
| 4 | 1 | Sí, el segundo |
| 5 a 9 | 1 | No, sigue alta |
| 10 y 11 | 0 | No, ya se soltó |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Lee el botón con sondeo durante 12 tics
docker exec jupyter python3 steps/poll.pySe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Qué imprime el script de sondeo
Escribe una cabecera en inglés: tick, pin y press seen. Después van doce filas, una por tic, con la lectura y la palabra yes cuando ve un flanco.
Hay dos yes, en los tics 2 y 4. La última línea dice que hubo una pulsación real, pero que el bucle contó 2.
Una interrupción avisa y llama al manejador
Con una interrupción el programa no pregunta. Cuando la patilla del botón sube, el chip pone a 1 una marca en el registro IFR. Si las interrupciones están activadas, llama a un manejador: una función que escribes tú.
El programa principal puede hacer otra cosa mientras tanto, y por eso las interrupciones ahorran trabajo y energía.
Atiende el botón con un manejador
docker exec jupyter python3 steps/interrupt.pySe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Un manejador también ve el rebote
El script escribe handler called at tick 2 y handler called at tick 4. El chip llamó al manejador dos veces con la misma señal, una por cada flanco.
Después hace que el manejador ignore una llamada que llega 3 tics o menos después de la última que guardó. Así queda 1 llamada: la línea final dice calls kept after waiting out the bounce: 1.
Un error frecuente
Advertencia
Mucha gente cree que una interrupción elimina el rebote. No lo elimina: el manejador se llamó por cada flanco, dos veces para una pulsación. La interrupción solo evita que el chip tenga que preguntar. Para ignorar el rebote, tu código tiene que esperar un tiempo antes de aceptar otro flanco.
Filtra las llamadas de un rebote
llamadas = [2, 4] # los tics en que se llamó al manejador
espera = 3 # cambia este valor
guardadas = []
for tic in llamadas:
if len(guardadas) == 0:
guardadas.append(tic)
elif tic - guardadas[-1] > espera:
guardadas.append(tic)
print("pulsaciones:", len(guardadas))