From 1b23210902fdf4775da1e28adba4bb17c51cc29e Mon Sep 17 00:00:00 2001 From: Blaz Kristan Date: Sat, 23 Oct 2021 15:41:35 +0200 Subject: [PATCH] Bus manager changes for easier CCT & auto white. Attempted per-strip auto white calculation (odd bug encountered). --- wled00/FX_fcn.cpp | 65 ++++++++++++++++++++++++++++---------------- wled00/bus_manager.h | 27 ++++++++---------- wled00/wled.h | 2 +- 3 files changed, 55 insertions(+), 39 deletions(-) diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index c7d67175..c457489b 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -194,19 +194,52 @@ void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w) { //auto calculate white channel value if enabled if (isRgbw) { - if (rgbwMode == RGBW_MODE_AUTO_BRIGHTER || (w == 0 && (rgbwMode == RGBW_MODE_DUAL || rgbwMode == RGBW_MODE_LEGACY))) - { - //white value is set to lowest RGB channel - //thank you to @Def3nder! - w = r < g ? (r < b ? r : b) : (g < b ? g : b); - } else if (rgbwMode == RGBW_MODE_AUTO_ACCURATE && w == 0) - { - w = r < g ? (r < b ? r : b) : (g < b ? g : b); - r -= w; g -= w; b -= w; + switch (rgbwMode) { + case RGBW_MODE_MANUAL_ONLY: + break; + default: + //white value is set to lowest RGB channel + //thank you to @Def3nder! + if (rgbwMode == RGBW_MODE_AUTO_BRIGHTER || w == 0) w = r < g ? (r < b ? r : b) : (g < b ? g : b); + if (rgbwMode == RGBW_MODE_AUTO_ACCURATE) { r -= w; g -= w; b -= w; } + break; } } if (SEGLEN) {//from segment + uint16_t realIndex = realPixelIndex(i); + uint16_t len = SEGMENT.length(); + + // determine if we can do white balance and accurate W calc + // NOTE & TODO: does not work correctly with custom mapping if map spans different strips + int16_t cct = -1; + for (uint8_t b = 0; b < busses.getNumBusses(); b++) { + Bus *bus = busses.getBus(b); + if (bus == nullptr || !bus->containsPixel(realIndex)) continue; + //if (bus == nullptr || bus->getStart()getStart()+bus->getLength()>realIndex) continue; + uint8_t busType = bus->getType(); +/* + // if we are in accurate white calculation mode subtract W but only for RGBW strip + if (rgbwMode == RGBW_MODE_AUTO_ACCURATE + && ( busType == TYPE_SK6812_RGBW + || busType == TYPE_TM1814 + || busType == TYPE_ANALOG_1CH + || busType == TYPE_ANALOG_2CH + || busType == TYPE_ANALOG_4CH + || busType == TYPE_ANALOG_5CH ) + ) { + // this will produce a bug (some out of bounds/mem leak error) + // causing loop() no longer being executed. + //r -= w; g -= w; b -= w; + } +*/ + if (allowCCT + || busType == TYPE_ANALOG_2CH + || busType == TYPE_ANALOG_5CH) { + if (cct<0) cct = SEGMENT.cct; + } + } + //color_blend(getpixel, col, _bri_t); (pseudocode for future blending of segments) if (_bri_t < 255) { r = scale8(r, _bri_t); @@ -217,20 +250,6 @@ void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w) uint32_t col = ((w << 24) | (r << 16) | (g << 8) | (b)); /* Set all the pixels in the group */ - uint16_t realIndex = realPixelIndex(i); - uint16_t len = SEGMENT.length(); - - // determine if we can do white balance - int16_t cct = -1; - for (uint8_t b = 0; b < busses.getNumBusses(); b++) { - Bus *bus = busses.getBus(b); - if (bus == nullptr || !bus->containsPixel(realIndex)) continue; - if (allowCCT || bus->getType() == TYPE_ANALOG_2CH || bus->getType() == TYPE_ANALOG_5CH) { - cct = SEGMENT.cct; - break; - } - } - for (uint16_t j = 0; j < SEGMENT.grouping; j++) { uint16_t indexSet = realIndex + (IS_REVERSE ? -j : j); if (indexSet >= SEGMENT.start && indexSet < SEGMENT.stop) { diff --git a/wled00/bus_manager.h b/wled00/bus_manager.h index 97a2560f..39855ecf 100644 --- a/wled00/bus_manager.h +++ b/wled00/bus_manager.h @@ -83,17 +83,17 @@ class Bus { virtual void setBrightness(uint8_t b) {}; virtual void cleanup() {}; virtual uint8_t getPins(uint8_t* pinArray) { return 0; } - virtual uint16_t getLength() { return 1; } + inline uint16_t getLength() { return _len; } virtual void setColorOrder() {} virtual uint8_t getColorOrder() { return COL_ORDER_RGB; } virtual uint8_t skippedLeds() { return 0; } - inline uint16_t getStart() { return _start; } - inline void setStart(uint16_t start) { _start = start; } - inline uint8_t getType() { return _type; } - inline bool isOk() { return _valid; } - inline bool isOffRefreshRequired() { return _needsRefresh; } - inline bool containsPixel(uint16_t pix) { return pix >= _start; } + inline uint16_t getStart() { return _start; } + inline void setStart(uint16_t start) { _start = start; } + inline uint8_t getType() { return _type; } + inline bool isOk() { return _valid; } + inline bool isOffRefreshRequired() { return _needsRefresh; } + bool containsPixel(uint16_t pix) { return pix >= _start && pix < _start+_len; } virtual bool isRgbw() { return false; } static bool isRgbw(uint8_t type) { @@ -108,6 +108,7 @@ class Bus { uint8_t _type = TYPE_NONE; uint8_t _bri = 255; uint16_t _start = 0; + uint16_t _len = 1; bool _valid = false; bool _needsRefresh = false; }; @@ -222,7 +223,6 @@ class BusDigital : public Bus { uint8_t _colorOrder = COL_ORDER_GRB; uint8_t _pins[2] = {255, 255}; uint8_t _iType = I_NONE; - uint16_t _len = 0; uint8_t _skip = 0; void * _busPtr = nullptr; }; @@ -271,11 +271,12 @@ class BusPwm : public Bus { uint8_t w = c >> 24; switch (_type) { - case TYPE_ANALOG_1CH: //one channel (white), use highest RGBW value - _data[0] = max(r, max(g, max(b, w))); + case TYPE_ANALOG_1CH: //one channel (white), relies on auto white calculation + _data[0] = w; //max(r, max(g, max(b, w))); break; case TYPE_ANALOG_2CH: //warm white + cold white // perhaps a non-linear adjustment would be in order. need to test + //w = max(r, max(g, max(b, w))); _data[1] = (w * cct) / 255; _data[0] = (w * (255-cct)) / 255; break; @@ -305,7 +306,7 @@ class BusPwm : public Bus { case TYPE_ANALOG_3CH: //standard dumb RGB case TYPE_ANALOG_4CH: //standard dumb RGBW case TYPE_ANALOG_5CH: //we'll want the white handling from 2CH here + RGB - _data[0] = r; _data[1] = g; _data[2] = b; _data[3] = w; _data[4] = 0; break; + _data[0] = r; _data[1] = g; _data[2] = b; _data[3] = w; _data[4] = w; break; } } @@ -402,12 +403,10 @@ class BusNetwork : public Bus { // break; // } _UDPchannels = _rgbw ? 4 : 3; - //_rgbw |= bc.rgbwOverride; // RGBW override in bit 7 or can have a special type _data = (byte *)malloc(bc.count * _UDPchannels); if (_data == nullptr) return; memset(_data, 0, bc.count * _UDPchannels); _len = bc.count; - //_colorOrder = bc.colorOrder; _client = IPAddress(bc.pins[0],bc.pins[1],bc.pins[2],bc.pins[3]); _broadcastLock = false; _valid = true; @@ -482,8 +481,6 @@ class BusNetwork : public Bus { private: IPAddress _client; - uint16_t _len = 0; - //uint8_t _colorOrder; uint8_t _bri = 255; uint8_t _UDPtype; uint8_t _UDPchannels; diff --git a/wled00/wled.h b/wled00/wled.h index ed4a0756..164eff48 100644 --- a/wled00/wled.h +++ b/wled00/wled.h @@ -8,7 +8,7 @@ */ // version code in format yymmddb (b = daily build) -#define VERSION 2110211 +#define VERSION 2110231 //uncomment this if you have a "my_config.h" file you'd like to use //#define WLED_USE_MY_CONFIG