Home > Arduino > Arduino RGB LED Controller

Arduino RGB LED Controller

August 23rd, 2011 Leave a comment Go to comments

When reorganizing our stock I found a whole bunch of diffused RGB LEDs (>100pcs) so I thought I would make something cool with them. Maybe some kind of individual controllable christmas light or some lights you could use for showcases etc.

RGB LEDs


So I decided once again to make a project using the Arduino Duemilanove, as it is so quick and easy to get a prototype working.
After some brainstorming, thinking about how I should do the PWM multiplexing, I designed a circuit capable of driving 8 individual RGB LEDs using 11 pins. The project would be easily expandable and would only cost 1 extra pin for each extra RGB LED.

Multiplexed RGB LED Circuit


On the schematic above you will see how I decided to use an ULN2803 for the multiplex “enabling”, though it can sinc up to 500mA, this circuit only requires a maximum of 75mA pr. LED – and because of the multiplexing this would actually only be a maximum of 75mA in total.
For the driving of each color I am using 3 PNP transistors (BC557), capable of driving 100mA – more than enough for a single color. The limiting resistors are set to about 25mA for each color (1.9V dropout on RED, 0.7V on green and blue)

Here is a short video demonstration of the circuit connected to the Arduino, displaying colors from the HSV Color model


The multiplexing is done using TIMER2 on the Arduino, which unfortunately also is used by the PWM. This took my some time to figure out a smart way (if it is) to deal with this, as the PWM frequency has to be higher than the multiplexing frequency to avoid random flickering.

I achived this by increasing the PWM frequency of the used PWM channels (9, 10, 11), which is located at TIMER2 and TIMER3. Then I set the TIMER2 to interrupt at overflow and made a prescaler in that interrupt, so the multiplex function would only be called once in a while.

The code used in the demonstration can be found beneath.

unsigned char Prescaler = 0;
#define PrescalerOverflowValue 4
ISR(TIMER2_OVF_vect)
{
  if (Prescaler < PrescalerOverflowValue)
    Prescaler++;
  else {
    Prescaler = 0;
    Multiplex();
  }
}


unsigned char CurrentLED = 1;
unsigned char LEDValues[8][3];
bool LEDMoveDir[8][3];
void Multiplex(void)
{
  PORTD &= 0b00000011; // Control pin 0-5
  PORTB &= 0b11101110; // Control pin 6-7

  analogWrite(9, 255-LEDValues[CurrentLED][0]);
  analogWrite(10, 255-LEDValues[CurrentLED][1]);
  analogWrite(11, 255-LEDValues[CurrentLED][2]);

  switch (CurrentLED)
  {
    case 0:
      //digitalWrite(2, 1); // Turn on LED 1
      PORTD |= 0b00000100;
      break;
    case 1:
      //digitalWrite(3, 1); // Turn on LED 1
      PORTD |= 0b00001000;
      break;
    case 2:
      //digitalWrite(4, 1); // Turn on LED 1
      PORTD |= 0b00010000;
      break;
    case 3:
      //digitalWrite(5, 1); // Turn on LED 1
      PORTD |= 0b00100000;
      break;
    case 4:
      //digitalWrite(6, 1); // Turn on LED 1
      PORTD |= 0b01000000;
      break;
    case 5:
      //digitalWrite(7, 1); // Turn on LED 1
      PORTD |= 0b10000000;
      break;
    case 6:
      //digitalWrite(8, 1); // Turn on LED 1
      PORTB |= 0b00000001;
      break;
    case 7:
      //digitalWrite(12, 1); // Turn on LED 1
      PORTB |= 0b00010000;
      break;
  }

  CurrentLED++;
  if (CurrentLED > 7)
    CurrentLED = 0;
}

void setPwmFrequency(int pin, int divisor) {
  byte mode;
  if(pin == 5 || pin == 6 || pin == 9 || pin == 10) {
    switch(divisor) {
      case 1: mode = 0x01; break;
      case 8: mode = 0x02; break;
      case 64: mode = 0x03; break;
      case 256: mode = 0x04; break;
      case 1024: mode = 0x05; break;
      default: return;
    }
    if(pin == 5 || pin == 6) {
      TCCR0B = TCCR0B & 0b11111000 | mode;
    } else {
      TCCR1B = TCCR1B & 0b11111000 | mode;
    }
  } else if(pin == 3 || pin == 11) {
    switch(divisor) {
      case 1: mode = 0x01; break;
      case 8: mode = 0x02; break;
      case 32: mode = 0x03; break;
      case 64: mode = 0x04; break;
      case 128: mode = 0x05; break;
      case 256: mode = 0x06; break;
      case 1024: mode = 0x7; break;
      default: return;
    }
    TCCR2B = TCCR2B & 0b11111000 | mode;
  }
}

int Red, Green, Blue;
int Hue1, Hue2, Hue3, Hue4, Hue5, Hue6, Hue7, Hue8, Saturation, Value;
void setup(void) {
  //Set the pin we want the ISR to toggle for output.
  pinMode(2,OUTPUT);
  pinMode(3,OUTPUT);
  pinMode(4,OUTPUT);
  pinMode(5,OUTPUT);
  pinMode(6,OUTPUT);
  pinMode(7,OUTPUT);
  pinMode(8,OUTPUT);
  pinMode(12,OUTPUT);

  pinMode(9,OUTPUT);
  pinMode(10,OUTPUT);
  pinMode(11,OUTPUT);

  digitalWrite(2, 0); // Turn off LED 4
  digitalWrite(3, 0); // Turn off LED 4
  digitalWrite(4, 0); // Turn off LED 4
  digitalWrite(5, 0); // Turn off LED 4
  digitalWrite(6, 0); // Turn off LED 4
  digitalWrite(7, 0); // Turn off LED 4
  digitalWrite(8, 0); // Turn off LED 4
  digitalWrite(12, 0); // Turn off LED 4

  digitalWrite(9, 1);
  digitalWrite(10, 1);
  digitalWrite(11, 1);

  setPwmFrequency(9, 8);
  setPwmFrequency(10, 8);
  setPwmFrequency(11, 8);
  analogWrite(9, 255);
  analogWrite(10, 255);
  analogWrite(11, 255);

  LEDValues[0][0] = 100;
  LEDValues[0][1] = 0;
  LEDValues[0][2] = 20;

  LEDValues[1][0] = 0;
  LEDValues[1][1] = 30;
  LEDValues[1][2] = 144;

  LEDValues[2][0] = 66;
  LEDValues[2][1] = 245;
  LEDValues[2][2] = 3;

  LEDValues[3][0] = 30;
  LEDValues[3][1] = 30;
  LEDValues[3][2] = 200;

  //Start up the serial port
  Serial.begin(19200);

  //Signal the program start
  Serial.println("RGB LED Controller");

  // Enable Timer 2 interrupt (also used for PWM though)
  // This interrupt is divided by a prescaler, and takes care of the multiplexing
  TIMSK2 = 1<<toie2;

  Hue1 = 0;
  Hue2 = 10;
  Hue3 = 20;
  Hue4 = 30;
  Hue5 = 40;
  Hue6 = 50;
  Hue7 = 60;
  Hue8 = 70;
  Saturation = 255;
  Value = 255;
}

unsigned char incomingByte = 0;
unsigned char getNumPos = 0;
unsigned char tempNum = 0;
unsigned char LEDSetNum = 0;
unsigned char LEDSetColor = 0;

void loop(void)
{
    delay(20);
    HSVtoRGB(&Red, &Green, &Blue, Hue1, Saturation, Value);

    LEDValues[0][0] = Red;
    LEDValues[0][1] = Green;
    LEDValues[0][2] = Blue;

    Hue1++;
    if (Hue1 > 359)
      Hue1 = 0;

    HSVtoRGB(&Red, &Green, &Blue, Hue2, Saturation, Value);

    LEDValues[1][0] = Red;
    LEDValues[1][1] = Green;
    LEDValues[1][2] = Blue;

    Hue2++;
    if (Hue2 > 359)
      Hue2 = 0;

    HSVtoRGB(&Red, &Green, &Blue, Hue3, Saturation, Value);

    LEDValues[2][0] = Red;
    LEDValues[2][1] = Green;
    LEDValues[2][2] = Blue;

    Hue3++;
    if (Hue3 > 359)
      Hue3 = 0;

    HSVtoRGB(&Red, &Green, &Blue, Hue4, Saturation, Value);

    LEDValues[3][0] = Red;
    LEDValues[3][1] = Green;
    LEDValues[3][2] = Blue;

    Hue4++;
    if (Hue4 > 359)
      Hue4 = 0;

    HSVtoRGB(&Red, &Green, &Blue, Hue5, Saturation, Value);

    LEDValues[4][0] = Red;
    LEDValues[4][1] = Green;
    LEDValues[4][2] = Blue;

    Hue5++;
    if (Hue5 > 359)
      Hue5 = 0;

    HSVtoRGB(&Red, &Green, &Blue, Hue6, Saturation, Value);

    LEDValues[5][0] = Red;
    LEDValues[5][1] = Green;
    LEDValues[5][2] = Blue;

    Hue6++;
    if (Hue6 > 359)
      Hue6 = 0;

    HSVtoRGB(&Red, &Green, &Blue, Hue7, Saturation, Value);

    LEDValues[6][0] = Red;
    LEDValues[6][1] = Green;
    LEDValues[6][2] = Blue;

    Hue7++;
    if (Hue7 > 359)
      Hue7 = 0;

    HSVtoRGB(&Red, &Green, &Blue, Hue8, Saturation, Value);

    LEDValues[7][0] = Red;
    LEDValues[7][1] = Green;
    LEDValues[7][2] = Blue;

    Hue8++;
    if (Hue8 > 359)
      Hue8 = 0;
}

void HSVtoRGB( int  *r, int *g,int *b, int h, int s, int v )
{
        int f;
        long p, q, t;

        if( s == 0 )
        {
                *r = *g = *b = v;
                return;
        }

        f = ((h%60)*255)/60;
        h /= 60;

       p = (v * (256 - s)) / 256;
       q = (v * ( 256 - (s * f)/256 ))/256;
       t = (v * ( 256 - (s * ( 256 - f ))/256))/256;

        switch( h ) {
                case 0:
                        *r = v;
                        *g = t;
                        *b = p;
                        break;
                case 1:
                        *r = q;
                        *g = v;
                        *b = p;
                        break;
                case 2:
                        *r = p;
                        *g = v;
                        *b = t;
                        break;
                case 3:
                        *r = p;
                        *g = q;
                        *b = v;
                        break;
                case 4:
                        *r = t;
                        *g = p;
                        *b = v;
                        break;
                default:
                        *r = v;
                        *g = p;
                        *b = q;
                        break;
        }
}

After playing around with the low-power diffused RGB LEDs I thought it was time for some more luminance so we ordered a couple of 1W RGB LEDs – 150mA for each color. After some redesign, using a BC327 (1A) instead, I hooked up the LED and was shocked by the brightness. It’s difficult to show on camera how bright they really are, but I shot a couple of short clips with them.

Categories: Arduino Tags:
  1. Jesús
    December 7th, 2011 at 04:07 | #1

    What’s the difference between the Duemilanove and the Uno? Is this circuit capable for another 8 LEDs connected in parallel one by one?

    Thanks.

  2. John
    December 8th, 2011 at 05:34 | #2

    Hi,

    The way you control the LEDs is very interesting! Did you use the concept of “Persistent of Vision” to cycle through the LEDs really fast? Meaning, you enabled LED1, sent PWM signals to LED1, disabled LED1, enabled LED2, sent PWM signals to LED2, disabled LED2…..all done really fast?

  3. December 8th, 2011 at 21:45 | #3

    @John
    Hi John.
    Yes we are using the persistent of vision technique, which in the electronics world is also known as multiplexing.
    The multiplexing is done in an interrupt routine, controlled by a timer. Have a look at the code and the multiplex() routine to see how it works.

    Best Regards
    Thomas Jespersen

  4. December 8th, 2011 at 21:48 | #4

    @Jesús
    The difference is not much. The board layout and functionality is exactly the same, and they are using the same processor: ATMEGA328.

    The only difference is that the UNO is the most recent Arduino board, and they decided to use another chip for the USB to serial conversion (programming etc.). So instead of using an FTDI FT232 chip, they are now using another Atmel microprocessor for the USB to UART conversion (Atmega16U2).

    Best Regards
    Thomas Jespersen

  5. Nadia Zeghloul
    December 9th, 2011 at 10:58 | #5

    Hello
    Already I want to apologize for my English … I’m French
    ^ ^
    I found your article on Arduino RGB LED Controller
    (http://blog.tkjelectronics.dk/2011/08/arduino-rgb-led-
    controller/).
    I want to make a suit with LEDs inside, I’ve already
    made one last year: http://www.youtube.com/watch?
    v=meBAXw0mf0Y
    But this time I use RGB LED to play with colors, not just
    the effect of delayed ignition LED
    I buy LED RGB common cathode:
    I made a ProtoBoard with 6 LED arduino to test my
    program and my mount, so far so good … except for now
    I only have six LEDs connected to my card … as I have
    to plug in between 200 and 300, I need more ULN2803
    of course … but the question is should I also use
    another component for the RGB output …
    Here is a diagram to explain:
    http://www.mimigyaru.com/autres/cosplay/Maiotome/sh
    emas_RGB.jpg
    … I guess I’m missing a component between the RGB
    outputs of the Arduino board and pulp of LED …

    if you could advise me! it would be really cool!

    thank you in advance!

  6. December 10th, 2011 at 13:53 | #6

    @Nadia Zeghloul
    Hi Nadia.
    Actually your circuit seems to be fine, as you are using the ULN2803 devices as you should for the sincing. The Arduino board is able to source up to 40mA per pin, so as long as you only drive a single LED a time, you would definitely be able to use this setup.
    But if you switch out the LEDs to some high power ones, as I did, you will have to add some driving/sourcing transistors at the common RED, GREEN and BLUE connection.

    But for your project I will say your schematic and setup will work fine.

    Best Regards
    Thomas Jespersen

  7. Nadia Zeghloul
    December 12th, 2011 at 15:32 | #7

    @Thomas Jespersen So If I have an LED DC Forward Current: 20mA
    I have 270 LED in the costume I calculated it would take me 2 to ULN2803 pin cathode, I will need how many transistor for RGB ports … knowing that the moment I plugged 6LED of the RGB port (and that each LED is then connected to a pin for the A output … and it did not scorched my card …)

  8. December 12th, 2011 at 17:26 | #8

    @Nadia Zeghloul
    Dear Nadia.
    Unfortunately I don’t understand how you are trying to connect all those LEDs.
    Do you want all to be individual controllable, or should some of them be alight simultaneously?

    Best Regards
    Thomas Jespersen

  9. Nadia Zeghloul
    December 13th, 2011 at 08:31 | #9

    ok ^ ^ I start again:
    I have my Arduino board, on the pins 11, 10 and 9 are respectively connected the inputs R, G and B of all the LED (as on the diagram above). For all the costume LED should change color at the same time!
    However they will not all be lit simultaneously: I simply put 6 different LED, multiply by 45 to get the number of LED 270;
    So the LEDs A, B, C, D, E and F are respectively connected to Pin A0, A1, A2, A3, A4 and A5. And since there are many LED between the cathodes of the LEDs and Arduino I put two ULN2803.
    Wholesale it’s like on the diagram, except that instead of having 3 LEDs per color that I would have 45!
    Knowing that the moment my ProtoBoard is exactly like on the diagram, except that I only have one LED per color! and it works perfectly, I did not even put resistance between my card and my LED! LEDs are a DC Forward Current 20mA Reverse Voltage and 5.0 V:

    http://www.ebay.com/itm/370262039446?item=370262039446&pt=Motors_Car_Truck_Parts_Accessories&cmd=ViewItem&hash=item5635565b96&vxp=mtr#ht_3465wt_952

    So my question is do I really add the transistor and if so how many, and what are their references?

  10. Jesús
    December 20th, 2011 at 00:04 | #10

    @Thomas Jespersen
    Thanks for you reply,

    So, I can use the UNO instead the Duemilanove. Which is better to work with a Mac? And, regarding another question I asked before, is this circuit capable for another 16 LEDs connected in parallel one by one?

    Best regards,

    Jesús

  11. September 10th, 2012 at 03:40 | #11

    Thomas,
    I’m not an engineer, but I am wondering if there are enough I/O on an arduino to multiplex 2 of ULN controllers to be able to control 16 separate LED.

  12. September 14th, 2012 at 21:01 | #12

    @Bryan
    The Arduino Uno itself only have 13 digital pins that is compatible with the digitalWrite function.
    But to be true the 5 analog input pins is actually just simple GPIO pins on the ATMEGA who have an alternate function as AD input. To use these pins you can simply write “digitalWrite(A0, HIGH);” etc.
    So if you take these 5 pins into account you would have a total of 18 pins, which will make it possible to multiplex 16 seperate LEDs but only with two colors (as you only have to pins left for the PWM).
    Another option would be to use a Shift register like the 74HC595 which gives you 8 outputs per chip and only requires 3 pins. But the most important thing is that you can chain them without any extra pins required.

  13. Chris
    October 3rd, 2012 at 07:08 | #13

    Is it possible to control the leds individually? so say i want to give each led a different color by retrieving values from a kind of ‘database’

    And i read often that the uln2803a is not suited for common cathode leds, do you know more about that? (i have these: https://www.sparkfun.com/products/10390)

    Kind regards,
    Chris

  14. October 8th, 2012 at 18:40 | #14

    @Chris
    Hi Chris.
    I agree that it can be a bit confusing whether or not the ULN2803 can be used to sink or source current.
    I have been looking and reading much on this IC recently and I can’t come up with any good explanation that our schematic works based solely on the datasheet.
    But you might find this page interesting and descriptive regarding this discussion: http://jaspreetscodezone.blogspot.dk/2008/02/uln-2803-pinout-working.html

    But as you can see with this project you are able to sink current and drive common cathode LEDs through the ULN2803. The maximum allowed sinking current is untested though!

    Regards Thomas

  15. Pargit
    October 16th, 2012 at 19:25 | #15

    hi,
    nice web site man.
    i tried building this circute but found out that my rgb leds are common anode and not common cathode.
    how can i change the code to work with the leds i have?
    i’m new to electronics so any help is appreciated.
    thanks
    Mor

  16. October 16th, 2012 at 22:36 | #16

    @Pargit
    Hi Mor.
    It is actually very simply to change the project to common anodes.
    The ULN chip outputs should still be connected to the common pin, in your case the common anode pin.
    For the 3 cathode pins these should then be connected to 3 BC547 NPN transistors – please notice the difference here as the one in the schematic is PNP transistors. And while the emitter on the PNP transistors were connected to 5V the emitter on the NPN transistor in your case should be connected to GND.
    Then your circuit will work.

    Next is a slight code change were you find the line in the code saying:

    analogWrite(9, 255-LEDValues[CurrentLED][0]);
    analogWrite(10, 255-LEDValues[CurrentLED][1]);
    analogWrite(11, 255-LEDValues[CurrentLED][2]);

    And change it to:

    analogWrite(9, LEDValues[CurrentLED][0]);
    analogWrite(10, LEDValues[CurrentLED][1]);
    analogWrite(11, LEDValues[CurrentLED][2]);

    I hope you can get it working.

    Regards Thomas

  17. Spring
    October 19th, 2012 at 13:13 | #17

    I thank you for the awesome tutorial, and am pleased to say I have 16 or so LEDs shipping in the mail right now for this project. I’m completely new to arduino programming so it’s a tad hard to follow your code (some java experience), but how difficult would it be to have a button that controls the pattern, with the fading lights as one, and perhaps lights flashing down the line as another? What would have to be changed in the code?

  18. October 20th, 2012 at 05:02 | #18

    @Spring
    Thank you for the kind words.

    The only thing for you to change in the code would be all the code inside the loop() function.
    This code should be replaced with your own that set the LEDValues arrays with the color information for each attached LED.

    The timer controller interrupt loop that I made for the multiplexing will then take care of the rest.

    Regards Thomas

  19. Spring
    October 20th, 2012 at 07:13 | #19

    After looking through your code and analyzing it a bit, I think I’ve figured out how it works fairly well. With that I think I’ve got a code snippet that will flash opposite lights on and off at hue[k] (unchanging at the moment) depending on the value of onOffCount. In order to change between these, would it be best to put a switch case controlled by a variable that counts external button presses, and would it be more efficient in the code to disregard the forloop and replace it with static declarations for each variable like in your version? I’m thinking of other patterns to try out right now, but suggestions on the current one are appreciated.

    for(int k=0; k<8; k++)
    {
        HSVtoRGB(&Red, &Green, &Blue, Hue[k], Saturation, Value[k]
        LEDValues[k][0] = Red;
        LEDValues[k][1] = Green;
        LEDValues[k][2] = Blue;

        //Turns every other LED on or off depending on counter
        if (onOffCount < 255)
        {
            if ((k+1)%2 == 0)
                Value[k] = 0;
            else
                Value[k] = 255;
        }
        else
        {
            if ((k+1)%2 == 0)
                Value[k] = 255;
            else
                Value[k] = 0;
        }

        onOffCount++
        if (onOffCount > 511)
            onOffCount = 0;
    }
  20. Spring
    October 25th, 2012 at 13:23 | #20

    Are you sure you pasted the correct code in the box? I copied it line for line and when I ran it, I found that half of the LEDs weren’t lighting. After looking into the setup loop, I found that you forgot to toggle the pinmodes of 6,7,8, and 12 to OUTPUT, as well as zero them out.

    I also found that the entire spectrum sweep was ‘lacking’ in colors; the orange part just looks a dull white, which, after examining the LEDs, leads me to believe that the channels aren’t going from 0-255 as designed, and that the HSVtoRGB void is the culprit, because changing saturation to 0 leaves the LEDs at an unchanging color, (probably 128 in each channel?) and changing the Value ends up with the same effect. (All LEDs that same color, unchanging).

    The biggest confusion I have is that when both saturation and value are at 255, the color goes back to cycling from 128-255 on each value (I believe) but every LED is the same color – there is no separation of hues by 10, and changing hue values in the setup loop doesn’t do anything. If you could check to see if this is your latest code, i would be extremely grateful, as i have a Halloween party to go to on Saturday

    TL;DR: No hue separation, half of pins not initialized, HSVtoRGB probably not working properly.

  21. November 4th, 2012 at 11:50 | #21

    @Spring
    Dear Spring.
    I would say that your code seems fine. I won’t use a switch-case for this.
    Though I guess you should move the HSVtoRGB and LEDValues setting just above the onOffCount++ so you use the latest Value[k] when setting the LED colors.
    As your code is now the LEDs will be updated, but 1 cycle shifted.

    I will get back to you about the code errors, though I don’t remember anything to be wrong.
    But as I still have the project on a breadboard I will test it for you and make a reply soon.

    Best Regards
    Thomas Jespersen

  22. November 4th, 2012 at 12:29 | #22

    @Spring
    Dear Spring.
    I have now tested the code, and you were right that I was missing the initialization of the 4 last output pins. I have now updated the code in the blog post.
    But even before I didn’t experience the issues you are talking about with the hues – all of my LEDs are changing colors (hues) as demonstrated in the video.

    Regards Thomas

  23. Pargit
    November 21st, 2012 at 06:42 | #23

    Hi Thomas,
    i have managed to build the circute, and tried to change it to work with 74595 chip (instead of using 8 legs on the ardu.
    i have changed the code of the first functions as such:

    unsigned char Prescaler = 0;
    #define PrescalerOverflowValue 4
    ISR(TIMER2_OVF_vect)
    {
      if (Prescaler  7)
        CurrentLED = 0;
    }

    void setPwmFrequency(int pin, int divisor) {
      byte mode;
      if(pin == 5 || pin == 6 || pin == 9 || pin == 10) {
        switch(divisor) {
          case 1: mode = 0x01; break;
          case 8: mode = 0x02; break;
          case 64: mode = 0x03; break;
          case 256: mode = 0x04; break;
          case 1024: mode = 0x05; break;
          default: return;
        }
        if(pin == 5 || pin == 6) {
          TCCR0B = TCCR0B &amp; 0b11111000 | mode;
        } else {
          TCCR1B = TCCR1B &amp; 0b11111000 | mode;
        }
      } else if(pin == 3 || pin == 11) {
        switch(divisor) {
          case 1: mode = 0x01; break;
          case 8: mode = 0x02; break;
          case 32: mode = 0x03; break;
          case 64: mode = 0x04; break;
          case 128: mode = 0x05; break;
          case 256: mode = 0x06; break;
          case 1024: mode = 0x7; break;
          default: return;
        }
        TCCR2B = TCCR2B &amp; 0b11111000 | mode;
      }
    }

    int Red, Green, Blue;
    int Hue1, Hue2, Hue3, Hue4, Hue5, Hue6, Hue7, Hue8, Saturation, Value;
    void setup(void) {

      pinMode(latchPin, OUTPUT);
      pinMode(clockPin, OUTPUT);
      pinMode(dataPin, OUTPUT);

      digitalWrite(9, 1);
      digitalWrite(10, 1);
      digitalWrite(11, 1);

      setPwmFrequency(9, 8);
      setPwmFrequency(10, 8);
      setPwmFrequency(11, 8);
      analogWrite(9, 255);
      analogWrite(10, 255);
      analogWrite(11, 255);

      //Start up the serial port
      Serial.begin(19200);

      //Signal the program start
      Serial.println("RGB LED Controller");

      // Enable Timer 2 interrupt (also used for PWM though)
      // This interrupt is divided by a prescaler, and takes care of the multiplexing
      TIMSK2 = 1&lt;&lt;TOIE2;

      Hue1 = 0;
      Hue2 = 10;
      Hue3 = 20;
      Hue4 = 30;
      Hue5 = 40;
      Hue6 = 50;
      Hue7 = 60;
      Hue8 = 70;
      Saturation = 255;
      Value = 255;
    }

    unsigned char incomingByte = 0;
    unsigned char getNumPos = 0;
    unsigned char tempNum = 0;
    unsigned char LEDSetNum = 0;
    unsigned char LEDSetColor = 0;

    this is not working now. i'm trying to find what is wrong, my guess is that i have somthing wrong with the setup of the ISR timers. can you check my code?

    thanks
    Mor

  24. November 25th, 2012 at 14:06 | #24

    @Pargit
    Hi Pargit.
    Have you pasted all the code in this comment, as it seems very incomplete to me?

    The ISR fx isn’t doing the counting as supposed to.
    The only thing it seems to be doing is setting the CurrentLED to 0 if Prescaler is 7, though Prescaler is never changed.

    Regards Thomas

  25. Pargit
    November 26th, 2012 at 14:58 | #25

    Hi Thomas,
    i’m trying to paste the whole code but it keeps trimming the same part of the multiplex() function (which is the one i have alterd).
    i paste it here: http://pastebin.com/z2qE1QWA you can se with the remarks the ways i tried to make it work. because i have trying to send to serial the number of led that is on and not seeing it in the console, my guess is that i’m not getting into the multiplex function at all.

    hope you can help.

    Pargit

  26. December 23rd, 2012 at 15:05 | #26

    @Pargit
    Please make sure that you are using an ATMEGA168 or ATMEGA328 Arduino board, as I’m relying on Timer 2, used for the PWM generation on pin 11, to generate the Multiplex interrupts.
    If not, try and move your test line, “DDRD = DDRD | B11111100;”, as the first line inside the ISR.

    Merry christmas.

    Regards Thomas

  27. Ron Jad
    March 13th, 2013 at 20:28 | #27

    Why is the ULN2803a needed can’t you just add it to Ground?

  28. Ron Jad
    March 13th, 2013 at 20:34 | #28

    I meant to say can’t you connect the the cathode to ground instead of the ULN2803a @Ron Jad

  29. March 13th, 2013 at 23:18 | #29

    @Ron Jad
    If you simply connect all of the cathodes to ground all the RGB LEDs will be lit at the same time and with the same color.
    By doing this you will eliminate the multiplexing option and the option to set individual colors on each RGB LED.

  30. July 12th, 2013 at 05:22 | #30

    Hello. I would like to try out this project but I have a few questions if I may. On the circuit schematic it indicates BC 857 transistors, but in the description it says BC557. Which is correct please? Also, seeing as how it looks like you are setting the ports via direct port manipulation, just to clarify, the LEDâ??s are connected to digital pins 2, 3, 4, 5, 6, 7, 8 and 12 and the transistors to digital pins 9, 10 and 11. Thanks for your help and I look forward to trying to understand your code as I implement your project, thanks Pedro.

  31. Diego
    August 18th, 2013 at 20:25 | #31

    hello thomas! Thanks for giving your projects! I am new to the programming of Arduino, which would have to modify in the program to work with Arduino MEGA2560. Thanks you very much !!

  32. Diego
    August 26th, 2013 at 20:27 | #32

    I solved the error!, As could do that through a switch that make LED white strobe effect! Thanks you

  33. August 26th, 2013 at 21:30 | #33

    @Peter Newman
    BC557 and BC857 is the same, a PNP transistor. The only difference is the package.
    And yes, you are correct about the pins!
    Good luck.

    Regards Thomas

  34. Alexander
    October 11th, 2013 at 02:46 | #34

    Hi,

    Do you have an Eagle .brd file for this? I love the project, however i’m not that good in creating a board.

    Thanks,
    Alexander

  35. October 15th, 2013 at 21:56 | #35

    @Alexander
    Hi Alexander.
    Thank you for your kind comment.
    Unfortunately there is no board layout for this project as we have simply made a test setup on the breadboards as shown in the video and not turned the project into a PCB.
    Furthermore the schematic is made in Altium so isn’t compatible with Eagle either.

    If you are interested we can help you creating the board. Feel free to contact me at thomas (at) tkjelectronics.dk

    Regards Thomas

  36. Peter Newman
    October 23rd, 2013 at 06:08 | #36

    @Thomas Jespersen

    Thank you for that info Thomas

  37. Prince gauatm
    November 10th, 2013 at 19:15 | #37

    if i dont want to use a arduino board is their any other way for controling RGB led
    plzz reply

  38. Will
    November 17th, 2013 at 23:56 | #38

    Hi
    I have been got the circuit working well with 3 common cathode RGB LEDs ( that’s all I had) however I have a few hundred common anode LEDs, so I have tried one of the above suggestions to get it working with common anode.
    I get nothing, how is it possible to get the ULN device to source not sink

  39. Karlinet
    January 17th, 2014 at 05:44 | #39

    Genial! felicidades y muchas gracias

  40. January 18th, 2014 at 10:06 | #40

    @Prince gauatm
    There is many ways that you can control RGB LEDs. This project can be used with any microcontroller application, you just have to change the code accordingly.
    But if you don’t want to make your own system you can also buy consumer RGB LED products that comes with a wireless remote control for changing colors.

  41. January 18th, 2014 at 10:18 | #41

    @Will
    The ULN2803 can only be used to source current. Sourcing drivers are simply not as common as sinking drivers.
    Though UDN2981 or TD62783 would be two options for you.

    Regards Thomas

  42. anon
    August 3rd, 2014 at 21:35 | #42

    how do i increase the output voltage? i want this to work with 10 w rgb leds so i need output with at lest 12 v

  43. Rayvanne
    August 17th, 2014 at 17:07 | #43

    Good day can you cover the program into mikroC i can’t understand some of the functions in the program.And im using PICkit2 my compilier is mikroC it is hard in my part to understand some of those function thank you sir

  44. Hannah
    August 19th, 2014 at 08:37 | #44

    Hi.. I tried simulating this in proteus using pic16f84a. I Connected all PORTB pins in the input of pins of ULN2803. then the bases of the transistors to A0 (R), A1 (G), A2 (B). I used a very simple code. I just wanna light up all the leds so I feed up all logic (1) Coz I understand Uln2805 has inverter in it.. It wont light though. Why? Thanks. I wanna build a led chaser to. My problem is the circuit.

  45. August 27th, 2014 at 20:59 | #45

    @anon
    Why do you need 12V? The single RGB diodes only requires about 2V (difference between the colors).
    To drive the 10W though you would need a high-power MOSFET driver for the current sourcing as well as sinking – replacing both the PNP transistors and the ULN2803A chip!

  46. August 27th, 2014 at 21:02 | #46

    @Rayvanne
    It would be easier for me to explain you the parts that you don’t understand as both Arduino and mikroC is based on the C-language.
    And except for pinMode, digitalWrite, analogWrite and the Serial writes the code should be completely portable and used in mikroC!

  47. August 27th, 2014 at 21:06 | #47

    @Hannah
    It’s true that the input ports of the ULN2803 is inverted if you were using the ULN2803 to source current.
    But in our case we are using the ULN2803 to sink the cathode currents, and therefor writing 1 to the input will make the output 0 which is the same as GND therefor sinking the current.
    Maybe your simulator doesn’t understand this usecase?

    I hope this gives you a bit better understanding of the circuit.

  48. January 23rd, 2015 at 11:34 | #48

    Hi !
    I’m trying to make something similar with 1W white led.
    You wrote : “After some redesign, using a BC327 (1A) instead”. What was this redesign ? I tried to replace BC357 by BC327 but I hava a little problem :
    PWM = 0 : 100% of the light
    PWM = 255 : always on, maybe 80% of the light

    Can I replace BC357 by 2SA1599 to have exactly the same working with small led ?
    Thanks

  49. February 3rd, 2015 at 14:31 | #49

    @Gloup
    You can indeed change the upper PNP transistors to BC327 to allow more current, but what have you then done about your sinking driver.
    The ULN2803 in the bottom is only capable of sinking 500mA per input. So this sinking chip with the darlington-pairs needs to be replaced as well.

    For these higher currents I would recommend you to make your own darlington-pair with individual transistors!

  50. Teresa
    April 6th, 2015 at 19:24 | #50

    Hi,
    So I’m working on a costume and sewing is where my skills are. I’m still learning all the electrical parts of it. I’m using RGB LEDs and having the color switch from pink to blue. It also has sound effects when it switches. I’m using Fiber Optic fabric, the fiber optics are woven with in the fabric and then at one end the fibers are connected to the RGB lights. Sever lights through the costume about 10 total. I hooked up part of the skirt last night and although it worked, not very bright. So i was looking at the High Power LEDs you where using. I found some to buy but I can’t find alot of tutorials with people using them. I’m tring to figure out will they work with my board? do I need resistors? Any help you could give would be appreciated! My board only has 14 PWM pins, I’m looking at the MA wondering if its even possible for me to use these. I’ve got three lights connected in parallel to 3 pins for 1/2 skirt, same for the other half. Then two connected in parallel for half the top of the dress and same for the other side. Using a total of 12 pins for all 5 bulbs….

  51. April 13th, 2015 at 22:00 | #51

    @Teresa
    If you are using the Fiber optic fabrics aren’t these the EL Wire? And if so the driver you have can’t be connected to a High Power LED module such as the ones used in our project.
    As I don’t know which “driver boards” you have I can’t tell you whether or not you can connect the high power LEDs to your board, nor how you should do so if possible.
    First you would have to make sure that your driver board is made for LED PWM driving and that the current the High Power LEDs use can be supplied by your driver board as well.
    Best regards
    Thomas Jespersen

  52. Jim
    January 16th, 2017 at 01:45 | #52

    @Thomas Jespersen
    This is actually what I’m trying to accomplish: continuously change every LED to the same color at once. Thanks!

  1. No trackbacks yet.