Why equal numbers are not white
255, 255, 255 gives about 40 % of the light from red, 48 % from green and 12 % from blue. White needs about a third red, three fifths green and hardly any blue, so the equal mix leans violet. Worked out from the datasheet, green full with red at 167 and blue at 122 is a better place to start.
Three ways to ask for white
Each bar is one colour's share of the light the LED gives out, from 5 V. The tick on each bar is the share that colour must supply for the mix to be white.
Equal numbers, 255 on every pin, put green at about 48 % of the light where white needs about 60 %. Red and blue take up the slack, blue most of all, and the mix sits on the violet side of white.
Equal light, turning red and green down until each gives as much light as blue at full, is the idea most people try next. It is the worst of the three: blue becomes a third of the light, where white wants about 7 %.
Green full, red 167, blue 122 puts every bar on its tick. That is white, on paper.
White is mostly green
The surprise is the ticks. The eye is far more sensitive to green light than to red or blue, and the white it sees is made mostly of green: about 60 % of the light, with about a third red and only about 7 % blue. Blue is the dimmest colour on this LED, by the datasheet about a quarter of green's light at the same current, and it is still too bright for white.
So the balance is not about making the three equally bright. It is about giving each colour the share of light the eye uses to build white.
Where 167 and 122 come from
They are arithmetic, not a measurement. The book takes each colour's light from the middle of its range in the datasheet, the currents from the earlier article, and each colour's position on the standard chart of colours the eye can see. Solving for the mix that lands on a screen's white gives green full, red at about 65 % and blue at about 48 %: 167 and 122 out of 255.
Every input has a range. The datasheet allows green anywhere from 5 to 7 lm, and blue from 1 to 2, a factor of two. Your LED will need its own trim, and the sketch is there to make that quick.
Trimming by eye
Run the sketch, which alternates 255, 255, 255 with the balanced white every two seconds. Hold a sheet of white paper behind the LED. Then change one number at a time by about 10: pink or violet means less red or less blue, a green tint means the other two up. The right numbers are the ones that look neutral in your room.
The code
Alternates the two whites every two seconds: all three at 255, then the balanced numbers. Compare them by eye. WHITE is set for a 3.3 V board; on an Uno use 167, 255, 122.
/*
RGB LED - equal numbers against white TK02 / /p/tk02
Wiring. Count from the square pad on the TinkerBlock board, LED side
up, header at the bottom:
GND -> GND
NC -> nothing (both NC pins are unconnected on the board)
NC -> nothing
RED -> a PWM pin: D9 on an Uno, GPIO 25 on an ESP32,
GPIO 4 on an ESP32-S3, GP13 on a Raspberry Pi Pico
GREEN -> D10, GPIO 26, GPIO 5, GP14
BLUE -> D11, GPIO 27, GPIO 6, GP15
Arduino IDE
Tools > Board your board, e.g. ESP32S3 Dev Module
Tools > Port the one that appears when you plug in
Tools > USB CDC On Boot Enabled (ESP32-S3 only)
No library needed. ESP32 boards need board package 2.0 or later.
*/
// Uno: 9, 10, 11. ESP32: 25, 26, 27. ESP32-S3: 4, 5, 6. Pico: 13, 14, 15.
const int RED_PIN = 4;
const int GREEN_PIN = 5;
const int BLUE_PIN = 6;
// A first guess at white. 3.3 V board: 84, 255, 122. Uno: 167, 255, 122.
const int WHITE[3] = {84, 255, 122};
void setColour(int r, int g, int b) {
analogWrite(RED_PIN, r);
analogWrite(GREEN_PIN, g);
analogWrite(BLUE_PIN, b);
}
void setup() {
Serial.begin(115200);
pinMode(RED_PIN, OUTPUT);
pinMode(GREEN_PIN, OUTPUT);
pinMode(BLUE_PIN, OUTPUT);
}
void loop() {
setColour(255, 255, 255);
Serial.println("255, 255, 255: equal numbers");
delay(2000);
setColour(WHITE[0], WHITE[1], WHITE[2]);
Serial.println("WHITE: balanced");
delay(2000);
}The numbers come from the datasheet's middle bins and are only a first guess. Trim WHITE one number at a time until it looks neutral on your LED, in your room. A white card behind the LED makes the comparison easier.
The same comparison in MicroPython. WHITE is set for a 3.3 V board, which is every board MicroPython runs on here.
"""
RGB LED - equal numbers against white, MicroPython TK02 / /p/tk02
Wiring. Count from the square pad on the TinkerBlock board, LED side
up, header at the bottom:
GND -> GND
NC -> nothing (both NC pins are unconnected on the board)
NC -> nothing
RED -> GPIO 25 on an ESP32, GPIO 4 on an ESP32-S3,
GP13 on a Raspberry Pi Pico
GREEN -> GPIO 26, GPIO 5, GP14
BLUE -> GPIO 27, GPIO 6, GP15
Thonny
Run > Configure interpreter MicroPython (ESP32) or
MicroPython (Raspberry Pi Pico)
Save it to the board as main.py to run it on every power-up.
Nothing to install: machine and time are built in.
"""
from machine import Pin, PWM
import time
# ESP32: 25, 26, 27. ESP32-S3: 4, 5, 6. Pico: 13, 14, 15.
red = PWM(Pin(4), freq=1000)
green = PWM(Pin(5), freq=1000)
blue = PWM(Pin(6), freq=1000)
# A first guess at white from a 3.3 V board: 84, 255, 122.
WHITE = (84, 255, 122)
def set_colour(r, g, b):
red.duty_u16(r * 257)
green.duty_u16(g * 257)
blue.duty_u16(b * 257)
while True:
set_colour(255, 255, 255)
print("255, 255, 255: equal numbers")
time.sleep_ms(2000)
set_colour(*WHITE)
print("WHITE: balanced")
time.sleep_ms(2000)Trim WHITE one number at a time, by about 10, and run it again. Pink means less red, violet or blue means less blue. Stop it with Ctrl-C in Thonny's shell.
When it does not work
It is a starting point, not a calibration. It comes from the middle of the datasheet's ranges, and your LED's green may be a sixth brighter or dimmer than that, and its blue a third. Change one number at a time, by about 10: pink means less red, blue or violet means less blue, green means turn the other two up.
Because white needs very little blue light. The eye makes white out of mostly green light, some red and a small amount of blue. Blue at full from 5 V already gives nearly twice the share of the light that white needs.
The white a computer screen shows, a slightly cool daylight white. A warmer white, like a filament bulb, needs more red and less blue. Trim by eye to whichever you want: there is no single right answer.
Yes, by about a fifth of the light, because two channels are turned down. It is the price of a neutral colour. The eye judges brightness by ratios, so the difference looks smaller than that.
Why the white you trimmed on an Uno is pink on an ESP32.
Why 3.3 V turns it pink →Edit this page — content/books/rgb-led/why-equal-numbers-are-not-white.mdx
Questions about this product
See what other owners have asked, and read their solutions.
RGB LED
Loading discussions…
Discuss this article
Ask about this page. The answer stays here, on the page it belongs to, for whoever hits the same wall next.