CCT bus manager logic simplification
CCT from RGB if none set (-1)
This commit is contained in:
parent
b3324d22f5
commit
ea0f37f5b9
10
wled00/FX.h
10
wled00/FX.h
@ -165,12 +165,12 @@
|
|||||||
#define FX_MODE_FIRE_FLICKER 45
|
#define FX_MODE_FIRE_FLICKER 45
|
||||||
#define FX_MODE_GRADIENT 46
|
#define FX_MODE_GRADIENT 46
|
||||||
#define FX_MODE_LOADING 47
|
#define FX_MODE_LOADING 47
|
||||||
#define FX_MODE_POLICE 48
|
#define FX_MODE_POLICE 48 // candidate for removal (after below three)
|
||||||
#define FX_MODE_POLICE_ALL 49 // candidate for removal
|
#define FX_MODE_POLICE_ALL 49 // candidate for removal
|
||||||
#define FX_MODE_TWO_DOTS 50
|
#define FX_MODE_TWO_DOTS 50
|
||||||
#define FX_MODE_TWO_AREAS 51
|
#define FX_MODE_TWO_AREAS 51 // candidate for removal
|
||||||
#define FX_MODE_RUNNING_DUAL 52
|
#define FX_MODE_RUNNING_DUAL 52
|
||||||
#define FX_MODE_HALLOWEEN 53
|
#define FX_MODE_HALLOWEEN 53 // candidate for removal
|
||||||
#define FX_MODE_TRICOLOR_CHASE 54
|
#define FX_MODE_TRICOLOR_CHASE 54
|
||||||
#define FX_MODE_TRICOLOR_WIPE 55
|
#define FX_MODE_TRICOLOR_WIPE 55
|
||||||
#define FX_MODE_TRICOLOR_FADE 56
|
#define FX_MODE_TRICOLOR_FADE 56
|
||||||
@ -247,7 +247,7 @@ class WS2812FX {
|
|||||||
|
|
||||||
// segment parameters
|
// segment parameters
|
||||||
public:
|
public:
|
||||||
typedef struct Segment { // 30 (32 in memory) bytes
|
typedef struct Segment { // 31 (32 in memory) bytes
|
||||||
uint16_t start;
|
uint16_t start;
|
||||||
uint16_t stop; //segment invalid if stop == 0
|
uint16_t stop; //segment invalid if stop == 0
|
||||||
uint16_t offset;
|
uint16_t offset;
|
||||||
@ -259,7 +259,7 @@ class WS2812FX {
|
|||||||
uint8_t grouping, spacing;
|
uint8_t grouping, spacing;
|
||||||
uint8_t opacity;
|
uint8_t opacity;
|
||||||
uint32_t colors[NUM_COLORS];
|
uint32_t colors[NUM_COLORS];
|
||||||
uint8_t cct; //0==2000K, 255==10160K
|
int16_t cct; //-1==auto (no RGB balance correction), 0==1900K, 255==10091K
|
||||||
char *name;
|
char *name;
|
||||||
bool setColor(uint8_t slot, uint32_t c, uint8_t segn) { //returns true if changed
|
bool setColor(uint8_t slot, uint32_t c, uint8_t segn) { //returns true if changed
|
||||||
if (slot >= NUM_COLORS || segn >= MAX_NUM_SEGMENTS) return false;
|
if (slot >= NUM_COLORS || segn >= MAX_NUM_SEGMENTS) return false;
|
||||||
|
@ -138,6 +138,7 @@ void WS2812FX::service() {
|
|||||||
|
|
||||||
if (!SEGMENT.getOption(SEG_OPTION_FREEZE)) { //only run effect function if not frozen
|
if (!SEGMENT.getOption(SEG_OPTION_FREEZE)) { //only run effect function if not frozen
|
||||||
_virtualSegmentLength = SEGMENT.virtualLength();
|
_virtualSegmentLength = SEGMENT.virtualLength();
|
||||||
|
busses.setSegmentCCT(SEGMENT.cct, correctWB);
|
||||||
_bri_t = SEGMENT.opacity; _colors_t[0] = SEGMENT.colors[0]; _colors_t[1] = SEGMENT.colors[1]; _colors_t[2] = SEGMENT.colors[2];
|
_bri_t = SEGMENT.opacity; _colors_t[0] = SEGMENT.colors[0]; _colors_t[1] = SEGMENT.colors[1]; _colors_t[2] = SEGMENT.colors[2];
|
||||||
if (!IS_SEGMENT_ON) _bri_t = 0;
|
if (!IS_SEGMENT_ON) _bri_t = 0;
|
||||||
for (uint8_t t = 0; t < MAX_NUM_TRANSITIONS; t++) {
|
for (uint8_t t = 0; t < MAX_NUM_TRANSITIONS; t++) {
|
||||||
@ -156,6 +157,7 @@ void WS2812FX::service() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
_virtualSegmentLength = 0;
|
_virtualSegmentLength = 0;
|
||||||
|
busses.setSegmentCCT(-1);
|
||||||
if(doShow) {
|
if(doShow) {
|
||||||
yield();
|
yield();
|
||||||
show();
|
show();
|
||||||
@ -191,21 +193,6 @@ void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w)
|
|||||||
uint16_t realIndex = realPixelIndex(i);
|
uint16_t realIndex = realPixelIndex(i);
|
||||||
uint16_t len = SEGMENT.length();
|
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 (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)
|
//color_blend(getpixel, col, _bri_t); (pseudocode for future blending of segments)
|
||||||
if (_bri_t < 255) {
|
if (_bri_t < 255) {
|
||||||
r = scale8(r, _bri_t);
|
r = scale8(r, _bri_t);
|
||||||
@ -226,14 +213,14 @@ void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w)
|
|||||||
if (indexMir >= SEGMENT.stop) indexMir -= len;
|
if (indexMir >= SEGMENT.stop) indexMir -= len;
|
||||||
|
|
||||||
if (indexMir < customMappingSize) indexMir = customMappingTable[indexMir];
|
if (indexMir < customMappingSize) indexMir = customMappingTable[indexMir];
|
||||||
busses.setPixelColor(indexMir, col, cct);
|
busses.setPixelColor(indexMir, col);
|
||||||
}
|
}
|
||||||
/* offset/phase */
|
/* offset/phase */
|
||||||
indexSet += SEGMENT.offset;
|
indexSet += SEGMENT.offset;
|
||||||
if (indexSet >= SEGMENT.stop) indexSet -= len;
|
if (indexSet >= SEGMENT.stop) indexSet -= len;
|
||||||
|
|
||||||
if (indexSet < customMappingSize) indexSet = customMappingTable[indexSet];
|
if (indexSet < customMappingSize) indexSet = customMappingTable[indexSet];
|
||||||
busses.setPixelColor(indexSet, col, cct);
|
busses.setPixelColor(indexSet, col);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else { //live data, etc.
|
} else { //live data, etc.
|
||||||
@ -618,7 +605,7 @@ void WS2812FX::resetSegments() {
|
|||||||
_segments[0].setOption(SEG_OPTION_SELECTED, 1);
|
_segments[0].setOption(SEG_OPTION_SELECTED, 1);
|
||||||
_segments[0].setOption(SEG_OPTION_ON, 1);
|
_segments[0].setOption(SEG_OPTION_ON, 1);
|
||||||
_segments[0].opacity = 255;
|
_segments[0].opacity = 255;
|
||||||
_segments[0].cct = 128;
|
_segments[0].cct = -1;
|
||||||
|
|
||||||
for (uint16_t i = 1; i < MAX_NUM_SEGMENTS; i++)
|
for (uint16_t i = 1; i < MAX_NUM_SEGMENTS; i++)
|
||||||
{
|
{
|
||||||
@ -626,7 +613,7 @@ void WS2812FX::resetSegments() {
|
|||||||
_segments[i].grouping = 1;
|
_segments[i].grouping = 1;
|
||||||
_segments[i].setOption(SEG_OPTION_ON, 1);
|
_segments[i].setOption(SEG_OPTION_ON, 1);
|
||||||
_segments[i].opacity = 255;
|
_segments[i].opacity = 255;
|
||||||
_segments[i].cct = 128;
|
_segments[i].cct = -1;
|
||||||
_segments[i].speed = DEFAULT_SPEED;
|
_segments[i].speed = DEFAULT_SPEED;
|
||||||
_segments[i].intensity = DEFAULT_INTENSITY;
|
_segments[i].intensity = DEFAULT_INTENSITY;
|
||||||
_segment_runtimes[i].reset();
|
_segment_runtimes[i].reset();
|
||||||
@ -1163,3 +1150,4 @@ uint32_t WS2812FX::gamma32(uint32_t color)
|
|||||||
}
|
}
|
||||||
|
|
||||||
WS2812FX* WS2812FX::instance = nullptr;
|
WS2812FX* WS2812FX::instance = nullptr;
|
||||||
|
int16_t Bus::_cct = -1;
|
@ -74,7 +74,7 @@ struct BusConfig {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//parent class of BusDigital and BusPwm
|
//parent class of BusDigital, BusPwm, and BusNetwork
|
||||||
class Bus {
|
class Bus {
|
||||||
public:
|
public:
|
||||||
Bus(uint8_t type, uint16_t start, uint8_t aw) {
|
Bus(uint8_t type, uint16_t start, uint8_t aw) {
|
||||||
@ -88,7 +88,6 @@ class Bus {
|
|||||||
virtual void show() {}
|
virtual void show() {}
|
||||||
virtual bool canShow() { return true; }
|
virtual bool canShow() { return true; }
|
||||||
virtual void setPixelColor(uint16_t pix, uint32_t c) {};
|
virtual void setPixelColor(uint16_t pix, uint32_t c) {};
|
||||||
virtual void setPixelColor(uint16_t pix, uint32_t c, uint8_t cct) {};
|
|
||||||
virtual uint32_t getPixelColor(uint16_t pix) { return 0; };
|
virtual uint32_t getPixelColor(uint16_t pix) { return 0; };
|
||||||
virtual void setBrightness(uint8_t b) {};
|
virtual void setBrightness(uint8_t b) {};
|
||||||
virtual void cleanup() {};
|
virtual void cleanup() {};
|
||||||
@ -111,6 +110,9 @@ class Bus {
|
|||||||
if (type > TYPE_ONOFF && type <= TYPE_ANALOG_5CH && type != TYPE_ANALOG_3CH) return true;
|
if (type > TYPE_ONOFF && type <= TYPE_ANALOG_5CH && type != TYPE_ANALOG_3CH) return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
static void setCCT(uint16_t cct) {
|
||||||
|
_cct = cct;
|
||||||
|
}
|
||||||
|
|
||||||
bool reversed = false;
|
bool reversed = false;
|
||||||
|
|
||||||
@ -122,16 +124,18 @@ class Bus {
|
|||||||
bool _valid = false;
|
bool _valid = false;
|
||||||
bool _needsRefresh = false;
|
bool _needsRefresh = false;
|
||||||
uint8_t _autoWhiteMode = 0;
|
uint8_t _autoWhiteMode = 0;
|
||||||
|
static int16_t _cct;
|
||||||
|
|
||||||
uint32_t autoWhiteCalc(uint32_t c) {
|
uint32_t autoWhiteCalc(uint32_t c) {
|
||||||
if (_autoWhiteMode == RGBW_MODE_MANUAL_ONLY) return c;
|
if (_autoWhiteMode == RGBW_MODE_MANUAL_ONLY) return c;
|
||||||
|
uint8_t w = W(c);
|
||||||
|
//ignore auto-white calculation if w>0 and mode DUAL (DUAL behaves as BRIGHTER if w==0)
|
||||||
|
if (w > 0 && _autoWhiteMode == RGBW_MODE_DUAL) return c;
|
||||||
uint8_t r = R(c);
|
uint8_t r = R(c);
|
||||||
uint8_t g = G(c);
|
uint8_t g = G(c);
|
||||||
uint8_t b = B(c);
|
uint8_t b = B(c);
|
||||||
uint8_t w = W(c);
|
w = r < g ? (r < b ? r : b) : (g < b ? g : b);
|
||||||
// ignore auto-white calculation if w>0 and mode DUAL (DUAL behaves as BRIGHTER if w==0)
|
if (_autoWhiteMode == RGBW_MODE_AUTO_ACCURATE) { r -= w; g -= w; b -= w; } //subtract w in ACCURATE mode
|
||||||
if (!(w > 0 && _autoWhiteMode == RGBW_MODE_DUAL)) w = r < g ? (r < b ? r : b) : (g < b ? g : b);
|
|
||||||
if (_autoWhiteMode == RGBW_MODE_AUTO_ACCURATE) { r -= w; g -= w; b -= w; } // subtract w in ACCURATE mode
|
|
||||||
return RGBW32(r, g, b, w);
|
return RGBW32(r, g, b, w);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -181,17 +185,13 @@ class BusDigital : public Bus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void setPixelColor(uint16_t pix, uint32_t c) {
|
void setPixelColor(uint16_t pix, uint32_t c) {
|
||||||
if (getAutoWhiteMode() != RGBW_MODE_MANUAL_ONLY) c = autoWhiteCalc(c);
|
c = autoWhiteCalc(c);
|
||||||
|
if (_cct >= 1900) c = colorBalanceFromKelvin(_cct, c); //color correction from CCT
|
||||||
if (reversed) pix = _len - pix -1;
|
if (reversed) pix = _len - pix -1;
|
||||||
else pix += _skip;
|
else pix += _skip;
|
||||||
PolyBus::setPixelColor(_busPtr, _iType, pix, c, _colorOrder);
|
PolyBus::setPixelColor(_busPtr, _iType, pix, c, _colorOrder);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setPixelColor(uint16_t pix, uint32_t c, uint8_t cct) {
|
|
||||||
c = colorBalanceFromKelvin(2000+(cct<<5), c); // color correction from CCT
|
|
||||||
setPixelColor(pix, c);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t getPixelColor(uint16_t pix) {
|
uint32_t getPixelColor(uint16_t pix) {
|
||||||
if (reversed) pix = _len - pix -1;
|
if (reversed) pix = _len - pix -1;
|
||||||
else pix += _skip;
|
else pix += _skip;
|
||||||
@ -282,22 +282,30 @@ class BusPwm : public Bus {
|
|||||||
_valid = true;
|
_valid = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
void setPixelColor(uint16_t pix, uint32_t c, uint8_t cct) {
|
void setPixelColor(uint16_t pix, uint32_t c) {
|
||||||
if (pix != 0 || !_valid) return; //only react to first pixel
|
if (pix != 0 || !_valid) return; //only react to first pixel
|
||||||
if (getAutoWhiteMode() != RGBW_MODE_MANUAL_ONLY) c = autoWhiteCalc(c);
|
if (_type == TYPE_ANALOG_3CH && _cct >= 1900) {
|
||||||
c = colorBalanceFromKelvin(2000+(cct<<5), c); // color correction from CCT (w remains unchanged)
|
c = colorBalanceFromKelvin(_cct, c); //color correction from CCT
|
||||||
|
}
|
||||||
|
c = autoWhiteCalc(c);
|
||||||
uint8_t r = R(c);
|
uint8_t r = R(c);
|
||||||
uint8_t g = G(c);
|
uint8_t g = G(c);
|
||||||
uint8_t b = B(c);
|
uint8_t b = B(c);
|
||||||
uint8_t w = W(c);
|
uint8_t w = W(c);
|
||||||
|
uint8_t cct = 0; //0 - full warm white, 255 - full cold white
|
||||||
|
if (_cct > -1) {
|
||||||
|
if (_cct >= 1900) cct = (_cct - 1900) >> 5;
|
||||||
|
else if (_cct < 256) cct = _cct;
|
||||||
|
} else {
|
||||||
|
cct = (approximateKelvinFromRGB(c) - 1900) >> 5;
|
||||||
|
}
|
||||||
|
|
||||||
switch (_type) {
|
switch (_type) {
|
||||||
case TYPE_ANALOG_1CH: //one channel (white), relies on auto white calculation
|
case TYPE_ANALOG_1CH: //one channel (white), relies on auto white calculation
|
||||||
_data[0] = w; //max(r, max(g, max(b, w)));
|
_data[0] = w;
|
||||||
break;
|
break;
|
||||||
case TYPE_ANALOG_2CH: //warm white + cold white
|
case TYPE_ANALOG_2CH: //warm white + cold white
|
||||||
// perhaps a non-linear adjustment would be in order. need to test
|
// 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[1] = (w * cct) / 255;
|
||||||
_data[0] = (w * (255-cct)) / 255;
|
_data[0] = (w * (255-cct)) / 255;
|
||||||
break;
|
break;
|
||||||
@ -313,25 +321,6 @@ class BusPwm : public Bus {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void setPixelColor(uint16_t pix, uint32_t c) {
|
|
||||||
if (pix != 0 || !_valid) return; //only react to first pixel
|
|
||||||
if (getAutoWhiteMode() != RGBW_MODE_MANUAL_ONLY) c = autoWhiteCalc(c);
|
|
||||||
uint8_t r = R(c);
|
|
||||||
uint8_t g = G(c);
|
|
||||||
uint8_t b = B(c);
|
|
||||||
uint8_t w = W(c);
|
|
||||||
|
|
||||||
switch (_type) {
|
|
||||||
case TYPE_ANALOG_1CH: //one channel (white), use highest RGBW value
|
|
||||||
_data[0] = max(r, max(g, max(b, w))); break;
|
|
||||||
case TYPE_ANALOG_2CH: //warm white + cold white
|
|
||||||
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] = w; break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//does no index check
|
//does no index check
|
||||||
uint32_t getPixelColor(uint16_t pix) {
|
uint32_t getPixelColor(uint16_t pix) {
|
||||||
if (!_valid) return 0;
|
if (!_valid) return 0;
|
||||||
@ -432,7 +421,8 @@ class BusNetwork : public Bus {
|
|||||||
|
|
||||||
void setPixelColor(uint16_t pix, uint32_t c) {
|
void setPixelColor(uint16_t pix, uint32_t c) {
|
||||||
if (!_valid || pix >= _len) return;
|
if (!_valid || pix >= _len) return;
|
||||||
if (getAutoWhiteMode() != RGBW_MODE_MANUAL_ONLY) c = autoWhiteCalc(c);
|
if (_cct >= 1900) c = colorBalanceFromKelvin(_cct, c); //color correction from CCT
|
||||||
|
c = autoWhiteCalc(c);
|
||||||
uint16_t offset = pix * _UDPchannels;
|
uint16_t offset = pix * _UDPchannels;
|
||||||
_data[offset] = R(c);
|
_data[offset] = R(c);
|
||||||
_data[offset+1] = G(c);
|
_data[offset+1] = G(c);
|
||||||
@ -440,11 +430,6 @@ class BusNetwork : public Bus {
|
|||||||
if (_rgbw) _data[offset+3] = W(c);
|
if (_rgbw) _data[offset+3] = W(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setPixelColor(uint16_t pix, uint32_t c, uint8_t cct) {
|
|
||||||
c = colorBalanceFromKelvin(2000+(cct<<5), c); // color correction from CCT
|
|
||||||
setPixelColor(pix, c);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t getPixelColor(uint16_t pix) {
|
uint32_t getPixelColor(uint16_t pix) {
|
||||||
if (!_valid || pix >= _len) return 0;
|
if (!_valid || pix >= _len) return 0;
|
||||||
uint16_t offset = pix * _UDPchannels;
|
uint16_t offset = pix * _UDPchannels;
|
||||||
@ -564,8 +549,7 @@ class BusManager {
|
|||||||
Bus* b = busses[i];
|
Bus* b = busses[i];
|
||||||
uint16_t bstart = b->getStart();
|
uint16_t bstart = b->getStart();
|
||||||
if (pix < bstart || pix >= bstart + b->getLength()) continue;
|
if (pix < bstart || pix >= bstart + b->getLength()) continue;
|
||||||
if (cct<0) busses[i]->setPixelColor(pix - bstart, c); // no white balance
|
busses[i]->setPixelColor(pix - bstart, c);
|
||||||
else busses[i]->setPixelColor(pix - bstart, c, cct); // do white balance
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -575,6 +559,18 @@ class BusManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setSegmentCCT(int16_t cct, bool allowWBCorrection = false) {
|
||||||
|
if (cct > 255) { //kelvin value, convert to 0-255
|
||||||
|
if (cct < 1900) cct = 1900;
|
||||||
|
if (cct > 10091) cct = 10091;
|
||||||
|
if (!allowWBCorrection) cct = (cct - 1900) >> 5;
|
||||||
|
} else if (cct > -1) {
|
||||||
|
//if white balance correction allowed, save as kelvin value instead of 0-255
|
||||||
|
if (allowWBCorrection) cct = 1900 + (cct << 5);
|
||||||
|
} else cct = -1;
|
||||||
|
Bus::setCCT(cct);
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t getPixelColor(uint16_t pix) {
|
uint32_t getPixelColor(uint16_t pix) {
|
||||||
for (uint8_t i = 0; i < numBusses; i++) {
|
for (uint8_t i = 0; i < numBusses; i++) {
|
||||||
Bus* b = busses[i];
|
Bus* b = busses[i];
|
||||||
|
@ -80,7 +80,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
|||||||
CJSON(strip.ablMilliampsMax, hw_led[F("maxpwr")]);
|
CJSON(strip.ablMilliampsMax, hw_led[F("maxpwr")]);
|
||||||
CJSON(strip.milliampsPerLed, hw_led[F("ledma")]);
|
CJSON(strip.milliampsPerLed, hw_led[F("ledma")]);
|
||||||
uint8_t rgbwMode = hw_led[F("rgbwm")] | RGBW_MODE_DUAL; // use global setting (legacy)
|
uint8_t rgbwMode = hw_led[F("rgbwm")] | RGBW_MODE_DUAL; // use global setting (legacy)
|
||||||
CJSON(allowCCT, hw_led["cct"]);
|
CJSON(correctWB, hw_led["cct"]);
|
||||||
|
|
||||||
JsonArray ins = hw_led["ins"];
|
JsonArray ins = hw_led["ins"];
|
||||||
|
|
||||||
@ -520,7 +520,7 @@ void serializeConfig() {
|
|||||||
hw_led[F("total")] = strip.getLengthTotal(); //no longer read, but provided for compatibility on downgrade
|
hw_led[F("total")] = strip.getLengthTotal(); //no longer read, but provided for compatibility on downgrade
|
||||||
hw_led[F("maxpwr")] = strip.ablMilliampsMax;
|
hw_led[F("maxpwr")] = strip.ablMilliampsMax;
|
||||||
hw_led[F("ledma")] = strip.milliampsPerLed;
|
hw_led[F("ledma")] = strip.milliampsPerLed;
|
||||||
hw_led["cct"] = allowCCT;
|
hw_led["cct"] = correctWB;
|
||||||
|
|
||||||
JsonArray hw_led_ins = hw_led.createNestedArray("ins");
|
JsonArray hw_led_ins = hw_led.createNestedArray("ins");
|
||||||
|
|
||||||
|
@ -245,19 +245,10 @@ void colorRGBtoRGBW(byte* rgb) //rgb to rgbw (http://codewelt.com/rgbw). (RGBW_M
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// adjust RGB values based on color temperature in K (range [2800-10200]) (https://en.wikipedia.org/wiki/Color_balance)
|
|
||||||
void colorBalanceFromKelvin(uint16_t kelvin, byte *rgb)
|
|
||||||
{
|
|
||||||
uint32_t col = RGBW32(rgb[0], rgb[1], rgb[2], 0);
|
|
||||||
col = colorBalanceFromKelvin(kelvin, col);
|
|
||||||
rgb[0] = R(col);
|
|
||||||
rgb[1] = G(col);
|
|
||||||
rgb[2] = B(col);
|
|
||||||
}
|
|
||||||
|
|
||||||
byte correctionRGB[4] = {0,0,0,0};
|
byte correctionRGB[4] = {0,0,0,0};
|
||||||
uint16_t lastKelvin = 0;
|
uint16_t lastKelvin = 0;
|
||||||
|
|
||||||
|
// adjust RGB values based on color temperature in K (range [2800-10200]) (https://en.wikipedia.org/wiki/Color_balance)
|
||||||
uint32_t colorBalanceFromKelvin(uint16_t kelvin, uint32_t rgb)
|
uint32_t colorBalanceFromKelvin(uint16_t kelvin, uint32_t rgb)
|
||||||
{
|
{
|
||||||
//remember so that slow colorKtoRGB() doesn't have to run for every setPixelColor()
|
//remember so that slow colorKtoRGB() doesn't have to run for every setPixelColor()
|
||||||
@ -270,3 +261,42 @@ uint32_t colorBalanceFromKelvin(uint16_t kelvin, uint32_t rgb)
|
|||||||
rgbw[3] = W(rgb);
|
rgbw[3] = W(rgb);
|
||||||
return colorFromRgbw(rgbw);
|
return colorFromRgbw(rgbw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//approximates a Kelvin color temperature from an RGB color.
|
||||||
|
//this does no check for the "whiteness" of the color,
|
||||||
|
//so should be used combined with a saturation check (as done by auto-white)
|
||||||
|
//values from http://www.vendian.org/mncharity/dir3/blackbody/UnstableURLs/bbr_color.html (10deg)
|
||||||
|
//equation spreadsheet at https://bit.ly/30RkHaN
|
||||||
|
//accuracy +-50K from 1900K up to 8000K
|
||||||
|
//minimum returned: 1900K, maximum returned: 10091K (range of 8192)
|
||||||
|
uint16_t approximateKelvinFromRGB(uint32_t rgb) {
|
||||||
|
//if not either red or blue is 255, color is dimmed. Scale up
|
||||||
|
uint8_t r = R(rgb), b = B(rgb);
|
||||||
|
if (r == b) return 6550; //red == blue at about 6600K (also can't go further if both R and B are 0)
|
||||||
|
|
||||||
|
if (r > b) {
|
||||||
|
//scale blue up as if red was at 255
|
||||||
|
uint16_t scale = 0xFFFF / r; //get scale factor (range 257-65535)
|
||||||
|
b = ((uint16_t)b * scale) >> 8;
|
||||||
|
//For all temps K<6600 R is bigger than B (for full bri colors R=255)
|
||||||
|
//-> Use 9 linear approximations for blackbody radiation blue values from 2000-6600K (blue is always 0 below 2000K)
|
||||||
|
if (b < 33) return 1900 + b *6;
|
||||||
|
if (b < 72) return 2100 + (b-33) *10;
|
||||||
|
if (b < 101) return 2492 + (b-72) *14;
|
||||||
|
if (b < 132) return 2900 + (b-101) *16;
|
||||||
|
if (b < 159) return 3398 + (b-132) *19;
|
||||||
|
if (b < 186) return 3906 + (b-159) *22;
|
||||||
|
if (b < 210) return 4500 + (b-186) *25;
|
||||||
|
if (b < 230) return 5100 + (b-210) *30;
|
||||||
|
return 5700 + (b-230) *34;
|
||||||
|
} else {
|
||||||
|
//scale red up as if blue was at 255
|
||||||
|
uint16_t scale = 0xFFFF / b; //get scale factor (range 257-65535)
|
||||||
|
r = ((uint16_t)r * scale) >> 8;
|
||||||
|
//For all temps K>6600 B is bigger than R (for full bri colors B=255)
|
||||||
|
//-> Use 2 linear approximations for blackbody radiation red values from 6600-10091K (blue is always 0 below 2000K)
|
||||||
|
if (r > 225) return 6600 + (254-r) *50;
|
||||||
|
uint16_t k = 8080 + (225-r) *86;
|
||||||
|
return (k > 10091) ? 10091 : k;
|
||||||
|
}
|
||||||
|
}
|
@ -510,7 +510,9 @@ ${i+1}:
|
|||||||
<hr style="width:260px">
|
<hr style="width:260px">
|
||||||
Make a segment for each output: <input type="checkbox" name="MS"> <br>
|
Make a segment for each output: <input type="checkbox" name="MS"> <br>
|
||||||
Custom bus start indices: <input type="checkbox" onchange="tglSi(this.checked)" id="si"> <br>
|
Custom bus start indices: <input type="checkbox" onchange="tglSi(this.checked)" id="si"> <br>
|
||||||
Allow WB correction: <input type="checkbox" name="CCT"> <br>
|
White Balance correction: <input type="checkbox" name="CCT"> <br>
|
||||||
|
Calculate CCT from RGB: TODO<br>
|
||||||
|
CCT blending mode: TODO<br>
|
||||||
<hr style="width:260px">
|
<hr style="width:260px">
|
||||||
<div id="btns"></div>
|
<div id="btns"></div>
|
||||||
Touch threshold: <input type="number" class="s" min="0" max="100" name="TT" required><br>
|
Touch threshold: <input type="number" class="s" min="0" max="100" name="TT" required><br>
|
||||||
|
@ -68,8 +68,8 @@ void colorRGBtoXY(byte* rgb, float* xy); // only defined if huesync disabled TOD
|
|||||||
void colorFromDecOrHexString(byte* rgb, char* in);
|
void colorFromDecOrHexString(byte* rgb, char* in);
|
||||||
bool colorFromHexString(byte* rgb, const char* in);
|
bool colorFromHexString(byte* rgb, const char* in);
|
||||||
|
|
||||||
void colorBalanceFromKelvin(uint16_t kelvin, byte *rgb);
|
|
||||||
uint32_t colorBalanceFromKelvin(uint16_t kelvin, uint32_t rgb);
|
uint32_t colorBalanceFromKelvin(uint16_t kelvin, uint32_t rgb);
|
||||||
|
uint16_t approximateKelvinFromRGB(uint32_t rgb);
|
||||||
|
|
||||||
//dmx.cpp
|
//dmx.cpp
|
||||||
void initDMX();
|
void initDMX();
|
||||||
|
File diff suppressed because one or more lines are too long
1576
wled00/html_ui.h
1576
wled00/html_ui.h
File diff suppressed because it is too large
Load Diff
@ -505,7 +505,7 @@ void serializeInfo(JsonObject root)
|
|||||||
leds[F("count")] = strip.getLengthTotal();
|
leds[F("count")] = strip.getLengthTotal();
|
||||||
leds[F("rgbw")] = strip.isRgbw;
|
leds[F("rgbw")] = strip.isRgbw;
|
||||||
leds[F("wv")] = false;
|
leds[F("wv")] = false;
|
||||||
leds["cct"] = allowCCT;
|
leds["cct"] = correctWB;
|
||||||
for (uint8_t s = 0; s < busses.getNumBusses(); s++) {
|
for (uint8_t s = 0; s < busses.getNumBusses(); s++) {
|
||||||
Bus *bus = busses.getBus(s);
|
Bus *bus = busses.getBus(s);
|
||||||
if (bus == nullptr || bus->getLength()==0) break;
|
if (bus == nullptr || bus->getLength()==0) break;
|
||||||
|
@ -95,7 +95,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
|||||||
uint8_t pins[5] = {255, 255, 255, 255, 255};
|
uint8_t pins[5] = {255, 255, 255, 255, 255};
|
||||||
|
|
||||||
autoSegments = request->hasArg(F("MS"));
|
autoSegments = request->hasArg(F("MS"));
|
||||||
allowCCT = request->hasArg(F("CCT"));
|
correctWB = request->hasArg(F("CCT"));
|
||||||
|
|
||||||
for (uint8_t s = 0; s < WLED_MAX_BUSSES; s++) {
|
for (uint8_t s = 0; s < WLED_MAX_BUSSES; s++) {
|
||||||
char lp[4] = "L0"; lp[2] = 48+s; lp[3] = 0; //ascii 0-9 //strip data pin
|
char lp[4] = "L0"; lp[2] = 48+s; lp[3] = 0; //ascii 0-9 //strip data pin
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// version code in format yymmddb (b = daily build)
|
// version code in format yymmddb (b = daily build)
|
||||||
#define VERSION 2111170
|
#define VERSION 2111240
|
||||||
|
|
||||||
//uncomment this if you have a "my_config.h" file you'd like to use
|
//uncomment this if you have a "my_config.h" file you'd like to use
|
||||||
//#define WLED_USE_MY_CONFIG
|
//#define WLED_USE_MY_CONFIG
|
||||||
@ -269,7 +269,7 @@ WLED_GLOBAL byte bootPreset _INIT(0); // save preset to load
|
|||||||
//if false, only one segment spanning the total LEDs is created,
|
//if false, only one segment spanning the total LEDs is created,
|
||||||
//but not on LED settings save if there is more than one segment currently
|
//but not on LED settings save if there is more than one segment currently
|
||||||
WLED_GLOBAL bool autoSegments _INIT(false);
|
WLED_GLOBAL bool autoSegments _INIT(false);
|
||||||
WLED_GLOBAL bool allowCCT _INIT(false); //CCT color correction
|
WLED_GLOBAL bool correctWB _INIT(false); //CCT color correction
|
||||||
|
|
||||||
WLED_GLOBAL byte col[] _INIT_N(({ 255, 160, 0, 0 })); // current RGB(W) primary color. col[] should be updated if you want to change the color.
|
WLED_GLOBAL byte col[] _INIT_N(({ 255, 160, 0, 0 })); // current RGB(W) primary color. col[] should be updated if you want to change the color.
|
||||||
WLED_GLOBAL byte colSec[] _INIT_N(({ 0, 0, 0, 0 })); // current RGB(W) secondary color
|
WLED_GLOBAL byte colSec[] _INIT_N(({ 0, 0, 0, 0 })); // current RGB(W) secondary color
|
||||||
|
@ -370,7 +370,7 @@ void getSettingsJS(byte subPage, char* dest)
|
|||||||
oappend(SET_F(");"));
|
oappend(SET_F(");"));
|
||||||
|
|
||||||
sappend('c',SET_F("MS"),autoSegments);
|
sappend('c',SET_F("MS"),autoSegments);
|
||||||
sappend('c',SET_F("CCT"),allowCCT);
|
sappend('c',SET_F("CCT"),correctWB);
|
||||||
|
|
||||||
for (uint8_t s=0; s < busses.getNumBusses(); s++) {
|
for (uint8_t s=0; s < busses.getNumBusses(); s++) {
|
||||||
Bus* bus = busses.getBus(s);
|
Bus* bus = busses.getBus(s);
|
||||||
|
Loading…
Reference in New Issue
Block a user