The FLS-M internally only uses CIE1931 xy chromaticity for all LED types. The possible CT range is based on the displayable color gamut.
The formula used for that is as follows:
void xy2mired(fixedPoint_t x, fixedPoint_t y, unsigned int *mired)
{
// McCamy's approximation
fixedPoint_t n = FIXEDPOINT_DIVIDE(
FIXEDPOINT_SUBTRACT(x, FLOAT_TO_FIXEDPOINT(0.3320)),
FIXEDPOINT_SUBTRACT(FLOAT_TO_FIXEDPOINT(0.1858), y)
);
fixedPoint_t nSquared = FIXEDPOINT_MULTIPLY(n, n);
fixedPoint_t nCubed = FIXEDPOINT_MULTIPLY(nSquared, n);
fixedPoint_t ct = // Scaled to 0K - 10000K -> 0.0 - 1.0
FIXEDPOINT_ADD(
FIXEDPOINT_ADD(
FIXEDPOINT_ADD(
FIXEDPOINT_MULTIPLY(CONVERT_TO_FIXEDPOINT(437,0,10000), nCubed),
FIXEDPOINT_MULTIPLY(CONVERT_TO_FIXEDPOINT(3601,0,10000), nSquared)
),
FIXEDPOINT_MULTIPLY(CONVERT_TO_FIXEDPOINT(6861,0,10000), n)
),
CONVERT_TO_FIXEDPOINT(5517,0,10000)
);
// TODO: rework
*mired = // Scaled to 0 - 1000 -> 0.0 - 1.0
CONVERT_FROM_FIXEDPOINT(
FIXEDPOINT_DIVIDE(
FIXEDPOINT_ONE_VALUE,
FIXEDPOINT_MULTIPLY(ct, CONVERT_TO_FIXEDPOINT(10,0,1))
),
0,
1000
);
}
Because the ESP32-C6 lacks a floating-point unit, we have to approximate with fixed-point math (in this case, 13-bit fractional depth). This leads to rounding errors, which are further amplified by the way mired is transformed into color temperature.
I’ll take a closer look at this for the next firmware release—it might make sense to add a dedicated color temperature field to the config builder.
Sorry for the inconvenience.