les vencimos · offline
L14. Varios botones, un comportamiento
Maestro
Un botón que solo copia el dedo no recuerda. Para un interruptor de verdad hacen falta dos gestos, o uno que alterne, y una variable que guarde el estado. Hoy son dos pulsadores: el pin 2 enciende, el pin 3 apaga, y el LED se queda. La luz ya no depende de lo que se lee ahora mismo. Depende de lo último que pediste.
Si enciendes solo mientras el pin 2 está en LOW, al soltar se apaga. Eso ya lo sabes. Un flexo de pared no funciona así: pulsas y se queda. Hace falta memoria. En el programa, la memoria de un sí o un no es una variable. int encendido = 0; vale como interruptores. Cuando el pin 2 se aprieta, pones 1. Cuando el pin 3 se aprieta, pones 0. El LED mira la variable, no el dedo de este instante.
Cableado: pin 2 a un pulsador hacia GND, pin 3 a otro, también hacia GND, los dos con INPUT_PULLUP. Masas juntas. Si olvidas la masa del segundo botón, ese «no hace nada» o hace ruido.
El rebote sigue existiendo. En esta lección, una espera corta de 30 ms después de ver LOW evita que un clic dudoso escriba la variable varias veces. No cambia la idea. La idea es la variable. Sin ella, dos botones solo pueden copiar el presente, y el presente al soltar es «nadie aprieta», o sea apagado, y has perdido el encendido.
Cuando esto te resulte pequeño, el mismo patrón sirve para un modo noche y un modo día, o para arrancar y parar una alarma. No añadas el tercer botón hoy.
Montaje
Pines de esta lección
Por qué
Con un solo if el mundo es el presente. Con una variable, el programa recuerda. encendido vale 1 o 0 aunque el dedo ya se haya ido. El pin 2 pone 1. El pin 3 pone 0. El digitalWrite del final mira la variable, no el dedo. Por eso el LED se queda.
Los dos pulsadores se cablean igual: un lado al pin, el otro a GND, INPUT_PULLUP. Si el del pin 3 lo pones a 5 V por diferenciarlo, deja de funcionar y además contradice la lección. El color del cable puede distinguirlos; el voltaje, no.
Hay una espera corta de 30 ms al detectar cada botón, la misma idea del rebote, aquí más simple. Si mantienes el pin 2 apretado, el loop sigue escribiendo 1 cada vuelta. No molesta, porque 1 escrito otra vez sigue siendo 1. El problema sería contar flancos, y aquí no se cuenta.
Si aprietas los dos a la vez, manda el que el loop mire el último. En este sketch el pin 3 va después, así que apagado gana el empate. No es filosofía: es el orden de las líneas. Cámbialo y gana el otro.
Práctica
- Añade el segundo pulsador en el pin 3, a GND, igual que el del 2.
- Carga el sketch de la variable encendido.
- Pulsa el 2 y suelta. El LED debe seguir encendido.
- Pulsa el 3 y suelta. El LED debe seguir apagado.
- Pulsa el 2 y, sin soltar, pulsa el 3. Anota quién gana. Tiene que ser el 3, el apagado.
- Suelta todo. El LED no debe cambiar solo.
- Invierte el orden de los dos if en una copia, carga, y comprueba que ahora gana el encendido. Luego deja el sketch de la lección.
Anota el montaje
Escribe qué cable va a qué pin, o qué has entendido del paso. Se guarda en este aparato.
Ejemplos resueltos
El LED solo vive mientras el dedo está
Se borró la variable y se volvió a escribir el LED dentro del if del pin 2, con un else que apaga. El pin 3 no hace nada. Es otra vez la lección anterior.
La variable se escribe en los if. El digitalWrite va fuera, una sola vez por vuelta, usando la variable. Soltar el dedo ya no es un else.
El pin 3 flotando
Se declaró INPUT_PULLUP solo en el 2. El 3 está en INPUT. A ratos lee LOW él solo y apaga el LED sin que pulses.
Los dos pines llevan INPUT_PULLUP. Los dos cables llegan a GND de verdad, no a una fila vacía.
En la mesa
Etiqueta los cables con un trozo de cinta: un punto para el pin 2, dos para el pin 3. Pulsa el de un punto, suelta, espera, mira. Pulsa el de dos puntos, suelta, espera, mira. Si pulsas los dos seguidos sin mirar entre medias, no sabes cuál ganó. La pausa es parte de la medida. Luego pulsa los dos a la vez y di quién manda: el que el programa mira más tarde, el pin 3, el de apagar.
Suelta los dos y cuenta hasta cinco. El LED no es un pulsador de timbre: no debe cambiar en esos cinco segundos. Si cambia, un pin está flotando. Casi siempre es el 3, declarado deprisa y dejado en INPUT. Corrija pinMode y repite la cuenta, no el montaje entero.
Cuando obedezca, explica en voz alta la variable como una nota en la mesa: el dedo escribe la nota, el LED la lee, y la nota se queda cuando el dedo se va. Si no puedes decirlo sin mirar el sketch, copia la variable a mano en el papel y vuelve a decirlo. Ese es el puente hacia los estados.
Sketch
int encendido = 0;
void setup() {
pinMode(2, INPUT_PULLUP);
pinMode(3, INPUT_PULLUP);
pinMode(13, OUTPUT);
}
void loop() {
if (digitalRead(2) == LOW) {
delay(30);
encendido = 1;
}
if (digitalRead(3) == LOW) {
delay(30);
encendido = 0;
}
digitalWrite(13, encendido ? HIGH : LOW);
}
Ejercicio
Monta los dos pulsadores, pin 2 y pin 3, a GND. Uno deja el LED encendido al soltar. El otro lo deja apagado. Si al soltar se apaga solo, la variable no está mandando: estás copiando el pin.
Autoevaluación
1. ¿Por qué no basta con leer el pin 2 para un interruptor que se queda?
Porque al soltar, la lectura vuelve a HIGH y perderías el encendido.
2. ¿Qué guarda el estado entre un clic y el siguiente?
Una variable del programa, no el botón.
3. ¿A dónde va el segundo pulsador?
Entre el pin 3 y GND, con INPUT_PULLUP, igual que el primero.