Mood Light

I figured I'd try to make a moodlight as a cool touch to any project. I have this WEIRD RGB LED, though. I can't get the code to work right. Can someone help me try to figure out what is wrong? It cycles through all the colors, but it occasionally acts erratically. Sometimes it will just fade in and out one color, and other times it will 'jump' from one color to another (not transitioning). Here's the code:

int onePin = 3;   //RED
int twoPin = 5;   //BLUE
int threePin = 6; //GREEN
int i;
int selPin;

void setup()
{
  Serial.begin(9600);
  pinMode(onePin, OUTPUT);
  pinMode(twoPin, OUTPUT);
  pinMode(threePin, OUTPUT);
  randomSeed(analogRead(0));
}

void loop() {
  //digitalWrite(onePin, LOW);
  //digitalWrite(twoPin, LOW);
  //digitalWrite(threePin, LOW);
  //delay(300);
  //digitalWrite(onePin, HIGH);
  //digitalWrite(twoPin, HIGH);
  //digitalWrite(threePin, HIGH);
  //delay(300);
    //digitalWrite(onePin, LOW);
    //digitalWrite(twoPin, LOW);
    //digitalWrite(threePin, HIGH);
    //delay(10000);
  selectPin();
  for(i = 255; i > 0; i--) {
    analogWrite(selPin, i);
    delay(5);
  }
  selectPin();
  for(i = 0; i < 255; i++) {
    analogWrite(selPin, i);
    delay(5);
  }
}
void selectPin() {
  selPin = random(7);
  switch(selPin) {
    case 0:
      selectPin();
      break;
    case 1:
      selectPin();
      break;
    case 2:
      selectPin();
      break;
    case 4:
      selectPin();
      break;
    case 7:
      selectPin();
      break;
  }
}

And here's a post on this unique LED that you MUST read before speculating on how to fix this:
http://forums.parallax.com/forums/default.aspx?f=5&m=266028&p=1

All help is appreciated! :smiley:

I'm guessing that as you have missed pin4 in the sequesnce of output pins, you are plugging the common anode/cathode of the LED into that pin.

Generally, that's not the greatest idea, because the microcontroller isn't designed to sink/source that much current, and as it is a common pin, all three colours will be sinking through the pin. This could be well over the limit for the microcontroller. Although it could be fine, this could cause your microcontroller to reset or otherwise act funny.

If you are using pin4 as the common pin, try using the Arduino +5/GND pins (as appropriate for the common cathode/anode LED). Make sure you have resistors between the individual colour pinsand the arduino to limit the total current.

Yea...This is a weird LED; it's nothing like the RGB ones I've bought from Sparkfun. And yes, one of the pins (the longest lead on the LED), is connected to +5V (it's the 'common'one, I guess). I have 1K resistors going from all the colors to the Arduono pins, except for red, which has about 660 ohms worth of resistors going to a pin because I think that the red LED within the case requires more voltage (before I was seeing less reds and purples, so I reduced the values for the resistors for the red LED portion). Should I be worried about the sinking/sourcing (which ever term is used to mean 'bring to ground' because that's what the microcontroller does in this case to light an LED) problem? I mean, how else am I going to do this?? Also, are you suggesting that the erratic behavior is coming from the fact that the ATmega168 might be resetting due to this problem? (that could explain the 'jumping' to colors; I guess I haven't paid attention to the reset LED (the one connected to pin 13 that blinks when the Arduino Diecimila restarts)). And I think I need to edit the code, too. I don't exactly see a whole spectrum of colors; there is a lack of purples and greens, and a few other color combinations.

Yea...This is a weird LED; it's nothing like the RGB ones I've bought from Sparkfun.

What is so weird about it? I read the thread you linked to. It sounds like a normal RGB LED.

If you connect the 3 colours across a power supply with no resistor, then the red LED will drop about 1.7 volts and the green and blue about 3 volts each.

...but they are directly in parallel across a supply, so by Kirchoff's Voltage Law, you have the same voltage dropped across them.

What happens is you effectively have the RED LED shorting out the green and blue LEDs because it has the lowest voltage drop.


Try this with a 1 colour LED. Power it off your arduino. It works. Now short it out with a wire. It doesn't work. This is what the red LED is doing to the green and blue ones.

So...Wait, I don't think you are getting what I meant about the setup I have. The RED LED has ~660 OHMS OF RESISTORS (in series) GOING TO DIGITAL (PWM) PIN 3, the BLUE LED going to digital (PWM) pin 5 with a 1Kohm resistor, and the GREEN LED going to a 1K R to digital (pwm) pin 6. The longest lead on the LED goes to +5V, and when the arduino brings one of the three pins (3, 5, or 6) LOW, the LED lights up. So I AM using resistors, so what's wrong? I still need to edit my code, right? I'm all ears! Thanks.

UPDATE:

Ok, so I figured I ought to try this with some code that is in working order, so I searched a little, and on the Arduino website (or Todbot blog, I can't remember), and I found this: (http://www.arduino.cc/en/Tutorial/ColorCrossfader). It works GREAT; cheers to Clay Shirky. BUT I STILL SEE A PROBLEM WITH THE LED. When the program tells me it is displaying, say, a blue, it's displaying a deep green, and when it says it's displaying a yellow, it's actually displaying a turquoise. ...OH! Ok...Here's the question: when the program THINKS it's lighting up the RED, GREEN, or BLUE (this is when it writes a value of 255 to the pins (all +5V pulses)), it's actually turning them COMPLETELY off (due to this LED). So when it writes a value of 0 (PWM with GND pulses dominating = completely grounded), this lights up the LED(s) because it is bringing them to GND (remember, the 'common' anode is connected right to +5V). WHEN I BOUGHT THE LED FROM SPARKFUN, ALL I HAD TO DO WAS CONNECT THE 'COMMON' LEAD (which was the longest one on the RGB LED) TO GND, AND APPLY +5V TO THE RED/BLUE/GREEN LEADS TO LIGHT THE LED(s). I tried that method with this LED, but it DID NOT LIGHT THE LED(s) AT ALL (it's reversed). COMPARE THE DATASHEETS:

Sparkfun: http://www.sparkfun.com/datasheets/Components/YSL-R596CR3G4B5C-C10.pdf
Radioshack: http://rsk.imageg.net/graphics/uc/rsk/Support/ProductManuals/2760028_DS_EN.pdf

And I guess I still need to worry about the voltage differences with the Red/Green/Blue LED's. Red = 2.6V, Green = 4V, Blue = 4V (MAXIMUM ratings). But I've applied 5V to them (with ~600ohm to red, 1K to Green, and 1K to blue), and they're fine; they aren't heating up or showing signs of damage. Help!

  1. what changes do I need to make in the code to fix the 'reversed' effect
  2. what about the different voltages for each color in the RGB LED
    BTW, I'm not seeing any oranges...

Thanks for your support.

It seems to me that you are randomly selecting a maximum of two pins to vary their pwm value in your loop and then looping again. As in the CrossFader program you tried, don't randomize the pin you select, but randomize a different pwm value on all three pins consecutively in each loop to get the effect you are looking for.

COMPARE THE DATASHEETS:

Sparkfun: http://www.sparkfun.com/datasheets/Components/YSL-R596CR3G4B5C-C10.pdf
Radioshack: http://rsk.imageg.net/graphics/uc/rsk/Support/ProductManuals/2760028_DS_EN.pdf

And I guess I still need to worry about the voltage differences with the Red/Green/Blue LED's. Red = 2.6V, Green = 4V, Blue = 4V (MAXIMUM ratings). But I've applied 5V to them (with ~600ohm to red, 1K to Green, and 1K to blue), and they're fine; they aren't heating up or showing signs of damage. Help!

  1. what changes do I need to make in the code to fix the 'reversed' effect
  2. what about the different voltages for each color in the RGB LED
    BTW, I'm not seeing any oranges...

Thanks for your support.

This LED isn't "Weird." Multi-element LEDs (whether multi-color, 7-segment, etc.) come 2 ways. Either common anode or common cathode. With a common anode (what you seem to have) the anode (long pin) goes to positive. Each junction (LED) is lit when its associated cathode is brought low. With a common cathode device, the cathode is tied to ground and each junction is lit when its associated anode is brought high.

Although our beloved Arduinos have the same source and sink current, many devices don't. Typically the pull up is weak (or even non-existent ("Open collector output"), and a (relatively) powerful transistor pulls down to drive an output pin. By way of example, the old 74xx series ICs level 1 output current is 0.4mA, but the level 0 current is 16mA. The old 74LSxx series ICs level 1 output current is 0.4mA, level 0 current is 8mA. So, anyhow, many devices use a common anode so that they are turned on by pulling the cathode low. Because that is where the current is!

Yes, your colors are reversed. The code was designed to output HIGH (analog write value 255) for full on. You are wired so that full on is output LOW (analogWrite value 0) Simple fix: Change your code in each place from:

analogWrite(selPin, i);

to:

analogWrite(selPin, 255 - i);

Or, change the logic similarly as needed in other places.

Oh. Right; that was an obvious fix; thanks. Here's the updated code:

int onePin = 3;   //RED
int twoPin = 5;   //BLUE
int threePin = 6; //GREEN
int i;
int selPin;
int prevPin;
int fstColor;
int scndColor;
int thdColor;

void setup()
{
  Serial.begin(9600);
  pinMode(onePin, OUTPUT);
  pinMode(twoPin, OUTPUT);
  pinMode(threePin, OUTPUT);
  randomSeed(analogRead(0));
  digitalWrite(onePin, HIGH);
  digitalWrite(twoPin, HIGH);
  digitalWrite(threePin, HIGH);
}

void loop() {
  crossFadeOne();
  for(i = 0; i < 255; i++) {          
    analogWrite(fstColor, 255 - i);     //Brighten
    analogWrite(scndColor, i);          //Darken
    delay(50);
  }
  crossFadeTwo();
  for(i = 255; i > 0; i--) {          
    analogWrite(fstColor, 255 - i);     //Darken
    analogWrite(thdColor, i);           //Brighten
    delay(50);
  }
}
void crossFadeOne() {
  selectPin();
  fstColor = selPin;
  selectPin();
  scndColor = selPin;
  if(fstColor == scndColor) {
    crossFadeOne();
  }
}
void crossFadeTwo() {
  selectPin();
  thdColor = selPin;
  if(fstColor == thdColor) {
    crossFadeTwo();
  }
}
void selectPin() {
  selPin = random(7);
  switch(selPin) {
    case 0:
      selectPin();
      break;
    case 1:
      selectPin();
      break;
    case 2:
      selectPin();
      break;
    case 4:
      selectPin();
      break;
    case 7:
      selectPin();
      break;
  }
}

BUT- there's one last problem: I am still having the 'jumping' problem - the color sequences sometimes do not crossfade, but instead 'jump' from one color combination to another (like from a deep purple to turquoise). What's the problem?

[kBit]

Although our beloved Arduinos have the same source and sink current,...

Which makes everything easier!

[trialex]

Generally, that's not the greatest idea, because the microcontroller isn't designed to sink/source that much current, and as it is a common pin, all three colours will be sinking through the pin. This could be well over the limit for the microcontroller. Although it could be fine, this could cause your microcontroller to reset or otherwise act funny.

Well, trialex, I guess you're wrong about the sourcing/sinking problem...

I HAVE NOT NOTICED the 'reset' indicator LED (I have a Diecimila) flash at all during this program, so the 'jumping' problem is NOT related to resets...

[trialex]

Generally, that's not the greatest idea, because the microcontroller isn't designed to sink/source that much current, and as it is a common pin, all three colours will be sinking through the pin. This could be well over the limit for the microcontroller. Although it could be fine, this could cause your microcontroller to reset or otherwise act funny.

Well, trialex, I guess you're wrong about the sourcing/sinking problem...

I HAVE NOT NOTICED the 'reset' indicator LED (I have a Diecimila) flash at all during this program, so the 'jumping' problem is NOT related to resets...

Gee, I was just trying to help! As at that stage you hadn't fully described how you had connected the LED, e.g. resistors, common cathode, common anode etc... I was just suggesting some things to try!

Lol; I wasn't trying to sound criticizing. Sorry if it came out that way ::). Now All I need to do is find a solution to the 'jumping' problem see above post...

I think the jumping has to do with the fact that you're not saving the value for any particular pin. So, you can go from full off to full on or visa versa, causing a "jump". If you always want smooth transitions I would think you need to track if each pin is full on or full off and adjust accordingly.

Ok. So I fixed the jumping. Here's the updated code. BUT with this setup, I can't get any whites. Also, there isn't nearly as much variation. How can I add that in??

int onePin = 3;   //RED
int twoPin = 5;   //BLUE
int threePin = 6; //GREEN
int i;
int selPin;
int prevPin;
int fstColor;
int scndColor;
int thdColor;

void setup()
{
  Serial.begin(9600);
  pinMode(onePin, OUTPUT);
  pinMode(twoPin, OUTPUT);
  pinMode(threePin, OUTPUT);
  randomSeed(analogRead(0));
  digitalWrite(onePin, HIGH);
  digitalWrite(twoPin, HIGH);
  digitalWrite(threePin, HIGH);
}

void loop() {
  crossFadeOne();
  for(i = 0; i < 255; i++) {          
    analogWrite(fstColor, 255 - i);     //Brighten
    analogWrite(scndColor, i);          //Darken
    delay(100);
  }
  crossFadeTwo();
  for(i = 255; i > 0; i--) {          
    analogWrite(fstColor, 255 - i);     //Darken
    analogWrite(scndColor, i);           //Brighten
    delay(100);
  }
}
void crossFadeOne() {
  selectPin();
  fstColor = selPin;
  if(fstColor == scndColor) {
    crossFadeOne();
  }
}
void crossFadeTwo() {
  selectPin();
  scndColor = selPin;
  if(fstColor == scndColor) {
    crossFadeTwo();
  }
}
void selectPin() {
  selPin = random(7);
  switch(selPin) {
    case 0:
      selectPin();
      break;
    case 1:
      selectPin();
      break;
    case 2:
      selectPin();
      break;
    case 4:
      selectPin();
      break;
    case 7:
      selectPin();
      break;
  }
}

Ok. So I fixed the jumping. Here's the updated code. BUT with this setup, I can't get any whites. Also, there isn't nearly as much variation. How can I add that in??

Think very carefully about what your algorithm is trying to do. The odds of showing a white are very low, and the variation is quite low.

You would need a completely different algorithm. I saw one many years ago that basically had a table of colours as RGB values, picked on at random, and then did a fade from the current colour to the new one.