Color mangling macros.

Removed legacy Auto White caclulation.
This commit is contained in:
Blaz Kristan 2021-10-26 20:35:45 +02:00
parent cde497c94e
commit a696afaeb8
12 changed files with 115 additions and 131 deletions

View File

@ -1150,10 +1150,10 @@ uint16_t WS2812FX::mode_fire_flicker(void) {
uint32_t it = now / cycleTime; uint32_t it = now / cycleTime;
if (SEGENV.step == it) return FRAMETIME; if (SEGENV.step == it) return FRAMETIME;
byte w = (SEGCOLOR(0) >> 24) & 0xFF; byte w = (SEGCOLOR(0) >> 24);
byte r = (SEGCOLOR(0) >> 16) & 0xFF; byte r = (SEGCOLOR(0) >> 16);
byte g = (SEGCOLOR(0) >> 8) & 0xFF; byte g = (SEGCOLOR(0) >> 8);
byte b = (SEGCOLOR(0) & 0xFF); byte b = (SEGCOLOR(0) );
byte lum = (SEGMENT.palette == 0) ? MAX(w, MAX(r, MAX(g, b))) : 255; byte lum = (SEGMENT.palette == 0) ? MAX(w, MAX(r, MAX(g, b))) : 255;
lum /= (((256-SEGMENT.intensity)/16)+1); lum /= (((256-SEGMENT.intensity)/16)+1);
for(uint16_t i = 0; i < SEGLEN; i++) { for(uint16_t i = 0; i < SEGLEN; i++) {

View File

@ -165,11 +165,7 @@ void WS2812FX::service() {
} }
void WS2812FX::setPixelColor(uint16_t n, uint32_t c) { void WS2812FX::setPixelColor(uint16_t n, uint32_t c) {
uint8_t w = (c >> 24); setPixelColor(n, R(c), G(c), B(c), W(c));
uint8_t r = (c >> 16);
uint8_t g = (c >> 8);
uint8_t b = c ;
setPixelColor(n, r, g, b, w);
} }
//used to map from segment index to physical pixel, taking into account grouping, offsets, reverse and mirroring //used to map from segment index to physical pixel, taking into account grouping, offsets, reverse and mirroring
@ -218,7 +214,7 @@ void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w)
b = scale8(b, _bri_t); b = scale8(b, _bri_t);
w = scale8(w, _bri_t); w = scale8(w, _bri_t);
} }
uint32_t col = ((w << 24) | (r << 16) | (g << 8) | (b)); uint32_t col = RGBW32(r, g, b, w);
/* Set all the pixels in the group */ /* Set all the pixels in the group */
for (uint16_t j = 0; j < SEGMENT.grouping; j++) { for (uint16_t j = 0; j < SEGMENT.grouping; j++) {
@ -243,8 +239,7 @@ void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w)
} }
} else { //live data, etc. } else { //live data, etc.
if (i < customMappingSize) i = customMappingTable[i]; if (i < customMappingSize) i = customMappingTable[i];
uint32_t col = ((w << 24) | (r << 16) | (g << 8) | (b)); busses.setPixelColor(i, RGBW32(r, g, b, w));
busses.setPixelColor(i, col);
} }
} }
@ -297,7 +292,7 @@ void WS2812FX::estimateCurrentAndLimitBri() {
uint32_t busPowerSum = 0; uint32_t busPowerSum = 0;
for (uint16_t i = 0; i < len; i++) { //sum up the usage of each LED for (uint16_t i = 0; i < len; i++) { //sum up the usage of each LED
uint32_t c = bus->getPixelColor(i); uint32_t c = bus->getPixelColor(i);
byte r = c >> 16, g = c >> 8, b = c, w = c >> 24; byte r = R(c), g = G(c), b = B(c), w = W(c);
if(useWackyWS2815PowerModel) { //ignore white component on WS2815 power calculation if(useWackyWS2815PowerModel) { //ignore white component on WS2815 power calculation
busPowerSum += (MAX(MAX(r,g),b)) * 3; busPowerSum += (MAX(MAX(r,g),b)) * 3;
@ -433,7 +428,7 @@ bool WS2812FX::setEffectConfig(uint8_t m, uint8_t s, uint8_t in, uint8_t p) {
} }
void WS2812FX::setColor(uint8_t slot, uint8_t r, uint8_t g, uint8_t b, uint8_t w) { void WS2812FX::setColor(uint8_t slot, uint8_t r, uint8_t g, uint8_t b, uint8_t w) {
setColor(slot, ((uint32_t)w << 24) |((uint32_t)r << 16) | ((uint32_t)g << 8) | b); setColor(slot, RGBW32(r, g, b, w));
} }
void WS2812FX::setColor(uint8_t slot, uint32_t c) { void WS2812FX::setColor(uint8_t slot, uint32_t c) {
@ -758,22 +753,22 @@ uint32_t WS2812FX::color_blend(uint32_t color1, uint32_t color2, uint16_t blend,
if(blend == blendmax) return color2; if(blend == blendmax) return color2;
uint8_t shift = b16 ? 16 : 8; uint8_t shift = b16 ? 16 : 8;
uint32_t w1 = (color1 >> 24) & 0xFF; uint32_t w1 = W(color1);
uint32_t r1 = (color1 >> 16) & 0xFF; uint32_t r1 = R(color1);
uint32_t g1 = (color1 >> 8) & 0xFF; uint32_t g1 = G(color1);
uint32_t b1 = color1 & 0xFF; uint32_t b1 = B(color1);
uint32_t w2 = (color2 >> 24) & 0xFF; uint32_t w2 = W(color2);
uint32_t r2 = (color2 >> 16) & 0xFF; uint32_t r2 = R(color2);
uint32_t g2 = (color2 >> 8) & 0xFF; uint32_t g2 = G(color2);
uint32_t b2 = color2 & 0xFF; uint32_t b2 = B(color2);
uint32_t w3 = ((w2 * blend) + (w1 * (blendmax - blend))) >> shift; uint32_t w3 = ((w2 * blend) + (w1 * (blendmax - blend))) >> shift;
uint32_t r3 = ((r2 * blend) + (r1 * (blendmax - blend))) >> shift; uint32_t r3 = ((r2 * blend) + (r1 * (blendmax - blend))) >> shift;
uint32_t g3 = ((g2 * blend) + (g1 * (blendmax - blend))) >> shift; uint32_t g3 = ((g2 * blend) + (g1 * (blendmax - blend))) >> shift;
uint32_t b3 = ((b2 * blend) + (b1 * (blendmax - blend))) >> shift; uint32_t b3 = ((b2 * blend) + (b1 * (blendmax - blend))) >> shift;
return ((w3 << 24) | (r3 << 16) | (g3 << 8) | (b3)); return RGBW32(r3, g3, b3, w3);
} }
/* /*
@ -801,17 +796,17 @@ void WS2812FX::fade_out(uint8_t rate) {
float mappedRate = float(rate) +1.1; float mappedRate = float(rate) +1.1;
uint32_t color = SEGCOLOR(1); // target color uint32_t color = SEGCOLOR(1); // target color
int w2 = (color >> 24) & 0xff; int w2 = W(color);
int r2 = (color >> 16) & 0xff; int r2 = R(color);
int g2 = (color >> 8) & 0xff; int g2 = G(color);
int b2 = color & 0xff; int b2 = B(color);
for(uint16_t i = 0; i < SEGLEN; i++) { for(uint16_t i = 0; i < SEGLEN; i++) {
color = getPixelColor(i); color = getPixelColor(i);
int w1 = (color >> 24) & 0xff; int w1 = W(color);
int r1 = (color >> 16) & 0xff; int r1 = R(color);
int g1 = (color >> 8) & 0xff; int g1 = G(color);
int b1 = color & 0xff; int b1 = B(color);
int wdelta = (w2 - w1) / mappedRate; int wdelta = (w2 - w1) / mappedRate;
int rdelta = (r2 - r1) / mappedRate; int rdelta = (r2 - r1) / mappedRate;
@ -845,9 +840,9 @@ void WS2812FX::blur(uint8_t blur_amount)
cur += carryover; cur += carryover;
if(i > 0) { if(i > 0) {
uint32_t c = getPixelColor(i-1); uint32_t c = getPixelColor(i-1);
uint8_t r = (c >> 16 & 0xFF); uint8_t r = R(c);
uint8_t g = (c >> 8 & 0xFF); uint8_t g = G(c);
uint8_t b = (c & 0xFF); uint8_t b = B(c);
setPixelColor(i-1, qadd8(r, part.red), qadd8(g, part.green), qadd8(b, part.blue)); setPixelColor(i-1, qadd8(r, part.red), qadd8(g, part.green), qadd8(b, part.blue));
} }
setPixelColor(i,cur.red, cur.green, cur.blue); setPixelColor(i,cur.red, cur.green, cur.blue);
@ -930,16 +925,16 @@ uint8_t WS2812FX::get_random_wheel_index(uint8_t pos) {
uint32_t WS2812FX::crgb_to_col(CRGB fastled) uint32_t WS2812FX::crgb_to_col(CRGB fastled)
{ {
return (((uint32_t)fastled.red << 16) | ((uint32_t)fastled.green << 8) | fastled.blue); return RGBW32(fastled.red, fastled.green, fastled.blue, 0);
} }
CRGB WS2812FX::col_to_crgb(uint32_t color) CRGB WS2812FX::col_to_crgb(uint32_t color)
{ {
CRGB fastled_col; CRGB fastled_col;
fastled_col.red = (color >> 16 & 0xFF); fastled_col.red = R(color);
fastled_col.green = (color >> 8 & 0xFF); fastled_col.green = G(color);
fastled_col.blue = (color & 0xFF); fastled_col.blue = B(color);
return fastled_col; return fastled_col;
} }
@ -1159,15 +1154,15 @@ uint8_t WS2812FX::gamma8(uint8_t b)
uint32_t WS2812FX::gamma32(uint32_t color) uint32_t WS2812FX::gamma32(uint32_t color)
{ {
if (!gammaCorrectCol) return color; if (!gammaCorrectCol) return color;
uint8_t w = (color >> 24); uint8_t w = W(color);
uint8_t r = (color >> 16); uint8_t r = R(color);
uint8_t g = (color >> 8); uint8_t g = G(color);
uint8_t b = color; uint8_t b = B(color);
w = gammaT[w]; w = gammaT[w];
r = gammaT[r]; r = gammaT[r];
g = gammaT[g]; g = gammaT[g];
b = gammaT[b]; b = gammaT[b];
return ((w << 24) | (r << 16) | (g << 8) | (b)); return RGBW32(r, g, b, w);
} }
WS2812FX* WS2812FX::instance = nullptr; WS2812FX* WS2812FX::instance = nullptr;

View File

@ -32,6 +32,13 @@ void colorRGBtoRGBW(byte* rgb);
#define SET_BIT(var,bit) ((var)|=(uint16_t)(0x0001<<(bit))) #define SET_BIT(var,bit) ((var)|=(uint16_t)(0x0001<<(bit)))
#define UNSET_BIT(var,bit) ((var)&=(~(uint16_t)(0x0001<<(bit)))) #define UNSET_BIT(var,bit) ((var)&=(~(uint16_t)(0x0001<<(bit))))
//color mangling macros
#define RGBW32(r,g,b,w) (uint32_t((byte(w) << 24) | (byte(r) << 16) | (byte(g) << 8) | (byte(b))))
#define R(c) (byte((c) >> 16))
#define G(c) (byte((c) >> 8))
#define B(c) (byte(c))
#define W(c) (byte((c) >> 24))
//temporary struct for passing bus configuration to bus //temporary struct for passing bus configuration to bus
struct BusConfig { struct BusConfig {
uint8_t type = TYPE_WS2812_RGB; uint8_t type = TYPE_WS2812_RGB;
@ -120,24 +127,15 @@ class Bus {
switch (_autoWhiteMode) { switch (_autoWhiteMode) {
case RGBW_MODE_MANUAL_ONLY: case RGBW_MODE_MANUAL_ONLY:
break; break;
case RGBW_MODE_LEGACY:
byte rgb[4];
rgb[0] = c >> 16;
rgb[1] = c >> 8;
rgb[2] = c ;
rgb[3] = c >> 24;
colorRGBtoRGBW(rgb);
c = ((rgb[3] << 24) | (rgb[0] << 16) | (rgb[1] << 8) | (rgb[2]));
break;
default: default:
//white value is set to lowest RGB channel, thank you to @Def3nder! //white value is set to lowest RGB channel, thank you to @Def3nder!
uint8_t r = c >> 16; uint8_t r = R(c);
uint8_t g = c >> 8; uint8_t g = G(c);
uint8_t b = c ; uint8_t b = B(c);
uint8_t w = c >> 24; uint8_t w = W(c);
if (_autoWhiteMode == RGBW_MODE_AUTO_BRIGHTER || w == 0) w = r < g ? (r < b ? r : b) : (g < b ? g : b); if (_autoWhiteMode == RGBW_MODE_AUTO_BRIGHTER || w == 0) w = r < g ? (r < b ? r : b) : (g < b ? g : b);
if (_autoWhiteMode == RGBW_MODE_AUTO_ACCURATE) { r -= w; g -= w; b -= w; } if (_autoWhiteMode == RGBW_MODE_AUTO_ACCURATE) { r -= w; g -= w; b -= w; }
c = ((w << 24) | (r << 16) | (g << 8) | (b)); c = RGBW32(r, g, b, w);
break; break;
} }
return c; return c;
@ -294,10 +292,10 @@ class BusPwm : public Bus {
if (pix != 0 || !_valid) return; //only react to first pixel if (pix != 0 || !_valid) return; //only react to first pixel
c = colorBalanceFromKelvin(2000+(cct<<5), c); // color correction from CCT (w remains unchanged) c = colorBalanceFromKelvin(2000+(cct<<5), c); // color correction from CCT (w remains unchanged)
if (getAutoWhiteMode() != RGBW_MODE_MANUAL_ONLY) c = autoWhiteCalc(c); if (getAutoWhiteMode() != RGBW_MODE_MANUAL_ONLY) c = autoWhiteCalc(c);
uint8_t r = c >> 16; uint8_t r = R(c);
uint8_t g = c >> 8; uint8_t g = G(c);
uint8_t b = c ; uint8_t b = B(c);
uint8_t w = c >> 24; uint8_t w = W(c);
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
@ -324,10 +322,10 @@ class BusPwm : public Bus {
void setPixelColor(uint16_t pix, uint32_t c) { 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 (getAutoWhiteMode() != RGBW_MODE_MANUAL_ONLY) c = autoWhiteCalc(c);
uint8_t r = c >> 16; uint8_t r = R(c);
uint8_t g = c >> 8; uint8_t g = G(c);
uint8_t b = c ; uint8_t b = B(c);
uint8_t w = c >> 24; uint8_t w = W(c);
switch (_type) { switch (_type) {
case TYPE_ANALOG_1CH: //one channel (white), use highest RGBW value case TYPE_ANALOG_1CH: //one channel (white), use highest RGBW value
@ -343,7 +341,7 @@ class BusPwm : public Bus {
//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;
return ((_data[3] << 24) | (_data[0] << 16) | (_data[1] << 8) | (_data[2])); return RGBW32(_data[0], _data[1], _data[2], _data[3]);
} }
void show() { void show() {
@ -442,10 +440,10 @@ class BusNetwork : public Bus {
if (!_valid || pix >= _len) return; if (!_valid || pix >= _len) return;
if (getAutoWhiteMode() != RGBW_MODE_MANUAL_ONLY) c = autoWhiteCalc(c); if (getAutoWhiteMode() != RGBW_MODE_MANUAL_ONLY) c = autoWhiteCalc(c);
uint16_t offset = pix * _UDPchannels; uint16_t offset = pix * _UDPchannels;
_data[offset] = 0xFF & (c >> 16); _data[offset] = R(c);
_data[offset+1] = 0xFF & (c >> 8); _data[offset+1] = G(c);
_data[offset+2] = 0xFF & (c ); _data[offset+2] = B(c);
if (_rgbw) _data[offset+3] = 0xFF & (c >> 24); if (_rgbw) _data[offset+3] = W(c);
} }
void setPixelColor(uint16_t pix, uint32_t c, uint8_t cct) { void setPixelColor(uint16_t pix, uint32_t c, uint8_t cct) {
@ -456,12 +454,7 @@ class BusNetwork : public Bus {
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;
return ( return RGBW32(_data[offset], _data[offset+1], _data[offset+2], _rgbw ? (_data[offset+3] << 24) : 0);
(_rgbw ? (_data[offset+3] << 24) : 0)
| (_data[offset] << 16)
| (_data[offset+1] << 8)
| (_data[offset+2] )
);
} }
void show() { void show() {

View File

@ -6,36 +6,25 @@
void colorFromUint32(uint32_t in, bool secondary) void colorFromUint32(uint32_t in, bool secondary)
{ {
if (secondary) { byte *_col = secondary ? colSec : col;
colSec[3] = in >> 24 & 0xFF; _col[0] = R(in);
colSec[0] = in >> 16 & 0xFF; _col[1] = G(in);
colSec[1] = in >> 8 & 0xFF; _col[2] = B(in);
colSec[2] = in & 0xFF; _col[3] = W(in);
} else {
col[3] = in >> 24 & 0xFF;
col[0] = in >> 16 & 0xFF;
col[1] = in >> 8 & 0xFF;
col[2] = in & 0xFF;
}
} }
//load a color without affecting the white channel //load a color without affecting the white channel
void colorFromUint24(uint32_t in, bool secondary) void colorFromUint24(uint32_t in, bool secondary)
{ {
if (secondary) { byte *_col = secondary ? colSec : col;
colSec[0] = in >> 16 & 0xFF; _col[0] = R(in);
colSec[1] = in >> 8 & 0xFF; _col[1] = G(in);
colSec[2] = in & 0xFF; _col[2] = B(in);
} else {
col[0] = in >> 16 & 0xFF;
col[1] = in >> 8 & 0xFF;
col[2] = in & 0xFF;
}
} }
//store color components in uint32_t //store color components in uint32_t
uint32_t colorFromRgbw(byte* rgbw) { uint32_t colorFromRgbw(byte* rgbw) {
return (rgbw[0] << 16) + (rgbw[1] << 8) + rgbw[2] + (rgbw[3] << 24); return RGBW32(rgbw[0], rgbw[1], rgbw[2], rgbw[3]);
} }
//relatively change white brightness, minumum A=5 //relatively change white brightness, minumum A=5
@ -195,10 +184,10 @@ void colorFromDecOrHexString(byte* rgb, char* in)
c = strtoul(in, NULL, 10); c = strtoul(in, NULL, 10);
} }
rgb[3] = (c >> 24) & 0xFF; rgb[0] = R(c);
rgb[0] = (c >> 16) & 0xFF; rgb[1] = G(c);
rgb[1] = (c >> 8) & 0xFF; rgb[2] = B(c);
rgb[2] = c & 0xFF; rgb[3] = W(c);
} }
//contrary to the colorFromDecOrHexString() function, this uses the more standard RRGGBB / RRGGBBWW order //contrary to the colorFromDecOrHexString() function, this uses the more standard RRGGBB / RRGGBBWW order
@ -210,14 +199,14 @@ bool colorFromHexString(byte* rgb, const char* in) {
uint32_t c = strtoul(in, NULL, 16); uint32_t c = strtoul(in, NULL, 16);
if (inputSize == 6) { if (inputSize == 6) {
rgb[0] = (c >> 16) & 0xFF; rgb[0] = (c >> 16);
rgb[1] = (c >> 8) & 0xFF; rgb[1] = (c >> 8);
rgb[2] = c & 0xFF; rgb[2] = c ;
} else { } else {
rgb[0] = (c >> 24) & 0xFF; rgb[0] = (c >> 24);
rgb[1] = (c >> 16) & 0xFF; rgb[1] = (c >> 16);
rgb[2] = (c >> 8) & 0xFF; rgb[2] = (c >> 8);
rgb[3] = c & 0xFF; rgb[3] = c ;
} }
return true; return true;
} }
@ -234,15 +223,16 @@ float maxf (float v, float w)
return v; return v;
} }
/*
uint32_t colorRGBtoRGBW(uint32_t c) uint32_t colorRGBtoRGBW(uint32_t c)
{ {
byte rgb[4]; byte rgb[4];
rgb[0] = c >> 16; rgb[0] = R(c);
rgb[1] = c >> 8; rgb[1] = G(c);
rgb[2] = c ; rgb[2] = B(c);
rgb[3] = c >> 24; rgb[3] = W(c);
colorRGBtoRGBW(rgb); colorRGBtoRGBW(rgb);
return ((rgb[3] << 24) | (rgb[0] << 16) | (rgb[1] << 8) | (rgb[2])); return RGBW32(rgb[0], rgb[1], rgb[2], rgb[3]);
} }
void colorRGBtoRGBW(byte* rgb) //rgb to rgbw (http://codewelt.com/rgbw). (RGBW_MODE_LEGACY) void colorRGBtoRGBW(byte* rgb) //rgb to rgbw (http://codewelt.com/rgbw). (RGBW_MODE_LEGACY)
@ -253,6 +243,7 @@ void colorRGBtoRGBW(byte* rgb) //rgb to rgbw (http://codewelt.com/rgbw). (RGBW_M
float sat = 100.0f * ((high - low) / high);; // maximum saturation is 100 (corrected from 255) float sat = 100.0f * ((high - low) / high);; // maximum saturation is 100 (corrected from 255)
rgb[3] = (byte)((255.0f - sat) / 255.0f * (rgb[0] + rgb[1] + rgb[2]) / 3); rgb[3] = (byte)((255.0f - sat) / 255.0f * (rgb[0] + rgb[1] + rgb[2]) / 3);
} }
*/
// adjust RGB values based on color temperature in K (range [2800-10200]) (https://en.wikipedia.org/wiki/Color_balance) // 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) void colorBalanceFromKelvin(uint16_t kelvin, byte *rgb)
@ -268,9 +259,9 @@ uint32_t colorBalanceFromKelvin(uint16_t kelvin, uint32_t rgb)
{ {
byte rgbw[4] = {0,0,0,0}; byte rgbw[4] = {0,0,0,0};
colorKtoRGB(kelvin, rgbw); // convert Kelvin to RGB colorKtoRGB(kelvin, rgbw); // convert Kelvin to RGB
rgbw[0] = ((uint16_t) rgbw[0] * ((rgb>>16) & 0xFF)) / 255; // correct R rgbw[0] = ((uint16_t) rgbw[0] * R(rgb)) / 255; // correct R
rgbw[1] = ((uint16_t) rgbw[1] * ((rgb>> 8) & 0xFF)) / 255; // correct G rgbw[1] = ((uint16_t) rgbw[1] * G(rgb)) / 255; // correct G
rgbw[2] = ((uint16_t) rgbw[2] * ((rgb ) & 0xFF)) / 255; // correct B rgbw[2] = ((uint16_t) rgbw[2] * B(rgb)) / 255; // correct B
rgbw[3] = ((rgb>>24) & 0xFF); rgbw[3] = W(rgb);
return colorFromRgbw(rgbw); return colorFromRgbw(rgbw);
} }

View File

@ -335,7 +335,7 @@ ${i+1}:
<div id="dig${i}r" style="display:inline"><br><span id="rev${i}">Reversed</span>: <input type="checkbox" name="CV${i}"></div> <div id="dig${i}r" style="display:inline"><br><span id="rev${i}">Reversed</span>: <input type="checkbox" name="CV${i}"></div>
<div id="dig${i}s" style="display:inline"><br>Skip 1<sup>st</sup> LED: <input id="sl${i}" type="checkbox" name="SL${i}"></div> <div id="dig${i}s" style="display:inline"><br>Skip 1<sup>st</sup> LED: <input id="sl${i}" type="checkbox" name="SL${i}"></div>
<div id="dig${i}f" style="display:inline"><br>Off Refresh: <input id="rf${i}" type="checkbox" name="RF${i}">&nbsp;</div> <div id="dig${i}f" style="display:inline"><br>Off Refresh: <input id="rf${i}" type="checkbox" name="RF${i}">&nbsp;</div>
<div id="dig${i}a" style="display:inline"><br>Auto-calculate white channel from RGB:<br><select name="AW${i}"><option value=0>None</option><option value=1>Brighter</option><option value=2>Accurate</option><option value=3>Dual</option><option value=4>Legacy</option></select>&nbsp;</div> <div id="dig${i}a" style="display:inline"><br>Auto-calculate white channel from RGB:<br><select name="AW${i}"><option value=0>None</option><option value=1>Brighter</option><option value=2>Accurate</option><option value=3>Dual</option></select>&nbsp;</div>
</div>`; </div>`;
f.insertAdjacentHTML("beforeend", cn); f.insertAdjacentHTML("beforeend", cn);
} }

View File

@ -21,10 +21,10 @@ void handleDMX()
for (int i = DMXStartLED; i < ledCount; i++) { // uses the amount of LEDs as fixture count for (int i = DMXStartLED; i < ledCount; i++) { // uses the amount of LEDs as fixture count
uint32_t in = strip.getPixelColor(i); // get the colors for the individual fixtures as suggested by Aircoookie in issue #462 uint32_t in = strip.getPixelColor(i); // get the colors for the individual fixtures as suggested by Aircoookie in issue #462
byte w = in >> 24 & 0xFF; byte w = W(in);
byte r = in >> 16 & 0xFF; byte r = R(in);
byte g = in >> 8 & 0xFF; byte g = G(in);
byte b = in & 0xFF; byte b = B(in);
int DMXFixtureStart = DMXStart + (DMXGap * (i - DMXStartLED)); int DMXFixtureStart = DMXStart + (DMXGap * (i - DMXStartLED));
for (int j = 0; j < DMXChannels; j++) { for (int j = 0; j < DMXChannels; j++) {

View File

@ -69,7 +69,6 @@ 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 colorRGBtoRGBW(byte* rgb); //rgb to rgbw (http://codewelt.com/rgbw). (RGBW_MODE_LEGACY)
void colorBalanceFromKelvin(uint16_t kelvin, byte *rgb); 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);

File diff suppressed because one or more lines are too long

View File

@ -89,7 +89,6 @@ void deserializeSegment(JsonObject elem, byte it, byte presetId)
const char* hexCol = colarr[i]; const char* hexCol = colarr[i];
if (hexCol == nullptr) { //Kelvin color temperature (or invalid), e.g 2400 if (hexCol == nullptr) { //Kelvin color temperature (or invalid), e.g 2400
int kelvin = colarr[i] | -1; int kelvin = colarr[i] | -1;
//kelvin = map(seg.cct, 0, 255, 2800, 10200)
if (kelvin < 0) continue; if (kelvin < 0) continue;
if (kelvin == 0) seg.setColor(i, 0, id); if (kelvin == 0) seg.setColor(i, 0, id);
if (kelvin > 0) colorKtoRGB(kelvin, brgbw); if (kelvin > 0) colorKtoRGB(kelvin, brgbw);
@ -223,7 +222,7 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId)
if (root["on"].is<const char*>() && root["on"].as<const char*>()[0] == 't') toggleOnOff(); if (root["on"].is<const char*>() && root["on"].as<const char*>()[0] == 't') toggleOnOff();
int tr = -1; int tr = -1;
if (!presetId || !currentPlaylist) { //do not apply transition time from preset if playlist active, as it would override playlist transition times if (!presetId || currentPlaylist < 0) { //do not apply transition time from preset if playlist active, as it would override playlist transition times
tr = root[F("transition")] | -1; tr = root[F("transition")] | -1;
if (tr >= 0) if (tr >= 0)
{ {
@ -394,8 +393,10 @@ void serializeSegment(JsonObject& root, WS2812FX::Segment& seg, byte id, bool fo
{ {
c = (i == 0)? col:colSec; c = (i == 0)? col:colSec;
} else { } else {
segcol[0] = (byte)(seg.colors[i] >> 16); segcol[1] = (byte)(seg.colors[i] >> 8); segcol[0] = R(seg.colors[i]);
segcol[2] = (byte)(seg.colors[i]); segcol[3] = (byte)(seg.colors[i] >> 24); segcol[1] = G(seg.colors[i]);
segcol[2] = B(seg.colors[i]);
segcol[3] = W(seg.colors[i]);
} }
char tmpcol[22]; char tmpcol[22];
sprintf_P(tmpcol, format, (unsigned)c[0], (unsigned)c[1], (unsigned)c[2], (unsigned)c[3]); sprintf_P(tmpcol, format, (unsigned)c[0], (unsigned)c[1], (unsigned)c[2], (unsigned)c[3]);
@ -454,7 +455,6 @@ void serializeState(JsonObject root, bool forPreset, bool includeBri, bool segme
for (byte s = 0; s < strip.getMaxSegments(); s++) for (byte s = 0; s < strip.getMaxSegments(); s++)
{ {
WS2812FX::Segment sg = strip.getSegment(s); WS2812FX::Segment sg = strip.getSegment(s);
// TODO: add logic to stop at 16 segments if using versionAPI==1 on ESP8266
if (sg.isActive()) if (sg.isActive())
{ {
JsonObject seg0 = seg.createNestedObject(); JsonObject seg0 = seg.createNestedObject();

View File

@ -69,7 +69,7 @@ void parseLxJson(int lxValue, byte segId, bool secondary)
} else { } else {
DEBUG_PRINT(F("LX: segment ")); DEBUG_PRINT(F("LX: segment "));
DEBUG_PRINTLN(segId); DEBUG_PRINTLN(segId);
strip.getSegment(segId).setColor(secondary, ((rgbw[3] << 24) | ((rgbw[0]&0xFF) << 16) | ((rgbw[1]&0xFF) << 8) | ((rgbw[2]&0xFF))), segId); strip.getSegment(segId).setColor(secondary, RGBW32(rgbw[0], rgbw[1], rgbw[2], rgbw[3]), segId);
} }
} }
} }

View File

@ -712,7 +712,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
strip.applyToAllSelected = true; strip.applyToAllSelected = true;
strip.setColor(2, t[0], t[1], t[2], t[3]); strip.setColor(2, t[0], t[1], t[2], t[3]);
} else { } else {
selseg.setColor(2,((t[0] << 16) + (t[1] << 8) + t[2] + (t[3] << 24)), selectedSeg); // defined above (SS=) selseg.setColor(2, RGBW32(t[0], t[1], t[2], t[3]), selectedSeg); // defined above (SS=)
} }
} }

View File

@ -645,6 +645,12 @@ WLED_GLOBAL UsermodManager usermods _INIT(UsermodManager());
//macro to convert F to const //macro to convert F to const
#define SET_F(x) (const char*)F(x) #define SET_F(x) (const char*)F(x)
//color mangling macros
#define RGBW32(r,g,b,w) (uint32_t((byte(w) << 24) | (byte(r) << 16) | (byte(g) << 8) | (byte(b))))
#define R(c) (byte((c) >> 16))
#define G(c) (byte((c) >> 8))
#define B(c) (byte(c))
#define W(c) (byte((c) >> 24))
class WLED { class WLED {
public: public: