Árbol de Navidad RGB


Se recomienda mirar los vídeos antes de la nota para una mejor compresión del proceso.


Este es un método de control para tiras de led RGB no inteligentes, es decir LEDs RGB estándar sin tener controlador interno como los Neopixel. Este proceso puede servir para controlar los leds RGB de manera multiplexada, primero tenemos que analizar una tira de leds RGB estándar de las que podremos encontrar en los comercios a precios reducidos.

Como podemos ver en esta tira estándar RGB, tenemos un segmento construido con 3 leds RGB cada uno con su resistencia lo cual los prepara para funcionar a 12V ya que la tira de led funciona como estándar en 12V.
A su vez podemos ver los terminales R, G, B y 12V que tiene en los dos extremos del segmento de tres leds. La tira de leds viene unida por defecto, pero nos da la posibilidad de recortarla con una tijera y soldare los cables en esos terminales de cobre.

El proyecto que estoy presentando requiere de al menos 8 segmentos de leds ya que vamos a utilizar un multiplexado mediante un multiplexor 4051 (aunque pueden ser registros de desplazamiento 74164, 74595, etc... )
En mi caso he utilizado 16 segmentos, que están en dos grupos de 8:

[Seg1]-[Seg2]-[Seg3]-[Seg4]-[Seg5]-[Seg6]-[Seg7]-[Seg8]-[Seg9]-[Seg10]-[Seg11]-[Seg12]-[Seg13]-[Seg14]-[Seg15]-[Seg16]

En mi caso he interconectado segmento 1 con segmento 9, segmento 2 con segmento 10, segmento 3 con segmento 11, .... , segmento 8 con segmento 16. De esta manera cuando activamos el segmento 1, se activara simultáneamente el segmento 9.

La manera de realizar este multiplexado es utilizando la linea de 12V de la tira, pero si la dejamos así como esta, no servirá porque los 12V recorren toda la tira de leds y todos los segmentos, entonces lo que tenemos que hacer es recortar e interrumpir solamente la linea de 12V (con cuidado de no cortar alguna de las tres lineas RGB que siguen), y si se logra una interrupción de la linea de 12V por cada segmento, tenemos que soldar un cable por cada segmento a la linea de 12V de esta manera lograremos controlar los 12V de cada segmento de forma independiente.


Como podemos ver en este diagrama extraído de un datasheet de una strip led rgb, nos muestra las conexiones de cada segmento de leds, con el recuadro "one section" estamos seleccionando un segmento de 3 leds RGB en la tira, las tres resistencias están una para cada color, y los leds por color están en serie para aprovechar mejor los 12V, en nuestro caso, tendremos que recortar cada linea de 12V de cada segmento y pondremos un cable en cada una de ellas.
Como podemos ver en este diagrama, tomamos una conexión por cada 12V de cada segmento, de esta manera vamos a poder multiplexar cada segmento de led y a la vez controlar los tres colores que van todos juntos entre todos los segmentos.
Este paso lo repetiremos en todos los segmentos a utilizar, en mi caso he utilizado 16 y los he interconectado como menciono anteriormente, esa interconexion se realiza uniendo estas lineas de 12V entre si (las que se deseen unir), luego cuando se seleccione con el multiplexado se encenderán simultáneamente.

Por otro lado tenemos el multiplexor 4051, se ha elegido este porque como podremos ver tenemos una tira de leds en ánodo común, lo que nos pide directamente 2 transistores por cada segmento, un PNP y un NPN para poder controlar la misma, pero en la practica son 16 transistores con sus resistencias y termina siendo un proceso engorroso para el armado, entonces buscando un poco existen algunas versiones de ULN que son con lógica emisor abierto pero son difíciles de conseguir, para ello y teniendo en cuenta el consumo (que en mi caso no supera los 10mA) he implementado el 4051 que es un multiplexor CMOS que nos permite trabajar con 12V sin problemas y que según datasheet soporta unos 30mA por salida lo cual nos sobra para el proyecto.


Como podemos ver, tenemos representada la tira de leds con estos 8 leds RGB (en la vida real serán 3 led RGB por cada segmento, aquí se ha representado solo con uno, pero es solo a modo representativo.
Pero lo importante es que vemos los 8 segmentos con los 3 transistores para controlar los 3 colores y en la parte superior vemos las 8 salidas de 12V que van hacia el multiplexor que nos entregara 12V en cada una de sus salidas según la selección binaria en su control.
La interfaz en este caso serán 3 lineas de control para el 4051 y 3 lineas PWM para los transistores, esta interfaz se puede conectar directamente a un microcontrolador o bien se puede controlar con lógica digital discreta.


En este otro circuito podemos ver como controlamos los transistores RGB con un contador binario 4029 que a su vez este es controlado mediante su clock con tres opciones, un 555 que genera el clock, un micrófono con su amplificador para hacerlo audioritmico y una "antena" que en realidad es dejar el clock al aire libre sin conexión para que se dispare de forma errática y genere efectos aleatorios.
Por otro lado tenemos en lugar del multiplexor un contador en anillo 4017 que se encargara de realizar la secuencia o barrido de los segmentos que a su vez esta controlado por un timer 555.

El mejor método es el primero donde le conectamos un microcontrolador ya que podremos realizar efectos a demanda y control.
En mi proyecto lo he realizado con un microcontrolador PIC pero también podemos hacerlo con cualquier otro microcontrolador o con placas de desarrollo como Arduino.

A continuación dejare dos códigos fuente con algunos efectos, realizado con PIC y realizado con Arduino para aquellos que quieran la segunda opción.

Con PIC

  1. #include <16F628a.h>
  2. #FUSES NOWDT
  3. #FUSES INTRC_IO
  4. #FUSES NOMCLR
  5. #use delay(int=4000000)
  6. #int_timer0
  7. void pwm_duty(int pwm0, int pwm1, int pwm2){
  8.    int cont;
  9.    if(cont>15)
  10.       cont=0;
  11.    else
  12.       cont++;
  13.    if(cont>0&&cont<pwm0)
  14.       output_high(PIN_B0);
  15.    else
  16.       output_low(PIN_B0);
  17.    if(cont>0&&cont<pwm1)
  18.       output_high(PIN_B1);
  19.    else
  20.       output_low(PIN_B1);
  21.    if(cont>0&&cont<pwm2)
  22.       output_high(PIN_B2);
  23.    else
  24.       output_low(PIN_B2);
  25.    set_timer0(0);      
  26. }
  27. void fadeRGB(void){
  28.    int r, g, b, i;
  29.    for(b=0;b<16;b++){
  30.       pwm_duty(16,0,b);
  31.       for(i=0;i<8;i++){
  32.          output_a(i);
  33.          delay_ms(1);
  34.       }
  35.    }
  36.    for(r=16;r>1;r--){
  37.       pwm_duty(r,0,16);
  38.       for(i=0;i<8;i++){
  39.          output_a(i);
  40.          delay_ms(1);
  41.       }
  42.    }
  43.    for(g=0;g<16;g++){
  44.       pwm_duty(0,g,16);
  45.       for(i=0;i<8;i++){
  46.          output_a(i);
  47.          delay_ms(1);
  48.       }
  49.    }
  50.    for(b=16;b>1;b--){
  51.       pwm_duty(0,16,b);
  52.       for(i=0;i<8;i++){
  53.          output_a(i);
  54.          delay_ms(1);
  55.       }
  56.    }
  57.    for(r=0;r<16;r++){
  58.       pwm_duty(r,16,0);
  59.       for(i=0;i<8;i++){
  60.          output_a(i);
  61.          delay_ms(1);
  62.       }
  63.    }
  64.    for(g=16;g>1;g--){
  65.       pwm_duty(16,g,0);
  66.       for(i=0;i<8;i++){
  67.          output_a(i);
  68.          delay_ms(1);
  69.       }
  70.    }
  71. }
  72. void mixRGB(void){
  73.    pwm_duty(8,8,8);
  74.    output_a(0b00000000);
  75.    delay_ms(1);
  76.    pwm_duty(0,0,16);
  77.    output_a(0b00000001);
  78.    delay_ms(1);
  79.    pwm_duty(0,16,0);
  80.    output_a(0b00000010);
  81.    delay_ms(1);
  82.    pwm_duty(0,16,16);
  83.    output_a(0b00000011);
  84.    delay_ms(1);
  85.    pwm_duty(16,0,0);
  86.    output_a(0b00000100);
  87.    delay_ms(1);
  88.    pwm_duty(16,0,16);
  89.    output_a(0b00000101);
  90.    delay_ms(1);
  91.    pwm_duty(16,16,0);
  92.    output_a(0b00000110);
  93.    delay_ms(1);
  94.    pwm_duty(16,16,16);
  95.    output_a(0b00000111);
  96.    delay_ms(1);
  97. }
  98. void flashRGB(void){
  99.    pwm_duty(8,8,8);
  100.    output_a(0b00000000);
  101.    delay_ms(100);
  102.    pwm_duty(0,0,16);
  103.    output_a(0b00000001);
  104.    delay_ms(100);
  105.    pwm_duty(0,16,0);
  106.    output_a(0b00000010);
  107.    delay_ms(100);
  108.    pwm_duty(0,16,16);
  109.    output_a(0b00000011);
  110.    delay_ms(100);
  111.    pwm_duty(16,0,0);
  112.    output_a(0b00000100);
  113.    delay_ms(100);
  114.    pwm_duty(16,0,16);
  115.    output_a(0b00000101);
  116.    delay_ms(100);
  117.    pwm_duty(16,16,0);
  118.    output_a(0b00000110);
  119.    delay_ms(100);
  120.    pwm_duty(16,16,16);
  121.    output_a(0b00000111);
  122.    delay_ms(100);
  123. }
  124. void coloresRGB(int r, int g, int b){
  125.    int i;
  126.    for(i=0;i<8;i++){
  127.       pwm_duty(r,g,b);
  128.       for(i=0;i<8;i++){
  129.          output_a(i);
  130.          delay_ms(1);
  131.       }
  132.    }
  133. }
  134. void main(){
  135.    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
  136.    set_timer0(0);
  137.    enable_interrupts(INT_TIMER0);
  138.    enable_interrupts(GLOBAL);
  139.    while(true){
  140.       int i, r, g, b;
  141.       for(i=0;i<5;i++)
  142.          fadeRGB();
  143.       for(i=0;i<100;i++)
  144.          mixRGB();
  145.       for(i=0;i<10;i++)
  146.          flashRGB();
  147.       for(r=0;r<8;r++)
  148.          for(i=0;i<100;i++)
  149.             coloresRGB(b,g,r);
  150.       for(g=0;g<8;g++)
  151.          for(i=0;i<100;i++)
  152.             coloresRGB(b,g,r);
  153.       for(b=0;b<8;b++)
  154.          for(i=0;i<100;i++)
  155.             coloresRGB(b,g,r);
  156.    }
  157. }

Con Arduino

  1. int led_R=9, led_G=10, led_B=11,
  2.     Mux_0=5, Mux_1=6, Mux_2=7;
  3. void setup(){
  4.    pinMode(led_R, OUTPUT);
  5.    pinMode(led_G, OUTPUT);
  6.    pinMode(led_B, OUTPUT);
  7.    pinMode(Mux_0, OUTPUT);
  8.    pinMode(Mux_1, OUTPUT);
  9.    pinMode(Mux_2, OUTPUT);
  10. }
  11. void pwm_duty(int r, int g, int b){
  12.    analogWrite(led_R, map(r,0,16,0,255));
  13.    delay(10);
  14.    analogWrite(led_G, map(g,0,16,0,255));
  15.    delay(10);
  16.    analogWrite(led_B, map(b,0,16,0,255));
  17.    delay(10);
  18. }
  19. void output_c(int valor){
  20.    switch(valor){
  21.    case 0:
  22.       digitalWrite(Mux_0, LOW);
  23.       digitalWrite(Mux_1, LOW);
  24.       digitalWrite(Mux_2, LOW);
  25.       break;  
  26.    case 1:
  27.       digitalWrite(Mux_0, HIGH);
  28.       digitalWrite(Mux_1, LOW);
  29.       digitalWrite(Mux_2, LOW);
  30.       break;  
  31.    case 2:
  32.       digitalWrite(Mux_0, LOW);
  33.       digitalWrite(Mux_1, HIGH);
  34.       digitalWrite(Mux_2, LOW);
  35.       break;  
  36.    case 3:
  37.       digitalWrite(Mux_0, HIGH);
  38.       digitalWrite(Mux_1, HIGH);
  39.       digitalWrite(Mux_2, LOW);
  40.       break;  
  41.    case 4:
  42.       digitalWrite(Mux_0, LOW);
  43.       digitalWrite(Mux_1, LOW);
  44.       digitalWrite(Mux_2, HIGH);
  45.       break;  
  46.    case 5:
  47.       digitalWrite(Mux_0, HIGH);
  48.       digitalWrite(Mux_1, LOW);
  49.       digitalWrite(Mux_2, HIGH);
  50.       break;  
  51.    case 6:
  52.       digitalWrite(Mux_0, LOW);
  53.       digitalWrite(Mux_1, HIGH);
  54.       digitalWrite(Mux_2, HIGH);
  55.       break;  
  56.    case 7:
  57.       digitalWrite(Mux_0, HIGH);
  58.       digitalWrite(Mux_1, HIGH);
  59.       digitalWrite(Mux_2, HIGH);
  60.       break;  
  61.    }
  62. }
  63. void fadeRGB(void){
  64.    int r, g, b, i;
  65.    for(b=0;b<16;b++){
  66.       pwm_duty(16,0,b);
  67.       for(i=0;i<8;i++){
  68.          output_c(i);
  69.          delay(1);
  70.       }
  71.    }
  72.    for(r=16;r>1;r--){
  73.       pwm_duty(r,0,16);
  74.       for(i=0;i<8;i++){
  75.          output_c(i);
  76.          delay(1);
  77.       }
  78.    }
  79.    for(g=0;g<16;g++){
  80.       pwm_duty(0,g,16);
  81.       for(i=0;i<8;i++){
  82.          output_c(i);
  83.          delay(1);
  84.       }
  85.    }
  86.    for(b=16;b>1;b--){
  87.       pwm_duty(0,16,b);
  88.       for(i=0;i<8;i++){
  89.          output_c(i);
  90.          delay(1);
  91.       }
  92.    }
  93.    for(r=0;r<16;r++){
  94.       pwm_duty(r,16,0);
  95.       for(i=0;i<8;i++){
  96.          output_c(i);
  97.          delay(1);
  98.       }
  99.    }
  100.    for(g=16;g>1;g--){
  101.       pwm_duty(16,g,0);
  102.       for(i=0;i<8;i++){
  103.          output_c(i);
  104.          delay(1);
  105.       }
  106.    }
  107. }
  108. void mixRGB(void){
  109.    pwm_duty(0,0,0);
  110.    output_c(0);
  111.    delay(1);
  112.    pwm_duty(0,0,16);
  113.    output_c(1);
  114.    delay(1);
  115.    pwm_duty(0,16,0);
  116.    output_c(2);
  117.    delay(1);
  118.    pwm_duty(0,16,16);
  119.    output_c(3);
  120.    delay(1);
  121.    pwm_duty(16,0,0);
  122.    output_c(4);
  123.    delay(1);
  124.    pwm_duty(16,0,16);
  125.    output_c(5);
  126.    delay(1);
  127.    pwm_duty(16,16,0);
  128.    output_c(6);
  129.    delay(1);
  130.    pwm_duty(16,16,16);
  131.    output_c(7);
  132.    delay(1);
  133. }
  134. void flashRGB(void){
  135.    pwm_duty(8,8,8);
  136.    output_c(0);
  137.    delay(100);
  138.    pwm_duty(0,0,16);
  139.    output_c(1);
  140.    delay(100);
  141.    pwm_duty(0,16,0);
  142.    output_c(2);
  143.    delay(100);
  144.    pwm_duty(0,16,16);
  145.    output_c(3);
  146.    delay(100);
  147.    pwm_duty(16,0,0);
  148.    output_c(4);
  149.    delay(100);
  150.    pwm_duty(16,0,16);
  151.    output_c(5);
  152.    delay(100);
  153.    pwm_duty(16,16,0);
  154.    output_c(6);
  155.    delay(100);
  156.    pwm_duty(16,16,16);
  157.    output_c(7);
  158.    delay(100);
  159. }
  160. void coloresRGB(int r, int g, int b){
  161.    int i;
  162.    for(i=0;i<8;i++){
  163.       pwm_duty(r,g,b);
  164.       for(i=0;i<8;i++){
  165.          output_c(i);
  166.          delay(1);
  167.       }
  168.    }
  169. }
  170. void loop(){
  171.    int i, r, g, b;
  172.    for(i=0;i<5;i++)
  173.       fadeRGB();
  174.    for(i=0;i<100;i++)
  175.       mixRGB();
  176.    for(i=0;i<10;i++)
  177.       flashRGB();
  178.    for(r=0;r<8;r++)
  179.       for(i=0;i<100;i++)
  180.          coloresRGB(b,g,r);
  181.    for(g=0;g<8;g++)
  182.       for(i=0;i<100;i++)
  183.          coloresRGB(b,g,r);
  184.    for(b=0;b<8;b++)
  185.       for(i=0;i<100;i++)
  186.          coloresRGB(b,g,r);
  187. }