From fb91d9b2d483c978c986a6f9999b5cf797e3a12c Mon Sep 17 00:00:00 2001 From: cschwinne Date: Fri, 27 Nov 2020 23:59:00 +0100 Subject: [PATCH] Color order override macros --- CHANGELOG.md | 6 ++++ wled00/FX.h | 3 +- wled00/FX_fcn.cpp | 64 ++++++++++++++------------------- wled00/NpbWrapper.h | 80 +++++++++++++++++++++++++++++++++++++----- wled00/cfg.cpp | 4 +-- wled00/const.h | 9 +++++ wled00/set.cpp | 2 +- wled00/wled.h | 2 +- wled00/wled_eeprom.cpp | 2 +- wled00/xml.cpp | 2 +- 10 files changed, 121 insertions(+), 53 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b36a67f..2fbe900f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ ### WLED version 0.11.0 +#### Build 2011270 + +- Added tooltips for speed and intensity sliders (PR #1378) +- Moved color order to NpbWrapper.h +- Added compile time define to override the color order for a specific range + #### Build 2011260 - Add `live` property to state, allowing toggling of realtime (not incl. in state resp.) diff --git a/wled00/FX.h b/wled00/FX.h index 8e27d2a7..6e0b4643 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -469,6 +469,7 @@ class WS2812FX { setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0), show(void), setRgbwPwm(void), + setColorOrder(uint8_t co), setPixelSegment(uint8_t n); bool @@ -484,7 +485,6 @@ class WS2812FX { rgbwMode = RGBW_MODE_DUAL, paletteFade = 0, paletteBlend = 0, - colorOrder = 0, milliampsPerLed = 55, getBrightness(void), getMode(void), @@ -494,6 +494,7 @@ class WS2812FX { getMaxSegments(void), //getFirstSelectedSegment(void), getMainSegmentId(void), + getColorOrder(void), gamma8(uint8_t), gamma8_cal(uint8_t, float), get_random_wheel_index(uint8_t); diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index 099f77cd..ddb49f6f 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -150,18 +150,8 @@ void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w) } } - //reorder channels to selected order RgbwColor col; - switch (colorOrder) - { - case 0: col.G = g; col.R = r; col.B = b; break; //0 = GRB, default - case 1: col.G = r; col.R = g; col.B = b; break; //1 = RGB, common for WS2811 - case 2: col.G = b; col.R = r; col.B = g; break; //2 = BRG - case 3: col.G = r; col.R = b; col.B = g; break; //3 = RBG - case 4: col.G = b; col.R = g; col.B = r; break; //4 = BGR - default: col.G = g; col.R = b; col.B = r; break; //5 = GBR - } - col.W = w; + col.R = r; col.G = g; col.B = b; col.W = w; uint16_t skip = _skipFirstMode ? LED_SKIP_AMOUNT : 0; if (SEGLEN) {//from segment @@ -258,7 +248,7 @@ void WS2812FX::show(void) { for (uint16_t i = 0; i < _length; i++) //sum up the usage of each LED { - RgbwColor c = bus->GetPixelColorRgbw(i); + RgbwColor c = bus->GetPixelColorRaw(i); if(useWackyWS2815PowerModel) { @@ -467,18 +457,7 @@ uint32_t WS2812FX::getPixelColor(uint16_t i) if (i >= _lengthRaw) return 0; - RgbwColor col = bus->GetPixelColorRgbw(i); - switch (colorOrder) - { - // W G R B - case 0: return ((col.W << 24) | (col.G << 8) | (col.R << 16) | (col.B)); //0 = GRB, default - case 1: return ((col.W << 24) | (col.R << 8) | (col.G << 16) | (col.B)); //1 = RGB, common for WS2811 - case 2: return ((col.W << 24) | (col.B << 8) | (col.R << 16) | (col.G)); //2 = BRG - case 3: return ((col.W << 24) | (col.B << 8) | (col.G << 16) | (col.R)); //3 = RBG - case 4: return ((col.W << 24) | (col.R << 8) | (col.B << 16) | (col.G)); //4 = BGR - case 5: return ((col.W << 24) | (col.G << 8) | (col.B << 16) | (col.R)); //5 = GBR - } - return 0; + return bus->GetPixelColorRgbw(i); } WS2812FX::Segment& WS2812FX::getSegment(uint8_t id) { @@ -498,6 +477,14 @@ uint32_t WS2812FX::getLastShow(void) { return _lastShow; } +uint8_t WS2812FX::getColorOrder(void) { + return bus->GetColorOrder(); +} + +void WS2812FX::setColorOrder(uint8_t co) { + bus->SetColorOrder(co); +} + void WS2812FX::setSegment(uint8_t n, uint16_t i1, uint16_t i2, uint8_t grouping, uint8_t spacing) { if (n >= MAX_NUM_SEGMENTS) return; Segment& seg = _segments[n]; @@ -936,27 +923,30 @@ void WS2812FX::setRgbwPwm(void) { _analogLastShow = nowUp; - RgbwColor color = bus->GetPixelColorRgbw(0); + RgbwColor c; + uint32_t col = bus->GetPixelColorRgbw(0); + c.R = col >> 16; c.G = col >> 8; c.B = col; c.W = col >> 24; + byte b = getBrightness(); if (color == _analogLastColor && b == _analogLastBri) return; // check color values for Warm / Cold white mix (for RGBW) // EsplanexaDevice.cpp #ifdef WLED_USE_5CH_LEDS - if (color.R == 255 && color.G == 255 && color.B == 255 && color.W == 255) { - bus->SetRgbwPwm(0, 0, 0, 0, color.W * b / 255); - } else if (color.R == 127 && color.G == 127 && color.B == 127 && color.W == 255) { - bus->SetRgbwPwm(0, 0, 0, color.W * b / 512, color.W * b / 255); - } else if (color.R == 0 && color.G == 0 && color.B == 0 && color.W == 255) { - bus->SetRgbwPwm(0, 0, 0, color.W * b / 255, 0); - } else if (color.R == 130 && color.G == 90 && color.B == 0 && color.W == 255) { - bus->SetRgbwPwm(0, 0, 0, color.W * b / 255, color.W * b / 512); - } else if (color.R == 255 && color.G == 153 && color.B == 0 && color.W == 255) { - bus->SetRgbwPwm(0, 0, 0, color.W * b / 255, 0); + if (c.R == 255 && c.G == 255 && c.B == 255 && c.W == 255) { + bus->SetRgbwPwm(0, 0, 0, 0, c.W * b / 255); + } else if (c.R == 127 && c.G == 127 && c.B == 127 && c.W == 255) { + bus->SetRgbwPwm(0, 0, 0, c.W * b / 512, c.W * b / 255); + } else if (c.R == 0 && c.G == 0 && c.B == 0 && c.W == 255) { + bus->SetRgbwPwm(0, 0, 0, c.W * b / 255, 0); + } else if (c.R == 130 && c.G == 90 && c.B == 0 && c.W == 255) { + bus->SetRgbwPwm(0, 0, 0, c.W * b / 255, c.W * b / 512); + } else if (c.R == 255 && c.G == 153 && c.B == 0 && c.W == 255) { + bus->SetRgbwPwm(0, 0, 0, c.W * b / 255, 0); } else { // not only white colors - bus->SetRgbwPwm(color.R * b / 255, color.G * b / 255, color.B * b / 255, color.W * b / 255); + bus->SetRgbwPwm(c.R * b / 255, c.G * b / 255, c.B * b / 255, c.W * b / 255); } #else - bus->SetRgbwPwm(color.R * b / 255, color.G * b / 255, color.B * b / 255, color.W * b / 255); + bus->SetRgbwPwm(c.R * b / 255, c.G * b / 255, c.B * b / 255, c.W * b / 255); #endif _analogLastColor = color; _analogLastBri = b; diff --git a/wled00/NpbWrapper.h b/wled00/NpbWrapper.h index d867ef86..6316dcf8 100644 --- a/wled00/NpbWrapper.h +++ b/wled00/NpbWrapper.h @@ -41,6 +41,13 @@ #define RLYMDE 1 //mode for relay, 0: LOW if LEDs are on 1: HIGH if LEDs are on #endif +//enable color order override for a specific range of the strip +//This can be useful if you want to chain multiple strings with incompatible color order +//#define COLOR_ORDER_OVERRIDE +#define COO_MIN 0 +#define COO_MAX 27 //not inclusive, this would set the override for LEDs 0-26 +#define COO_ORDER COL_ORDER_GRB + //END CONFIGURATION #if defined(USE_APA102) || defined(USE_WS2801) || defined(USE_LPD8806) || defined(USE_P9813) @@ -168,6 +175,7 @@ #include +#include "const.h" enum NeoPixelType { @@ -296,23 +304,41 @@ public: } } - void SetPixelColor(uint16_t indexPixel, RgbwColor color) + void SetPixelColor(uint16_t indexPixel, RgbwColor c) { + RgbwColor col; + + uint8_t co = _colorOrder; + #ifdef COLOR_ORDER_OVERRIDE + if (indexPixel >= COO_MIN && indexPixel < COO_MAX) co = COO_ORDER; + #endif + + //reorder channels to selected order + switch (co) + { + case 0: col.G = c.G; col.R = c.R; col.B = c.B; break; //0 = GRB, default + case 1: col.G = c.R; col.R = c.G; col.B = c.B; break; //1 = RGB, common for WS2811 + case 2: col.G = c.B; col.R = c.R; col.B = c.G; break; //2 = BRG + case 3: col.G = c.R; col.R = c.B; col.B = c.G; break; //3 = RBG + case 4: col.G = c.B; col.R = c.G; col.B = c.R; break; //4 = BGR + default: col.G = c.G; col.R = c.B; col.B = c.R; break; //5 = GBR + } + col.W = c.W; + switch (_type) { case NeoPixelType_Grb: { - _pGrb->SetPixelColor(indexPixel, RgbColor(color.R,color.G,color.B)); + _pGrb->SetPixelColor(indexPixel, RgbColor(col.R,col.G,col.B)); } break; case NeoPixelType_Grbw: { #if defined(USE_LPD8806) || defined(USE_WS2801) - _pGrbw->SetPixelColor(indexPixel, RgbColor(color.R,color.G,color.B)); + _pGrbw->SetPixelColor(indexPixel, RgbColor(col.R,col.G,col.B)); #else - _pGrbw->SetPixelColor(indexPixel, color); + _pGrbw->SetPixelColor(indexPixel, col); #endif } break; - } - + } } void SetBrightness(byte b) @@ -323,9 +349,15 @@ public: } } - // NOTE: Due to feature differences, some support RGBW but the method name - // here needs to be unique, thus GetPixeColorRgbw - RgbwColor GetPixelColorRgbw(uint16_t indexPixel) const + void SetColorOrder(byte colorOrder) { + _colorOrder = colorOrder; + } + + uint8_t GetColorOrder() { + return _colorOrder; + } + + RgbwColor GetPixelColorRaw(uint16_t indexPixel) const { switch (_type) { case NeoPixelType_Grb: return _pGrb->GetPixelColor(indexPixel); break; @@ -334,6 +366,34 @@ public: return 0; } + // NOTE: Due to feature differences, some support RGBW but the method name + // here needs to be unique, thus GetPixeColorRgbw + uint32_t GetPixelColorRgbw(uint16_t indexPixel) const + { + RgbwColor col(0,0,0,0); + switch (_type) { + case NeoPixelType_Grb: col = _pGrb->GetPixelColor(indexPixel); break; + case NeoPixelType_Grbw: col = _pGrbw->GetPixelColor(indexPixel); break; + } + + uint8_t co = _colorOrder; + #ifdef COLOR_ORDER_OVERRIDE + if (indexPixel >= COO_MIN && indexPixel < COO_MAX) co = COO_ORDER; + #endif + + switch (co) + { + // W G R B + case 0: return ((col.W << 24) | (col.G << 8) | (col.R << 16) | (col.B)); //0 = GRB, default + case 1: return ((col.W << 24) | (col.R << 8) | (col.G << 16) | (col.B)); //1 = RGB, common for WS2811 + case 2: return ((col.W << 24) | (col.B << 8) | (col.R << 16) | (col.G)); //2 = BRG + case 3: return ((col.W << 24) | (col.B << 8) | (col.G << 16) | (col.R)); //3 = RBG + case 4: return ((col.W << 24) | (col.R << 8) | (col.B << 16) | (col.G)); //4 = BGR + case 5: return ((col.W << 24) | (col.G << 8) | (col.B << 16) | (col.R)); //5 = GBR + } + return 0; + } + uint8_t* GetPixels(void) { switch (_type) { @@ -351,6 +411,8 @@ private: NeoPixelBrightnessBus* _pGrb; NeoPixelBrightnessBus* _pGrbw; + byte _colorOrder = 0; + void cleanup() { switch (_type) { diff --git a/wled00/cfg.cpp b/wled00/cfg.cpp index 07afdf60..c12f8848 100644 --- a/wled00/cfg.cpp +++ b/wled00/cfg.cpp @@ -99,7 +99,7 @@ void deserializeConfig() { //int hw_led_ins_0_pin_0 = hw_led_ins_0[F("pin")][0]; // 2 - strip.colorOrder = hw_led_ins_0[F("order")]; + strip.setColorOrder(hw_led_ins_0[F("order")]); //bool hw_led_ins_0_rev = hw_led_ins_0[F("rev")]; // false skipFirstLed = hw_led_ins_0[F("skip")]; // 0 useRGBW = (hw_led_ins_0[F("type")] == TYPE_SK6812_RGBW); @@ -390,7 +390,7 @@ void serializeConfig() { #ifdef DATAPIN hw_led_ins_0_pin.add(DATAPIN); #endif - hw_led_ins_0[F("order")] = strip.colorOrder; //color order + hw_led_ins_0[F("order")] = strip.getColorOrder(); hw_led_ins_0[F("rev")] = false; hw_led_ins_0[F("skip")] = skipFirstLed ? 1 : 0; diff --git a/wled00/const.h b/wled00/const.h index 8dc1a286..421747a4 100644 --- a/wled00/const.h +++ b/wled00/const.h @@ -104,6 +104,15 @@ #define TYPE_TM1814 54 +//Color orders +#define COL_ORDER_GRB 0 //GRB(w),defaut +#define COL_ORDER_RGB 1 //common for WS2811 +#define COL_ORDER_BRG 2 +#define COL_ORDER_RBG 3 +#define COL_ORDER_BGR 4 +#define COL_ORDER_GBR 5 + + //Button type #define BTN_TYPE_NONE 0 #define BTN_TYPE_RESERVED 1 diff --git a/wled00/set.cpp b/wled00/set.cpp index 96e0b85f..e2b8ff1b 100644 --- a/wled00/set.cpp +++ b/wled00/set.cpp @@ -82,7 +82,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage) strip.milliampsPerLed = request->arg(F("LA")).toInt(); useRGBW = request->hasArg(F("EW")); - strip.colorOrder = request->arg(F("CO")).toInt(); + strip.setColorOrder(request->arg(F("CO")).toInt()); strip.rgbwMode = request->arg(F("AW")).toInt(); briS = request->arg(F("CA")).toInt(); diff --git a/wled00/wled.h b/wled00/wled.h index e2add60b..7c2b032f 100644 --- a/wled00/wled.h +++ b/wled00/wled.h @@ -8,7 +8,7 @@ */ // version code in format yymmddb (b = daily build) -#define VERSION 2011230 +#define VERSION 2011270 //uncomment this if you have a "my_config.h" file you'd like to use //#define WLED_USE_MY_CONFIG diff --git a/wled00/wled_eeprom.cpp b/wled00/wled_eeprom.cpp index 514c37eb..1451a746 100644 --- a/wled00/wled_eeprom.cpp +++ b/wled00/wled_eeprom.cpp @@ -224,7 +224,7 @@ void loadSettingsFromEEPROM() if (lastEEPROMversion > 9) { - strip.colorOrder = EEPROM.read(383); + strip.setColorOrder(EEPROM.read(383)); irEnabled = EEPROM.read(385); strip.ablMilliampsMax = EEPROM.read(387) + ((EEPROM.read(388) << 8) & 0xFF00); } else if (lastEEPROMversion > 1) //ABL is off by default when updating from version older than 0.8.2 diff --git a/wled00/xml.cpp b/wled00/xml.cpp index 0ad71259..c24adfe1 100644 --- a/wled00/xml.cpp +++ b/wled00/xml.cpp @@ -268,7 +268,7 @@ void getSettingsJS(byte subPage, char* dest) sappend('v',SET_F("CA"),briS); sappend('c',SET_F("EW"),useRGBW); - sappend('i',SET_F("CO"),strip.colorOrder); + sappend('i',SET_F("CO"),strip.getColorOrder()); sappend('v',SET_F("AW"),strip.rgbwMode); sappend('c',SET_F("BO"),turnOnAtBoot);