Moved auto white calculation to bus manager.
Other minor fixes.
This commit is contained in:
parent
0d77027f60
commit
090e29effd
@ -166,7 +166,7 @@
|
|||||||
#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
|
||||||
#define FX_MODE_POLICE_ALL 49
|
#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
|
||||||
#define FX_MODE_RUNNING_DUAL 52
|
#define FX_MODE_RUNNING_DUAL 52
|
||||||
@ -231,7 +231,7 @@
|
|||||||
#define FX_MODE_CHUNCHUN 111
|
#define FX_MODE_CHUNCHUN 111
|
||||||
#define FX_MODE_DANCING_SHADOWS 112
|
#define FX_MODE_DANCING_SHADOWS 112
|
||||||
#define FX_MODE_WASHING_MACHINE 113
|
#define FX_MODE_WASHING_MACHINE 113
|
||||||
#define FX_MODE_CANDY_CANE 114
|
#define FX_MODE_CANDY_CANE 114 // candidate for removal
|
||||||
#define FX_MODE_BLENDS 115
|
#define FX_MODE_BLENDS 115
|
||||||
#define FX_MODE_TV_SIMULATOR 116
|
#define FX_MODE_TV_SIMULATOR 116
|
||||||
#define FX_MODE_DYNAMIC_SMOOTH 117
|
#define FX_MODE_DYNAMIC_SMOOTH 117
|
||||||
@ -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;
|
uint8_t cct; //0==2000K, 255==10160K
|
||||||
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;
|
||||||
@ -658,7 +658,6 @@ class WS2812FX {
|
|||||||
|
|
||||||
uint8_t
|
uint8_t
|
||||||
mainSegment = 0,
|
mainSegment = 0,
|
||||||
rgbwMode = RGBW_MODE_DUAL,
|
|
||||||
paletteFade = 0,
|
paletteFade = 0,
|
||||||
paletteBlend = 0,
|
paletteBlend = 0,
|
||||||
milliampsPerLed = 55,
|
milliampsPerLed = 55,
|
||||||
|
@ -192,21 +192,25 @@ uint16_t WS2812FX::realPixelIndex(uint16_t i) {
|
|||||||
|
|
||||||
void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w)
|
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SEGLEN) {//from segment
|
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 (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);
|
||||||
@ -217,20 +221,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));
|
uint32_t col = ((w << 24) | (r << 16) | (g << 8) | (b));
|
||||||
|
|
||||||
/* Set all the pixels in the group */
|
/* 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++) {
|
for (uint16_t j = 0; j < SEGMENT.grouping; j++) {
|
||||||
uint16_t indexSet = realIndex + (IS_REVERSE ? -j : j);
|
uint16_t indexSet = realIndex + (IS_REVERSE ? -j : j);
|
||||||
if (indexSet >= SEGMENT.start && indexSet < SEGMENT.stop) {
|
if (indexSet >= SEGMENT.start && indexSet < SEGMENT.stop) {
|
||||||
|
@ -10,8 +10,9 @@
|
|||||||
#include "bus_wrapper.h"
|
#include "bus_wrapper.h"
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
|
|
||||||
//color.cpp
|
//colors.cpp
|
||||||
uint32_t colorBalanceFromKelvin(uint16_t kelvin, uint32_t rgb);
|
uint32_t colorBalanceFromKelvin(uint16_t kelvin, uint32_t rgb);
|
||||||
|
void colorRGBtoRGBW(byte* rgb);
|
||||||
|
|
||||||
// enable additional debug output
|
// enable additional debug output
|
||||||
#ifdef WLED_DEBUG
|
#ifdef WLED_DEBUG
|
||||||
@ -34,17 +35,18 @@ uint32_t colorBalanceFromKelvin(uint16_t kelvin, uint32_t rgb);
|
|||||||
//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;
|
||||||
uint16_t count = 1;
|
uint16_t count;
|
||||||
uint16_t start = 0;
|
uint16_t start;
|
||||||
uint8_t colorOrder = COL_ORDER_GRB;
|
uint8_t colorOrder;
|
||||||
bool reversed = false;
|
bool reversed;
|
||||||
uint8_t skipAmount;
|
uint8_t skipAmount;
|
||||||
bool refreshReq;
|
bool refreshReq;
|
||||||
uint8_t pins[5] = {LEDPIN, 255, 255, 255, 255};
|
uint8_t pins[5] = {LEDPIN, 255, 255, 255, 255};
|
||||||
BusConfig(uint8_t busType, uint8_t* ppins, uint16_t pstart, uint16_t len = 1, uint8_t pcolorOrder = COL_ORDER_GRB, bool rev = false, uint8_t skip = 0) {
|
uint8_t autoWhite;
|
||||||
|
BusConfig(uint8_t busType, uint8_t* ppins, uint16_t pstart, uint16_t len = 1, uint8_t pcolorOrder = COL_ORDER_GRB, bool rev = false, uint8_t skip = 0, uint8_t aw = 0) {
|
||||||
refreshReq = (bool) GET_BIT(busType,7);
|
refreshReq = (bool) GET_BIT(busType,7);
|
||||||
type = busType & 0x7F; // bit 7 may be/is hacked to include refresh info (1=refresh in off state, 0=no refresh)
|
type = busType & 0x7F; // bit 7 may be/is hacked to include refresh info (1=refresh in off state, 0=no refresh)
|
||||||
count = len; start = pstart; colorOrder = pcolorOrder; reversed = rev; skipAmount = skip;
|
count = len; start = pstart; colorOrder = pcolorOrder; reversed = rev; skipAmount = skip; autoWhite = aw;
|
||||||
uint8_t nPins = 1;
|
uint8_t nPins = 1;
|
||||||
if (type >= TYPE_NET_DDP_RGB && type < 96) nPins = 4; //virtual network bus. 4 "pins" store IP address
|
if (type >= TYPE_NET_DDP_RGB && type < 96) nPins = 4; //virtual network bus. 4 "pins" store IP address
|
||||||
else if (type > 47) nPins = 2;
|
else if (type > 47) nPins = 2;
|
||||||
@ -68,9 +70,10 @@ struct BusConfig {
|
|||||||
//parent class of BusDigital and BusPwm
|
//parent class of BusDigital and BusPwm
|
||||||
class Bus {
|
class Bus {
|
||||||
public:
|
public:
|
||||||
Bus(uint8_t type, uint16_t start) {
|
Bus(uint8_t type, uint16_t start, uint8_t aw) {
|
||||||
_type = type;
|
_type = type;
|
||||||
_start = start;
|
_start = start;
|
||||||
|
_autoWhiteMode = isRgbw(_type) ? aw : RGBW_MODE_MANUAL_ONLY;
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual ~Bus() {} //throw the bus under the bus
|
virtual ~Bus() {} //throw the bus under the bus
|
||||||
@ -83,19 +86,19 @@ class Bus {
|
|||||||
virtual void setBrightness(uint8_t b) {};
|
virtual void setBrightness(uint8_t b) {};
|
||||||
virtual void cleanup() {};
|
virtual void cleanup() {};
|
||||||
virtual uint8_t getPins(uint8_t* pinArray) { return 0; }
|
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 void setColorOrder() {}
|
||||||
virtual uint8_t getColorOrder() { return COL_ORDER_RGB; }
|
virtual uint8_t getColorOrder() { return COL_ORDER_RGB; }
|
||||||
virtual uint8_t skippedLeds() { return 0; }
|
virtual uint8_t skippedLeds() { return 0; }
|
||||||
|
inline uint8_t getAutoWhiteMode() { return _autoWhiteMode; }
|
||||||
|
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; }
|
||||||
|
|
||||||
inline uint16_t getStart() { return _start; }
|
virtual bool isRgbw() { return Bus::isRgbw(_type); }
|
||||||
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; }
|
|
||||||
|
|
||||||
virtual bool isRgbw() { return false; }
|
|
||||||
static bool isRgbw(uint8_t type) {
|
static bool isRgbw(uint8_t type) {
|
||||||
if (type == TYPE_SK6812_RGBW || type == TYPE_TM1814) return true;
|
if (type == TYPE_SK6812_RGBW || type == TYPE_TM1814) return true;
|
||||||
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;
|
||||||
@ -108,14 +111,43 @@ class Bus {
|
|||||||
uint8_t _type = TYPE_NONE;
|
uint8_t _type = TYPE_NONE;
|
||||||
uint8_t _bri = 255;
|
uint8_t _bri = 255;
|
||||||
uint16_t _start = 0;
|
uint16_t _start = 0;
|
||||||
|
uint16_t _len = 1;
|
||||||
bool _valid = false;
|
bool _valid = false;
|
||||||
bool _needsRefresh = false;
|
bool _needsRefresh = false;
|
||||||
|
uint8_t _autoWhiteMode = 0;
|
||||||
|
|
||||||
|
uint32_t autoWhiteCalc(uint32_t c) {
|
||||||
|
switch (_autoWhiteMode) {
|
||||||
|
case RGBW_MODE_MANUAL_ONLY:
|
||||||
|
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:
|
||||||
|
//white value is set to lowest RGB channel, thank you to @Def3nder!
|
||||||
|
uint8_t r = c >> 16;
|
||||||
|
uint8_t g = c >> 8;
|
||||||
|
uint8_t b = c ;
|
||||||
|
uint8_t w = c >> 24;
|
||||||
|
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; }
|
||||||
|
c = ((w << 24) | (r << 16) | (g << 8) | (b));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class BusDigital : public Bus {
|
class BusDigital : public Bus {
|
||||||
public:
|
public:
|
||||||
BusDigital(BusConfig &bc, uint8_t nr) : Bus(bc.type, bc.start) {
|
BusDigital(BusConfig &bc, uint8_t nr) : Bus(bc.type, bc.start, bc.autoWhite) {
|
||||||
if (!IS_DIGITAL(bc.type) || !bc.count) return;
|
if (!IS_DIGITAL(bc.type) || !bc.count) return;
|
||||||
if (!pinManager.allocatePin(bc.pins[0], true, PinOwner::BusDigital)) return;
|
if (!pinManager.allocatePin(bc.pins[0], true, PinOwner::BusDigital)) return;
|
||||||
_pins[0] = bc.pins[0];
|
_pins[0] = bc.pins[0];
|
||||||
@ -157,6 +189,7 @@ 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);
|
||||||
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);
|
||||||
@ -192,10 +225,6 @@ class BusDigital : public Bus {
|
|||||||
_colorOrder = colorOrder;
|
_colorOrder = colorOrder;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool isRgbw() {
|
|
||||||
return Bus::isRgbw(_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline uint8_t skippedLeds() {
|
inline uint8_t skippedLeds() {
|
||||||
return _skip;
|
return _skip;
|
||||||
}
|
}
|
||||||
@ -222,7 +251,6 @@ class BusDigital : public Bus {
|
|||||||
uint8_t _colorOrder = COL_ORDER_GRB;
|
uint8_t _colorOrder = COL_ORDER_GRB;
|
||||||
uint8_t _pins[2] = {255, 255};
|
uint8_t _pins[2] = {255, 255};
|
||||||
uint8_t _iType = I_NONE;
|
uint8_t _iType = I_NONE;
|
||||||
uint16_t _len = 0;
|
|
||||||
uint8_t _skip = 0;
|
uint8_t _skip = 0;
|
||||||
void * _busPtr = nullptr;
|
void * _busPtr = nullptr;
|
||||||
};
|
};
|
||||||
@ -230,7 +258,7 @@ class BusDigital : public Bus {
|
|||||||
|
|
||||||
class BusPwm : public Bus {
|
class BusPwm : public Bus {
|
||||||
public:
|
public:
|
||||||
BusPwm(BusConfig &bc) : Bus(bc.type, bc.start) {
|
BusPwm(BusConfig &bc) : Bus(bc.type, bc.start, bc.autoWhite) {
|
||||||
_valid = false;
|
_valid = false;
|
||||||
if (!IS_PWM(bc.type)) return;
|
if (!IS_PWM(bc.type)) return;
|
||||||
uint8_t numPins = NUM_PWM_PINS(bc.type);
|
uint8_t numPins = NUM_PWM_PINS(bc.type);
|
||||||
@ -265,23 +293,26 @@ class BusPwm : public Bus {
|
|||||||
void setPixelColor(uint16_t pix, uint32_t c, uint8_t cct) {
|
void setPixelColor(uint16_t pix, uint32_t c, uint8_t cct) {
|
||||||
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);
|
||||||
uint8_t r = c >> 16;
|
uint8_t r = c >> 16;
|
||||||
uint8_t g = c >> 8;
|
uint8_t g = c >> 8;
|
||||||
uint8_t b = c ;
|
uint8_t b = c ;
|
||||||
uint8_t w = c >> 24;
|
uint8_t w = c >> 24;
|
||||||
|
|
||||||
switch (_type) {
|
switch (_type) {
|
||||||
case TYPE_ANALOG_1CH: //one channel (white), use highest RGBW value
|
case TYPE_ANALOG_1CH: //one channel (white), relies on auto white calculation
|
||||||
_data[0] = max(r, max(g, max(b, w)));
|
_data[0] = w; //max(r, max(g, max(b, 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] = 255 - _data[1]; // or (w * (255-cct)) / 255;
|
_data[0] = (w * (255-cct)) / 255;
|
||||||
break;
|
break;
|
||||||
case TYPE_ANALOG_5CH: //RGB + warm white + cold white
|
case TYPE_ANALOG_5CH: //RGB + 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
|
||||||
_data[4] = (w * cct) / 255; w = 255 - w; // or (w * (255-cct)) / 255;
|
_data[4] = (w * cct) / 255;
|
||||||
|
w = (w * (255-cct)) / 255;
|
||||||
case TYPE_ANALOG_4CH: //RGBW
|
case TYPE_ANALOG_4CH: //RGBW
|
||||||
_data[3] = w;
|
_data[3] = w;
|
||||||
case TYPE_ANALOG_3CH: //standard dumb RGB
|
case TYPE_ANALOG_3CH: //standard dumb RGB
|
||||||
@ -292,6 +323,7 @@ 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);
|
||||||
uint8_t r = c >> 16;
|
uint8_t r = c >> 16;
|
||||||
uint8_t g = c >> 8;
|
uint8_t g = c >> 8;
|
||||||
uint8_t b = c ;
|
uint8_t b = c ;
|
||||||
@ -304,7 +336,7 @@ class BusPwm : public Bus {
|
|||||||
case TYPE_ANALOG_3CH: //standard dumb RGB
|
case TYPE_ANALOG_3CH: //standard dumb RGB
|
||||||
case TYPE_ANALOG_4CH: //standard dumb RGBW
|
case TYPE_ANALOG_4CH: //standard dumb RGBW
|
||||||
case TYPE_ANALOG_5CH: //we'll want the white handling from 2CH here + RGB
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -335,14 +367,12 @@ class BusPwm : public Bus {
|
|||||||
uint8_t getPins(uint8_t* pinArray) {
|
uint8_t getPins(uint8_t* pinArray) {
|
||||||
if (!_valid) return 0;
|
if (!_valid) return 0;
|
||||||
uint8_t numPins = NUM_PWM_PINS(_type);
|
uint8_t numPins = NUM_PWM_PINS(_type);
|
||||||
for (uint8_t i = 0; i < numPins; i++) pinArray[i] = _pins[i];
|
for (uint8_t i = 0; i < numPins; i++) {
|
||||||
|
pinArray[i] = _pins[i];
|
||||||
|
}
|
||||||
return numPins;
|
return numPins;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isRgbw() {
|
|
||||||
return Bus::isRgbw(_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void cleanup() {
|
inline void cleanup() {
|
||||||
deallocatePins();
|
deallocatePins();
|
||||||
}
|
}
|
||||||
@ -378,7 +408,7 @@ class BusPwm : public Bus {
|
|||||||
|
|
||||||
class BusNetwork : public Bus {
|
class BusNetwork : public Bus {
|
||||||
public:
|
public:
|
||||||
BusNetwork(BusConfig &bc) : Bus(bc.type, bc.start) {
|
BusNetwork(BusConfig &bc) : Bus(bc.type, bc.start, bc.autoWhite) {
|
||||||
_valid = false;
|
_valid = false;
|
||||||
// switch (bc.type) {
|
// switch (bc.type) {
|
||||||
// case TYPE_NET_ARTNET_RGB:
|
// case TYPE_NET_ARTNET_RGB:
|
||||||
@ -399,12 +429,10 @@ class BusNetwork : public Bus {
|
|||||||
// break;
|
// break;
|
||||||
// }
|
// }
|
||||||
_UDPchannels = _rgbw ? 4 : 3;
|
_UDPchannels = _rgbw ? 4 : 3;
|
||||||
//_rgbw |= bc.rgbwOverride; // RGBW override in bit 7 or can have a special type
|
|
||||||
_data = (byte *)malloc(bc.count * _UDPchannels);
|
_data = (byte *)malloc(bc.count * _UDPchannels);
|
||||||
if (_data == nullptr) return;
|
if (_data == nullptr) return;
|
||||||
memset(_data, 0, bc.count * _UDPchannels);
|
memset(_data, 0, bc.count * _UDPchannels);
|
||||||
_len = bc.count;
|
_len = bc.count;
|
||||||
//_colorOrder = bc.colorOrder;
|
|
||||||
_client = IPAddress(bc.pins[0],bc.pins[1],bc.pins[2],bc.pins[3]);
|
_client = IPAddress(bc.pins[0],bc.pins[1],bc.pins[2],bc.pins[3]);
|
||||||
_broadcastLock = false;
|
_broadcastLock = false;
|
||||||
_valid = true;
|
_valid = true;
|
||||||
@ -412,6 +440,7 @@ 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);
|
||||||
uint16_t offset = pix * _UDPchannels;
|
uint16_t offset = pix * _UDPchannels;
|
||||||
_data[offset] = 0xFF & (c >> 16);
|
_data[offset] = 0xFF & (c >> 16);
|
||||||
_data[offset+1] = 0xFF & (c >> 8);
|
_data[offset+1] = 0xFF & (c >> 8);
|
||||||
@ -479,8 +508,6 @@ class BusNetwork : public Bus {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
IPAddress _client;
|
IPAddress _client;
|
||||||
uint16_t _len = 0;
|
|
||||||
//uint8_t _colorOrder;
|
|
||||||
uint8_t _bri = 255;
|
uint8_t _bri = 255;
|
||||||
uint8_t _UDPtype;
|
uint8_t _UDPtype;
|
||||||
uint8_t _UDPchannels;
|
uint8_t _UDPchannels;
|
||||||
|
@ -61,7 +61,6 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
|||||||
|
|
||||||
CJSON(apBehavior, ap[F("behav")]);
|
CJSON(apBehavior, ap[F("behav")]);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
JsonArray ap_ip = ap["ip"];
|
JsonArray ap_ip = ap["ip"];
|
||||||
for (byte i = 0; i < 4; i++) {
|
for (byte i = 0; i < 4; i++) {
|
||||||
@ -83,7 +82,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")]);
|
||||||
CJSON(strip.rgbwMode, hw_led[F("rgbwm")]);
|
uint8_t rgbwMode = hw_led[F("rgbwm")] | RGBW_MODE_DUAL; // use global setting (legacy)
|
||||||
CJSON(allowCCT, hw_led["cct"]);
|
CJSON(allowCCT, hw_led["cct"]);
|
||||||
|
|
||||||
JsonArray ins = hw_led["ins"];
|
JsonArray ins = hw_led["ins"];
|
||||||
@ -112,13 +111,14 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
|||||||
uint16_t start = elm["start"] | 0;
|
uint16_t start = elm["start"] | 0;
|
||||||
if (length==0 || start + length > MAX_LEDS) continue; // zero length or we reached max. number of LEDs, just stop
|
if (length==0 || start + length > MAX_LEDS) continue; // zero length or we reached max. number of LEDs, just stop
|
||||||
uint8_t ledType = elm["type"] | TYPE_WS2812_RGB;
|
uint8_t ledType = elm["type"] | TYPE_WS2812_RGB;
|
||||||
|
uint8_t awMode = elm[F("rgbwm")] | rgbwMode;
|
||||||
bool reversed = elm["rev"];
|
bool reversed = elm["rev"];
|
||||||
bool refresh = elm["ref"] | false;
|
bool refresh = elm["ref"] | false;
|
||||||
ledType |= refresh << 7; // hack bit 7 to indicate strip requires off refresh
|
ledType |= refresh << 7; // hack bit 7 to indicate strip requires off refresh
|
||||||
s++;
|
s++;
|
||||||
uint16_t busEnd = start + length;
|
uint16_t busEnd = start + length;
|
||||||
if (busEnd > lC) lC = busEnd;
|
if (busEnd > lC) lC = busEnd;
|
||||||
BusConfig bc = BusConfig(ledType, pins, start, length, colorOrder, reversed, skipFirst);
|
BusConfig bc = BusConfig(ledType, pins, start, length, colorOrder, reversed, skipFirst, awMode);
|
||||||
mem += BusManager::memUsage(bc);
|
mem += BusManager::memUsage(bc);
|
||||||
if (mem <= MAX_LED_MEMORY && busses.getNumBusses() <= WLED_MAX_BUSSES) busses.add(bc); // finalization will be done in WLED::beginStrip()
|
if (mem <= MAX_LED_MEMORY && busses.getNumBusses() <= WLED_MAX_BUSSES) busses.add(bc); // finalization will be done in WLED::beginStrip()
|
||||||
}
|
}
|
||||||
@ -530,7 +530,6 @@ void serializeConfig() {
|
|||||||
hw_led[F("total")] = ledCount;
|
hw_led[F("total")] = ledCount;
|
||||||
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[F("rgbwm")] = strip.rgbwMode;
|
|
||||||
hw_led["cct"] = allowCCT;
|
hw_led["cct"] = allowCCT;
|
||||||
|
|
||||||
JsonArray hw_led_ins = hw_led.createNestedArray("ins");
|
JsonArray hw_led_ins = hw_led.createNestedArray("ins");
|
||||||
@ -551,6 +550,7 @@ void serializeConfig() {
|
|||||||
ins["type"] = bus->getType() & 0x7F;
|
ins["type"] = bus->getType() & 0x7F;
|
||||||
ins["ref"] = bus->isOffRefreshRequired();
|
ins["ref"] = bus->isOffRefreshRequired();
|
||||||
ins[F("rgbw")] = bus->isRgbw();
|
ins[F("rgbw")] = bus->isRgbw();
|
||||||
|
ins[F("rgbwm")] = bus->getAutoWhiteMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
// button(s)
|
// button(s)
|
||||||
|
@ -64,7 +64,6 @@ void colorHStoRGB(uint16_t hue, byte sat, byte* rgb) //hue, sat to rgb
|
|||||||
case 4: rgb[0]=t,rgb[1]=p,rgb[2]=255;break;
|
case 4: rgb[0]=t,rgb[1]=p,rgb[2]=255;break;
|
||||||
case 5: rgb[0]=255,rgb[1]=p,rgb[2]=q;
|
case 5: rgb[0]=255,rgb[1]=p,rgb[2]=q;
|
||||||
}
|
}
|
||||||
if (strip.isRgbw && strip.rgbwMode == RGBW_MODE_LEGACY) colorRGBtoRGBW(col);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void colorKtoRGB(uint16_t kelvin, byte* rgb) //white spectrum to rgb, calc
|
void colorKtoRGB(uint16_t kelvin, byte* rgb) //white spectrum to rgb, calc
|
||||||
@ -111,7 +110,6 @@ void colorCTtoRGB(uint16_t mired, byte* rgb) //white spectrum to rgb, bins
|
|||||||
} else {
|
} else {
|
||||||
rgb[0]=237;rgb[1]=255;rgb[2]=239;//150
|
rgb[0]=237;rgb[1]=255;rgb[2]=239;//150
|
||||||
}
|
}
|
||||||
if (strip.isRgbw && strip.rgbwMode == RGBW_MODE_LEGACY) colorRGBtoRGBW(col);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef WLED_DISABLE_HUESYNC
|
#ifndef WLED_DISABLE_HUESYNC
|
||||||
@ -169,7 +167,6 @@ void colorXYtoRGB(float x, float y, byte* rgb) //coordinates to rgb (https://www
|
|||||||
rgb[0] = 255.0*r;
|
rgb[0] = 255.0*r;
|
||||||
rgb[1] = 255.0*g;
|
rgb[1] = 255.0*g;
|
||||||
rgb[2] = 255.0*b;
|
rgb[2] = 255.0*b;
|
||||||
if (strip.isRgbw && strip.rgbwMode == RGBW_MODE_LEGACY) colorRGBtoRGBW(col);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void colorRGBtoXY(byte* rgb, float* xy) //rgb to coordinates (https://www.developers.meethue.com/documentation/color-conversions-rgb-xy)
|
void colorRGBtoXY(byte* rgb, float* xy) //rgb to coordinates (https://www.developers.meethue.com/documentation/color-conversions-rgb-xy)
|
||||||
@ -244,3 +241,24 @@ 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)
|
||||||
|
void colorBalanceFromKelvin(uint16_t kelvin, byte *rgb)
|
||||||
|
{
|
||||||
|
byte rgbw[4] = {0,0,0,0};
|
||||||
|
colorKtoRGB(kelvin, rgbw); // convert Kelvin to RGB
|
||||||
|
rgb[0] = ((uint16_t) rgbw[0] * rgb[0]) / 255; // correct R
|
||||||
|
rgb[1] = ((uint16_t) rgbw[1] * rgb[1]) / 255; // correct G
|
||||||
|
rgb[2] = ((uint16_t) rgbw[2] * rgb[2]) / 255; // correct B
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t colorBalanceFromKelvin(uint16_t kelvin, uint32_t rgb)
|
||||||
|
{
|
||||||
|
byte rgbw[4] = {0,0,0,0};
|
||||||
|
colorKtoRGB(kelvin, rgbw); // convert Kelvin to RGB
|
||||||
|
rgbw[0] = ((uint16_t) rgbw[0] * ((rgb>>16) & 0xFF)) / 255; // correct R
|
||||||
|
rgbw[1] = ((uint16_t) rgbw[1] * ((rgb>> 8) & 0xFF)) / 255; // correct G
|
||||||
|
rgbw[2] = ((uint16_t) rgbw[2] * ((rgb ) & 0xFF)) / 255; // correct B
|
||||||
|
rgbw[3] = ((rgb>>24) & 0xFF);
|
||||||
|
return colorFromRgbw(rgbw);
|
||||||
|
}
|
||||||
|
@ -170,6 +170,7 @@
|
|||||||
gId("dig"+n+"r").style.display = (t>=80 && t<96) ? "none":"inline"; // hide reversed for virtual
|
gId("dig"+n+"r").style.display = (t>=80 && t<96) ? "none":"inline"; // hide reversed for virtual
|
||||||
gId("dig"+n+"s").style.display = ((t>=80 && t<96) || (t > 40 && t < 48)) ? "none":"inline"; // hide skip 1st for virtual & analog
|
gId("dig"+n+"s").style.display = ((t>=80 && t<96) || (t > 40 && t < 48)) ? "none":"inline"; // hide skip 1st for virtual & analog
|
||||||
gId("dig"+n+"f").style.display = (t>=16 && t<32 || t>=50 && t<64) ? "inline":"none"; // hide refresh
|
gId("dig"+n+"f").style.display = (t>=16 && t<32 || t>=50 && t<64) ? "inline":"none"; // hide refresh
|
||||||
|
gId("dig"+n+"a").style.display = (isRGBW) ? "inline":"none"; // auto calculate white
|
||||||
gId("rev"+n).innerHTML = (t > 40 && t < 48) ? "Inverted output":"Reversed (rotated 180°)"; // change reverse text for analog
|
gId("rev"+n).innerHTML = (t > 40 && t < 48) ? "Inverted output":"Reversed (rotated 180°)"; // change reverse text for analog
|
||||||
gId("psd"+n).innerHTML = (t > 40 && t < 48) ? "Index:":"Start:"; // change analog start description
|
gId("psd"+n).innerHTML = (t > 40 && t < 48) ? "Index:":"Start:"; // change analog start description
|
||||||
}
|
}
|
||||||
@ -334,6 +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}"> </div>
|
<div id="dig${i}f" style="display:inline"><br>Off Refresh: <input id="rf${i}" type="checkbox" name="RF${i}"> </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> </div>
|
||||||
</div>`;
|
</div>`;
|
||||||
f.insertAdjacentHTML("beforeend", cn);
|
f.insertAdjacentHTML("beforeend", cn);
|
||||||
}
|
}
|
||||||
@ -558,16 +560,6 @@ ${i+1}:
|
|||||||
<option value="2">Linear (never wrap)</option>
|
<option value="2">Linear (never wrap)</option>
|
||||||
<option value="3">None (not recommended)</option>
|
<option value="3">None (not recommended)</option>
|
||||||
</select><br>
|
</select><br>
|
||||||
<span class="wc">
|
|
||||||
Auto-calculate white channel from RGB:<br>
|
|
||||||
<select name="AW">
|
|
||||||
<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>
|
|
||||||
<br></span>
|
|
||||||
<hr style="width:260px">
|
<hr style="width:260px">
|
||||||
<div id="cfg">Config template: <input type="file" name="data2" accept=".json"> <input type="button" value="Apply" onclick="loadCfg(d.Sf.data2);"><br></div>
|
<div id="cfg">Config template: <input type="file" name="data2" accept=".json"> <input type="button" value="Apply" onclick="loadCfg(d.Sf.data2);"><br></div>
|
||||||
<hr>
|
<hr>
|
||||||
|
File diff suppressed because one or more lines are too long
@ -74,6 +74,8 @@ void deserializeSegment(JsonObject elem, byte it, byte presetId)
|
|||||||
if (elem["on"].is<const char*>() && elem["on"].as<const char*>()[0] == 't') on = !on;
|
if (elem["on"].is<const char*>() && elem["on"].as<const char*>()[0] == 't') on = !on;
|
||||||
seg.setOption(SEG_OPTION_ON, on, id);
|
seg.setOption(SEG_OPTION_ON, on, id);
|
||||||
|
|
||||||
|
seg.cct = elem["cct"] | seg.cct;
|
||||||
|
|
||||||
JsonArray colarr = elem["col"];
|
JsonArray colarr = elem["col"];
|
||||||
if (!colarr.isNull())
|
if (!colarr.isNull())
|
||||||
{
|
{
|
||||||
@ -314,6 +316,11 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId)
|
|||||||
|
|
||||||
usermods.readFromJsonState(root);
|
usermods.readFromJsonState(root);
|
||||||
|
|
||||||
|
int8_t ledmap = root[F("ledmap")] | -1;
|
||||||
|
if (ledmap >= 0) {
|
||||||
|
strip.deserializeMap(ledmap);
|
||||||
|
}
|
||||||
|
|
||||||
int ps = root[F("psave")] | -1;
|
int ps = root[F("psave")] | -1;
|
||||||
if (ps > 0) {
|
if (ps > 0) {
|
||||||
savePreset(ps, true, nullptr, root);
|
savePreset(ps, true, nullptr, root);
|
||||||
@ -365,6 +372,7 @@ void serializeSegment(JsonObject& root, WS2812FX::Segment& seg, byte id, bool fo
|
|||||||
root["on"] = seg.getOption(SEG_OPTION_ON);
|
root["on"] = seg.getOption(SEG_OPTION_ON);
|
||||||
byte segbri = seg.opacity;
|
byte segbri = seg.opacity;
|
||||||
root["bri"] = (segbri) ? segbri : 255;
|
root["bri"] = (segbri) ? segbri : 255;
|
||||||
|
root["cct"] = seg.cct;
|
||||||
|
|
||||||
if (segmentBounds && seg.name != nullptr) root["n"] = reinterpret_cast<const char *>(seg.name); //not good practice, but decreases required JSON buffer
|
if (segmentBounds && seg.name != nullptr) root["n"] = reinterpret_cast<const char *>(seg.name); //not good practice, but decreases required JSON buffer
|
||||||
|
|
||||||
@ -480,7 +488,24 @@ void serializeInfo(JsonObject root)
|
|||||||
JsonObject leds = root.createNestedObject("leds");
|
JsonObject leds = root.createNestedObject("leds");
|
||||||
leds[F("count")] = ledCount;
|
leds[F("count")] = ledCount;
|
||||||
leds[F("rgbw")] = strip.isRgbw;
|
leds[F("rgbw")] = strip.isRgbw;
|
||||||
leds[F("wv")] = strip.isRgbw && (strip.rgbwMode == RGBW_MODE_MANUAL_ONLY || strip.rgbwMode == RGBW_MODE_DUAL); //should a white channel slider be displayed?
|
leds[F("wv")] = false;
|
||||||
|
leds["cct"] = allowCCT;
|
||||||
|
for (uint8_t s = 0; s < busses.getNumBusses(); s++) {
|
||||||
|
Bus *bus = busses.getBus(s);
|
||||||
|
if (bus == nullptr || bus->getLength()==0) break;
|
||||||
|
switch (bus->getType()) {
|
||||||
|
case TYPE_ANALOG_5CH:
|
||||||
|
case TYPE_ANALOG_2CH:
|
||||||
|
leds["cct"] = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
switch (bus->getAutoWhiteMode()) {
|
||||||
|
case RGBW_MODE_MANUAL_ONLY:
|
||||||
|
case RGBW_MODE_DUAL:
|
||||||
|
if (bus->isRgbw()) leds[F("wv")] = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
leds[F("pwr")] = strip.currentMilliamps;
|
leds[F("pwr")] = strip.currentMilliamps;
|
||||||
leds[F("fps")] = strip.getFps();
|
leds[F("fps")] = strip.getFps();
|
||||||
leds[F("maxpwr")] = (strip.currentMilliamps)? strip.ablMilliampsMax : 0;
|
leds[F("maxpwr")] = (strip.currentMilliamps)? strip.ablMilliampsMax : 0;
|
||||||
|
@ -30,7 +30,7 @@ void toggleOnOff()
|
|||||||
{
|
{
|
||||||
briLast = bri;
|
briLast = bri;
|
||||||
bri = 0;
|
bri = 0;
|
||||||
unloadPlaylist();
|
//unloadPlaylist(); // no longer necessary
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,25 +38,15 @@ void toggleOnOff()
|
|||||||
//scales the brightness with the briMultiplier factor
|
//scales the brightness with the briMultiplier factor
|
||||||
byte scaledBri(byte in)
|
byte scaledBri(byte in)
|
||||||
{
|
{
|
||||||
uint32_t d = in*briMultiplier;
|
uint16_t val = ((uint16_t)in*briMultiplier)/100;
|
||||||
uint32_t val = d/100;
|
|
||||||
if (val > 255) val = 255;
|
if (val > 255) val = 255;
|
||||||
return (byte)val;
|
return (byte)val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void setAllLeds() {
|
void setAllLeds() {
|
||||||
if (strip.isRgbw && strip.rgbwMode == RGBW_MODE_LEGACY)
|
|
||||||
{
|
|
||||||
colorRGBtoRGBW(col);
|
|
||||||
colorRGBtoRGBW(colSec);
|
|
||||||
}
|
|
||||||
strip.setColor(0, col[0], col[1], col[2], col[3]);
|
strip.setColor(0, col[0], col[1], col[2], col[3]);
|
||||||
strip.setColor(1, colSec[0], colSec[1], colSec[2], colSec[3]);
|
strip.setColor(1, colSec[0], colSec[1], colSec[2], colSec[3]);
|
||||||
if (strip.isRgbw && strip.rgbwMode == RGBW_MODE_LEGACY)
|
|
||||||
{
|
|
||||||
col[3] = 0; colSec[3] = 0;
|
|
||||||
}
|
|
||||||
if (!realtimeMode || !arlsForceMaxBri)
|
if (!realtimeMode || !arlsForceMaxBri)
|
||||||
{
|
{
|
||||||
strip.setBrightness(scaledBri(briT));
|
strip.setBrightness(scaledBri(briT));
|
||||||
@ -190,8 +180,10 @@ void updateInterfaces(uint8_t callMode)
|
|||||||
espalexaDevice->setColor(col[0], col[1], col[2]);
|
espalexaDevice->setColor(col[0], col[1], col[2]);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef WLED_DISABLE_BLYNK
|
||||||
if (callMode != CALL_MODE_BLYNK &&
|
if (callMode != CALL_MODE_BLYNK &&
|
||||||
callMode != CALL_MODE_NO_NOTIFY) updateBlynk();
|
callMode != CALL_MODE_NO_NOTIFY) updateBlynk();
|
||||||
|
#endif
|
||||||
doPublishMqtt = true;
|
doPublishMqtt = true;
|
||||||
lastInterfaceUpdate = millis();
|
lastInterfaceUpdate = millis();
|
||||||
}
|
}
|
||||||
@ -285,7 +277,9 @@ void handleNightlight()
|
|||||||
setLedsStandard();
|
setLedsStandard();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifndef WLED_DISABLE_BLYNK
|
||||||
updateBlynk();
|
updateBlynk();
|
||||||
|
#endif
|
||||||
if (macroNl > 0)
|
if (macroNl > 0)
|
||||||
applyPreset(macroNl);
|
applyPreset(macroNl);
|
||||||
nightlightActiveOld = false;
|
nightlightActiveOld = false;
|
||||||
|
@ -118,6 +118,7 @@ int16_t loadPlaylist(JsonObject playlistObj, byte presetId) {
|
|||||||
|
|
||||||
|
|
||||||
void handlePlaylist() {
|
void handlePlaylist() {
|
||||||
|
static unsigned long presetCycledTime = 0;
|
||||||
if (currentPlaylist < 0 || playlistEntries == nullptr) return;
|
if (currentPlaylist < 0 || playlistEntries == nullptr) return;
|
||||||
|
|
||||||
if (millis() - presetCycledTime > (100*playlistEntryDur)) {
|
if (millis() - presetCycledTime > (100*playlistEntryDur)) {
|
||||||
|
@ -90,7 +90,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t colorOrder, type, skip;
|
uint8_t colorOrder, type, skip, awMode;
|
||||||
uint16_t length, start;
|
uint16_t length, start;
|
||||||
uint8_t pins[5] = {255, 255, 255, 255, 255};
|
uint8_t pins[5] = {255, 255, 255, 255, 255};
|
||||||
|
|
||||||
@ -106,6 +106,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
|||||||
char cv[4] = "CV"; cv[2] = 48+s; cv[3] = 0; //strip reverse
|
char cv[4] = "CV"; cv[2] = 48+s; cv[3] = 0; //strip reverse
|
||||||
char sl[4] = "SL"; sl[2] = 48+s; sl[3] = 0; //skip 1st LED
|
char sl[4] = "SL"; sl[2] = 48+s; sl[3] = 0; //skip 1st LED
|
||||||
char rf[4] = "RF"; rf[2] = 48+s; rf[3] = 0; //refresh required
|
char rf[4] = "RF"; rf[2] = 48+s; rf[3] = 0; //refresh required
|
||||||
|
char aw[4] = "AW"; aw[2] = 48+s; aw[3] = 0; //auto white calculate mode
|
||||||
if (!request->hasArg(lp)) {
|
if (!request->hasArg(lp)) {
|
||||||
DEBUG_PRINTLN(F("No data.")); break;
|
DEBUG_PRINTLN(F("No data.")); break;
|
||||||
}
|
}
|
||||||
@ -117,7 +118,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
|||||||
type = request->arg(lt).toInt();
|
type = request->arg(lt).toInt();
|
||||||
type |= request->hasArg(rf) << 7; // off refresh override
|
type |= request->hasArg(rf) << 7; // off refresh override
|
||||||
skip = request->hasArg(sl) ? LED_SKIP_AMOUNT : 0;
|
skip = request->hasArg(sl) ? LED_SKIP_AMOUNT : 0;
|
||||||
|
awMode = request->arg(aw).toInt();
|
||||||
colorOrder = request->arg(co).toInt();
|
colorOrder = request->arg(co).toInt();
|
||||||
start = (request->hasArg(ls)) ? request->arg(ls).toInt() : t;
|
start = (request->hasArg(ls)) ? request->arg(ls).toInt() : t;
|
||||||
if (request->hasArg(lc) && request->arg(lc).toInt() > 0) {
|
if (request->hasArg(lc) && request->arg(lc).toInt() > 0) {
|
||||||
@ -128,7 +129,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
|||||||
|
|
||||||
// actual finalization is done in WLED::loop() (removing old busses and adding new)
|
// actual finalization is done in WLED::loop() (removing old busses and adding new)
|
||||||
if (busConfigs[s] != nullptr) delete busConfigs[s];
|
if (busConfigs[s] != nullptr) delete busConfigs[s];
|
||||||
busConfigs[s] = new BusConfig(type, pins, start, length, colorOrder, request->hasArg(cv), skip);
|
busConfigs[s] = new BusConfig(type, pins, start, length, colorOrder, request->hasArg(cv), skip, awMode);
|
||||||
doInitBusses = true;
|
doInitBusses = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,8 +168,6 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
|||||||
strip.ablMilliampsMax = request->arg(F("MA")).toInt();
|
strip.ablMilliampsMax = request->arg(F("MA")).toInt();
|
||||||
strip.milliampsPerLed = request->arg(F("LA")).toInt();
|
strip.milliampsPerLed = request->arg(F("LA")).toInt();
|
||||||
|
|
||||||
strip.rgbwMode = request->arg(F("AW")).toInt();
|
|
||||||
|
|
||||||
briS = request->arg(F("CA")).toInt();
|
briS = request->arg(F("CA")).toInt();
|
||||||
|
|
||||||
turnOnAtBoot = request->hasArg(F("BO"));
|
turnOnAtBoot = request->hasArg(F("BO"));
|
||||||
@ -530,10 +529,11 @@ bool updateVal(const String* req, const char* key, byte* val, byte minv, byte ma
|
|||||||
int out = getNumVal(req, pos+1);
|
int out = getNumVal(req, pos+1);
|
||||||
if (out == 0)
|
if (out == 0)
|
||||||
{
|
{
|
||||||
|
// we only have ~ (and perhaps -)
|
||||||
if (req->charAt(pos+4) == '-') {
|
if (req->charAt(pos+4) == '-') {
|
||||||
*val = min((int)maxv, max((int)minv, (int)(*val -1)));
|
*val = (int)(*val -1) < (int)minv ? maxv : min((int)maxv,(*val -1));
|
||||||
} else {
|
} else {
|
||||||
*val = min((int)maxv, max((int)minv, (int)(*val +1)));
|
*val = (int)(*val +1) > (int)maxv ? minv : max((int)minv,(*val +1));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
out += *val;
|
out += *val;
|
||||||
|
@ -637,9 +637,10 @@ WLED_GLOBAL UsermodManager usermods _INIT(UsermodManager());
|
|||||||
#define WLED_WIFI_CONFIGURED (strlen(clientSSID) >= 1 && strcmp(clientSSID, DEFAULT_CLIENT_SSID) != 0)
|
#define WLED_WIFI_CONFIGURED (strlen(clientSSID) >= 1 && strcmp(clientSSID, DEFAULT_CLIENT_SSID) != 0)
|
||||||
#define WLED_MQTT_CONNECTED (mqtt != nullptr && mqtt->connected())
|
#define WLED_MQTT_CONNECTED (mqtt != nullptr && mqtt->connected())
|
||||||
|
|
||||||
//macro to convert F to const
|
// append new c string to temp buffer efficiently
|
||||||
#define SET_F(x) (const char*)F(x)
|
bool oappend(const char* txt);
|
||||||
|
// append new number to temp buffer efficiently
|
||||||
|
bool oappendi(int i);
|
||||||
|
|
||||||
class WLED {
|
class WLED {
|
||||||
public:
|
public:
|
||||||
|
@ -320,7 +320,7 @@ void loadSettingsFromEEPROM()
|
|||||||
receiveDirect = !EEPROM.read(2200);
|
receiveDirect = !EEPROM.read(2200);
|
||||||
notifyMacro = EEPROM.read(2201);
|
notifyMacro = EEPROM.read(2201);
|
||||||
|
|
||||||
strip.rgbwMode = EEPROM.read(2203);
|
//strip.rgbwMode = EEPROM.read(2203);
|
||||||
//skipFirstLed = EEPROM.read(2204);
|
//skipFirstLed = EEPROM.read(2204);
|
||||||
|
|
||||||
bootPreset = EEPROM.read(389);
|
bootPreset = EEPROM.read(389);
|
||||||
|
@ -370,9 +370,11 @@ 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);
|
||||||
|
|
||||||
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) continue;
|
||||||
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
|
||||||
char lc[4] = "LC"; lc[2] = 48+s; lc[3] = 0; //strip length
|
char lc[4] = "LC"; lc[2] = 48+s; lc[3] = 0; //strip length
|
||||||
char co[4] = "CO"; co[2] = 48+s; co[3] = 0; //strip color order
|
char co[4] = "CO"; co[2] = 48+s; co[3] = 0; //strip color order
|
||||||
@ -381,6 +383,7 @@ void getSettingsJS(byte subPage, char* dest)
|
|||||||
char cv[4] = "CV"; cv[2] = 48+s; cv[3] = 0; //strip reverse
|
char cv[4] = "CV"; cv[2] = 48+s; cv[3] = 0; //strip reverse
|
||||||
char sl[4] = "SL"; sl[2] = 48+s; sl[3] = 0; //skip 1st LED
|
char sl[4] = "SL"; sl[2] = 48+s; sl[3] = 0; //skip 1st LED
|
||||||
char rf[4] = "RF"; rf[2] = 48+s; rf[3] = 0; //off refresh
|
char rf[4] = "RF"; rf[2] = 48+s; rf[3] = 0; //off refresh
|
||||||
|
char aw[4] = "AW"; aw[2] = 48+s; aw[3] = 0; //auto white channel calculation
|
||||||
oappend(SET_F("addLEDs(1);"));
|
oappend(SET_F("addLEDs(1);"));
|
||||||
uint8_t pins[5];
|
uint8_t pins[5];
|
||||||
uint8_t nPins = bus->getPins(pins);
|
uint8_t nPins = bus->getPins(pins);
|
||||||
@ -395,6 +398,7 @@ void getSettingsJS(byte subPage, char* dest)
|
|||||||
sappend('c',cv,bus->reversed);
|
sappend('c',cv,bus->reversed);
|
||||||
sappend('c',sl,bus->skippedLeds());
|
sappend('c',sl,bus->skippedLeds());
|
||||||
sappend('c',rf,bus->isOffRefreshRequired());
|
sappend('c',rf,bus->isOffRefreshRequired());
|
||||||
|
sappend('v',aw,bus->getAutoWhiteMode());
|
||||||
}
|
}
|
||||||
sappend('v',SET_F("MA"),strip.ablMilliampsMax);
|
sappend('v',SET_F("MA"),strip.ablMilliampsMax);
|
||||||
sappend('v',SET_F("LA"),strip.milliampsPerLed);
|
sappend('v',SET_F("LA"),strip.milliampsPerLed);
|
||||||
@ -407,7 +411,6 @@ void getSettingsJS(byte subPage, char* dest)
|
|||||||
}
|
}
|
||||||
|
|
||||||
sappend('v',SET_F("CA"),briS);
|
sappend('v',SET_F("CA"),briS);
|
||||||
sappend('v',SET_F("AW"),strip.rgbwMode);
|
|
||||||
|
|
||||||
sappend('c',SET_F("BO"),turnOnAtBoot);
|
sappend('c',SET_F("BO"),turnOnAtBoot);
|
||||||
sappend('v',SET_F("BP"),bootPreset);
|
sappend('v',SET_F("BP"),bootPreset);
|
||||||
|
Loading…
Reference in New Issue
Block a user