openshwprojects / OpenBK7231T_App

Open source firmware (Tasmota/Esphome replacement) for BK7231T, BK7231N, BL2028N, T34, XR809, W800/W801, W600/W601, BL602 and LN882H
https://openbekeniot.github.io/webapp/devicesList.html
1.44k stars 268 forks source link

RGBCW Bulbs with no COOL LEDs issue. Inaccurate Temperature setting #763

Open panchomira opened 1 year ago

panchomira commented 1 year ago

First at all. Thanks to the owner of this project! Its amazing to be able to really be the owners of the products that we buy, ant the possibility to run open source firmware.

AGC_20230403_065551593

LAMP: Etheos 9w E27 Chip: Chipset: BK7231N with BP5758D Driver Firmware: Version: 1.15.637

The problem that, besides me, I saw another one have it and probably a few more will have.

As far as I can tell, my bulb does not have a cool white LED. Therefore, the original Tuya firmware achieves Cool white with the help of RGB LEDs.

AGC_20230403_065641214

Currently, I am using Flag 24 ([LED] Emulate Cool White with RGB in device with four PWMS - Red is 0, Green 1, Blue 2, and Warm is 4), which tries to do the same thing, but it's way off because it doesn't work the same way as the original firmware.

In the original firmware, when you set the temperature to around 4500K, all the warm white LEDs and RGB LEDs turn on (although I don't think they're all at the same intensity). Then, when you select the coolest white, only the warm white LED, the blue and green RGB LED turn on, not red. See documentation at the end

I tested the white balance on the original firmware using a camera, and it's pretty accurate in terms of the Kelvin temperature. Even when emulating temperature with RGB, it produces very little color in the final light projection, staying very true to a pure white.

Now, on OpenBK, it goes with all the RGB LEDs as soon as soon as the lamp its not in the warmest setting, and stays the same (but changing the intensity of all RGB LEDs) even in the Coolest setting (not the way the original firmware does it) See documentation below

Here are screenshot of the configuration and how it reflects on the LEDs of the bulb. Both in stock firmware and OpenBK Original Firmware:

Warmest Screenshot_20230403-035835_Tuya Smart 2023-04-03-04-00-48-153 Middle Screenshot_20230403-040103_Tuya Smart 2023-04-03-04-01-09-826 Coolest Screenshot_20230403-040610_Tuya Smart 2023-04-03-04-01-22-084

OPENBK firmware:

Warmest: (So far so good) Captura de Pantalla 2023-04-03 a la(s) 04 02 17 2023-04-03-04-02-26-174 Middle: (Not ok) Captura de Pantalla 2023-04-03 a la(s) 04 02 48 Coolest: (the worst) here the white LEDs are turned off, which in the original firmware doesn't happen. Captura de Pantalla 2023-04-03 a la(s) 04 03 35 2023-04-03-04-03-43-555

I would love to solve this issue because the temperature is not usable in the current state of OpenBk and this type of lamp. However, I have little to no knowledge in writing firmware.

If someone can help me with this, I am willing to spend some hours trying to calibrate it.

openshwprojects commented 1 year ago

Hello, do you know the math behind it?

I have no experience when it comes to colours, but I know where the related code snippet is. I have moved it to separate function: https://github.com/openshwprojects/OpenBK7231T_App/commit/3ff88ff989c260720a07133d2aec01f3fd34eff6

With Github you can do a fork and you will get automatic github build on your fork and in potential pull request.

Are you interested in changing this function to reflect the desired behaviour? image

The +0 is Red, the +1 is Green, and +2 is Blue.

If I understand correctly, you just want to add a fractions there? Like chVal * 0.5 to make red contribution smaller? Etc etc?

openshwprojects commented 1 year ago

Wait, is it a PWM based device or a I2C driver? Because the I2C colour setting does not currently go through the LED_ApplyEmulatedCool route.

panchomira commented 1 year ago

Wait, is it a PWM based device or a I2C driver? Because the I2C colour setting does not currently go through the LED_ApplyEmulatedCool route.

Hello! Thanks for the super fast response!

I forgot to mention that my bulb is using the BP5758D Driver. What I just tried (but didn't work) was to do a calibration with "led_gammaCtrl" to make the "white" RGB perform as the coolest setting in white mode (because the coolest mode tries to use all RGB like if it was white). I managed to do it, but it doesn't apply to the "coolest white" with RGB emulation.

Im totally willing to learn and fix it. (as far as I can haha)

openshwprojects commented 1 year ago

I have corrected the code so the calculation is shared between I2C drivers and PWM.

https://github.com/openshwprojects/OpenBK7231T_App/commit/6b502cfbb78c41320ddd09162b15d9d114118439

This function: image maps cool value to RGB.

You can edit it freely, if you think that we should use different fractions for each colour.

Maybe we should use luminance algorithm? image

openshwprojects commented 1 year ago

This approach allows you to change the fractions of R G B for cool emulation. But... do you also want to keep Warm LEDs on with the coolest option?

panchomira commented 1 year ago

This approach allows you to change the fractions of R G B for cool emulation. But... do you also want to keep Warm LEDs on with the coolest option?

Amazing! And thanks!

About the Warm LEDs, yes, we should keep it on since is the way the original firmware achieves color accuracy and brightness. As I mentioned on the post, once the setting is in its coolest, only the blue and green are turned on (besides the Warm LEDs, of course), and in the middle, the three RGB are turned on. I guess this has to do with color accuracy (even if it means no color on the final projection of light). If I find a way to emulate this maybe we can find a fix for all the bulbs that don't have the Cool LEDs from now on.

So, I'll take a look at the code right not and start thinking about it. I have to sleep in a few mins but I'll keep texting here for future considerations on how to fix it.

panchomira commented 1 year ago

Okay, I don't know what im doing exactly. But I tried to make ChatGPT teach me a little bit and make the changes I was looking for (just to set an example). It may be totally wrong anyways.

`

void LED_CalculateEmulatedCool(float inCool, float *outRGB) {
    if (inCool <= x) { // If inCool is less than or equal to x, all three RGB LEDs turn on at 50%.
        outRGB[0] = 0.5;
        outRGB[1] = 0.5;
        outRGB[2] = 0.5;
    } else { // If inCool is greater than x, the green and blue RGB LEDs are turned on at 50%, and the red LED is turned off.
        outRGB[0] = 0;
        outRGB[1] = 0.5;
        outRGB[2] = 0.5;
    }
}

void LED_ApplyEmulatedCool(int firstChannelIndex, float chVal) {
    float rgb[3];
    LED_CalculateEmulatedCool(chVal, rgb);
    CHANNEL_Set_FloatPWM(firstChannelIndex + 0, rgb[0], CHANNEL_SET_FLAG_SKIP_MQTT | CHANNEL_SET_FLAG_SILENT);
    CHANNEL_Set_FloatPWM(firstChannelIndex + 1, rgb[1], CHANNEL_SET_FLAG_SKIP_MQTT | CHANNEL_SET_FLAG_SILENT);
    CHANNEL_Set_FloatPWM(firstChannelIndex + 2, rgb[2], CHANNEL_SET_FLAG_SKIP_MQTT | CHANNEL_SET_FLAG_SILENT);
}

void LED_I2CDriver_WriteRGBCW(float* finalRGBCW) {
#ifdef ENABLE_DRIVER_LED
    if (CFG_HasFlag(OBK_FLAG_LED_EMULATE_COOL_WITH_RGB)) {
        if (g_lightMode == Light_Temperature) {
            // the format is RGBCW
            // Emulate C with RGB
            finalRGBCW[0] = finalRGBCW[1] = finalRGBCW[2] = finalRGBCW[3];
            LED_CalculateEmulatedCool(finalRGBCW[3], finalRGBCW);
            // C is unused
            finalRGBCW[3] = 0;
            // keep W at maximum
            finalRGBCW[4] = 1.0;
            // set RGB values
            CHANNEL_Set_FloatPWM(0, finalRGBCW[0], CHANNEL_SET_FLAG_SKIP_MQTT | CHANNEL_SET_FLAG_SILENT);
            CHANNEL_Set_FloatPWM(1, finalRGBCW[1], CHANNEL_SET_FLAG_SKIP_MQTT | CHANNEL_SET_FLAG_SILENT);
            CHANNEL_Set_FloatPWM(2, finalRGBCW[2], CHANNEL_SET_FLAG_SKIP_MQTT | CHANNEL_SET_FLAG_SILENT);
            // set white value
            CHANNEL_Set_FloatPWM(3, 1.0, CHANNEL_SET_FLAG_SKIP_MQTT | CHANNEL_SET_FLAG_SILENT);
        }
    }
#endif
}

`

openshwprojects commented 1 year ago

You should only modify finalRGBCW inside LED_I2CDriver_WriteRGBCW to suit your needs, no need for PWM calls.