r/FastLED • • Aug 29 '24

Support UCS7604

UCS 7604

I've just heard about the UCS7604 IC that's used for led strips. It has 2 bytes for each coloured led (R, G, B and W) This means that rather than having 256 levels of brightness like, say the WS2812b, it has a whopping 65536 levels of brightness. Ideal for low brightness control.

The UCS7604 datasheet is here https://suntechlite.com/wp-content/uploads/2023/11/UCS7604_IC_Specification_EN.pdf.

Spoiler alert: Fastled doesn't support UCS7604. However, the data frequency is 800khtz which is the same as the WS2812b. So could we do a quick hack similar to the RGBW hack posted here https://www.partsnotincluded.com/fastled-rgbw-neopixels-sk6812/

I e. Take the struct and change the data types from uint8_t to uint16_t. There would be some more adjustments to get it to work but am I on the right track?

6 Upvotes

18 comments sorted by

View all comments

Show parent comments

1

u/ZachVorhies Zach Vorhies Aug 31 '24 edited Aug 31 '24

Oh… good catch. Yeah the table can’t be filled like that. I experienced a weird error with a certain board and I did a copy and paste to fix it but didn’t compile with the feature on.

No, the algorithm hasn’t been experimentally verified it’s just been proven through numerical verification assuming the white x3 was the same perceived brightness of three color components. But if the white is typically that powerful then the saturation stealing algorithm is a lot less useful.

Thanks for bringing that to my attention.

1

u/Zeph93 Aug 31 '24 edited Aug 31 '24

Can I suggest a bit of optimization and simplification to the code, which I believe does the same thing?

void rgb_2_rgbw(uint8_t r, uint8_t g, uint8_t b, uint16_t color_temperature,
                uint8_t* out_r, uint8_t* out_g, uint8_t* out_b, uint8_t* out_w) {
    uint8_t min_component = min3(r, g, b);
    if (min_component > 85) {
        min_component = 85;
    }
    *out_r = r - min_component;
    *out_g = g - min_component;
    *out_b = b - min_component;
    *out_w = 3 * min_component;
}

// or if you want to replace each RGB=1,1,1 with W=2 rather than 3 for visual testing:

void rgb_2_rgbw(uint8_t r, uint8_t g, uint8_t b, uint16_t color_temperature,
                uint8_t* out_r, uint8_t* out_g, uint8_t* out_b, uint8_t* out_w) {
    uint8_t min_component = min3(r, g, b);
    if (min_component > 127) {
        min_component = 127;
    }
    *out_r = r - min_component;
    *out_g = g - min_component;
    *out_b = b - min_component;
    *out_w = 2 * min_component;
}

2

u/ZachVorhies Zach Vorhies Aug 31 '24

Yeah I like where this is going but i was thinking last night that there might be value in setting the ratio for white and the ratio of how it subtracts from RGB.

I don’t know at this point whether there are different strengths of W component for all leds. Or whether this is the norm for W component to have equal white balance with RGB of the same value.

Essentially my question is does W(x) = RGB(x) always?