Color.LED
(Color v0.4.0)
Copy Markdown
Colour conversion for multi-channel addressable LEDs — fixtures with one or more extra white channels alongside R, G, B.
Two channel layouts are supported:
RGBW —
Color.LED.RGBW. Three coloured LEDs plus a single white LED per pixel. The white LED's colour temperature is fixed by the chip variant. Used by e.g. WS2814 (warm, neutral and cool variants) and the SK6812-RGBW family.RGBWW / RGB+CCT —
Color.LED.RGBWW. Three coloured LEDs plus a warm white and a cool white LED per pixel. Used by e.g. WS2805 and several SK6812 variants. The two whites can be blended to reach any CCT on the line between them.
These structs are intentionally device-referred. They do
not implement Color.Behaviour (which assumes a device-
independent colour space with a single from_xyz/1) because
converting to an RGBW/RGBWW pixel requires the white LED's
colour temperature — there is no canonical answer without that
parameter. Use Color.LED.RGBW.from_srgb/2 and
Color.LED.RGBWW.from_srgb/2 explicitly.
Channel semantics
All channels — r, g, b, w, ww, cw — are linear
drive values in [0.0, 1.0], not sRGB-companded values. A
value of 0.0 means "LED off"; 1.0 means "LED at full". The
library applies sRGB companding when converting from a
Color.SRGB struct, and un-compands back on the way out.
The R/G/B primaries are assumed to match the sRGB working space
(close enough for all WS281x / SK681x chips; exact for chips
binned to sRGB). If you need a different primary set, stage the
conversion through Color.RGB (linear, any working space) and
then translate the matrix yourself.
Extraction algorithm
For RGBW, given a target linear-sRGB (R, G, B) and a white LED
whose spectral output corresponds to linear-sRGB (Rw, Gw, Bw)
at full drive, the extraction is:
w = min(1, R/Rw, G/Gw, B/Bw) (clamped to ≥ 0)
r = R − w·Rw
g = G − w·Gw
b = B − w·BwThis maximises the white channel while keeping all RGB channels non-negative — more light from the (usually more efficient) white LED, less from the RGB LEDs.
For RGBWW the algorithm first picks a blend ratio between the
warm and cool whites matching the target's correlated colour
temperature, synthesises an effective mixed white at that
blend, then runs the RGBW extraction against that mixed white.
The resulting total white is split back into ww and cw by
the same ratio.
Chip presets
chip_options/1 returns the default CCT options for the common
chip variants:
| Chip | Kind | Typical white temperature(s) |
|---|---|---|
:ws2814_ww | RGBW | 3000 K (warm) |
:ws2814_nw | RGBW | 4500 K (neutral) |
:ws2814_cw | RGBW | 6000 K (cool) |
:sk6812_ww | RGBW | 3000 K |
:sk6812_nw | RGBW | 4500 K |
:sk6812_cw | RGBW | 6500 K |
:ws2805 | RGBWW | 3000 K warm + 6500 K cool |
These are typical values from datasheets and vendor pages — actual parts vary by batch and binning. Measure yours if you need calibration-grade accuracy.
Example
# Build a pixel for a WS2805 fixture from an sRGB colour
options = Color.LED.chip_options(:ws2805)
{:ok, target} = Color.new("#ffa500") # orange
pixel = Color.LED.RGBWW.from_srgb(target, options)
# => %Color.LED.RGBWW{r: …, g: …, b: …, ww: …, cw: …,
# warm_temperature: 3000,
# cool_temperature: 6500,
# alpha: nil}
# Preview what the pixel will actually emit:
{:ok, srgb_preview} = Color.LED.RGBWW.to_srgb(pixel)
Summary
Functions
Returns the recommended extraction options for a named LED chip variant.
Returns the list of supported chip presets.
Types
Functions
Returns the recommended extraction options for a named LED chip variant.
The returned keyword list can be passed directly to
Color.LED.RGBW.from_srgb/2 or Color.LED.RGBWW.from_srgb/2 —
the :kind entry tells you which one.
Arguments
chipis a chip atom. See the chip table in the module doc.
Returns
- A keyword list with at least
:kind(:rgbwor:rgbww) and the relevant temperature(s).
Examples
iex> Color.LED.chip_options(:ws2814_ww)
[kind: :rgbw, white_temperature: 3000]
iex> Color.LED.chip_options(:ws2805)
[kind: :rgbww, warm_temperature: 3000, cool_temperature: 6500]
@spec chips() :: [chip()]
Returns the list of supported chip presets.
Examples
iex> :ws2814_nw in Color.LED.chips()
true
iex> :ws2805 in Color.LED.chips()
true