les vencimos · offline
L28. Varias cosas a la vez
Maestro
El chip no hace dos cosas en el mismo instante. Hace un loop tan rápido que parece que sí. La condición es no dormirlo. Un parpadeo por millis, un botón que conmuta, un sensor que solo mira. Cada uno con su reloj o su estado. Si metes un delay de un segundo solo para el LED, paras también el sensor.
Reúne tres piezas que ya conoces. El LED 13 parpadea cada 400 ms con millis. El pin 2, al pulsarse, cambia una variable que permite o prohíbe el parpadeo. A0 se lee cada vuelta. Si pasa de 512, mandas una línea por Serial, pero no en cada vuelta: guardas otro reloj y escribes como mucho cinco veces por segundo. Si no, el monitor se ahoga y parece que todo va lento.
Eso es a la vez en un microcontrolador. Nadie interrumpe a nadie. Cada tarea mira si le toca y, si no, cede el turno. El orden dentro de loop casi no importa si ninguna tarea se queda un segundo dentro.
Cuando una tarea necesite de verdad una espera, que sea de las cortas, de rebote. Si una medición tarda, como pulseIn del ultrasonidos, esa espera sí bloquea un poco. Se pone al final y se acepta, o se espacia para no llamarla mil veces.
Montaje
Pines de esta lección
Por qué
Varias cosas a la vez, en este chip, son varias restas de millis y ningún delay largo. tLed y tSerie son relojes distintos. Si compartes uno, la impresión y el parpadeo se obligan al mismo periodo y dejas de poder afinarlos.
El permiso es un estado, el de la lección anterior, leído en flanco. Si no hay permiso, el LED se apaga y no se agenda otro cambio. Al devolver el permiso, el ritmo sigue con el reloj, no con un arranque especial. La serie no pide permiso en este sketch: sigue imprimiendo. Es deliberado, para ver que una tarea puede vivir cuando la otra está callada.
Imprimir solo si el valor pasa de 512 evita llenar el monitor cuando el potenciómetro está bajo. No es que la medida no exista: es que no se cuenta. Si depuras y no ves números, gira al extremo alto antes de creer que el USB murió.
delay(30) en el flanco es el único bloqueo, y es breve. Si lo subes a 500 para calmar un rebote que ya no está, vuelves a trabar las tres tareas. El rebote se cura con 30, no con medio segundo.
Práctica
- Monta LED en 13, botón en 2 a GND, potenciómetro en A0 como ya sabes.
- Carga. Abre el monitor a 9600.
- Gira el potenciómetro por encima de la mitad. Tienen que salir números, y el LED sigue su ritmo.
- Un golpe en el botón. El LED se queda apagado. Los números, si sigues alto, continúan.
- Otro golpe. El LED vuelve al ritmo.
- Baja el potenciómetro. Los números paran. El LED, si hay permiso, no para.
- Confirma que no hay delay largo. Si el LED se congela al pulsar, hay uno escondido.
Anota el montaje
Escribe qué cable va a qué pin, o qué has entendido del paso. Se guarda en este aparato.
Ejemplos resueltos
Un solo reloj para las dos tareas
tLed se usa también para decidir la impresión. Cada vez que el LED cambia, se imprime, o al revés: las dos quedan atadas a 400 ms y no puedes dejar la serie a 200.
Cada tarea con su unsigned long. Actualizas una y no tocas la otra.
El permiso apaga también el monitor
Se metió el println dentro del if del permiso. Al quitar el permiso parece que A0 se rompió.
En este sketch la serie va por libre. Si quieres callarla, que sea una decisión escrita, no un efecto de haber anidado de más.
En la mesa
Haz tres gestos separados, no a la vez. Primero gira el potenciómetro alto y mira letras, con el LED parpadeando. Luego baja el potenciómetro y confirma que las letras paran y el LED no. Luego un golpe de botón y confirma que el LED se calla y, si subes otra vez el potenciómetro, las letras siguen. Si un gesto estropea los otros dos, hay un delay o un if de más que anida lo que no debía.
Cuenta, con el permiso puesto, cuántas veces cambia el LED en cuatro segundos: cerca de diez, por el periodo de cuatrocientos milisegundos. Si el botón lo frena, el delay del rebote se te ha ido de las manos. Devuélvelo a treinta.
Cuando los tres gestos sean independientes, para. No añadas una pantalla hoy. Esta lección ya es el techo de varias cosas a la vez que el curso pide. Más cosas sin este orden se caen.
Sketch
unsigned long tLed = 0;
unsigned long tSerie = 0;
bool luz = false;
bool permitido = true;
int antesBtn = HIGH;
void setup() {
pinMode(13, OUTPUT);
pinMode(2, INPUT_PULLUP);
Serial.begin(9600);
}
void loop() {
unsigned long ahora = millis();
int btn = digitalRead(2);
if (antesBtn == HIGH && btn == LOW) {
delay(30);
permitido = !permitido;
}
antesBtn = digitalRead(2);
if (permitido && ahora - tLed >= 400) {
tLed = ahora;
luz = !luz;
digitalWrite(13, luz ? HIGH : LOW);
}
if (!permitido) digitalWrite(13, LOW);
if (ahora - tSerie >= 200) {
tSerie = ahora;
int v = analogRead(A0);
if (v > 512) Serial.println(v);
}
}
Ejercicio
Monta el parpadeo con permiso del botón y la lectura de A0. Suelta el botón de permiso y gira el potenciómetro: el texto debe seguir saliendo. Si se congela, hay un delay de más.
Autoevaluación
1. ¿El chip ejecuta dos tareas en el mismo instante?
No. Recorre el loop tan rápido que lo parece, si nadie lo duerme.
2. ¿Qué rompe esa ilusión?
Un delay largo. Para el LED y, con él, el sensor y el botón.
3. ¿Por qué no imprimimos A0 en cada vuelta?
Porque inundas el monitor y el conjunto parece lento.