@@ -304,7 +304,7 @@ static uint8_t precise_kelvin_convert_to_percentage(uint16_t kelvin)
304304 * @param brightness Brightness value in the range 0-100
305305 * @param white_value Array to store the calculated cold and warm values for white output
306306 */
307- static void cct_and_brightness_convert_and_power_limit (lightbulb_led_beads_comb_t led_beads , float multiple , uint8_t cct , uint8_t brightness , uint16_t white_value [])
307+ static esp_err_t cct_and_brightness_convert_and_power_limit (lightbulb_led_beads_comb_t led_beads , float multiple , uint8_t cct , uint8_t brightness , uint16_t white_value [])
308308{
309309 uint16_t max_value = 0 ;
310310 hal_get_driver_feature (QUERY_MAX_INPUT_VALUE , & max_value );
@@ -353,6 +353,18 @@ static void cct_and_brightness_convert_and_power_limit(lightbulb_led_beads_comb_
353353 hal_get_curve_table_value ((uint16_t )value , & white_value [i ]);
354354 }
355355 }
356+
357+ #if CONFIG_ENABLE_LIGHTBULB_DEBUG
358+ uint16_t test_power = white_value [0 ] + white_value [1 ] + white_value [2 ] + white_value [3 ] + white_value [4 ];
359+ uint16_t limit_power = max_value * multiple * (brightness / 100.0 );
360+
361+ if (test_power > limit_power ) {
362+ ESP_LOGE (TAG , "Power exceeds expected, current: %d, expected:%d" , test_power , limit_power );
363+ return ESP_FAIL ;
364+ }
365+ #endif
366+
367+ return ESP_OK ;
356368}
357369
358370/**
@@ -414,33 +426,72 @@ static uint8_t process_white_brightness_limit(uint8_t brightness)
414426/**
415427 * @brief Recalculate color power
416428 * @attention 300% = 100% + 100% + 100% : Full power output on each channel. If single channel output is 3w then total output is 9w.
417- * @note
418- * input output(color_max_power = 100) output(color_max_power = 200) output(color_max_power = 300)
419- * 255,255,0 127,127,0 255,255,0 255,255,0
420- * 127,127,0 63,63,0 127,127,0 127,127,0
421- * 63,63,0 31,31,0 63,63,0 63,63,0
422- * 255,255,255 85,85,85 170,170,170 255,255,255
423- * 127,127,127 42,42,42 84,84,84 127,127,127
424- * 63,63,63 21,21,21 42,42,42 63,63,63
425429 *
430+ * lightbulb_power_limit_t limit = {
431+ * .color_max_power = 100,
432+ * .color_max_value = 100,
433+ * .color_min_value = 10,
434+ * .white_max_power = 100,
435+ * .white_max_brightness = 100,
436+ * .white_min_brightness = 10
437+ * };
438+ *
439+ * lightbulb_gamma_config_t Gamma = {
440+ * .balance_coefficient = {1.0, 1.0, 1.0, 1.0, 1.0},
441+ * .color_curve_coefficient = 2.0,
442+ * .white_curve_coefficient = 2.0,
443+ * };
444+ *
445+ * @note
446+ * input(hsv) output(color_max_power = 100) output(color_max_power = 200) output(color_max_power = 300)
447+ * 0,100,100 255,0,0 255,0,0 255,0,0
448+ * 0,100,1 79,0,0 79,0,0 79,0,0
449+ * 60,100,100 127,127,0 255,255,0 255,255,0
450+ * 60,100,1 39,39,0 79,79,0 79,79,0
451+ * 0,50,100 127,63,63 255,127,127 255,127,127
452+ * 0,50,1 40,19,19 79,38,38 79,38,38
453+ * 60,50,100 102,102,50 204,204,101 254,254,126
454+ * 60,50,1 31,31,15 63,63,30 79,79,38
455+ * 0,0,100 85,85,85 170,170,170 255,255,255
456+ * 0,0,1 26,26,26 52,52,52 79,79,79
426457 */
427- static void process_color_power_limit (float multiple , float rgbcw [5 ], uint16_t value , uint16_t out [5 ])
458+ static esp_err_t process_color_power_limit (float multiple , float rgbcw [5 ], uint16_t value , uint16_t out [5 ])
428459{
429460 uint16_t max_value ;
430- float max_power ;
431461 hal_get_driver_feature (QUERY_MAX_INPUT_VALUE , & max_value );
432- max_power = multiple * (max_value );
433-
434- float baseline = MAX (rgbcw [0 ], rgbcw [1 ]);
435- baseline = MAX (baseline , rgbcw [2 ]);
436- baseline = MAX (baseline , rgbcw [3 ]);
437- baseline = MAX (baseline , rgbcw [4 ]);
438- max_power = MIN (max_power , max_value / baseline );
439- ESP_LOGD (TAG , "%f, %d, %f" , max_power , max_value , baseline );
440- for (int i = 0 ; i < 5 ; i ++ ) {
441- float value = round (max_power * rgbcw [i ]);
442- hal_get_curve_table_value ((uint16_t )value , & out [i ]);
462+
463+ float scaled [5 ];
464+ float max_scale = 0.0f ;
465+ float max_scale_limit = (float )max_value ;
466+
467+ for (int i = 0 ; i < 5 ; ++ i ) {
468+ scaled [i ] = rgbcw [i ] * multiple ;
469+ if (scaled [i ] > max_scale ) {
470+ max_scale = scaled [i ];
471+ }
443472 }
473+
474+ float scale_factor = 1.0f ;
475+ if (max_scale > 1.0f ) {
476+ scale_factor = max_scale_limit / (max_scale * max_scale_limit );
477+ }
478+
479+ for (int i = 0 ; i < 5 ; ++ i ) {
480+ float value_f = scaled [i ] * scale_factor * max_value * (value / 100.0 );
481+ hal_get_curve_table_value ((uint16_t )value_f , & out [i ]);
482+ }
483+
484+ #if CONFIG_ENABLE_LIGHTBULB_DEBUG
485+ uint16_t test_power = out [0 ] + out [1 ] + out [2 ] + out [3 ] + out [4 ];
486+ uint16_t limit_power = max_value * multiple * (value / 100.0 );
487+
488+ if (test_power > limit_power ) {
489+ ESP_LOGE (TAG , "Power exceeds expected, current: %d, expected:%d" , test_power , limit_power );
490+ return ESP_FAIL ;
491+ }
492+ #endif
493+
494+ return ESP_OK ;
444495}
445496
446497static void timercb (TimerHandle_t tmr )
@@ -1247,11 +1298,11 @@ static esp_err_t lightbulb_hsv2rgb_adjusted(uint16_t hue, uint8_t saturation, ui
12471298 }
12481299 }
12491300
1250- * red = interpolated_rgbcw [0 ] * value / 100.0 ;
1251- * green = interpolated_rgbcw [1 ] * value / 100.0 ;
1252- * blue = interpolated_rgbcw [2 ] * value / 100.0 ;
1253- * cold = interpolated_rgbcw [3 ] * value / 100.0 ;
1254- * warm = interpolated_rgbcw [4 ] * value / 100.0 ;
1301+ * red = interpolated_rgbcw [0 ];
1302+ * green = interpolated_rgbcw [1 ];
1303+ * blue = interpolated_rgbcw [2 ];
1304+ * cold = interpolated_rgbcw [3 ];
1305+ * warm = interpolated_rgbcw [4 ];
12551306
12561307 return ESP_OK ;
12571308}
@@ -1265,14 +1316,21 @@ static esp_err_t _lightbulb_hsv2rgb(uint16_t hue, uint8_t saturation, uint8_t va
12651316
12661317 ESP_LOGI (TAG , "Convert 8 bit value [r:%d g:%d b:%d]" , _red , _green , _blue );
12671318
1268- * red = _red / 255.0 ;
1269- * green = _green / 255.0 ;
1270- * blue = _blue / 255.0 ;
1319+ if (value == 0 ) {
1320+ * red = 0 ;
1321+ * green = 0 ;
1322+ * blue = 0 ;
1323+ } else {
1324+ * red = _red / 255.0 ;
1325+ * green = _green / 255.0 ;
1326+ * blue = _blue / 255.0 ;
1327+ float total = * red + * green + * blue ;
1328+
1329+ * red = * red / total ;
1330+ * green = * green / total ;
1331+ * blue = * blue / total ;
1332+ }
12711333
1272- float total = * red + * green + * blue ;
1273- * red = * red / total ;
1274- * green = * green / total ;
1275- * blue = * blue / total ;
12761334 * cold = 0 ;
12771335 * warm = 0 ;
12781336
@@ -1486,10 +1544,10 @@ esp_err_t lightbulb_set_hsv(uint16_t hue, uint8_t saturation, uint8_t value)
14861544 ESP_LOGI (TAG , "Convert write value [r:%0.2f%% g:%0.2f%% b:%0.2f%% c:%0.2f%% w:%0.2f%%]" , color_param [0 ] * 100 , color_param [1 ] * 100 , color_param [2 ] * 100 , color_param [3 ] * 100 , color_param [4 ] * 100 );
14871545
14881546 // 3. Redistribute power
1489- process_color_power_limit (s_lb_obj -> power .color_max_power / 100.0 , color_param , _value , color_value );
1547+ err |= process_color_power_limit (s_lb_obj -> power .color_max_power / 100.0 , color_param , _value , color_value );
14901548 ESP_LOGI (TAG , "hal write value [r:%d g:%d b:%d c:%d w:%d], channel_mask:%d fade_ms:%d" , color_value [0 ], color_value [1 ], color_value [2 ], color_value [3 ], color_value [4 ], channel_mask , fade_time );
14911549
1492- err = hal_set_channel_group (color_value , channel_mask , fade_time );
1550+ err | = hal_set_channel_group (color_value , channel_mask , fade_time );
14931551 LIGHTBULB_CHECK (err == ESP_OK , "set hal channel group fail" , goto EXIT );
14941552
14951553 s_lb_obj -> status .on = true;
@@ -1623,10 +1681,10 @@ esp_err_t lightbulb_set_cctb(uint16_t cct, uint8_t brightness)
16231681 _brightness = process_white_brightness_limit (_brightness );
16241682
16251683 // 2. convert to cold warm and redistribute power
1626- cct_and_brightness_convert_and_power_limit (s_lb_obj -> cap .led_beads , s_lb_obj -> power .white_max_power / 100.0 , cct , _brightness , white_value );
1684+ err |= cct_and_brightness_convert_and_power_limit (s_lb_obj -> cap .led_beads , s_lb_obj -> power .white_max_power / 100.0 , cct , _brightness , white_value );
16271685 ESP_LOGI (TAG , "hal write value [r:%d g:%d b:%d c:%d w:%d], channel_mask:%d fade_ms:%d" , white_value [0 ], white_value [1 ], white_value [2 ], white_value [3 ], white_value [4 ], channel_mask , fade_time );
16281686
1629- err = hal_set_channel_group (white_value , channel_mask , fade_time );
1687+ err | = hal_set_channel_group (white_value , channel_mask , fade_time );
16301688 LIGHTBULB_CHECK (err == ESP_OK , "set hal channel group fail" , goto EXIT );
16311689
16321690 s_lb_obj -> status .on = true;
0 commit comments