RGB LEDS lighting up wrong color

I am currently working on a color theory project where you push a button to make three LEDS fade through colors that go along with the button pushed (cool color button makes leds fade though blue, purple, green).

Right now I have all three Superflux (shared anode) RGB LEDs hooked up. I plan on having 6 buttons with 6 different color words but right now I just have one and am trying to do some cool colors. My colors I want are red, orange and yellow but the LEDs don’t light up at all. When I try blue, indigo, violet, they light up as pinks and red.

The only thing that I can see that could be wrong is maybe that I am using 150-Ohm resistors for every RGB pin of every LED and maybe that is wrong. Other than that I am sure I have everything hooked up right. Oh, well I think I do, When I unplug the wire hooked from the 5V to the + row on the breadboard (which then has a wire going to the anode on each LED) it doesn’t change anything and the LEDs are still lit up. Can they get power from the PWM inputs?

Here is the sketch…

struct color
{
unsigned char red;
unsigned char green;
unsigned char blue;
};

unsigned char buttonPin = 3;
color ledPins = { 9, 10, 11 };

color black = { 0, 0, 0 };
color white = { 255, 255, 255 };

color red = { 255, 0, 0 };
color orange = { 255, 127, 0 };
color yellow = { 255, 255, 0 };

void setup()
{
pinMode(buttonPin, INPUT);
pinMode(ledPins.red, OUTPUT);
pinMode(ledPins.green, OUTPUT);
pinMode(ledPins.blue, OUTPUT);
}

void showColor(struct color pins, struct color values)
{
analogWrite(pins.red, values.red);
analogWrite(pins.green, values.green);
analogWrite(pins.blue, values.blue);
}

void fadeToColor(struct color pins, struct color oldValues, struct color newValues, int delayMillisec)
{
float rdiff = (float)((int)newValues.red - oldValues.red) / delayMillisec;
float gdiff = (float)((int)newValues.green - oldValues.green) / delayMillisec;
float bdiff = (float)((int)newValues.blue - oldValues.blue) / delayMillisec;

float r = oldValues.red;
float g = oldValues.green;
float b = oldValues.blue;
for (int i = 0; i < delayMillisec; i++)
{
r += rdiff;
g += gdiff;
b += bdiff;

analogWrite(pins.red, r);
analogWrite(pins.green, g);
analogWrite(pins.blue, b);

delayMicroseconds(1000);

if (!isRunning())
return;
}
}

bool isRunning()
{
static bool pushed = false;
static bool running = true;
if (digitalRead(buttonPin) == LOW)
{
if (!pushed)
{
running = !running;
pushed = true;
}
}
else
{
pushed = false;
}
return running;
}

int pos = 0;
color colors = { black, red, orange, yellow };
int numColors = sizeof(colors) / sizeof(color);

void loop()
{
if (isRunning())
{
int last = pos;
pos++;
if (pos >= numColors)
pos = 0;

fadeToColor(ledPins, colors[last], colors[pos], 700);
if (isRunning())
delay(300);
}
else
{
showColor(ledPins, black);
}
}

If I knew how to draw a diagram better I would and if it is necessary to fully access my problem I will try.

Thanks so much for any help you can give me.

  • Aidyn

perhaps running a simple sketch like this can help verify the wiring is ok

int ledPins[] = { 9, 10, 11 };

void setup()
{
  // no need to set pins as outputs for analogWrite
}

void loop()
{
// light each led in sequence for one second  
 for(int i=0; i < 3; i++){
    analogWrite(ledPins[i], 255); 
    delay(1000);
    analogWrite(ledPins[i], 0);   
 }
}

If you have common anodes going to +ve and the cathodes to the PWM output then remember that writing an analogue value of 0 will turn on the LED and a value of 255 will turn it off. This is because you are sinking current, not sourcing it.

Hmmm, I'm just going to rewire the whole thing again. What is the best way to hook three LEDs to three PWM outputs? Is there even another way?

You don’t need to change the wiring if you have the anodes connected to +5 volts and each cathode connected through resistors to the three pins.

But you do need to invert the rgb values.
You could add a function like this:

void analogWriteInverted( byte pin, byte value)
{
   analogWrite(pin, 255-value);
}

You would replace all analogWrites with this function, so your loop would look like:

void loop()
{
// light each led in sequence for one second  
 for(int i=0; i < 3; i++){
    analogWriteInverted(ledPins[i], 255);
    delay(1000);
    analogWriteInverted(ledPins[i], 0);  
 }
}

or you could just modify your code to do the subtraction

Ah, ok. I'll try that. Thank you.

Alright! That fixed my problem.

I'm going to ask another question here in case you guys check back and hope to get an answer.

I don't know much about buttons and how the code works. Right now I have it (the code) so it turns on the lights when I press the button. What I want is 5 more buttons and when each one is pressed a different array of colors is shown. How exactly would I need to modify my code to do this?

Thank you soooooo much for your help. This thing is due tomorrow and I have it all pretty much constructed, I just need to get my code right.

Maybe you could post your code as is now?

I'll gladly help. [if I'm able to that is]

It is the same as it is in the first post. (I inverted all the color values I needed by hand)

My LEDs still aren't all lighting up the same either, the first one does what I want and the others are dimmer and slightly different colors. Here is a picture of my breadboard...

Those wires for each LED are soldered to the pins of the LED.

A is for anode and the RGB goes to the corresponding pin of the LED. I think all else is pretty self explanatory.

I also noticed when I plug the 2 LEDs lighting up wrong into the spot where the working one (LED 1) was they still weren't right. Could this mean they are blown?

That is not a good sign. If you are sure the I/O pin stays in the same 'state' while changing, and after a change the LEDs light up differently, that is a concern. [some drift is usual I think, or at least, I've seen it before]

Ok, nevermind it was just some sloppy wiring. The LEDs all work right when plugged into the first spot but not when all in the spots shown in the picture. Only the first one works then.

Alpha, did you look at the code and see how I would go about putting in more than one button to change it to different colors? That's what I'm trying to figure out code wise right now and I don't really know how to multiply what I've already done once.

I forgot to look at your code, but here is what I hacked together now:

[CODE UNTESTED]

#define NUMBER_OF_BUTTONS 5

struct color
{
unsigned char red;
unsigned char green;
unsigned char blue;
};

color ledPins = { 9, 10, 11 };

color black = { 0, 0, 0 };
color white = { 255, 255, 255 };

color red = { 255, 0, 0 };
color orange = { 255, 127, 0 };
color yellow = { 255, 255, 0 };

int pos = 0;

color colors1 = { black, red, orange, yellow };
color colors2 = { black, red, orange, yellow };
color colors3 = { black, red, orange, yellow };
color colors4 = { black, red, orange, yellow };
color colors5 = { black, red, orange, yellow };

color* colors = { colors1 , colors2 , colors3 , colors4 , colors5 };
int numColors = 4;

unsigned char buttonPins = {3,4,5,6,7};
byte currentButton=0;

void setup()
{
for(byte i=0; i<NUMBER_OF_BUTTONS; i++){
pinMode(buttonPins*, INPUT);*

  • }*
  • pinMode(ledPins.red, OUTPUT);*
  • pinMode(ledPins.green, OUTPUT);*
  • pinMode(ledPins.blue, OUTPUT);*
    }
    void showColor(struct color pins, struct color values)
    {
  • analogWrite(pins.red, values.red);*
  • analogWrite(pins.green, values.green);*
  • analogWrite(pins.blue, values.blue);*
    }
    void fadeToColor(struct color pins, struct color oldValues, struct color newValues, int delayMillisec)
    {
    float rdiff = (float)((int)newValues.red - oldValues.red) / delayMillisec;
    float gdiff = (float)((int)newValues.green - oldValues.green) / delayMillisec;
    float bdiff = (float)((int)newValues.blue - oldValues.blue) / delayMillisec;
    float r = oldValues.red;
    float g = oldValues.green;
    float b = oldValues.blue;
    for (int i = 0; i < delayMillisec; i++)
    {
  • r += rdiff;*
  • g += gdiff;*
  • b += bdiff;*
  • analogWrite(pins.red, r);*
  • analogWrite(pins.green, g);*
  • analogWrite(pins.blue, b);*
  • delayMicroseconds(1000);*
  • if (!isRunning())*
  • return;*
    }
    }
    bool isRunning()
    {
    static bool pushed = false;
    static bool running = true;
    for(byte i=0; i<NUMBER_OF_BUTTONS; i++){
    _ if (digitalRead(buttonPins*) == LOW)_
    _
    {_
    _
    if (!pushed)_
    _
    {_
    _
    currentButton = i;_
    _
    running = !running;_
    _
    pushed = true;_
    _
    }_
    _
    }_
    _
    else*_
    * {*
    * pushed = false;*
    * }*
    }
    return running;
    }
    void loop()
    {
    if (isRunning())
    {
    * int last = pos;*
    * pos++;*
    * if (pos >= numColors)*
    * pos = 0;*

* fadeToColor(ledPins, colors[currentButton][last], colors[currentButton][pos], 700);*
* if (isRunning())*
* delay(300);*
}
else
{
* showColor(ledPins, black);*
}
}
[/quote]

Holy Cow, thanks. Once I get these LEDs straight I will try that.

Do you know about the wiring stuff? From that picture I posted does everything look alright.

Thanks again, I really owe you one.

The wiring looks correct :)

Should the LEDs still be lit up when I pull the 5V power Hookup out? (Going from the 5v output to the breadboard)? That is what it is doing and I think that is why my LEDs are behaving oddly.

That is very strange...

[this reminded me that I did not invert your variables]

Wait, invert the variables? What does that mean exactly?

Yeah, I think there are some power problems going on here. I don't even have to have the 5v wires plugged in for it Not to work right.

Wait, invert the variables? What does that mean exactly?

It was your words actually :)

It is the same as it is in the first post. (I inverted all the color values I needed by hand)

Power problems... Hmmm.

Are you using high intensity leds? Maybe they are using to much ampere?

Maybe.

http://store.fungizmos.com/index.php?main_page=product_info&cPath=68&products_id=203

Intensity - Min: 6000mcd Max: 8000 mcd

Maybe I'll just use one instead of three at once.