I have been toiling with this. The first thing I discovered is that I had the colour pins for the LED wrong. With the flat to my right (5 mm Common Anode LED) I expected the pins to be RAGB - instead they are RABG - so I swapped the pins Now, at least, the primary colours are correct, but I still have mixing problems.
I started to suspect the relative intensities of the individual colours in the LED. Checking a tutorial that deals with loading resistors for LEDs I discover the formula
R=(Vs - Vf)/If
Vs is the source voltage – usually a battery or power supply voltage. Vf and If are the LED’s forward voltage and the desired current that runs through it. This gives me (according to my always suspect mathematics) a value of 32 ohms for the resistor for Red. That seems incredibly low (I am using 10K).
Question: What does the value given by this formula actually represent? Is it a resistance which will stop me frying (another) LED? Is it a resistance which will produce maximum luminosity from the LED? What DOES this value represent?
Question: Given that the datasheet for the LED tells me
Luminous Intensity (mcd): 500 (Red) 1200 (Green) 600 (Blue)
how do I balance the colour intensity for each primary? Do I use different loading resistors for each cathode? If so, how do I calculate appropriate resistance values?
'Scuse me for being a bit of a pain, but I would like to get to the bottom of this. The code I am using is
// pins for the LEDs:
#define RED_PIN 3
#define GREEN_PIN 5
#define BLUE_PIN 6
// variable
bool debug = true;
void setup()
{
// initialize serial I/O
Serial.begin(9600);
// initialize pins
pinMode(RED_PIN, OUTPUT);
pinMode(GREEN_PIN, OUTPUT);
pinMode(BLUE_PIN, OUTPUT);
}
void loop()
{
// if there's any serial input available, read it
while (Serial.available() > 0)
{
// note something is read
if (debug)
{
Serial.println();
Serial.println("Something has been read");
}
// look for the next valid integer in the incoming serial stream
int red = Serial.parseInt();
if (debug)
{
Serial.print("Red Value => ");
Serial.println(red);
}
// do it again
int green = Serial.parseInt();
if (debug)
{
Serial.print("Green Value => ");
Serial.println(green);
}
// do it again
int blue = Serial.parseInt();
if (debug)
{
Serial.print("Blue Value => ");
Serial.println(blue);
Serial.println();
}
// look for the newline. That's the end of your sentence
// Note: to do this you must adjust the settings in your Serial
// Monitor to add the newline character when 'Enter' is pressed.
// It is not there by default.
if (Serial.read() == '\n')
{
// constrain entered integers to ASCII range
red = constrain(red, 0, 255);
green = constrain(green, 0, 255);
blue = constrain(blue, 0, 255);
if (debug)
{
Serial.print("Red Value constrained to => ");
Serial.println(red);
Serial.print("Green Value constrained to => ");
Serial.println(green);
Serial.print("Blue Value constrained to => ");
Serial.println(blue);
Serial.println();
}
// because I am using a "Common Anode" LED, I get bright colour
// when pin value is low, so I have to reverse the values
// entered
red = 255 - red;
green = 255 - green;
blue = 255 - blue;
if (debug)
{
Serial.print("Final Red Value => ");
Serial.println(red);
Serial.print("Final Green Value => ");
Serial.println(green);
Serial.print("Final Blue Value => ");
Serial.println(blue);
Serial.println();
}
// write the colour values to respective pins
analogWrite(RED_PIN, red);
analogWrite(GREEN_PIN, green);
analogWrite(BLUE_PIN, blue);
// print the three numbers in hexadecimal
if (debug)
{
Serial.print(red, HEX);
Serial.print(", ");
Serial.print(green, HEX);
Serial.print(", ");
Serial.println(blue, HEX);
Serial.println();
}
}
}
}