Ejercicio 03 — LED RGB mezclando colores con 3 salidas PWM

Dificultad: amarillo · Módulo 03 (Salidas analogicas (PWM))

Enunciado

LED RGB mezclando colores con 3 salidas PWM. Ciclo de colores (1 s cada uno).

Montaje (Arduino UNO)

LED RGB (cátodo común): Rpin 9, Gpin 10, Bpin 11 cada patilla de color con resistencia 220 ohm; COM a GND

Cómo se resuelve

El ejercicio vistoso del módulo, y el primero que usa tres salidas PWM a la vez. Un LED RGB no cambia de color: son tres LEDs (rojo, verde y azul) dentro de la misma cápsula, con una patilla común. Si cada uno recibe su propia intensidad, el ojo suma las tres luces y ve un color único. Todo lo que hay aquí es el ejercicio 02 repetido tres veces, más la idea de mezcla aditiva.

El montaje es lo que más cuidado pide. El LED es de cátodo común: R al pin 9, G al pin 10 y B al pin 11 (los tres con ~, imprescindible), cada color con su propia resistencia de 220 Ω, y la patilla común, que es la más larga, a GND. La tentación de poner una sola resistencia en el común hay que resistirla: los tres colores compartirían la limitación de corriente y el brillo de cada uno dependería de cuántos estuvieran encendidos, con lo que el amarillo saldría más apagado que el rojo y el blanco más apagado todavía. Si tu LED RGB resulta ser de ánodo común, la patilla larga va a 5 V y la lógica se invierte: 255 apaga y 0 enciende a tope. En Wokwi es de cátodo común.

En el código, los tres pines se declaran con nombre:

const int R = 9;
const int G = 10;
const int B = 11;

Y setup() hace tres pinMode(..., OUTPUT), uno por color. Nada nuevo, solo por triplicado.

Lo interesante es la primera función propia del curso:

void color(int r, int g, int b) {
    analogWrite(R, r);
    analogWrite(G, g);
    analogWrite(B, b);
}

Merece la pena detenerse en por qué existe. Sin ella, cada color del ciclo serían tres analogWrite seguidos, y el loop() tendría veintiuna líneas en las que es facilísimo equivocarse de pin o dejarse un canal sin escribir (y un canal sin escribir se queda con el valor anterior, así que el color sale contaminado por el de antes). Con la función, cada color es una línea que se lee como lo que significa. Fíjate además en la distinción entre las mayúsculas y las minúsculas: R, G y B son los pines, constantes globales; r, g y b son los valores de intensidad que recibe la función. Son cosas distintas y por eso se escriben distinto.

El loop() recorre siete colores, un segundo cada uno:

color(255,   0,   0);   delay(1000);   // rojo
color(  0, 255,   0);   delay(1000);   // verde
color(  0,   0, 255);   delay(1000);   // azul
color(255, 255,   0);   delay(1000);   // amarillo (R+G)
color(  0, 255, 255);   delay(1000);   // cian     (G+B)
color(255,   0, 255);   delay(1000);   // magenta  (R+B)
color(255, 255, 255);   delay(1000);   // blanco   (R+G+B)

Los tres primeros son las primarias solas. Los tres siguientes son las mezclas por parejas, y aquí es donde la intuición de la clase de plástica falla: esto es mezcla aditiva, de luz, no sustractiva, de pintura. Rojo más verde no da marrón ni naranja: da amarillo. Verde más azul da cian, rojo más azul da magenta, y los tres juntos dan blanco, porque sumar las tres primarias de luz es justo lo que compone la luz blanca.

Si esperabas naranja en el cuarto paso, la explicación es que el naranja no es una mezcla al 100 % de dos primarias, sino una mezcla desequilibrada: el rojo a tope con el verde a media potencia, algo como color(255, 128, 0). Ese es el experimento natural al terminar el ejercicio: bajar uno de los canales y ver cómo el color se desliza. Con color(255, 64, 0) sale un rojo anaranjado, con color(255, 192, 0) un ámbar. La alineación de los números en el código, con los ceros y los 255 en columna, no es adorno: hace que se vea de un vistazo qué canal está a tope en cada línea.

Y una observación que enlaza con el ejercicio 01: aquí los siete colores son escalones secos porque el brillo salta de golpe. Un ciclo de color suave se consigue combinando esto con la rampa del for del primer ejercicio, subiendo un canal mientras se baja otro.

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 03: Salidas analógicas (PWM)
 * Ejercicio 03 — PRÁCTICA (rellena los TODO)
 * Enunciado: LED RGB mezclando colores con 3 salidas PWM. Ciclo de colores (1 s cada uno).
 * Dificultad: amarillo
 * Placa: Arduino UNO    Montaje: LED RGB (cátodo común): R->pin 9, G->pin 10, B->pin 11
 *                       cada patilla de color con resistencia 220 ohm; COM a GND
 * Correr: Arduino IDE / Wokwi (wokwi/ej03) / arduino-cli (ver README)
 *
 * Pista: un color = (r, g, b), cada uno 0..255. Amarillo = R+G, cian = G+B, magenta = R+B.
 */
const int R = 9;    // pin PWM (~)
const int G = 10;   // pin PWM (~)
const int B = 11;   // pin PWM (~)
 
// Pone un color dado por sus tres componentes (0..255).
void color(int r, int g, int b) {
    // TODO: analogWrite(R, r), analogWrite(G, g), analogWrite(B, b)
}
 
void setup() {
    // TODO: configura R, G y B como salidas (3 pinMode)
}
 
void loop() {
    // TODO: llama a color(...) para rojo, verde, azul, amarillo, cian, magenta y blanco
    //       con un delay(1000) entre cada uno
}

Solución — cópiala y ejecútala

/*
 * Curso de Arduino — Módulo 03: Salidas analógicas (PWM)
 * Ejercicio 03 — MODELO (resuelto)
 * Enunciado: LED RGB mezclando colores con 3 salidas PWM. Ciclo de colores (1 s cada uno).
 * Dificultad: amarillo
 * Placa: Arduino UNO    Montaje: LED RGB (cátodo común): R->pin 9, G->pin 10, B->pin 11
 *                       cada patilla de color con resistencia 220 ohm; COM a GND
 * Correr: Arduino IDE / Wokwi (wokwi/ej03) / arduino-cli (ver README)
 *
 * Idea: cada color = una intensidad PWM (0..255). Mezclar R+G+B da el color final.
 */
const int R = 9;    // pin PWM (~)
const int G = 10;   // pin PWM (~)
const int B = 11;   // pin PWM (~)
 
// Pone un color dado por sus tres componentes (0..255).
void color(int r, int g, int b) {
    analogWrite(R, r);
    analogWrite(G, g);
    analogWrite(B, b);
}
 
void setup() {
    pinMode(R, OUTPUT);
    pinMode(G, OUTPUT);
    pinMode(B, OUTPUT);
}
 
void loop() {
    color(255,   0,   0);   delay(1000);   // rojo
    color(  0, 255,   0);   delay(1000);   // verde
    color(  0,   0, 255);   delay(1000);   // azul
    color(255, 255,   0);   delay(1000);   // amarillo (R+G)
    color(  0, 255, 255);   delay(1000);   // cian     (G+B)
    color(255,   0, 255);   delay(1000);   // magenta  (R+B)
    color(255, 255, 255);   delay(1000);   // blanco   (R+G+B)
}

Cómo ejecutar la simulación

Sin instalar nada, en el navegador

  1. Abre wokwi.com y crea un proyecto nuevo de la placa que pide el ejercicio.
  2. Pega la solución (o tu intento) en la pestaña sketch.ino.
  3. Abre la pestaña diagram.json, borra lo que haya y pega el circuito de aquí abajo.
  4. 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-rgb-led", "id": "rgb", "top": -60, "left": 200, "attrs": { "common": "cathode" } },
    { "type": "wokwi-resistor", "id": "r1", "top": 100, "left": 150, "attrs": { "value": "220" } },
    { "type": "wokwi-resistor", "id": "r2", "top": 140, "left": 150, "attrs": { "value": "220" } },
    { "type": "wokwi-resistor", "id": "r3", "top": 180, "left": 150, "attrs": { "value": "220" } }
  ],
  "connections": [
    [ "uno:9", "r1:1", "green", [] ],
    [ "r1:2", "rgb:R", "green", [] ],
    [ "uno:10", "r2:1", "green", [] ],
    [ "r2:2", "rgb:G", "green", [] ],
    [ "uno:11", "r3:1", "green", [] ],
    [ "r3:2", "rgb:B", "green", [] ],
    [ "rgb:COM", "uno:GND.1", "black", [] ]
  ],
  "dependencies": {}
}

En VS Code, con el repo del curso

El paquete de simulación de este ejercicio está en practica/03-salidas-analogicas-pwm/wokwi/ej03/. Con la extensión Wokwi instalada y la licencia activada (lo cuenta el onboarding del curso):

make sim EJ=03-salidas-analogicas-pwm/ej03

y después, en VS Code, Ctrl+Shift+PWokwi: 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.

Conexiones