RETO 10: LED RGB, JUGANDO CON LOS COLORES PRIMARIOS DE LA LUZ

Modelo aditivo colores primarios

Modelo aditivo de colores rojo, verde y azul (Fuente Wikipedia).

El objetivo de este reto es doble, por un lado tecnológico, aprendiendo a montar y programar un led RGB desde nuestra placa de Arduino y, por otra parte, físico, comprendiendo el modelo aditivo de colores primarios.

Los leds RGB se basan en este modelo de color fundamentado en la síntesis aditiva, con el que es posible representar un color mediante la mezcla por adición de los tres colores de luz primarios (rojo, verde y azul).

Recordad que los colores secundarios (según el modelo aditivo RGB) son: 

  • rojo + verde = AMARILLO
  • rojo + azul = MAGENTA
  • verde + azul = CIAN

El modelo de color RGB no define por sí mismo lo que significa exactamente el color rojo, verde o azul, por lo que los mismos valores RGB pueden mostrar colores notablemente diferentes en distintos dispositivos que usen este modelo de color.

Es apasionante comprender el funcionamiento del ojo humano y cómo es capaz de procesar la información (al igual que nuestro microprocesador en la placa de Arduino, el ATmega 328) gracias a las células sensibles a la luz o fotorreceptores, estos son, los bastones y los conos. Os recomiendo que leáis acerca de ello.

Ahora que ya hemos entendido que el color resultante es la suma de los tres primarios, comentaremos varios aspectos respecto a los valores numéricos que asignaremos en nuestro código a cada uno de los colores primarios:

  • El resultado de la mezcla es un color monocromático.

  • La intensidad de cada señal (o luz de color) va desde 0 (no interviene en la mezcla) hasta 255.

  • De este modo, el rojo se obtiene con la siguiente mezcla (255, 0, 0) = (R, G, B).

  • El verde con (0, 255, 0) = (R, G, B).

  • El azul (0, 0, 255) = (R, G, B).

  • El color negro o, lo que es lo mismo, la ausencia de color se obtiene con (0, 0, 0).

  • El color blanco, como ya te has podido imaginar, con (255, 255, 255).

  • El color amarillo (255, 255, 0); cian (0, 255, 255) y magenta (255, 0, 255). 

  • MUCHO CUIDADO con esto anterior ya que el led RGB tiene la configuración GBR, es decir cambia el orden de los pines de nuestro led. Lo entenderás más adelante con los códigos de ejemplo.

Círculo cromático RGB.

Círculo cromático RGB (Fuente Wikipedia).

Como ya hemos visto cómo funciona un led monocromático en el primer reto, y teniendo en cuenta que un led RGB dispone en su interior de 3 leds individuales -rojo, verde y azul- únicamente vamos a indicar algunos aspectos concretos de los LED RGB:

  • Tiene 4 terminales, de los cuales uno es el COMÚN a los 3 leds (el terminal o patita más larga). 

  • Si desconociéramos el tipo de Led RGB que tenemos, podríamos identificar cada terminal, o pin, conectando GND a nuestro Arduino e ir probando cada una de las patas independientemente para ver qué color producen.

  • Hay dos tipos de LED RGB

    • Negativo común o cátodo común (este es el que usaremos en nuestra práctica). Cátodo significa negativo. Por tanto en este tipo de led RGB la patita más larga será el terminal negativo. 
    • Positivo común o ánodo común. Por tanto en este tipo de led RGB la patita más larga será el terminal positivo. 

led rgb arduino led rgb ardunio esquema electricoPasamos a realizar nuestro montaje. Debería quedaros algo parecido a este esquema:

LED RGB arduino Led GBR

Un primer ejemplo de código sencillo sería este:

#define RGB_GREEN 3
#define RGB_BLUE 5
#define RGB_RED 6
#define espera 300

void setup() {
  // put your setup code here, to run once:
pinMode (RGB_RED, OUTPUT);
pinMode (RGB_GREEN, OUTPUT);
pinMode (RGB_BLUE, OUTPUT);
}


void loop() {
  // put your main code here, to run repeatedly:
digitalWrite(RGB_GREEN, HIGH); 
digitalWrite(RGB_BLUE, LOW); 
digitalWrite(RGB_RED, LOW); 
delay (espera); 
digitalWrite(RGB_GREEN, LOW); 
digitalWrite(RGB_BLUE, HIGH); 
digitalWrite(RGB_RED, LOW); 
delay (espera); 
digitalWrite(RGB_GREEN, LOW); 
digitalWrite(RGB_BLUE, LOW); 
digitalWrite(RGB_RED, HIGH); 
delay(espera); 
}

En nuestro esquema hemos utilizado los pines 3, 5 y 6. Podéis usar otros pero aseguraros de que puedan hacer PWM (Los que tienen  el símbolo ~ en la placa de Arduino Uno) para poder poner distintas intensidades. La PWM es una señal digital pulsada –Pulse-Width Modulation o modulación de ancho de pulso- la cual es suficiente para emular una señal analógica en muchas aplicaciones [por esto la función que usamos es analogWrite y no digitalWrite]. Los pines de salidas digitales con la capacidad de actuar como salidas PWM son: 3, 5, 6, 9, 10 y 11.

Sobre este tipo de señales digitales que se pueden modular para aparentar que son analógicas ya lo vimos en el Reto 8: El Potenciómetro, un input analógico.

Por ejemplo, podemos variar la intensidad luminosa en un LED mediante un PWM. El LED realmente se enciende y apaga varias veces por segundo, pero este parpadeo es tan rápido que el ojo humano no lo aprecia a simple vista. El efecto global percibido es que el LED brilla con menor intensidad.

Señal pwm arduino led rgb

Pulse Width Modulation arduino

La señal con PWM al 100% equivaldría a una señal digital en la que está todo el rato activa. En el caso de un PWM al 50% tendríamos una señal activa la mitad del tiempo, con lo que, al hacer esto a gran velocidad, nos daría la sensación de un led que brilla la mitad de intenso o, si fuera el caso de un motor, giraría a la mitad de su máxima velocidad.

A continuación otro tipo de código más complejo que el anterior. Puesto que la ventaja del LED RGB es la mezcla de colores parece evidente que codifiquemos alguna función capaz de realizar y controlar numéricamente dicha mezcla. Esto lo ejecutaremos gracias a la función void Color()

/*
Hay que destacar en este código la función void Color() que nos servirá
para definir las mezclas de luces coloreadas (G, B, R).
 
 */
 
 void setup() {
  for (int i =3 ; i<7 ; i++) {
  pinMode(i, OUTPUT);
   }
}

void Color(int G, int B, int R) {     
  analogWrite(3, G) ;   // Green - Verde 
  analogWrite(5, B) ;   // Blue - Azul
  analogWrite(6, R) ;   // Red - Rojo
    }

void loop() {    
 Color(255,0,0);      //Green. Primero realizamos una comprobación de los 3 colores primarios. 
  delay(1000);      
  Color(0,255 ,0);    //Blue
  delay(1000);
  Color(0,0,255);     //Red
  delay(1000);
  Color(0,0,0);       //Sin color o apagado. 
  delay(3000);
  Color(0,255,148);   //Purple, NUESTRA PRIMERA MEZCLA! HOMENAJE A PRINCE ;)
  delay(4000);
   }

Como puedes ver la función Color() es la responsable de la mezcla.
En nuestro primer conjunto de instrucciones conviene comprobar que tenemos bien identificados los pines.

EXTRA BALLS:

  1. Un sencillo pero interesante reto de ampliación sería averiguar qué mezcla de colores RGB necesitaríamos para sacar un color determinado y luego programarlo. Pista: deberás utilizar cualquier programa de edición de colores ya sea en Mac, Windows, Linux… Mezclador colores primarios RGB
  2. Te reto ahora a que calcules cuántos colores diferentes podría sacar un led rgb aunque muchos de ellos los apreciemos como el mismo al ser el componente de poca definición y variaciones casi inapreciables.
  3. Ahora una novedad, vamos a presentar a la función random(N)

Esta función tiene la curiosidad que devuelve un número al azar comprendido entre el cero y el N. Nos podrá ser muy útil si queremos sacar colores aleatorios, en este caso con nuestro divertido LED RGB. Probad este psicodélico sketch:

void setup() {      
  for (int i =3; i<7; i++) {
  pinMode(i, OUTPUT);
  }
}

void Color(int G, int B, int R) {
  analogWrite(3, G) ;   // Green - Verde
  analogWrite(5, B) ;   // Blue - Azul
  analogWrite(6, R) ;   // Red - Rojo
       }

void loop()  { 
  Color(random(255), random(255), random(255)) ;
  delay(400);
       }

4. Por último un reto más artístico: programar un faro de costa. Consistiría en conseguir el efecto de secuencia que emite los destellos largos y cortos de cualquier faro en la costa. Para ello nos serviremos de las estructuras de control for (vistas por primera vez en el Reto #1 «Efecto coche fantástico», aquí) para ir encendiendo y apagando progresivamente el led.

Os comparto un ejemplo:

void setup() {
Serial.begin(9600);
for (int i =3 ; i<7 ; i++) {
pinMode(i, OUTPUT);
}
}

void Color(int G, int B, int R) { 
analogWrite(3, G) ; // Red - Rojo
analogWrite(5, B) ; // Green - Verde 
analogWrite(6, R) ; // Blue - Azul
}

void loop() { 
Color(255,0,0); // Empiezo con un parpadeo doble. 
delay(200);
Color(0,0,0);
delay(700);
Color(255,0,0);
delay(200);
Color(0,0,0);
delay(2000);

for (int x=0; x<2; x++) { //REPETICIÓN DOS VECES

for (int i=0; i<256; i++) { //Subida progresiva dei ntensidad hasta el valor máximo (255).
Serial.println(i);
Color(i,0,0);
delay (7);
}

delay (1000);
for (int i=255; i>0; i--) { //Bajada progresiva de intensidad hasta el valor mínimo (0). 
Serial.println(i); 
Color(i,0,0);
delay (7);
}
Color(0,0,0);
delay(2000);
}
delay (3000);
}

led rgb arduino

 

«Un líder que actúa como «pequeño timón» es constante -como un faro, no como una veleta-, una fuente de luz constante y digna de confianza, no alguien que gira con cualquier viento social»

Stephen R. Covey