Demo 1: RGB Color Mixing - Additive Color Theory

Circuit Diagram

Arduino Uno RGB LED (Common Cathode) Pin 9 (PWM) ---[220Ω]----> R (Red Anode) Pin 10 (PWM) ---[220Ω]----> G (Green Anode) Pin 11 (PWM) ---[220Ω]----> B (Blue Anode) | (Common Cathode) GND Note: For Common ANODE RGB LEDs: Connect common pin to +5V Drive pins LOW to turn on colors (Invert all PWM values: 255 - value)

Theory & Physics

Additive Color Mixing: RGB LEDs combine three primary colors of light. Unlike subtractive mixing (paint), light combines additively:

Red + Green = Yellow
Red + Blue = Magenta
Green + Blue = Cyan
Red + Green + Blue = White

Color Space: RGB uses a 3D color space where each axis (R, G, B) ranges from 0-255 (8-bit), creating 16,777,216 possible colors (2²⁴).

Trichromatic Theory: Human eyes have three types of cone cells sensitive to different wavelengths:
  • S-cones: Blue (~420-440nm)
  • M-cones: Green (~530-540nm)
  • L-cones: Red (~560-580nm)
RGB LEDs exploit this by stimulating these three receptor types.

Calculations

Individual LED Forward Voltages:
- Red: Vf ≈ 2.0V
- Green: Vf ≈ 3.2V
- Blue: Vf ≈ 3.2V

Current Limiting for Each Color:
Using 220Ω resistors for all (simplicity):

Red: I = (5V - 2.0V) / 220Ω = 13.6mA
Green: I = (5V - 3.2V) / 220Ω = 8.2mA
Blue: I = (5V - 3.2V) / 220Ω = 8.2mA

Note: For balanced brightness, you may want different resistors:
  • Red: 220Ω (standard)
  • Green: 100-150Ω (brighter)
  • Blue: 100-150Ω (brighter)

Arduino Code

// RGB Color Mixing Demo const int RED_PIN = 9; const int GREEN_PIN = 10; const int BLUE_PIN = 11; void setup() { pinMode(RED_PIN, OUTPUT); pinMode(GREEN_PIN, OUTPUT); pinMode(BLUE_PIN, OUTPUT); Serial.begin(9600); } void loop() { // Cycle through basic colors Serial.println("Red"); setColor(255, 0, 0); delay(1000); Serial.println("Green"); setColor(0, 255, 0); delay(1000); Serial.println("Blue"); setColor(0, 0, 255); delay(1000); Serial.println("Yellow (R+G)"); setColor(255, 255, 0); delay(1000); Serial.println("Cyan (G+B)"); setColor(0, 255, 255); delay(1000); Serial.println("Magenta (R+B)"); setColor(255, 0, 255); delay(1000); Serial.println("White (R+G+B)"); setColor(255, 255, 255); delay(1000); Serial.println("Orange"); setColor(255, 128, 0); delay(1000); Serial.println("Purple"); setColor(128, 0, 128); delay(1000); Serial.println("OFF"); setColor(0, 0, 0); delay(1000); } void setColor(int red, int green, int blue) { analogWrite(RED_PIN, red); analogWrite(GREEN_PIN, green); analogWrite(BLUE_PIN, blue); }

Color Reference Table

Color Preview R G B Hex
Red
255 0 0 #FF0000
Green
0 255 0 #00FF00
Blue
0 0 255 #0000FF
Yellow
255 255 0 #FFFF00
Cyan
0 255 255 #00FFFF
Magenta
255 0 255 #FF00FF
White
255 255 255 #FFFFFF
Orange
255 128 0 #FF8000
Purple
128 0 128 #800080

Use Cases

Demo 2: RGB Rainbow Fade (HSV Color Space)

Circuit Diagram

Same circuit as Demo 1: Pin 9 (PWM) ---[220Ω]----> R (Red Anode) Pin 10 (PWM) ---[220Ω]----> G (Green Anode) Pin 11 (PWM) ---[220Ω]----> B (Blue Anode) | GND

Theory & Physics

HSV Color Space: Hue-Saturation-Value is an alternative to RGB that's more intuitive for creating color effects.
  • Hue (H): The color itself, 0-360° around the color wheel
    • 0° = Red
    • 60° = Yellow
    • 120° = Green
    • 180° = Cyan
    • 240° = Blue
    • 300° = Magenta
  • Saturation (S): Color intensity (0-100%), 0% = grayscale, 100% = pure color
  • Value (V): Brightness (0-100%), 0% = black, 100% = full brightness
Conversion Algorithm: HSV must be converted to RGB for LED output. This involves dividing the hue into six sectors and calculating intermediate values.

Calculations

HSV to RGB Conversion:

Given H (0-360), S (0-1), V (0-1):

1. C = V × S (chroma)
2. X = C × (1 - |((H/60) mod 2) - 1|)
3. m = V - C

Depending on H sector:
- 0° ≤ H < 60°: R'=C, G'=X, B'=0
- 60° ≤ H < 120°: R'=X, G'=C, B'=0
- 120° ≤ H < 180°: R'=0, G'=C, B'=X
- 180° ≤ H < 240°: R'=0, G'=X, B'=C
- 240° ≤ H < 300°: R'=X, G'=0, B'=C
- 300° ≤ H < 360°: R'=C, G'=0, B'=X

Final: R = (R'+m)×255, G = (G'+m)×255, B = (B'+m)×255

Arduino Code

// RGB Rainbow Fade using HSV const int RED_PIN = 9; const int GREEN_PIN = 10; const int BLUE_PIN = 11; void setup() { pinMode(RED_PIN, OUTPUT); pinMode(GREEN_PIN, OUTPUT); pinMode(BLUE_PIN, OUTPUT); Serial.begin(9600); } void loop() { // Cycle through full color spectrum for(int hue = 0; hue < 360; hue++) { int rgb[3]; HSVtoRGB(hue, 100, 100, rgb); analogWrite(RED_PIN, rgb[0]); analogWrite(GREEN_PIN, rgb[1]); analogWrite(BLUE_PIN, rgb[2]); Serial.print("Hue: "); Serial.print(hue); Serial.print(" RGB: "); Serial.print(rgb[0]); Serial.print(","); Serial.print(rgb[1]); Serial.print(","); Serial.println(rgb[2]); delay(20); // Smooth transition } } // Convert HSV to RGB void HSVtoRGB(int hue, int sat, int val, int colors[3]) { // Convert percentages to 0-1 range float s = sat / 100.0; float v = val / 100.0; float h = hue / 60.0; float c = v * s; float x = c * (1 - abs(fmod(h, 2) - 1)); float m = v - c; float r, g, b; if(h >= 0 && h < 1) { r = c; g = x; b = 0; } else if(h >= 1 && h < 2) { r = x; g = c; b = 0; } else if(h >= 2 && h < 3) { r = 0; g = c; b = x; } else if(h >= 3 && h < 4) { r = 0; g = x; b = c; } else if(h >= 4 && h < 5) { r = x; g = 0; b = c; } else { r = c; g = 0; b = x; } colors[0] = (int)((r + m) * 255); colors[1] = (int)((g + m) * 255); colors[2] = (int)((b + m) * 255); }

Use Cases