Bus manager changes for easier CCT & auto white.

Attempted per-strip auto white calculation (odd bug encountered).
This commit is contained in:
Blaz Kristan 2021-10-23 15:41:35 +02:00
parent 4bb30deca6
commit 1b23210902
3 changed files with 55 additions and 39 deletions

View File

@ -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()<realIndex || bus->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) {

View File

@ -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;

View File

@ -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