Skip to content

Commit 8873832

Browse files
authored
Merge pull request wled#4419 from DedeHai/PWM_brightness_fix
BUGFIX PWM brightness discontinuity (fixes wled#4396)
2 parents 9dad436 + 0ad65f4 commit 8873832

File tree

1 file changed

+8
-12
lines changed

1 file changed

+8
-12
lines changed

wled00/bus_manager.cpp

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -563,19 +563,15 @@ void BusPwm::show() {
563563
const unsigned maxBri = (1<<_depth); // possible values: 16384 (14), 8192 (13), 4096 (12), 2048 (11), 1024 (10), 512 (9) and 256 (8)
564564
[[maybe_unused]] const unsigned bitShift = dithering * 4; // if dithering, _depth is 12 bit but LEDC channel is set to 8 bit (using 4 fractional bits)
565565

566-
// use CIE brightness formula (cubic) to fit (or approximate linearity of) human eye perceived brightness
567-
// the formula is based on 12 bit resolution as there is no need for greater precision
566+
// use CIE brightness formula (linear + cubic) to approximate human eye perceived brightness
568567
// see: https://en.wikipedia.org/wiki/Lightness
569-
unsigned pwmBri = (unsigned)_bri * 100; // enlarge to use integer math for linear response
570-
if (pwmBri < 2040) {
571-
// linear response for values [0-20]
572-
pwmBri = ((pwmBri << 12) + 115043) / 230087; //adding '0.5' before division for correct rounding
573-
} else {
574-
// cubic response for values [21-255]
575-
pwmBri += 4080;
576-
float temp = (float)pwmBri / 29580.0f;
577-
temp = temp * temp * temp * (float)maxBri;
578-
pwmBri = (unsigned)temp; // pwmBri is in range [0-maxBri]
568+
unsigned pwmBri = _bri;
569+
if (pwmBri < 21) { // linear response for values [0-20]
570+
pwmBri = (pwmBri * maxBri + 2300 / 2) / 2300 ; // adding '0.5' before division for correct rounding, 2300 gives a good match to CIE curve
571+
} else { // cubic response for values [21-255]
572+
float temp = float(pwmBri + 41) / float(255 + 41); // 41 is to match offset & slope to linear part
573+
temp = temp * temp * temp * (float)maxBri;
574+
pwmBri = (unsigned)temp; // pwmBri is in range [0-maxBri] C
579575
}
580576

581577
[[maybe_unused]] unsigned hPoint = 0; // phase shift (0 - maxBri)

0 commit comments

Comments
 (0)