Ejercicio 04 — Leer un número (0..255) desde el serie con parseInt, hacer eco de lo…
Dificultad: amarillo · Módulo 05 (Comunicacion serie)
Enunciado
Leer un número (0..255) desde el serie con parseInt, hacer eco de lo recibido y fijar el brillo de un LED por PWM (analogWrite).
Montaje (Arduino UNO)
LED + 220 ohm en el pin 9 (PWM, a GND)
Cómo se resuelve
El reto del módulo, y el más corto de los cuatro: apenas ocho líneas de loop(). Lo interesante es que junta tres cosas que hasta ahora iban por separado: recibir un dato por serie, validarlo y usarlo para gobernar una salida analógica.
Primer cambio, el montaje. El LED ya no va en el pin 8 sino en el pin 9, y el motivo no es capricho: aquí no hay que encender y apagar, hay que graduar el brillo, y eso requiere PWM. En el Arduino UNO solo algunos pines saben hacer PWM, y son los que llevan una tilde ~ impresa al lado del número en la placa. El 9 la lleva; el 8 no. Si dejas el LED en el 8, analogWrite no hace lo que esperas. El resto del montaje es el de siempre: resistencia de 220 Ω en serie, patilla larga hacia la resistencia, corta a GND.
Segundo cambio, cómo se lee. Lo que se espera no es un comando sino una cifra, y para eso existe Serial.parseInt():
int brillo = Serial.parseInt();parseInt recorre el buffer, se salta lo que no sean dígitos y devuelve el primer número entero que consigue componer. Ya no hace falta leer carácter a carácter ni convertir texto a número a mano: si escribes 128, llegan los tres caracteres '1', '2', '8' y parseInt te devuelve el entero 128. Sigue haciendo falta el if (Serial.available() > 0) de siempre, por la misma razón que en los ejercicios anteriores: no tiene sentido intentar interpretar un buffer vacío.
Conviene saber qué hace parseInt cuando lo que llega no es un número: devuelve 0, sin quejarse. Si escribes “hola”, el LED se apaga y no hay ningún mensaje de error. No es un fallo del sketch, es cómo funciona la función, pero explica un comportamiento que de otro modo desconcierta.
Tercer cambio, y el que de verdad separa un programa cuidadoso de uno descuidado:
brillo = constrain(brillo, 0, 255);analogWrite espera un valor entre 0 y 255, y parseInt puede devolverte cualquier entero: un 999 porque te sobró una tecla, un -5 porque escribiste un guion. constrain(valor, minimo, maximo) recorta el valor al intervalo: si está por debajo devuelve el mínimo, si está por encima el máximo, y si está dentro lo deja igual. Es la lección general del ejercicio: cuando un dato viene de fuera, no te fíes de él. No importa que seas tú quien lo teclea; el programa no puede saberlo, y validar en la frontera cuesta una línea.
Con el valor ya saneado, aplicarlo es trivial, porque analogWrite es lo que aprendiste en el módulo de PWM:
analogWrite(PIN_LED, brillo);0 apaga el LED, 255 lo pone al máximo, 128 lo deja a media luz. Merece la pena que pruebes valores bajos (10, 20, 40): verás que el brillo no crece de forma proporcional al número, porque el ojo no percibe la luz linealmente.
Y por último, el eco:
Serial.print("Eco -> brillo = ");
Serial.println(brillo);Parece redundante (tú acabas de escribir el número, ¿para qué te lo repite?) y es justo lo contrario: es información nueva, porque lo que la placa devuelve no es lo que escribiste, es lo que entendió y aplicó. Escribe 999 y el eco dirá 255, confirmándote que el constrain hizo su trabajo. Escribe hola y el eco dirá 0, y ahí entiendes por qué el LED se apagó. Y si el eco dice 128 pero el LED no cambia, el problema no está en la comunicación: está en el pin, en el cable o en la polaridad del LED.
Esa es la razón de fondo por la que se hace eco en cualquier sistema que reciba órdenes: separa el fallo de comunicación del fallo de ejecución, que desde fuera se parecen mucho y se arreglan en sitios completamente distintos.
Para practicar — cópialo y complétalo
Pega este esqueleto y completa los TODO. Es la mejor forma de aprender: inténtalo antes de mirar la solución.
/*
* Curso de Arduino — Módulo 05: Comunicación serie
* Ejercicio 04 — PRÁCTICA (rellena los TODO)
* Enunciado: Leer un número (0..255) desde el serie con parseInt, hacer eco
* de lo recibido y fijar el brillo de un LED por PWM (analogWrite).
* Dificultad: amarillo
* Placa: Arduino UNO Montaje: LED + 220 ohm en el pin 9 (PWM, a GND)
* Correr: Arduino IDE / Wokwi (wokwi/ej04) / arduino-cli (ver README)
* Escribe un número (p.ej. 128) en el monitor serie y pulsa Enviar.
*/
const int PIN_LED = 9; // pin 9 admite PWM (~)
void setup() {
// TODO: configura PIN_LED como salida
// TODO: abre el puerto serie a 9600 baudios
// TODO: imprime una instrucción: "Escribe un brillo (0-255):"
}
void loop() {
// TODO: if (Serial.available() > 0) { ... }
// TODO: lee un número -> int brillo = Serial.parseInt();
// TODO: recorta al rango 0..255 -> brillo = constrain(brillo, 0, 255);
// TODO: aplica el brillo -> analogWrite(PIN_LED, brillo);
// TODO: haz eco del valor aplicado con Serial.print / Serial.println
}Solución — cópiala y ejecútala
/*
* Curso de Arduino — Módulo 05: Comunicación serie
* Ejercicio 04 — MODELO (resuelto)
* Enunciado: Leer un número (0..255) desde el serie con parseInt, hacer eco
* de lo recibido y fijar el brillo de un LED por PWM (analogWrite).
* Dificultad: amarillo
* Placa: Arduino UNO Montaje: LED + 220 ohm en el pin 9 (PWM, a GND)
* Correr: Arduino IDE / Wokwi (wokwi/ej04) / arduino-cli (ver README)
* Escribe un número (p.ej. 128) en el monitor serie y pulsa Enviar.
*/
const int PIN_LED = 9; // pin 9 admite PWM (~)
void setup() {
pinMode(PIN_LED, OUTPUT);
Serial.begin(9600);
Serial.println("Escribe un brillo (0-255):");
}
void loop() {
if (Serial.available() > 0) { // ¿hay datos esperando?
int brillo = Serial.parseInt(); // extrae el primer número del buffer
brillo = constrain(brillo, 0, 255); // recorta al rango válido de PWM
analogWrite(PIN_LED, brillo); // aplica el brillo
Serial.print("Eco -> brillo = "); // eco de lo que se aplicó
Serial.println(brillo);
}
}Cómo ejecutar la simulación
Sin instalar nada, en el navegador
- Abre wokwi.com y crea un proyecto nuevo de la placa que pide el ejercicio.
- Pega la solución (o tu intento) en la pestaña
sketch.ino. - Abre la pestaña
diagram.json, borra lo que haya y pega el circuito de aquí abajo. - Dale al play. Verás el circuito funcionando: LEDs, pantallas y monitor serie.
Circuito del ejercicio (diagram.json)
{
"version": 1,
"author": "ESIBot",
"editor": "wokwi",
"parts": [
{ "type": "wokwi-arduino-uno", "id": "uno", "top": 0, "left": 0, "attrs": {} },
{ "type": "wokwi-led", "id": "led1", "top": -110, "left": 140, "attrs": { "color": "red" } },
{ "type": "wokwi-resistor", "id": "r1", "top": -40, "left": 130, "attrs": { "value": "220" } }
],
"connections": [
[ "uno:9", "r1:1", "green", [ "v0" ] ],
[ "r1:2", "led1:A", "green", [ "v0" ] ],
[ "led1:C", "uno:GND.1", "black", [ "v0" ] ]
],
"dependencies": {}
}En VS Code, con el repo del curso
El paquete de simulación de este ejercicio está en practica/05-comunicacion-serie/wokwi/ej04/. Con la extensión Wokwi instalada y la licencia activada (lo cuenta el onboarding del curso):
make sim EJ=05-comunicacion-serie/ej04y después, en VS Code, Ctrl+Shift+P → Wokwi: Start Simulator. La extensión no compila: simula un firmware ya compilado, y de compilarlo se encarga ese make.
Cómo usarlo
Con placa: abre el .ino en el Arduino IDE, elige placa y puerto y pulsa Subir. Sin placa: simulalo en Wokwi con cualquiera de las dos vias de arriba. Antes de mirar la solucion, intenta completar tu el esqueleto: es la mejor forma de aprender.