From 53e3fc29bfb64eb212862a7114119b42c815f5ea Mon Sep 17 00:00:00 2001 From: Def3nder Date: Tue, 5 Nov 2019 15:55:43 +0100 Subject: [PATCH 01/21] Alexa RGBW Support When adding an RGBW device to Alexa and then selecting a white color tone, Alexa will send CT values to the device. Having a warm white or cold white strip should use 100% of that strip and then add the RGB colors to get either a warmer color or a colder one. --- .../dependencies/espalexa/EspalexaDevice.cpp | 106 ++++++++++++++---- .../dependencies/espalexa/EspalexaDevice.h | 4 + wled00/wled12_alexa.ino | 2 +- wled00/wled14_colors.ino | 2 +- 4 files changed, 90 insertions(+), 24 deletions(-) diff --git a/wled00/src/dependencies/espalexa/EspalexaDevice.cpp b/wled00/src/dependencies/espalexa/EspalexaDevice.cpp index 43ad6f02fc..517689862d 100644 --- a/wled00/src/dependencies/espalexa/EspalexaDevice.cpp +++ b/wled00/src/dependencies/espalexa/EspalexaDevice.cpp @@ -95,6 +95,18 @@ float EspalexaDevice::getY() return _y; } +float EspalexaDevice::minf (float v, float w) +{ + if (w > v) return v; + return w; +} + +float EspalexaDevice::maxf (float v, float w) +{ + if (w > v) return w; + return v; +} + uint16_t EspalexaDevice::getCt() { if (_ct == 0) return 500; @@ -110,8 +122,8 @@ uint32_t EspalexaDevice::getKelvin() uint32_t EspalexaDevice::getRGB() { if (_rgb != 0) return _rgb; //color has not changed - uint8_t rgb[3]; - float r, g, b; + uint8_t rgb[4]; + float r, g, b, w; if (_mode == EspalexaColorMode::none) return 0; @@ -122,27 +134,38 @@ uint32_t EspalexaDevice::getRGB() float temp = 10000/ _ct; //kelvins = 1,000,000/mired (and that /100) float r, g, b; - if( temp <= 66 ){ - r = 255; - g = temp; - g = 99.470802 * log(g) - 161.119568; - if( temp <= 19){ - b = 0; - } else { - b = temp-10; - b = 138.517731 * log(b) - 305.044793; + // Cold white to warm white receiving from Alexa: _ct = 199 234 284 350 383 + switch (_ct) { + case 199: rgb[0]=255,rgb[1]=255,rgb[2]=255;rgb[3]=255;break; + case 234: rgb[0]=127,rgb[1]=127,rgb[2]=127;rgb[3]=255;break; + case 284: rgb[0]=0,rgb[1]=0,rgb[2]=0;rgb[3]=255;break; + case 350: rgb[0]=130,rgb[1]=90,rgb[2]=0;rgb[3]=255;break; + case 383: rgb[0]=255,rgb[1]=153,rgb[2]=0;rgb[3]=255;break; + default: { + if( temp <= 66 ){ + r = 255; + g = temp; + g = 99.470802 * log(g) - 161.119568; + if( temp <= 19){ + b = 0; + } else { + b = temp-10; + b = 138.517731 * log(b) - 305.044793; + } + } else { + r = temp - 60; + r = 329.698727 * pow(r, -0.13320476); + g = temp - 60; + g = 288.12217 * pow(g, -0.07551485 ); + b = 255; + } + + rgb[0] = (byte)constrain(r,0.1,255.1); + rgb[1] = (byte)constrain(g,0.1,255.1); + rgb[2] = (byte)constrain(b,0.1,255.1); + RGBtoRGBW(rgb); } - } else { - r = temp - 60; - r = 329.698727 * pow(r, -0.13320476); - g = temp - 60; - g = 288.12217 * pow(g, -0.07551485 ); - b = 255; } - - rgb[0] = (byte)constrain(r,0.1,255.1); - rgb[1] = (byte)constrain(g,0.1,255.1); - rgb[2] = (byte)constrain(b,0.1,255.1); } else if (_mode == EspalexaColorMode::hs) { float h = ((float)_hue)/65535.0; @@ -160,6 +183,7 @@ uint32_t EspalexaDevice::getRGB() case 4: rgb[0]=t,rgb[1]=p,rgb[2]=255;break; case 5: rgb[0]=255,rgb[1]=p,rgb[2]=q; } + RGBtoRGBW(rgb); } else if (_mode == EspalexaColorMode::xy) { //Source: https://www.developers.meethue.com/documentation/color-conversions-rgb-xy @@ -215,11 +239,17 @@ uint32_t EspalexaDevice::getRGB() rgb[0] = 255.0*r; rgb[1] = 255.0*g; rgb[2] = 255.0*b; + RGBtoRGBW(rgb); } - _rgb = ((rgb[0] << 16) | (rgb[1] << 8) | (rgb[2])); + _rgb = ((rgb[3] << 24) | (rgb[0] << 16) | (rgb[1] << 8) | (rgb[2])); return _rgb; } +uint8_t EspalexaDevice::getW() +{ + return (getRGB() >> 24) & 0xFF; +} + uint8_t EspalexaDevice::getR() { return (getRGB() >> 16) & 0xFF; @@ -312,6 +342,38 @@ void EspalexaDevice::setColor(uint8_t r, uint8_t g, uint8_t b) _mode = EspalexaColorMode::xy; } +void EspalexaDevice::RGBtoRGBW(byte* rgb) //rgb to rgbw (http://codewelt.com/rgbw) +{ + // https://stackoverflow.com/questions/40312216/converting-rgb-to-rgbw + float Ri=rgb[0], Gi=rgb[1], Bi=rgb[2]; + //Get the maximum between R, G, and B + float tM = maxf(Ri, maxf(Gi, Bi)); + + //If the maximum value is 0, immediately return pure black. + if(tM == 0) rgb[3] = 0; + else + { + //This section serves to figure out what the color with 100% hue is + float multiplier = 255.0f / tM; + float hR = Ri * multiplier; + float hG = Gi * multiplier; + float hB = Bi * multiplier; + + //This calculates the Whiteness (not strictly speaking Luminance) of the color + float M = maxf(hR, maxf(hG, hB)); + float m = minf(hR, minf(hG, hB)); + float Luminance = ((M + m) / 2.0f - 127.5f) * (255.0f/127.5f) / multiplier; + + //Calculate and trim the output values + int Wo = (byte)constrain(Luminance,0.1,255.1); + int Bo = (byte)constrain(Bi - Luminance,0.1,255.1); + int Ro = (byte)constrain(Ri - Luminance,0.1,255.1); + int Go = (byte)constrain(Gi - Luminance,0.1,255.1); + + rgb[0]=Ro; rgb[1]=Go; rgb[2]=Bo; rgb[3]=Wo; + } +} + void EspalexaDevice::doCallback() { if (_callback != nullptr) {_callback(_val); return;} diff --git a/wled00/src/dependencies/espalexa/EspalexaDevice.h b/wled00/src/dependencies/espalexa/EspalexaDevice.h index 8d7be8736c..e9f597023a 100644 --- a/wled00/src/dependencies/espalexa/EspalexaDevice.h +++ b/wled00/src/dependencies/espalexa/EspalexaDevice.h @@ -47,7 +47,10 @@ class EspalexaDevice { uint32_t getKelvin(); float getX(); float getY(); + float minf (float v, float w); + float maxf (float v, float w); uint32_t getRGB(); + uint8_t getW(); uint8_t getR(); uint8_t getG(); uint8_t getB(); @@ -63,6 +66,7 @@ class EspalexaDevice { void setColor(uint16_t hue, uint8_t sat); void setColorXY(float x, float y); void setColor(uint8_t r, uint8_t g, uint8_t b); + void RGBtoRGBW(byte* rgb); void doCallback(); diff --git a/wled00/wled12_alexa.ino b/wled00/wled12_alexa.ino index b858d23823..3c2c1cb5c7 100644 --- a/wled00/wled12_alexa.ino +++ b/wled00/wled12_alexa.ino @@ -62,10 +62,10 @@ void onAlexaChange(EspalexaDevice* dev) } else //color { uint32_t color = espalexaDevice->getRGB(); + col[3] = ((color >> 24) & 0xFF); col[0] = ((color >> 16) & 0xFF); col[1] = ((color >> 8) & 0xFF); col[2] = (color & 0xFF); - if (useRGBW) colorRGBtoRGBW(col); colorUpdated(10); } } diff --git a/wled00/wled14_colors.ino b/wled00/wled14_colors.ino index de57be9ebd..050d90d3f3 100644 --- a/wled00/wled14_colors.ino +++ b/wled00/wled14_colors.ino @@ -158,6 +158,6 @@ void colorRGBtoRGBW(byte* rgb) //rgb to rgbw (http://codewelt.com/rgbw) float low = minf(rgb[0],minf(rgb[1],rgb[2])); float high = maxf(rgb[0],maxf(rgb[1],rgb[2])); if (high < 0.1f) return; - float sat = 255.0f * ((high - low) / high); + 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); } From 6e88bd1c92659c8067822822600e96ace869e62d Mon Sep 17 00:00:00 2001 From: Unknown Date: Sun, 24 Nov 2019 14:34:58 +0100 Subject: [PATCH 02/21] 40 keys IR Remote Added IR remote with 40 keys to use with RGBW stripes. --- platformio.ini | 20 +++++++++- wled00/NpbWrapper.h | 13 +++++-- wled00/ir_codes.h | 79 ++++++++++++++++++++++++++++++++-------- wled00/wled00.ino | 4 +- wled00/wled14_colors.ino | 16 ++++++++ wled00/wled20_ir.ino | 59 ++++++++++++++++++++++++++++-- 6 files changed, 166 insertions(+), 25 deletions(-) diff --git a/platformio.ini b/platformio.ini index cb5f4a84dc..02e94f3b3c 100644 --- a/platformio.ini +++ b/platformio.ini @@ -4,7 +4,8 @@ [platformio] src_dir = ./wled00 data_dir = ./wled00/data -lib_extra_dirs = ./wled00/src +;lib_extra_dirs = ./wled00/src +lib_dir = ./wled00/src ; Please uncomment one of the 5 lines below to select your board ; env_default = nodemcuv2 ; env_default = esp01 @@ -96,6 +97,7 @@ build_flags = -D PIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH -D ARDUINO_ARCH_ESP32 -D WLED_DISABLE_INFRARED + -D WLED_DISABLE_ANALOG_LEDS # see: http://docs.platformio.org/en/latest/platforms/espressif8266.html [env:nodemcuv2] @@ -122,6 +124,22 @@ build_flags = lib_deps = ${common.lib_deps_external} +[env:esp8285] +board = esp8285 +platform = ${common:esp8266.platform} +monitor_speed = ${common.monitor_speed} +upload_speed = ${common.upload_speed} +framework = ${common.framework} +build_flags = + ${common.build_flags} + ${common:esp8266.build_flags} + -D WLED_DISABLE_BLYNK + -D WLED_DISABLE_CRONIXIE + -D WLED_DISABLE_HUESYNC + -D WLED_DEBUG +lib_deps = + ${common.lib_deps_external} + [env:esp01_1m] board = esp01_1m platform = ${common:esp8266_1M.platform} diff --git a/wled00/NpbWrapper.h b/wled00/NpbWrapper.h index 7adc73f238..630786b7f7 100644 --- a/wled00/NpbWrapper.h +++ b/wled00/NpbWrapper.h @@ -6,8 +6,8 @@ #define LEDPIN 2 //strip pin. Any for ESP32, gpio2 or 3 is recommended for ESP8266 (gpio2/3 are labeled D4/RX on NodeMCU and Wemos) //#define USE_APA102 // Uncomment for using APA102 LEDs. #define BTNPIN 0 //button pin. Needs to have pullup (gpio0 recommended) -#define IR_PIN 4 //infrared pin (-1 to disable) -#define RLYPIN 12 //pin for relay, will be set HIGH if LEDs are on (-1 to disable). Also usable for standby leds, triggers,... +#define IR_PIN 3 //infrared pin (-1 to disable) MagicHome: 4, H801 Wifi: 3 +#define RLYPIN -1 //pin for relay, will be set HIGH if LEDs are on (-1 to disable). Also usable for standby leds, triggers,... #define AUXPIN -1 //debug auxiliary output pin (-1 to disable) #define RLYMDE 1 //mode for relay, 0: LOW if LEDs are on 1: HIGH if LEDs are on @@ -21,11 +21,18 @@ #endif #ifndef WLED_DISABLE_ANALOG_LEDS - //PWM pins - PINs 5,12,13,15 are used with Magic Home LED Controller + /*PWM pins - PINs 5,12,13,15 are used with Magic Home LED Controller #define RPIN 5 //R pin for analog LED strip #define GPIN 12 //G pin for analog LED strip #define BPIN 13 //B pin for analog LED strip #define WPIN 15 //W pin for analog LED strip + */ + //PWM pins - PINs 15,13,12,14 are used with H801 Wifi LED Controller + #define RPIN 15 //R pin for analog LED strip + #define GPIN 13 //G pin for analog LED strip + #define BPIN 12 //B pin for analog LED strip + #define WPIN 14 //W pin for analog LED + // #endif //automatically uses the right driver method for each platform diff --git a/wled00/ir_codes.h b/wled00/ir_codes.h index e9043bd9fc..e89fc473de 100644 --- a/wled00/ir_codes.h +++ b/wled00/ir_codes.h @@ -30,6 +30,48 @@ #define IR24_FADE 0xF7C837 #define IR24_SMOOTH 0xF7E817 +// 40-key defs for blue remote control +#define IR44_BPLUS 0xFF3AC5 // +#define IR44_BMINUS 0xFFBA45 // +#define IR44_OFF 0xFF827D // +#define IR44_ON 0xFF02FD // +#define IR44_RED 0xFF1AE5 // +#define IR44_GREEN 0xFF9A65 // +#define IR44_BLUE 0xFFA25D // +#define IR44_WHITE 0xFF22DD // natural white +#define IR44_REDDISH 0xFF2AD5 // +#define IR44_GREENISH 0xFFAA55 // +#define IR44_DEEPBLUE 0xFF926D // +#define IR44_WARMWHITE2 0xFF12ED // warmest white +#define IR44_ORANGE 0xFF0AF5 // +#define IR44_TURQUOISE 0xFF8A75 // +#define IR44_PURPLE 0xFFB24D // +#define IR44_WARMWHITE 0xFF32CD // warm white +#define IR44_YELLOWISH 0xFF38C7 // +#define IR44_CYAN 0xFFB847 // +#define IR44_MAGENTA 0xFF7887 // +#define IR44_COLDWHITE 0xFFF807 // cold white +#define IR44_YELLOW 0xFF18E7 // +#define IR44_AQUA 0xFF9867 // +#define IR44_PINK 0xFF58A7 // +#define IR44_COLDWHITE2 0xFFD827 // coldest white +#define IR44_WPLUS 0xFF28D7 // white chanel bright plus +#define IR44_WMINUS 0xFFA857 // white chanel bright minus +#define IR44_WOFF 0xFF6897 // white chanel on +#define IR44_WON 0xFFE817 // white chanel off +#define IR44_W25 0xFF08F7 // white chanel 25% +#define IR44_W50 0xFF8877 // white chanel 50% +#define IR44_W75 0xFF48B7 // white chanel 75% +#define IR44_W100 0xFFC837 // white chanel 100% +#define IR44_JUMP3 0xFF30CF // JUMP3 +#define IR44_FADE3 0xFFB04F // FADE3 +#define IR44_JUMP7 0xFF708F // JUMP7 +#define IR44_QUICK 0xFFF00F // QUICK +#define IR44_FADE7 0xFF10EF // FADE7 +#define IR44_FLASH 0xFF906F // FLASH +#define IR44_AUTO 0xFF50AF // AUTO +#define IR44_SLOW 0xFFD02F // SLOW + /* 44-key defs, to be done later #define IR44_BPlus 0xFF3AC5 // #define IR44_BMinus 0xFFBA45 // @@ -77,19 +119,24 @@ #define IR44_FADE7 0xFFE01F // */ -#define COLOR_RED 0xFF0000 -#define COLOR_REDDISH 0xFF7800 -#define COLOR_ORANGE 0xFFA000 -#define COLOR_YELLOWISH 0xFFC800 -#define COLOR_YELLOW 0xFFFF00 -#define COLOR_GREEN 0x00FF00 -#define COLOR_GREENISH 0x00FF78 -#define COLOR_TURQUOISE 0x00FFA0 -#define COLOR_CYAN 0x00FFDC -#define COLOR_AQUA 0x00C8FF -#define COLOR_BLUE 0x00A0FF -#define COLOR_DEEPBLUE 0x0000FF -#define COLOR_PURPLE 0xAA00FF -#define COLOR_MAGENTA 0xFF00DC -#define COLOR_PINK 0xFF00A0 -#define COLOR_WHITE 0xFFFFDC +#define COLOR_RED 0xFF0000 +#define COLOR_REDDISH 0xFF7800 +#define COLOR_ORANGE 0xFFA000 +#define COLOR_YELLOWISH 0xFFC800 +#define COLOR_YELLOW 0xFFFF00 +#define COLOR_GREEN 0x00FF00 +#define COLOR_GREENISH 0x00FF78 +#define COLOR_TURQUOISE 0x00FFA0 +#define COLOR_CYAN 0x00FFDC +#define COLOR_AQUA 0x00C8FF +#define COLOR_BLUE 0x00A0FF +#define COLOR_DEEPBLUE 0x0000FF +#define COLOR_PURPLE 0xAA00FF +#define COLOR_MAGENTA 0xFF00DC +#define COLOR_PINK 0xFF00A0 +#define COLOR_WHITE 0xFFFFDC +#define COLOR_WARMWHITE2 0xFFFF9900 +#define COLOR_WARMWHITE 0xFF825A00 +#define COLOR_NEUTRALWHITE 0xFF000000 +#define COLOR_COLDWHITE 0xFF7F7F7F +#define COLOR_COLDWHITE2 0xFFFFFFFF \ No newline at end of file diff --git a/wled00/wled00.ino b/wled00/wled00.ino index 85fda67adb..166c02b3a2 100644 --- a/wled00/wled00.ino +++ b/wled00/wled00.ino @@ -172,7 +172,7 @@ bool useHSBDefault = useHSB; //Sync CONFIG bool buttonEnabled = true; -bool irEnabled = false; //Infrared receiver +bool irEnabled = true; //Infrared receiver uint16_t udpPort = 21324; //WLED notifier default port uint16_t udpRgbPort = 19446; //Hyperion port @@ -301,6 +301,8 @@ byte briOld = 0; byte briT = 0; byte briIT = 0; byte briLast = 127; //brightness before turned off. Used for toggle function +byte white = 0; +byte whiteLast = 0; //white level before turned off. Used for toggle function //button bool buttonPressedBefore = false; diff --git a/wled00/wled14_colors.ino b/wled00/wled14_colors.ino index 050d90d3f3..da1b3aae4e 100644 --- a/wled00/wled14_colors.ino +++ b/wled00/wled14_colors.ino @@ -10,6 +10,22 @@ void colorFromUint32(uint32_t in) col[2] = in & 0xFF; } +void colorFromUint24(uint32_t in) +{ + col[0] = in >> 16 & 0xFF; + col[1] = in >> 8 & 0xFF; + col[2] = in & 0xFF; +} + +//relatively change white brightness, minumum A=5 +void relativeChangeWhite(int8_t amount, byte lowerBoundary =0) +{ + int16_t new_val = (int16_t) col[3] + amount; + if (new_val > 0xFF) new_val = 0xFF; + else if (new_val < lowerBoundary) new_val = lowerBoundary; + col[3] = new_val; +} + void colorHStoRGB(uint16_t hue, byte sat, byte* rgb) //hue, sat to rgb { float h = ((float)hue)/65535.0; diff --git a/wled00/wled20_ir.ino b/wled00/wled20_ir.ino index 88d1bdffc8..067fb25aff 100644 --- a/wled00/wled20_ir.ino +++ b/wled00/wled20_ir.ino @@ -48,15 +48,23 @@ void decodeIR(uint32_t code) if (code == 0xFFFFFFFF) //repeated code, continue brightness up/down { irTimesRepeated++; - if (lastValidCode == IR24_BRIGHTER) + if (lastValidCode == IR24_BRIGHTER | lastValidCode == IR44_BPLUS ) { relativeChange(&bri, 10); colorUpdated(2); } - else if (lastValidCode == IR24_DARKER) + else if (lastValidCode == IR24_DARKER | lastValidCode == IR44_BMINUS ) { relativeChange(&bri, -10, 5); colorUpdated(2); } - else if (lastValidCode == IR24_ON && irTimesRepeated > 7) + if (lastValidCode == IR44_WPLUS) + { + relativeChangeWhite(10); colorUpdated(2); + } + else if (lastValidCode == IR44_WMINUS) + { + relativeChangeWhite(-10, 5); colorUpdated(2); + } + else if ((lastValidCode == IR24_ON | lastValidCode == IR44_ON) && irTimesRepeated > 7 ) { nightlightActive = true; nightlightStartTime = millis(); @@ -110,7 +118,50 @@ void decodeIR24(uint32_t code) void decodeIR44(uint32_t code) { - //not implemented for now + switch (code) { + case IR44_BPLUS : relativeChange(&bri, 10); break; + case IR44_BMINUS : relativeChange(&bri, -10, 5); break; + case IR44_OFF : briLast = bri; bri = 0; break; + case IR44_ON : bri = briLast; break; + case IR44_RED : colorFromUint24(COLOR_RED); break; + case IR44_REDDISH : colorFromUint24(COLOR_REDDISH); break; + case IR44_ORANGE : colorFromUint24(COLOR_ORANGE); break; + case IR44_YELLOWISH : colorFromUint24(COLOR_YELLOWISH); break; + case IR44_YELLOW : colorFromUint24(COLOR_YELLOW); break; + case IR44_GREEN : colorFromUint24(COLOR_GREEN); break; + case IR44_GREENISH : colorFromUint24(COLOR_GREENISH); break; + case IR44_TURQUOISE : colorFromUint24(COLOR_TURQUOISE); break; + case IR44_CYAN : colorFromUint24(COLOR_CYAN); break; + case IR44_AQUA : colorFromUint24(COLOR_AQUA); break; + case IR44_BLUE : colorFromUint24(COLOR_BLUE); break; + case IR44_DEEPBLUE : colorFromUint24(COLOR_DEEPBLUE); break; + case IR44_PURPLE : colorFromUint24(COLOR_PURPLE); break; + case IR44_MAGENTA : colorFromUint24(COLOR_MAGENTA); break; + case IR44_PINK : colorFromUint24(COLOR_PINK); break; + case IR44_WARMWHITE2 : colorFromUint32(COLOR_WARMWHITE2); effectCurrent = 0; break; + case IR44_WARMWHITE : colorFromUint32(COLOR_WARMWHITE); effectCurrent = 0; break; + case IR44_WHITE : colorFromUint32(COLOR_NEUTRALWHITE); effectCurrent = 0; break; + case IR44_COLDWHITE : colorFromUint32(COLOR_COLDWHITE); effectCurrent = 0; break; + case IR44_COLDWHITE2 : colorFromUint32(COLOR_COLDWHITE2); effectCurrent = 0; break; + case IR44_WPLUS : relativeChangeWhite(10); break; + case IR44_WMINUS : relativeChangeWhite(-10, 5); break; + case IR44_WOFF : whiteLast = col[3]; col[3] = 0; break; + case IR44_WON : col[3] = whiteLast; break; + case IR44_W25 : bri = 63; break; + case IR44_W50 : bri = 127; break; + case IR44_W75 : bri = 191; break; + case IR44_W100 : bri = 255; break; + case IR44_QUICK : relativeChange(&effectSpeed, 10); break; + case IR44_SLOW : relativeChange(&effectSpeed, -10, 5); break; + case IR44_JUMP7 : relativeChange(&effectIntensity, 10); break; + case IR44_AUTO : relativeChange(&effectIntensity, -10, 5); break; + case IR44_JUMP3 : if (!applyPreset(1)) effectCurrent = FX_MODE_STATIC; break; + case IR44_FADE3 : if (!applyPreset(2)) effectCurrent = FX_MODE_BREATH; break; + case IR44_FADE7 : if (!applyPreset(3)) effectCurrent = FX_MODE_FIRE_FLICKER; break; + case IR44_FLASH : if (!applyPreset(4)) effectCurrent = FX_MODE_RAINBOW; break; + } + lastValidCode = code; + colorUpdated(2); //for notifier, IR is considered a button input } From 30ed694b138f8fdf32a90e711741ea0037468c7f Mon Sep 17 00:00:00 2001 From: Unknown Date: Sun, 24 Nov 2019 23:20:42 +0100 Subject: [PATCH 03/21] ESU8285 flash size corrected --- platformio.ini | 10 +++++----- wled00/NpbWrapper.h | 20 ++++++++++---------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/platformio.ini b/platformio.ini index 02e94f3b3c..0a338306e4 100644 --- a/platformio.ini +++ b/platformio.ini @@ -75,8 +75,8 @@ build_flags = ; -D WLED_DISABLE_ALEXA -D WLED_DISABLE_BLYNK -D WLED_DISABLE_CRONIXIE - ; -D WLED_DISABLE_HUESYNC - -D WLED_DISABLE_INFRARED + -D WLED_DISABLE_HUESYNC + ; -D WLED_DISABLE_INFRARED [common:esp8266_512k] platform = espressif8266@1.8.0 @@ -126,13 +126,13 @@ lib_deps = [env:esp8285] board = esp8285 -platform = ${common:esp8266.platform} +platform = espressif8266@1.8.0 monitor_speed = ${common.monitor_speed} upload_speed = ${common.upload_speed} framework = ${common.framework} build_flags = - ${common.build_flags} - ${common:esp8266.build_flags} + -D PIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH_LOW_FLASH + -Wl,-Teagle.flash.1m256.ld ;;;; Compile with no SPIFFS to leave space for OTA -D WLED_DISABLE_BLYNK -D WLED_DISABLE_CRONIXIE -D WLED_DISABLE_HUESYNC diff --git a/wled00/NpbWrapper.h b/wled00/NpbWrapper.h index 630786b7f7..f12031a848 100644 --- a/wled00/NpbWrapper.h +++ b/wled00/NpbWrapper.h @@ -5,8 +5,8 @@ //PIN CONFIGURATION #define LEDPIN 2 //strip pin. Any for ESP32, gpio2 or 3 is recommended for ESP8266 (gpio2/3 are labeled D4/RX on NodeMCU and Wemos) //#define USE_APA102 // Uncomment for using APA102 LEDs. -#define BTNPIN 0 //button pin. Needs to have pullup (gpio0 recommended) -#define IR_PIN 3 //infrared pin (-1 to disable) MagicHome: 4, H801 Wifi: 3 +#define BTNPIN -1 //button pin. Needs to have pullup (gpio0 recommended) +#define IR_PIN 0 //infrared pin (-1 to disable) MagicHome: 4, H801 Wifi: 0 #define RLYPIN -1 //pin for relay, will be set HIGH if LEDs are on (-1 to disable). Also usable for standby leds, triggers,... #define AUXPIN -1 //debug auxiliary output pin (-1 to disable) @@ -21,18 +21,18 @@ #endif #ifndef WLED_DISABLE_ANALOG_LEDS - /*PWM pins - PINs 5,12,13,15 are used with Magic Home LED Controller - #define RPIN 5 //R pin for analog LED strip - #define GPIN 12 //G pin for analog LED strip - #define BPIN 13 //B pin for analog LED strip - #define WPIN 15 //W pin for analog LED strip - */ - //PWM pins - PINs 15,13,12,14 are used with H801 Wifi LED Controller + //PWM pins - PINs 15,13,12,14 (W2 = 04)are used with H801 Wifi LED Controller #define RPIN 15 //R pin for analog LED strip #define GPIN 13 //G pin for analog LED strip #define BPIN 12 //B pin for analog LED strip - #define WPIN 14 //W pin for analog LED + #define WPIN 14 //W pin for analog LED strip (W1: 14, W2: 04) // + /*PWM pins - PINs 5,12,13,15 are used with Magic Home LED Controller + #define RPIN 5 //R pin for analog LED strip + #define GPIN 12 //G pin for analog LED strip + #define BPIN 13 //B pin for analog LED strip + #define WPIN 15 //W pin for analog LED strip (W1: 14, W2: 04) + */ #endif //automatically uses the right driver method for each platform From 86761272d9a97c748d5f90ef6153beef64b3cea3 Mon Sep 17 00:00:00 2001 From: Def3nder Date: Mon, 25 Nov 2019 09:28:39 +0100 Subject: [PATCH 04/21] ESP32 fixes for Solid RGBW ...not implemented for ESP32 yet ESP32 Solid RGBW defines moved from env:esp32dev to env:esp32 ESP32 Solid RGBW defines --- platformio.ini | 2 ++ wled00/wled00.ino | 1 + 2 files changed, 3 insertions(+) diff --git a/platformio.ini b/platformio.ini index 0a338306e4..24202916c6 100644 --- a/platformio.ini +++ b/platformio.ini @@ -98,6 +98,8 @@ build_flags = -D ARDUINO_ARCH_ESP32 -D WLED_DISABLE_INFRARED -D WLED_DISABLE_ANALOG_LEDS + # disable ANALOG LEDS because the analogWrite-function needs to be adapted to ESP32 + -D WLED_DISABLE_ANALOG_LEDS # see: http://docs.platformio.org/en/latest/platforms/espressif8266.html [env:nodemcuv2] diff --git a/wled00/wled00.ino b/wled00/wled00.ino index 166c02b3a2..96a772c615 100644 --- a/wled00/wled00.ino +++ b/wled00/wled00.ino @@ -88,6 +88,7 @@ #endif #ifdef ARDUINO_ARCH_ESP32 + #define WLED_DISABLE_ANALOG_LEDS // Solid RGBW not implemented for ESP32 yet /*#ifndef WLED_DISABLE_INFRARED #include #endif*/ //there are issues with ESP32 infrared, so it is disabled for now From adb0b707f61d2fa767b5cbeab35e3f23f1e16f3d Mon Sep 17 00:00:00 2001 From: Def3nder <33399267+Def3nder@users.noreply.github.com> Date: Mon, 25 Nov 2019 10:30:47 +0100 Subject: [PATCH 05/21] Update readme.md --- readme.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index 6a4b41e2d0..6b2a34e257 100644 --- a/readme.md +++ b/readme.md @@ -5,12 +5,16 @@ [![](https://img.shields.io/badge/quick_start-wiki-blue.svg?style=flat-square)](https://github.com/Aircoookie/WLED/wiki) [![](https://img.shields.io/badge/app-wled-blue.svg?style=flat-square)](https://github.com/Aircoookie/WLED-App) -## Welcome to my project WLED! +## Welcome to the modded version of the brilliant project WLED! + +The Mod enables **analog RGBW stripes** instead of digital ones. + +### All the acknowledgement goes to Aircoookie, the author of WLED. A fast and feature-rich implementation of an ESP8266/ESP32 webserver to control NeoPixel (WS2812B, WS2811, SK6812, APA102) LEDs! ### Features: -- WS2812FX library integrated for 80 special effects +- WS2812FX library integrated for 80+ special effects - FastLED noise effects and palettes - Customizable Mobile and desktop UI with color and effect controls - Settings page - configuration over network From 13a8183675663eaec266c01f2acbdaf510594b19 Mon Sep 17 00:00:00 2001 From: Def3nder <33399267+Def3nder@users.noreply.github.com> Date: Mon, 25 Nov 2019 10:33:50 +0100 Subject: [PATCH 06/21] Update readme.md --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 6b2a34e257..e3910d3f0f 100644 --- a/readme.md +++ b/readme.md @@ -1,6 +1,6 @@ ![WLED logo](https://raw.githubusercontent.com/Aircoookie/WLED/master/wled_logo.png) -[![](https://img.shields.io/github/release/Aircoookie/WLED.svg?style=flat-square)](https://github.com/Aircoookie/WLED/releases) +[![](https://img.shields.io/github/release/Def3nder/WLED.svg?style=flat-square)](https://github.com/Def3nder/WLED/releases) [![](https://img.shields.io/discord/473448917040758787.svg?colorB=blue&label=discord&style=flat-square)](https://discord.gg/KuqP7NE) [![](https://img.shields.io/badge/quick_start-wiki-blue.svg?style=flat-square)](https://github.com/Aircoookie/WLED/wiki) [![](https://img.shields.io/badge/app-wled-blue.svg?style=flat-square)](https://github.com/Aircoookie/WLED-App) From 99a609c74e0c75e0e5dbc452dbe6f13d4ba6e1b3 Mon Sep 17 00:00:00 2001 From: Def3nder Date: Mon, 25 Nov 2019 10:35:57 +0100 Subject: [PATCH 07/21] Update readme.md Update readme.md --- readme.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/readme.md b/readme.md index 6a4b41e2d0..e3910d3f0f 100644 --- a/readme.md +++ b/readme.md @@ -1,16 +1,20 @@ ![WLED logo](https://raw.githubusercontent.com/Aircoookie/WLED/master/wled_logo.png) -[![](https://img.shields.io/github/release/Aircoookie/WLED.svg?style=flat-square)](https://github.com/Aircoookie/WLED/releases) +[![](https://img.shields.io/github/release/Def3nder/WLED.svg?style=flat-square)](https://github.com/Def3nder/WLED/releases) [![](https://img.shields.io/discord/473448917040758787.svg?colorB=blue&label=discord&style=flat-square)](https://discord.gg/KuqP7NE) [![](https://img.shields.io/badge/quick_start-wiki-blue.svg?style=flat-square)](https://github.com/Aircoookie/WLED/wiki) [![](https://img.shields.io/badge/app-wled-blue.svg?style=flat-square)](https://github.com/Aircoookie/WLED-App) -## Welcome to my project WLED! +## Welcome to the modded version of the brilliant project WLED! + +The Mod enables **analog RGBW stripes** instead of digital ones. + +### All the acknowledgement goes to Aircoookie, the author of WLED. A fast and feature-rich implementation of an ESP8266/ESP32 webserver to control NeoPixel (WS2812B, WS2811, SK6812, APA102) LEDs! ### Features: -- WS2812FX library integrated for 80 special effects +- WS2812FX library integrated for 80+ special effects - FastLED noise effects and palettes - Customizable Mobile and desktop UI with color and effect controls - Settings page - configuration over network From 77e6fab0709050f73a473d235c3621134116c9a3 Mon Sep 17 00:00:00 2001 From: Unknown Date: Sun, 15 Dec 2019 12:29:33 +0100 Subject: [PATCH 08/21] Use different IR remotes in the settings To turn off IR remote use "0" in the settings, use 1 to 4 for different IR remote types. --- platformio.ini | 23 +++-- wled00/html_settings.h | 2 +- wled00/ir_codes.h | 224 ++++++++++++++++++++++++---------------- wled00/wled00.ino | 2 +- wled00/wled02_xml.ino | 2 +- wled00/wled03_set.ino | 2 +- wled00/wled20_ir.ino | 225 ++++++++++++++++++++++++++++++++--------- 7 files changed, 336 insertions(+), 144 deletions(-) diff --git a/platformio.ini b/platformio.ini index 24202916c6..3886d8c95a 100644 --- a/platformio.ini +++ b/platformio.ini @@ -128,16 +128,27 @@ lib_deps = [env:esp8285] board = esp8285 -platform = espressif8266@1.8.0 +platform = ${common:esp8266_1M.platform} monitor_speed = ${common.monitor_speed} upload_speed = ${common.upload_speed} framework = ${common.framework} build_flags = - -D PIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH_LOW_FLASH - -Wl,-Teagle.flash.1m256.ld ;;;; Compile with no SPIFFS to leave space for OTA - -D WLED_DISABLE_BLYNK - -D WLED_DISABLE_CRONIXIE - -D WLED_DISABLE_HUESYNC + ${common.build_flags} + ${common:esp8266_1M.build_flags} + -D WLED_DEBUG +lib_deps = + ${common.lib_deps_external} + +[env:esp8285_5CH] +board = esp8285 +platform = ${common:esp8266_1M.platform} +monitor_speed = ${common.monitor_speed} +upload_speed = ${common.upload_speed} +framework = ${common.framework} +build_flags = + ${common.build_flags} + ${common:esp8266_1M.build_flags} + -D WLED_USE_5CH_LEDS -D WLED_DEBUG lib_deps = ${common.lib_deps_external} diff --git a/wled00/html_settings.h b/wled00/html_settings.h index f688c56d46..5d5a271d8b 100644 --- a/wled00/html_settings.h +++ b/wled00/html_settings.h @@ -259,7 +259,7 @@ const char PAGE_settings_sync[] PROGMEM = R"=====(

Sync setup

Button setup

On/Off button enabled:
-Infrared receiver enabled:
+Infrared receiver type (0 = disabled):
IR info

WLED Broadcast

UDP Port:
diff --git a/wled00/ir_codes.h b/wled00/ir_codes.h index e89fc473de..3bd056028c 100644 --- a/wled00/ir_codes.h +++ b/wled00/ir_codes.h @@ -30,95 +30,147 @@ #define IR24_FADE 0xF7C837 #define IR24_SMOOTH 0xF7E817 +// 24-key defs for white remote control with CW / WW / CT+ and CT- keys (from ALDI LED pillar lamp) +#define IR24_CT_BRIGHTER 0xF700FF // BRI + +#define IR24_CT_DARKER 0xF7807F // BRI - +#define IR24_CT_OFF 0xF740BF // OFF +#define IR24_CT_ON 0xF7C03F // ON +#define IR24_CT_RED 0xF720DF // RED +#define IR24_CT_REDDISH 0xF710EF // REDDISH +#define IR24_CT_ORANGE 0xF730CF // ORANGE +#define IR24_CT_YELLOWISH 0xF708F7 // YELLOWISH +#define IR24_CT_YELLOW 0xF728D7 // YELLOW +#define IR24_CT_GREEN 0xF7A05F // GREEN +#define IR24_CT_GREENISH 0xF7906F // GREENISH +#define IR24_CT_TURQUOISE 0xF7B04F // TURQUOISE +#define IR24_CT_CYAN 0xF78877 // CYAN +#define IR24_CT_AQUA 0xF7A857 // AQUA +#define IR24_CT_BLUE 0xF7609F // BLUE +#define IR24_CT_DEEPBLUE 0xF750AF // DEEPBLUE +#define IR24_CT_PURPLE 0xF7708F // PURPLE +#define IR24_CT_MAGENTA 0xF748B7 // MAGENTA +#define IR24_CT_PINK 0xF76897 // PINK +#define IR24_CT_COLDWHITE 0xF7E01F // CW +#define IR24_CT_WARMWHITE 0xF7D02F // WW +#define IR24_CT_CTPLUS 0xF7F00F // CT+ +#define IR24_CT_CTMINUS 0xF7C837 // CT- +#define IR24_CT_MEMORY 0xF7E817 // MEMORY + +// 24-key defs for old remote control +#define IR24_OLD_BRIGHTER 0xFF906F // Brightness Up +#define IR24_OLD_DARKER 0xFFB847 // Brightness Down +#define IR24_OLD_OFF 0xFFF807 // Power OFF +#define IR24_OLD_ON 0xFFB04F // Power On +#define IR24_OLD_RED 0xFF9867 // RED +#define IR24_OLD_REDDISH 0xFFE817 // Light RED +#define IR24_OLD_ORANGE 0xFF02FD // Orange +#define IR24_OLD_YELLOWISH 0xFF50AF // Light Orange +#define IR24_OLD_YELLOW 0xFF38C7 // YELLOW +#define IR24_OLD_GREEN 0xFFD827 // GREEN +#define IR24_OLD_GREENISH 0xFF48B7 // Light GREEN +#define IR24_OLD_TURQUOISE 0xFF32CD // TURQUOISE +#define IR24_OLD_CYAN 0xFF7887 // CYAN +#define IR24_OLD_AQUA 0xFF28D7 // AQUA +#define IR24_OLD_BLUE 0xFF8877 // BLUE +#define IR24_OLD_DEEPBLUE 0xFF6897 // Dark BLUE +#define IR24_OLD_PURPLE 0xFF20DF // PURPLE +#define IR24_OLD_MAGENTA 0xFF708F // MAGENTA +#define IR24_OLD_PINK 0xFFF00F // PINK +#define IR24_OLD_WHITE 0xFFA857 // WHITE +#define IR24_OLD_FLASH 0xFFB24D // FLASH Mode +#define IR24_OLD_STROBE 0xFF00FF // STROBE Mode +#define IR24_OLD_FADE 0xFF58A7 // FADE Mode +#define IR24_OLD_SMOOTH 0xFF30CF // SMOOTH Mode + // 40-key defs for blue remote control -#define IR44_BPLUS 0xFF3AC5 // -#define IR44_BMINUS 0xFFBA45 // -#define IR44_OFF 0xFF827D // -#define IR44_ON 0xFF02FD // -#define IR44_RED 0xFF1AE5 // -#define IR44_GREEN 0xFF9A65 // -#define IR44_BLUE 0xFFA25D // -#define IR44_WHITE 0xFF22DD // natural white -#define IR44_REDDISH 0xFF2AD5 // -#define IR44_GREENISH 0xFFAA55 // -#define IR44_DEEPBLUE 0xFF926D // -#define IR44_WARMWHITE2 0xFF12ED // warmest white -#define IR44_ORANGE 0xFF0AF5 // -#define IR44_TURQUOISE 0xFF8A75 // -#define IR44_PURPLE 0xFFB24D // -#define IR44_WARMWHITE 0xFF32CD // warm white -#define IR44_YELLOWISH 0xFF38C7 // -#define IR44_CYAN 0xFFB847 // -#define IR44_MAGENTA 0xFF7887 // -#define IR44_COLDWHITE 0xFFF807 // cold white -#define IR44_YELLOW 0xFF18E7 // -#define IR44_AQUA 0xFF9867 // -#define IR44_PINK 0xFF58A7 // -#define IR44_COLDWHITE2 0xFFD827 // coldest white -#define IR44_WPLUS 0xFF28D7 // white chanel bright plus -#define IR44_WMINUS 0xFFA857 // white chanel bright minus -#define IR44_WOFF 0xFF6897 // white chanel on -#define IR44_WON 0xFFE817 // white chanel off -#define IR44_W25 0xFF08F7 // white chanel 25% -#define IR44_W50 0xFF8877 // white chanel 50% -#define IR44_W75 0xFF48B7 // white chanel 75% -#define IR44_W100 0xFFC837 // white chanel 100% -#define IR44_JUMP3 0xFF30CF // JUMP3 -#define IR44_FADE3 0xFFB04F // FADE3 -#define IR44_JUMP7 0xFF708F // JUMP7 -#define IR44_QUICK 0xFFF00F // QUICK -#define IR44_FADE7 0xFF10EF // FADE7 -#define IR44_FLASH 0xFF906F // FLASH -#define IR44_AUTO 0xFF50AF // AUTO -#define IR44_SLOW 0xFFD02F // SLOW +#define IR40_BPLUS 0xFF3AC5 // +#define IR40_BMINUS 0xFFBA45 // +#define IR40_OFF 0xFF827D // +#define IR40_ON 0xFF02FD // +#define IR40_RED 0xFF1AE5 // +#define IR40_GREEN 0xFF9A65 // +#define IR40_BLUE 0xFFA25D // +#define IR40_WHITE 0xFF22DD // natural white +#define IR40_REDDISH 0xFF2AD5 // +#define IR40_GREENISH 0xFFAA55 // +#define IR40_DEEPBLUE 0xFF926D // +#define IR40_WARMWHITE2 0xFF12ED // warmest white +#define IR40_ORANGE 0xFF0AF5 // +#define IR40_TURQUOISE 0xFF8A75 // +#define IR40_PURPLE 0xFFB24D // +#define IR40_WARMWHITE 0xFF32CD // warm white +#define IR40_YELLOWISH 0xFF38C7 // +#define IR40_CYAN 0xFFB847 // +#define IR40_MAGENTA 0xFF7887 // +#define IR40_COLDWHITE 0xFFF807 // cold white +#define IR40_YELLOW 0xFF18E7 // +#define IR40_AQUA 0xFF9867 // +#define IR40_PINK 0xFF58A7 // +#define IR40_COLDWHITE2 0xFFD827 // coldest white +#define IR40_WPLUS 0xFF28D7 // white chanel bright plus +#define IR40_WMINUS 0xFFA857 // white chanel bright minus +#define IR40_WOFF 0xFF6897 // white chanel on +#define IR40_WON 0xFFE817 // white chanel off +#define IR40_W25 0xFF08F7 // white chanel 25% +#define IR40_W50 0xFF8877 // white chanel 50% +#define IR40_W75 0xFF48B7 // white chanel 75% +#define IR40_W100 0xFFC837 // white chanel 100% +#define IR40_JUMP3 0xFF30CF // JUMP3 +#define IR40_FADE3 0xFFB04F // FADE3 +#define IR40_JUMP7 0xFF708F // JUMP7 +#define IR40_QUICK 0xFFF00F // QUICK +#define IR40_FADE7 0xFF10EF // FADE7 +#define IR40_FLASH 0xFF906F // FLASH +#define IR40_AUTO 0xFF50AF // AUTO +#define IR40_SLOW 0xFFD02F // SLOW -/* 44-key defs, to be done later -#define IR44_BPlus 0xFF3AC5 // -#define IR44_BMinus 0xFFBA45 // -#define IR44_ON 0xFF827D // -#define IR44_OFF 0xFF02FD // -#define IR44_R 0xFF1AE5 // -#define IR44_G 0xFF9A65 // -#define IR44_B 0xFFA25D // -#define IR44_W 0xFF22DD // -#define IR44_B1 0xFF2AD5 // -#define IR44_B2 0xFFAA55 // -#define IR44_B3 0xFF926D // -#define IR44_B4 0xFF12ED // -#define IR44_B5 0xFF0AF5 // -#define IR44_B6 0xFF8A75 // -#define IR44_B7 0xFFB24D // -#define IR44_B8 0xFF32CD // -#define IR44_B9 0xFF38C7 // -#define IR44_B10 0xFFB847 // -#define IR44_B11 0xFF7887 // -#define IR44_B12 0xFFF807 // -#define IR44_B13 0xFF18E7 // -#define IR44_B14 0xFF9867 // -#define IR44_B15 0xFF58A7 // -#define IR44_B16 0xFFD827 // -#define IR44_UPR 0xFF28D7 // -#define IR44_UPG 0xFFA857 // -#define IR44_UPB 0xFF6897 // -#define IR44_QUICK 0xFFE817 // -#define IR44_DOWNR 0xFF08F7 // -#define IR44_DOWNG 0xFF8877 // -#define IR44_DOWNB 0xFF48B7 // -#define IR44_SLOW 0xFFC837 // -#define IR44_DIY1 0xFF30CF // -#define IR44_DIY2 0xFFB04F // -#define IR44_DIY3 0xFF708F // -#define IR44_AUTO 0xFFF00F // -#define IR44_DIY4 0xFF10EF // -#define IR44_DIY5 0xFF906F // -#define IR44_DIY6 0xFF50AF // -#define IR44_FLASH 0xFFD02F // -#define IR44_JUMP3 0xFF20DF // -#define IR44_JUMP7 0xFFA05F // -#define IR44_FADE3 0xFF609F // -#define IR44_FADE7 0xFFE01F // -*/ +// 44-key defs, to be done later +#define IR44_BPLUS 0xFF3AC5 // +#define IR44_BMINUS 0xFFBA45 // +#define IR44_OFF 0xFF827D // +#define IR44_ON 0xFF02FD // +#define IR44_RED 0xFF1AE5 // +#define IR44_GREEN 0xFF9A65 // +#define IR44_BLUE 0xFFA25D // +#define IR44_WHITE 0xFF22DD // natural white +#define IR44_REDDISH 0xFF2AD5 // +#define IR44_GREENISH 0xFFAA55 // +#define IR44_DEEPBLUE 0xFF926D // +#define IR44_WARMWHITE2 0xFF12ED // warmest white +#define IR44_ORANGE 0xFF0AF5 // +#define IR44_TURQUOISE 0xFF8A75 // +#define IR44_PURPLE 0xFFB24D // +#define IR44_WARMWHITE 0xFF32CD // warm white +#define IR44_YELLOWISH 0xFF38C7 // +#define IR44_CYAN 0xFFB847 // +#define IR44_MAGENTA 0xFF7887 // +#define IR44_COLDWHITE 0xFFF807 // cold white +#define IR44_YELLOW 0xFF18E7 // +#define IR44_AQUA 0xFF9867 // +#define IR44_PINK 0xFF58A7 // +#define IR44_COLDWHITE2 0xFFD827 // coldest white +#define IR44_REDPLUS 0xFF28D7 // +#define IR44_GREENPLUS 0xFFA857 // +#define IR44_BLUEPLUS 0xFF6897 // +#define IR44_QUICK 0xFFE817 // +#define IR44_REDMINUS 0xFF08F7 // +#define IR44_GREENMINUS 0xFF8877 // +#define IR44_BLUEMINUS 0xFF48B7 // +#define IR44_SLOW 0xFFC837 // +#define IR44_DIY1 0xFF30CF // +#define IR44_DIY2 0xFFB04F // +#define IR44_DIY3 0xFF708F // +#define IR44_AUTO 0xFFF00F // +#define IR44_DIY4 0xFF10EF // +#define IR44_DIY5 0xFF906F // +#define IR44_DIY6 0xFF50AF // +#define IR44_FLASH 0xFFD02F // +#define IR44_JUMP3 0xFF20DF // +#define IR44_JUMP7 0xFFA05F // +#define IR44_FADE3 0xFF609F // +#define IR44_FADE7 0xFFE01F // +// Color definitions #define COLOR_RED 0xFF0000 #define COLOR_REDDISH 0xFF7800 #define COLOR_ORANGE 0xFFA000 diff --git a/wled00/wled00.ino b/wled00/wled00.ino index 96a772c615..9cb21b91de 100644 --- a/wled00/wled00.ino +++ b/wled00/wled00.ino @@ -173,7 +173,7 @@ bool useHSBDefault = useHSB; //Sync CONFIG bool buttonEnabled = true; -bool irEnabled = true; //Infrared receiver +byte irEnabled = 1; //Infrared receiver uint16_t udpPort = 21324; //WLED notifier default port uint16_t udpRgbPort = 19446; //Hyperion port diff --git a/wled00/wled02_xml.ino b/wled00/wled02_xml.ino index e0546f0adb..b5f3e9fe01 100644 --- a/wled00/wled02_xml.ino +++ b/wled00/wled02_xml.ino @@ -292,7 +292,7 @@ void getSettingsJS(byte subPage, char* dest) if (subPage == 4) { sappend('c',"BT",buttonEnabled); - sappend('c',"IR",irEnabled); + sappend('v',"IR",irEnabled); sappend('v',"UP",udpPort); sappend('c',"RB",receiveNotificationBrightness); sappend('c',"RC",receiveNotificationColor); diff --git a/wled00/wled03_set.ino b/wled00/wled03_set.ino index 0bd3fa1c82..493ae963c1 100644 --- a/wled00/wled03_set.ino +++ b/wled00/wled03_set.ino @@ -146,7 +146,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage) if (subPage == 4) { buttonEnabled = request->hasArg("BT"); - irEnabled = request->hasArg("IR"); + irEnabled = request->arg("IR").toInt(); int t = request->arg("UP").toInt(); if (t > 0) udpPort = t; receiveNotificationBrightness = request->hasArg("RB"); diff --git a/wled00/wled20_ir.ino b/wled00/wled20_ir.ino index 067fb25aff..061961616c 100644 --- a/wled00/wled20_ir.ino +++ b/wled00/wled20_ir.ino @@ -48,19 +48,19 @@ void decodeIR(uint32_t code) if (code == 0xFFFFFFFF) //repeated code, continue brightness up/down { irTimesRepeated++; - if (lastValidCode == IR24_BRIGHTER | lastValidCode == IR44_BPLUS ) + if (lastValidCode == IR24_BRIGHTER | lastValidCode == IR40_BPLUS ) { relativeChange(&bri, 10); colorUpdated(2); } - else if (lastValidCode == IR24_DARKER | lastValidCode == IR44_BMINUS ) + else if (lastValidCode == IR24_DARKER | lastValidCode == IR40_BMINUS ) { relativeChange(&bri, -10, 5); colorUpdated(2); } - if (lastValidCode == IR44_WPLUS) + if (lastValidCode == IR40_WPLUS) { relativeChangeWhite(10); colorUpdated(2); } - else if (lastValidCode == IR44_WMINUS) + else if (lastValidCode == IR40_WMINUS) { relativeChangeWhite(-10, 5); colorUpdated(2); } @@ -76,8 +76,16 @@ void decodeIR(uint32_t code) if (decodeIRCustom(code)) return; if (code > 0xFFFFFF) return; //invalid code - else if (code > 0xFF0000) decodeIR44(code); //is in 44-key remote range else if (code > 0xF70000 && code < 0xF80000) decodeIR24(code); //is in 24-key remote range + else if (code > 0xFF0000) { + switch (irEnabled) { + case 1: decodeIR24OLD(code); break; // white 24-key remote (old) - it sends 0xFF0000 values + case 2: decodeIR24CT(code); break; // white 24-key remote with CW, WW, CT+ and CT- keys + case 3: decodeIR40(code); break; // blue 40-key remote with 25%, 50%, 75% and 100% keys + case 4: decodeIR44(code); break; // white 44-key remote with color-up/down keys and DIY1 to 6 keys + default: return; + } + } //code <= 0xF70000 also invalid } @@ -116,49 +124,170 @@ void decodeIR24(uint32_t code) } +void decodeIR24OLD(uint32_t code) +{ + switch (code) { + case IR24_OLD_BRIGHTER : relativeChange(&bri, 10); break; + case IR24_OLD_DARKER : relativeChange(&bri, -10, 5); break; + case IR24_OLD_OFF : briLast = bri; bri = 0; break; + case IR24_OLD_ON : bri = briLast; break; + case IR24_OLD_RED : colorFromUint32(COLOR_RED); break; + case IR24_OLD_REDDISH : colorFromUint32(COLOR_REDDISH); break; + case IR24_OLD_ORANGE : colorFromUint32(COLOR_ORANGE); break; + case IR24_OLD_YELLOWISH : colorFromUint32(COLOR_YELLOWISH); break; + case IR24_OLD_YELLOW : colorFromUint32(COLOR_YELLOW); break; + case IR24_OLD_GREEN : colorFromUint32(COLOR_GREEN); break; + case IR24_OLD_GREENISH : colorFromUint32(COLOR_GREENISH); break; + case IR24_OLD_TURQUOISE : colorFromUint32(COLOR_TURQUOISE); break; + case IR24_OLD_CYAN : colorFromUint32(COLOR_CYAN); break; + case IR24_OLD_AQUA : colorFromUint32(COLOR_AQUA); break; + case IR24_OLD_BLUE : colorFromUint32(COLOR_BLUE); break; + case IR24_OLD_DEEPBLUE : colorFromUint32(COLOR_DEEPBLUE); break; + case IR24_OLD_PURPLE : colorFromUint32(COLOR_PURPLE); break; + case IR24_OLD_MAGENTA : colorFromUint32(COLOR_MAGENTA); break; + case IR24_OLD_PINK : colorFromUint32(COLOR_PINK); break; + case IR24_OLD_WHITE : colorFromUint32(COLOR_WHITE); effectCurrent = 0; break; + case IR24_OLD_FLASH : if (!applyPreset(1)) effectCurrent = FX_MODE_COLORTWINKLE; break; + case IR24_OLD_STROBE : if (!applyPreset(2)) effectCurrent = FX_MODE_RAINBOW_CYCLE; break; + case IR24_OLD_FADE : if (!applyPreset(3)) effectCurrent = FX_MODE_BREATH; break; + case IR24_OLD_SMOOTH : if (!applyPreset(4)) effectCurrent = FX_MODE_RAINBOW; break; + default: return; + } + lastValidCode = code; + colorUpdated(2); //for notifier, IR is considered a button input +} + + +void decodeIR24CT(uint32_t code) +{ + switch (code) { + case IR24_CT_BRIGHTER : relativeChange(&bri, 10); break; + case IR24_CT_DARKER : relativeChange(&bri, -10, 5); break; + case IR24_CT_OFF : briLast = bri; bri = 0; break; + case IR24_CT_ON : bri = briLast; break; + case IR24_CT_RED : colorFromUint32(COLOR_RED); break; + case IR24_CT_REDDISH : colorFromUint32(COLOR_REDDISH); break; + case IR24_CT_ORANGE : colorFromUint32(COLOR_ORANGE); break; + case IR24_CT_YELLOWISH : colorFromUint32(COLOR_YELLOWISH); break; + case IR24_CT_YELLOW : colorFromUint32(COLOR_YELLOW); break; + case IR24_CT_GREEN : colorFromUint32(COLOR_GREEN); break; + case IR24_CT_GREENISH : colorFromUint32(COLOR_GREENISH); break; + case IR24_CT_TURQUOISE : colorFromUint32(COLOR_TURQUOISE); break; + case IR24_CT_CYAN : colorFromUint32(COLOR_CYAN); break; + case IR24_CT_AQUA : colorFromUint32(COLOR_AQUA); break; + case IR24_CT_BLUE : colorFromUint32(COLOR_BLUE); break; + case IR24_CT_DEEPBLUE : colorFromUint32(COLOR_DEEPBLUE); break; + case IR24_CT_PURPLE : colorFromUint32(COLOR_PURPLE); break; + case IR24_CT_MAGENTA : colorFromUint32(COLOR_MAGENTA); break; + case IR24_CT_PINK : colorFromUint32(COLOR_PINK); break; + case IR24_CT_COLDWHITE : colorFromUint32(COLOR_COLDWHITE); effectCurrent = 0; break; + case IR24_CT_WARMWHITE : colorFromUint32(COLOR_WARMWHITE); effectCurrent = 0; break; + case IR24_CT_CTPLUS : colorFromUint32(COLOR_COLDWHITE2); effectCurrent = 0; break; + case IR24_CT_CTMINUS : colorFromUint32(COLOR_WARMWHITE2); effectCurrent = 0; break; + case IR24_CT_MEMORY : colorFromUint32(COLOR_NEUTRALWHITE); effectCurrent = 0; break; + default: return; + } + lastValidCode = code; + colorUpdated(2); //for notifier, IR is considered a button input +} + + +void decodeIR40(uint32_t code) +{ + switch (code) { + case IR40_BPLUS : relativeChange(&bri, 10); break; + case IR40_BMINUS : relativeChange(&bri, -10, 5); break; + case IR40_OFF : briLast = bri; bri = 0; break; + case IR40_ON : bri = briLast; break; + case IR40_RED : colorFromUint24(COLOR_RED); break; + case IR40_REDDISH : colorFromUint24(COLOR_REDDISH); break; + case IR40_ORANGE : colorFromUint24(COLOR_ORANGE); break; + case IR40_YELLOWISH : colorFromUint24(COLOR_YELLOWISH); break; + case IR40_YELLOW : colorFromUint24(COLOR_YELLOW); break; + case IR40_GREEN : colorFromUint24(COLOR_GREEN); break; + case IR40_GREENISH : colorFromUint24(COLOR_GREENISH); break; + case IR40_TURQUOISE : colorFromUint24(COLOR_TURQUOISE); break; + case IR40_CYAN : colorFromUint24(COLOR_CYAN); break; + case IR40_AQUA : colorFromUint24(COLOR_AQUA); break; + case IR40_BLUE : colorFromUint24(COLOR_BLUE); break; + case IR40_DEEPBLUE : colorFromUint24(COLOR_DEEPBLUE); break; + case IR40_PURPLE : colorFromUint24(COLOR_PURPLE); break; + case IR40_MAGENTA : colorFromUint24(COLOR_MAGENTA); break; + case IR40_PINK : colorFromUint24(COLOR_PINK); break; + case IR40_WARMWHITE2 : colorFromUint32(COLOR_WARMWHITE2); effectCurrent = 0; break; + case IR40_WARMWHITE : colorFromUint32(COLOR_WARMWHITE); effectCurrent = 0; break; + case IR40_WHITE : colorFromUint32(COLOR_NEUTRALWHITE); effectCurrent = 0; break; + case IR40_COLDWHITE : colorFromUint32(COLOR_COLDWHITE); effectCurrent = 0; break; + case IR40_COLDWHITE2 : colorFromUint32(COLOR_COLDWHITE2); effectCurrent = 0; break; + case IR40_WPLUS : relativeChangeWhite(10); break; + case IR40_WMINUS : relativeChangeWhite(-10, 5); break; + case IR40_WOFF : whiteLast = col[3]; col[3] = 0; break; + case IR40_WON : col[3] = whiteLast; break; + case IR40_W25 : bri = 63; break; + case IR40_W50 : bri = 127; break; + case IR40_W75 : bri = 191; break; + case IR40_W100 : bri = 255; break; + case IR40_QUICK : relativeChange(&effectSpeed, 10); break; + case IR40_SLOW : relativeChange(&effectSpeed, -10, 5); break; + case IR40_JUMP7 : relativeChange(&effectIntensity, 10); break; + case IR40_AUTO : relativeChange(&effectIntensity, -10, 5); break; + case IR40_JUMP3 : if (!applyPreset(1)) effectCurrent = FX_MODE_STATIC; break; + case IR40_FADE3 : if (!applyPreset(2)) effectCurrent = FX_MODE_BREATH; break; + case IR40_FADE7 : if (!applyPreset(3)) effectCurrent = FX_MODE_FIRE_FLICKER; break; + case IR40_FLASH : if (!applyPreset(4)) effectCurrent = FX_MODE_RAINBOW; break; + } + lastValidCode = code; + colorUpdated(2); //for notifier, IR is considered a button input +} + + void decodeIR44(uint32_t code) { switch (code) { - case IR44_BPLUS : relativeChange(&bri, 10); break; - case IR44_BMINUS : relativeChange(&bri, -10, 5); break; - case IR44_OFF : briLast = bri; bri = 0; break; - case IR44_ON : bri = briLast; break; - case IR44_RED : colorFromUint24(COLOR_RED); break; - case IR44_REDDISH : colorFromUint24(COLOR_REDDISH); break; - case IR44_ORANGE : colorFromUint24(COLOR_ORANGE); break; - case IR44_YELLOWISH : colorFromUint24(COLOR_YELLOWISH); break; - case IR44_YELLOW : colorFromUint24(COLOR_YELLOW); break; - case IR44_GREEN : colorFromUint24(COLOR_GREEN); break; - case IR44_GREENISH : colorFromUint24(COLOR_GREENISH); break; - case IR44_TURQUOISE : colorFromUint24(COLOR_TURQUOISE); break; - case IR44_CYAN : colorFromUint24(COLOR_CYAN); break; - case IR44_AQUA : colorFromUint24(COLOR_AQUA); break; - case IR44_BLUE : colorFromUint24(COLOR_BLUE); break; - case IR44_DEEPBLUE : colorFromUint24(COLOR_DEEPBLUE); break; - case IR44_PURPLE : colorFromUint24(COLOR_PURPLE); break; - case IR44_MAGENTA : colorFromUint24(COLOR_MAGENTA); break; - case IR44_PINK : colorFromUint24(COLOR_PINK); break; - case IR44_WARMWHITE2 : colorFromUint32(COLOR_WARMWHITE2); effectCurrent = 0; break; - case IR44_WARMWHITE : colorFromUint32(COLOR_WARMWHITE); effectCurrent = 0; break; - case IR44_WHITE : colorFromUint32(COLOR_NEUTRALWHITE); effectCurrent = 0; break; - case IR44_COLDWHITE : colorFromUint32(COLOR_COLDWHITE); effectCurrent = 0; break; - case IR44_COLDWHITE2 : colorFromUint32(COLOR_COLDWHITE2); effectCurrent = 0; break; - case IR44_WPLUS : relativeChangeWhite(10); break; - case IR44_WMINUS : relativeChangeWhite(-10, 5); break; - case IR44_WOFF : whiteLast = col[3]; col[3] = 0; break; - case IR44_WON : col[3] = whiteLast; break; - case IR44_W25 : bri = 63; break; - case IR44_W50 : bri = 127; break; - case IR44_W75 : bri = 191; break; - case IR44_W100 : bri = 255; break; - case IR44_QUICK : relativeChange(&effectSpeed, 10); break; - case IR44_SLOW : relativeChange(&effectSpeed, -10, 5); break; - case IR44_JUMP7 : relativeChange(&effectIntensity, 10); break; - case IR44_AUTO : relativeChange(&effectIntensity, -10, 5); break; - case IR44_JUMP3 : if (!applyPreset(1)) effectCurrent = FX_MODE_STATIC; break; - case IR44_FADE3 : if (!applyPreset(2)) effectCurrent = FX_MODE_BREATH; break; - case IR44_FADE7 : if (!applyPreset(3)) effectCurrent = FX_MODE_FIRE_FLICKER; break; - case IR44_FLASH : if (!applyPreset(4)) effectCurrent = FX_MODE_RAINBOW; break; + case IR44_BPLUS : relativeChange(&bri, 10); break; + case IR44_BMINUS : relativeChange(&bri, -10, 5); break; + case IR44_OFF : briLast = bri; bri = 0; break; + case IR44_ON : bri = briLast; break; + case IR44_RED : colorFromUint24(COLOR_RED); break; + case IR44_GREEN : colorFromUint24(COLOR_GREEN); break; + case IR44_BLUE : colorFromUint24(COLOR_BLUE); break; + case IR44_WHITE : colorFromUint32(COLOR_NEUTRALWHITE); effectCurrent = 0; break; break; + case IR44_REDDISH : colorFromUint24(COLOR_REDDISH); break; + case IR44_GREENISH : colorFromUint24(COLOR_GREENISH); break; + case IR44_DEEPBLUE : colorFromUint24(COLOR_DEEPBLUE); break; + case IR44_WARMWHITE2 : colorFromUint32(COLOR_WARMWHITE2); effectCurrent = 0; break; + case IR44_ORANGE : colorFromUint24(COLOR_ORANGE); break; + case IR44_TURQUOISE : colorFromUint24(COLOR_TURQUOISE); break; + case IR44_PURPLE : colorFromUint24(COLOR_PURPLE); break; + case IR44_WARMWHITE : colorFromUint32(COLOR_WARMWHITE); effectCurrent = 0; break; + case IR44_YELLOWISH : colorFromUint24(COLOR_YELLOWISH); break; + case IR44_CYAN : colorFromUint24(COLOR_CYAN); break; + case IR44_MAGENTA : colorFromUint24(COLOR_MAGENTA); break; + case IR44_COLDWHITE : colorFromUint32(COLOR_COLDWHITE); effectCurrent = 0; break; + case IR44_YELLOW : colorFromUint24(COLOR_YELLOW); break; + case IR44_AQUA : colorFromUint24(COLOR_AQUA); break; + case IR44_PINK : colorFromUint24(COLOR_PINK); break; + case IR44_COLDWHITE2 : colorFromUint32(COLOR_COLDWHITE2); effectCurrent = 0; break; + case IR44_REDPLUS : relativeChange(&effectCurrent, 1); break; + case IR44_REDMINUS : relativeChange(&effectCurrent, -1, 0); break; + case IR44_GREENPLUS : relativeChange(&effectPalette, 1); break; + case IR44_GREENMINUS : relativeChange(&effectPalette, -1, 0); break; + case IR44_BLUEPLUS : relativeChange(&effectIntensity, 10); break; + case IR44_BLUEMINUS : relativeChange(&effectIntensity, -10, 5); break; + case IR44_QUICK : relativeChange(&effectSpeed, 10); break; + case IR44_SLOW : relativeChange(&effectSpeed, -10, 5); break; + case IR44_DIY1 : if (!applyPreset(1)) effectCurrent = FX_MODE_STATIC; break; + case IR44_DIY2 : if (!applyPreset(2)) effectCurrent = FX_MODE_BREATH; break; + case IR44_DIY3 : if (!applyPreset(3)) effectCurrent = FX_MODE_FIRE_FLICKER; break; + case IR44_DIY4 : if (!applyPreset(4)) effectCurrent = FX_MODE_RAINBOW; break; + case IR44_DIY5 : if (!applyPreset(5)) effectCurrent = FX_MODE_METEOR_SMOOTH; break; + case IR44_DIY6 : if (!applyPreset(6)) effectCurrent = FX_MODE_RAIN; break; + case IR44_AUTO : effectCurrent = FX_MODE_STATIC; break; + case IR44_FLASH : effectCurrent = FX_MODE_PALETTE; break; + case IR44_JUMP3 : bri = 63; break; + case IR44_JUMP7 : bri = 127; break; + case IR44_FADE3 : bri = 191; break; + case IR44_FADE7 : bri = 255; break; } lastValidCode = code; colorUpdated(2); //for notifier, IR is considered a button input @@ -167,7 +296,7 @@ void decodeIR44(uint32_t code) void initIR() { - if (irEnabled) + if (irEnabled > 0) { irrecv = new IRrecv(IR_PIN); irrecv->enableIRIn(); @@ -177,10 +306,10 @@ void initIR() void handleIR() { - if (irEnabled && millis() - irCheckedTime > 120) + if (irEnabled > 0 && millis() - irCheckedTime > 120) { irCheckedTime = millis(); - if (irEnabled) + if (irEnabled > 0) { if (irrecv == NULL) { From 4f28120d7e2a1ad835c75e29c5df1e0f2cb80c8b Mon Sep 17 00:00:00 2001 From: Unknown Date: Sun, 15 Dec 2019 12:36:39 +0100 Subject: [PATCH 09/21] Use 5CH solid RGB stripes adapt the logic to use CW and WW for different CT-values --- wled00/NpbWrapper.h | 38 ++++++++++++++++++++++++++++++++------ wled00/wled00.ino | 2 +- 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/wled00/NpbWrapper.h b/wled00/NpbWrapper.h index f12031a848..16e7e63984 100644 --- a/wled00/NpbWrapper.h +++ b/wled00/NpbWrapper.h @@ -26,6 +26,7 @@ #define GPIN 13 //G pin for analog LED strip #define BPIN 12 //B pin for analog LED strip #define WPIN 14 //W pin for analog LED strip (W1: 14, W2: 04) + #define W2PIN 04 //W2 pin for analog LED strip // /*PWM pins - PINs 5,12,13,15 are used with Magic Home LED Controller #define RPIN 5 //R pin for analog LED strip @@ -125,8 +126,12 @@ class NeoPixelWrapper pinMode(GPIN, OUTPUT); pinMode(BPIN, OUTPUT); switch (_type) { - case NeoPixelType_Grb: break; - case NeoPixelType_Grbw: pinMode(WPIN, OUTPUT); break; + case NeoPixelType_Grb: break; + #ifdef WLED_USE_5CH_LEDS + case NeoPixelType_Grbw: pinMode(WPIN, OUTPUT); pinMode(W2PIN, OUTPUT); break; + #else + case NeoPixelType_Grbw: pinMode(WPIN, OUTPUT); break; + #endif } analogWriteRange(255); //same range as one RGB channel analogWriteFreq(880); //PWM frequency proven as good for LEDs @@ -136,14 +141,18 @@ class NeoPixelWrapper } #ifndef WLED_DISABLE_ANALOG_LEDS - void SetRgbwPwm(uint8_t r, uint8_t g, uint8_t b, uint8_t w) + void SetRgbwPwm(uint8_t r, uint8_t g, uint8_t b, uint8_t w, uint8_t w2=0) { analogWrite(RPIN, r); analogWrite(GPIN, g); analogWrite(BPIN, b); switch (_type) { - case NeoPixelType_Grb: break; - case NeoPixelType_Grbw: analogWrite(WPIN, w); break; + case NeoPixelType_Grb: break; + #ifdef WLED_USE_5CH_LEDS + case NeoPixelType_Grbw: analogWrite(WPIN, w); analogWrite(W2PIN, w2); break; + #else + case NeoPixelType_Grbw: analogWrite(WPIN, w); break; + #endif } } #endif @@ -167,7 +176,24 @@ class NeoPixelWrapper #ifndef WLED_DISABLE_ANALOG_LEDS RgbwColor colorW = _pGrbw->GetPixelColor(0); b = _pGrbw->GetBrightness(); - SetRgbwPwm(colorW.R * b / 255, colorW.G * b / 255, colorW.B * b / 255, colorW.W * b / 255); + // check color values for Warm / COld white mix (for RGBW) // EsplanexaDevice.cpp + #ifdef WLED_USE_5CH_LEDS + if (colorW.R == 255 & colorW.G == 255 && colorW.B == 255 && colorW.W == 255) { + SetRgbwPwm(0, 0, 0, 0, colorW.W * b / 255); + } else if (colorW.R == 127 & colorW.G == 127 && colorW.B == 127 && colorW.W == 255) { + SetRgbwPwm(0, 0, 0, colorW.W * b / 512, colorW.W * b / 255); + } else if (colorW.R == 0 & colorW.G == 0 && colorW.B == 0 && colorW.W == 255) { + SetRgbwPwm(0, 0, 0, colorW.W * b / 255, 0); + } else if (colorW.R == 130 & colorW.G == 90 && colorW.B == 0 && colorW.W == 255) { + SetRgbwPwm(0, 0, 0, colorW.W * b / 255, colorW.W * b / 512); + } else if (colorW.R == 255 & colorW.G == 153 && colorW.B == 0 && colorW.W == 255) { + SetRgbwPwm(0, 0, 0, colorW.W * b / 255, 0); + } else { // not only white colors + SetRgbwPwm(colorW.R * b / 255, colorW.G * b / 255, colorW.B * b / 255, colorW.W * b / 255); + } + #else + SetRgbwPwm(colorW.R * b / 255, colorW.G * b / 255, colorW.B * b / 255, colorW.W * b / 255); + #endif #endif } break; diff --git a/wled00/wled00.ino b/wled00/wled00.ino index 9cb21b91de..d181029425 100644 --- a/wled00/wled00.ino +++ b/wled00/wled00.ino @@ -303,7 +303,7 @@ byte briT = 0; byte briIT = 0; byte briLast = 127; //brightness before turned off. Used for toggle function byte white = 0; -byte whiteLast = 0; //white level before turned off. Used for toggle function +byte whiteLast = 127; //white level before turned off. Used for toggle function //button bool buttonPressedBefore = false; From 05ad1a8954c4de12bb29397e950dd9f92af7391f Mon Sep 17 00:00:00 2001 From: Unknown Date: Sun, 15 Dec 2019 12:43:54 +0100 Subject: [PATCH 10/21] change from Opt-Out to Opt-In for solid (analoge) RGB stripes Changed code from #define WLED_DISABLE_ANALOG_LEDS to #define WLED_USE_ANALOG_LEDS --- platformio.ini | 7 +++---- wled00/wled00.ino | 7 +++++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/platformio.ini b/platformio.ini index 3886d8c95a..c34968cd53 100644 --- a/platformio.ini +++ b/platformio.ini @@ -96,10 +96,7 @@ platform = espressif32@1.7.0 build_flags = -D PIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH -D ARDUINO_ARCH_ESP32 - -D WLED_DISABLE_INFRARED - -D WLED_DISABLE_ANALOG_LEDS - # disable ANALOG LEDS because the analogWrite-function needs to be adapted to ESP32 - -D WLED_DISABLE_ANALOG_LEDS + -D WLED_DISABLE_INFRARED # see: http://docs.platformio.org/en/latest/platforms/espressif8266.html [env:nodemcuv2] @@ -135,6 +132,7 @@ framework = ${common.framework} build_flags = ${common.build_flags} ${common:esp8266_1M.build_flags} + -D WLED_USE_ANALOG_LEDS -D WLED_DEBUG lib_deps = ${common.lib_deps_external} @@ -148,6 +146,7 @@ framework = ${common.framework} build_flags = ${common.build_flags} ${common:esp8266_1M.build_flags} + -D WLED_USE_ANALOG_LEDS -D WLED_USE_5CH_LEDS -D WLED_DEBUG lib_deps = diff --git a/wled00/wled00.ino b/wled00/wled00.ino index d181029425..0ca367ddf7 100644 --- a/wled00/wled00.ino +++ b/wled00/wled00.ino @@ -33,7 +33,10 @@ //#define WLED_DEBUG //to toggle using analog RGB or RGBW led strips (un)comment the following line -//#define WLED_DISABLE_ANALOG_LEDS +//#define WLED_USE_ANALOG_LEDS + +//to toggle using 5CH analog RGBWS led strips (un)comment the following line +//#define WLED_USE_5CH_LEDS //library inclusions #include @@ -88,7 +91,7 @@ #endif #ifdef ARDUINO_ARCH_ESP32 - #define WLED_DISABLE_ANALOG_LEDS // Solid RGBW not implemented for ESP32 yet + #undef WLED_USE_ANALOG_LEDS // Solid RGBW not implemented for ESP32 yet /*#ifndef WLED_DISABLE_INFRARED #include #endif*/ //there are issues with ESP32 infrared, so it is disabled for now From d00538db6af131e2d502aab99930a2c175415900 Mon Sep 17 00:00:00 2001 From: Unknown Date: Sun, 15 Dec 2019 19:56:56 +0100 Subject: [PATCH 11/21] DEFINES for different devices added --- platformio.ini | 28 +++++-- wled00/NpbWrapper.h | 44 ++++++----- wled00/wled20_ir.ino | 182 ++++++++++++++++++++++--------------------- 3 files changed, 139 insertions(+), 115 deletions(-) diff --git a/platformio.ini b/platformio.ini index c34968cd53..b11e5e3831 100644 --- a/platformio.ini +++ b/platformio.ini @@ -88,8 +88,8 @@ build_flags = ; -D WLED_DISABLE_ALEXA -D WLED_DISABLE_BLYNK -D WLED_DISABLE_CRONIXIE - ; -D WLED_DISABLE_HUESYNC - -D WLED_DISABLE_INFRARED + -D WLED_DISABLE_HUESYNC + ; -D WLED_DISABLE_INFRARED [common:esp32] platform = espressif32@1.7.0 @@ -123,7 +123,21 @@ build_flags = lib_deps = ${common.lib_deps_external} -[env:esp8285] +[env:esp8285_4CH_H801] +board = esp8285 +platform = ${common:esp8266_1M.platform} +monitor_speed = ${common.monitor_speed} +upload_speed = ${common.upload_speed} +framework = ${common.framework} +build_flags = + ${common.build_flags} + ${common:esp8266_1M.build_flags} + -D WLED_USE_ANALOG_LEDS + -D WLED_USE_H801 +lib_deps = + ${common.lib_deps_external} + +[env:esp8285_4CH_MagicHome] board = esp8285 platform = ${common:esp8266_1M.platform} monitor_speed = ${common.monitor_speed} @@ -133,11 +147,10 @@ build_flags = ${common.build_flags} ${common:esp8266_1M.build_flags} -D WLED_USE_ANALOG_LEDS - -D WLED_DEBUG lib_deps = ${common.lib_deps_external} -[env:esp8285_5CH] +[env:esp8285_5CH_H801] board = esp8285 platform = ${common:esp8266_1M.platform} monitor_speed = ${common.monitor_speed} @@ -147,8 +160,8 @@ build_flags = ${common.build_flags} ${common:esp8266_1M.build_flags} -D WLED_USE_ANALOG_LEDS - -D WLED_USE_5CH_LEDS - -D WLED_DEBUG + -D WLED_USE_5CH_LEDS + -D WLED_USE_H801 lib_deps = ${common.lib_deps_external} @@ -175,6 +188,7 @@ framework = ${common.framework} build_flags = ${common.build_flags} ${common:esp8266_512k.build_flags} + -D WLED_DISABLE_INFRARED lib_deps = ${common.lib_deps_external} diff --git a/wled00/NpbWrapper.h b/wled00/NpbWrapper.h index 16e7e63984..0f1c510d34 100644 --- a/wled00/NpbWrapper.h +++ b/wled00/NpbWrapper.h @@ -5,8 +5,13 @@ //PIN CONFIGURATION #define LEDPIN 2 //strip pin. Any for ESP32, gpio2 or 3 is recommended for ESP8266 (gpio2/3 are labeled D4/RX on NodeMCU and Wemos) //#define USE_APA102 // Uncomment for using APA102 LEDs. -#define BTNPIN -1 //button pin. Needs to have pullup (gpio0 recommended) -#define IR_PIN 0 //infrared pin (-1 to disable) MagicHome: 4, H801 Wifi: 0 +#ifdef WLED_USE_H801 + #define BTNPIN -1 //button pin. Needs to have pullup (gpio0 recommended) + #define IR_PIN 0 //infrared pin (-1 to disable) MagicHome: 4, H801 Wifi: 0 +#else + #define BTNPIN 0 //button pin. Needs to have pullup (gpio0 recommended) + #define IR_PIN 4 //infrared pin (-1 to disable) MagicHome: 4, H801 Wifi: 0 +#endif #define RLYPIN -1 //pin for relay, will be set HIGH if LEDs are on (-1 to disable). Also usable for standby leds, triggers,... #define AUXPIN -1 //debug auxiliary output pin (-1 to disable) @@ -20,20 +25,21 @@ #endif #endif -#ifndef WLED_DISABLE_ANALOG_LEDS +#ifdef WLED_USE_ANALOG_LEDS //PWM pins - PINs 15,13,12,14 (W2 = 04)are used with H801 Wifi LED Controller - #define RPIN 15 //R pin for analog LED strip - #define GPIN 13 //G pin for analog LED strip - #define BPIN 12 //B pin for analog LED strip - #define WPIN 14 //W pin for analog LED strip (W1: 14, W2: 04) - #define W2PIN 04 //W2 pin for analog LED strip - // - /*PWM pins - PINs 5,12,13,15 are used with Magic Home LED Controller - #define RPIN 5 //R pin for analog LED strip - #define GPIN 12 //G pin for analog LED strip - #define BPIN 13 //B pin for analog LED strip - #define WPIN 15 //W pin for analog LED strip (W1: 14, W2: 04) - */ + #ifdef WLED_USE_H801 + #define RPIN 15 //R pin for analog LED strip + #define GPIN 13 //G pin for analog LED strip + #define BPIN 12 //B pin for analog LED strip + #define WPIN 14 //W pin for analog LED strip (W1: 14, W2: 04) + #define W2PIN 04 //W2 pin for analog LED strip + #else + //PWM pins - PINs 5,12,13,15 are used with Magic Home LED Controller + #define RPIN 5 //R pin for analog LED strip + #define GPIN 12 //G pin for analog LED strip + #define BPIN 15 //B pin for analog LED strip + #define WPIN 13 //W pin for analog LED strip (W1: 14, W2: 04) + #endif #endif //automatically uses the right driver method for each platform @@ -120,7 +126,7 @@ class NeoPixelWrapper _pGrbw->Begin(); break; - #ifndef WLED_DISABLE_ANALOG_LEDS + #ifdef WLED_USE_ANALOG_LEDS //init PWM pins - PINs 5,12,13,15 are used with Magic Home LED Controller pinMode(RPIN, OUTPUT); pinMode(GPIN, OUTPUT); @@ -140,7 +146,7 @@ class NeoPixelWrapper } } -#ifndef WLED_DISABLE_ANALOG_LEDS +#ifdef WLED_USE_ANALOG_LEDS void SetRgbwPwm(uint8_t r, uint8_t g, uint8_t b, uint8_t w, uint8_t w2=0) { analogWrite(RPIN, r); @@ -164,7 +170,7 @@ class NeoPixelWrapper { case NeoPixelType_Grb: { _pGrb->Show(); - #ifndef WLED_DISABLE_ANALOG_LEDS + #ifdef WLED_USE_ANALOG_LEDS RgbColor color = _pGrb->GetPixelColor(0); b = _pGrb->GetBrightness(); SetRgbwPwm(color.R * b / 255, color.G * b / 255, color.B * b / 255, 0); @@ -173,7 +179,7 @@ class NeoPixelWrapper break; case NeoPixelType_Grbw: { _pGrbw->Show(); - #ifndef WLED_DISABLE_ANALOG_LEDS + #ifdef WLED_USE_ANALOG_LEDS RgbwColor colorW = _pGrbw->GetPixelColor(0); b = _pGrbw->GetBrightness(); // check color values for Warm / COld white mix (for RGBW) // EsplanexaDevice.cpp diff --git a/wled00/wled20_ir.ino b/wled00/wled20_ir.ino index 061961616c..29df7f8bb3 100644 --- a/wled00/wled20_ir.ino +++ b/wled00/wled20_ir.ino @@ -147,10 +147,10 @@ void decodeIR24OLD(uint32_t code) case IR24_OLD_MAGENTA : colorFromUint32(COLOR_MAGENTA); break; case IR24_OLD_PINK : colorFromUint32(COLOR_PINK); break; case IR24_OLD_WHITE : colorFromUint32(COLOR_WHITE); effectCurrent = 0; break; - case IR24_OLD_FLASH : if (!applyPreset(1)) effectCurrent = FX_MODE_COLORTWINKLE; break; - case IR24_OLD_STROBE : if (!applyPreset(2)) effectCurrent = FX_MODE_RAINBOW_CYCLE; break; - case IR24_OLD_FADE : if (!applyPreset(3)) effectCurrent = FX_MODE_BREATH; break; - case IR24_OLD_SMOOTH : if (!applyPreset(4)) effectCurrent = FX_MODE_RAINBOW; break; + case IR24_OLD_FLASH : if (!applyPreset(1)) effectCurrent = FX_MODE_COLORTWINKLE; effectPalette = 0; break; + case IR24_OLD_STROBE : if (!applyPreset(2)) effectCurrent = FX_MODE_RAINBOW_CYCLE; effectPalette = 0; break; + case IR24_OLD_FADE : if (!applyPreset(3)) effectCurrent = FX_MODE_BREATH; effectPalette = 0; break; + case IR24_OLD_SMOOTH : if (!applyPreset(4)) effectCurrent = FX_MODE_RAINBOW; effectPalette = 0; break; default: return; } lastValidCode = code; @@ -184,7 +184,9 @@ void decodeIR24CT(uint32_t code) case IR24_CT_WARMWHITE : colorFromUint32(COLOR_WARMWHITE); effectCurrent = 0; break; case IR24_CT_CTPLUS : colorFromUint32(COLOR_COLDWHITE2); effectCurrent = 0; break; case IR24_CT_CTMINUS : colorFromUint32(COLOR_WARMWHITE2); effectCurrent = 0; break; - case IR24_CT_MEMORY : colorFromUint32(COLOR_NEUTRALWHITE); effectCurrent = 0; break; + case IR24_CT_MEMORY : { + if (col[3] > 0) col[3] = 0; + else colorFromUint32(COLOR_NEUTRALWHITE); effectCurrent = 0; } break; default: return; } lastValidCode = code; @@ -195,46 +197,46 @@ void decodeIR24CT(uint32_t code) void decodeIR40(uint32_t code) { switch (code) { - case IR40_BPLUS : relativeChange(&bri, 10); break; - case IR40_BMINUS : relativeChange(&bri, -10, 5); break; - case IR40_OFF : briLast = bri; bri = 0; break; - case IR40_ON : bri = briLast; break; - case IR40_RED : colorFromUint24(COLOR_RED); break; - case IR40_REDDISH : colorFromUint24(COLOR_REDDISH); break; - case IR40_ORANGE : colorFromUint24(COLOR_ORANGE); break; - case IR40_YELLOWISH : colorFromUint24(COLOR_YELLOWISH); break; - case IR40_YELLOW : colorFromUint24(COLOR_YELLOW); break; - case IR40_GREEN : colorFromUint24(COLOR_GREEN); break; - case IR40_GREENISH : colorFromUint24(COLOR_GREENISH); break; - case IR40_TURQUOISE : colorFromUint24(COLOR_TURQUOISE); break; - case IR40_CYAN : colorFromUint24(COLOR_CYAN); break; - case IR40_AQUA : colorFromUint24(COLOR_AQUA); break; - case IR40_BLUE : colorFromUint24(COLOR_BLUE); break; - case IR40_DEEPBLUE : colorFromUint24(COLOR_DEEPBLUE); break; - case IR40_PURPLE : colorFromUint24(COLOR_PURPLE); break; - case IR40_MAGENTA : colorFromUint24(COLOR_MAGENTA); break; - case IR40_PINK : colorFromUint24(COLOR_PINK); break; - case IR40_WARMWHITE2 : colorFromUint32(COLOR_WARMWHITE2); effectCurrent = 0; break; - case IR40_WARMWHITE : colorFromUint32(COLOR_WARMWHITE); effectCurrent = 0; break; - case IR40_WHITE : colorFromUint32(COLOR_NEUTRALWHITE); effectCurrent = 0; break; - case IR40_COLDWHITE : colorFromUint32(COLOR_COLDWHITE); effectCurrent = 0; break; - case IR40_COLDWHITE2 : colorFromUint32(COLOR_COLDWHITE2); effectCurrent = 0; break; - case IR40_WPLUS : relativeChangeWhite(10); break; - case IR40_WMINUS : relativeChangeWhite(-10, 5); break; - case IR40_WOFF : whiteLast = col[3]; col[3] = 0; break; - case IR40_WON : col[3] = whiteLast; break; - case IR40_W25 : bri = 63; break; - case IR40_W50 : bri = 127; break; - case IR40_W75 : bri = 191; break; - case IR40_W100 : bri = 255; break; - case IR40_QUICK : relativeChange(&effectSpeed, 10); break; - case IR40_SLOW : relativeChange(&effectSpeed, -10, 5); break; - case IR40_JUMP7 : relativeChange(&effectIntensity, 10); break; - case IR40_AUTO : relativeChange(&effectIntensity, -10, 5); break; - case IR40_JUMP3 : if (!applyPreset(1)) effectCurrent = FX_MODE_STATIC; break; - case IR40_FADE3 : if (!applyPreset(2)) effectCurrent = FX_MODE_BREATH; break; - case IR40_FADE7 : if (!applyPreset(3)) effectCurrent = FX_MODE_FIRE_FLICKER; break; - case IR40_FLASH : if (!applyPreset(4)) effectCurrent = FX_MODE_RAINBOW; break; + case IR40_BPLUS : relativeChange(&bri, 10); break; + case IR40_BMINUS : relativeChange(&bri, -10, 5); break; + case IR40_OFF : briLast = bri; bri = 0; break; + case IR40_ON : bri = briLast; break; + case IR40_RED : colorFromUint24(COLOR_RED); break; + case IR40_REDDISH : colorFromUint24(COLOR_REDDISH); break; + case IR40_ORANGE : colorFromUint24(COLOR_ORANGE); break; + case IR40_YELLOWISH : colorFromUint24(COLOR_YELLOWISH); break; + case IR40_YELLOW : colorFromUint24(COLOR_YELLOW); break; + case IR40_GREEN : colorFromUint24(COLOR_GREEN); break; + case IR40_GREENISH : colorFromUint24(COLOR_GREENISH); break; + case IR40_TURQUOISE : colorFromUint24(COLOR_TURQUOISE); break; + case IR40_CYAN : colorFromUint24(COLOR_CYAN); break; + case IR40_AQUA : colorFromUint24(COLOR_AQUA); break; + case IR40_BLUE : colorFromUint24(COLOR_BLUE); break; + case IR40_DEEPBLUE : colorFromUint24(COLOR_DEEPBLUE); break; + case IR40_PURPLE : colorFromUint24(COLOR_PURPLE); break; + case IR40_MAGENTA : colorFromUint24(COLOR_MAGENTA); break; + case IR40_PINK : colorFromUint24(COLOR_PINK); break; + case IR40_WARMWHITE2 : colorFromUint32(COLOR_WARMWHITE2); effectCurrent = 0; break; + case IR40_WARMWHITE : colorFromUint32(COLOR_WARMWHITE); effectCurrent = 0; break; + case IR40_WHITE : colorFromUint32(COLOR_NEUTRALWHITE); effectCurrent = 0; break; + case IR40_COLDWHITE : colorFromUint32(COLOR_COLDWHITE); effectCurrent = 0; break; + case IR40_COLDWHITE2 : colorFromUint32(COLOR_COLDWHITE2); effectCurrent = 0; break; + case IR40_WPLUS : relativeChangeWhite(10); break; + case IR40_WMINUS : relativeChangeWhite(-10, 5); break; + case IR40_WOFF : whiteLast = col[3]; col[3] = 0; break; + case IR40_WON : col[3] = whiteLast; break; + case IR40_W25 : bri = 63; break; + case IR40_W50 : bri = 127; break; + case IR40_W75 : bri = 191; break; + case IR40_W100 : bri = 255; break; + case IR40_QUICK : relativeChange(&effectSpeed, 10); break; + case IR40_SLOW : relativeChange(&effectSpeed, -10, 5); break; + case IR40_JUMP7 : relativeChange(&effectIntensity, 10); break; + case IR40_AUTO : relativeChange(&effectIntensity, -10, 5); break; + case IR40_JUMP3 : if (!applyPreset(1)) effectCurrent = FX_MODE_STATIC; effectPalette = 0; break; + case IR40_FADE3 : if (!applyPreset(2)) effectCurrent = FX_MODE_BREATH; effectPalette = 0; break; + case IR40_FADE7 : if (!applyPreset(3)) effectCurrent = FX_MODE_FIRE_FLICKER; effectPalette = 0; break; + case IR40_FLASH : if (!applyPreset(4)) effectCurrent = FX_MODE_RAINBOW; effectPalette = 0; break; } lastValidCode = code; colorUpdated(2); //for notifier, IR is considered a button input @@ -244,50 +246,52 @@ void decodeIR40(uint32_t code) void decodeIR44(uint32_t code) { switch (code) { - case IR44_BPLUS : relativeChange(&bri, 10); break; - case IR44_BMINUS : relativeChange(&bri, -10, 5); break; - case IR44_OFF : briLast = bri; bri = 0; break; - case IR44_ON : bri = briLast; break; - case IR44_RED : colorFromUint24(COLOR_RED); break; - case IR44_GREEN : colorFromUint24(COLOR_GREEN); break; - case IR44_BLUE : colorFromUint24(COLOR_BLUE); break; - case IR44_WHITE : colorFromUint32(COLOR_NEUTRALWHITE); effectCurrent = 0; break; break; - case IR44_REDDISH : colorFromUint24(COLOR_REDDISH); break; - case IR44_GREENISH : colorFromUint24(COLOR_GREENISH); break; - case IR44_DEEPBLUE : colorFromUint24(COLOR_DEEPBLUE); break; - case IR44_WARMWHITE2 : colorFromUint32(COLOR_WARMWHITE2); effectCurrent = 0; break; - case IR44_ORANGE : colorFromUint24(COLOR_ORANGE); break; - case IR44_TURQUOISE : colorFromUint24(COLOR_TURQUOISE); break; - case IR44_PURPLE : colorFromUint24(COLOR_PURPLE); break; - case IR44_WARMWHITE : colorFromUint32(COLOR_WARMWHITE); effectCurrent = 0; break; - case IR44_YELLOWISH : colorFromUint24(COLOR_YELLOWISH); break; - case IR44_CYAN : colorFromUint24(COLOR_CYAN); break; - case IR44_MAGENTA : colorFromUint24(COLOR_MAGENTA); break; - case IR44_COLDWHITE : colorFromUint32(COLOR_COLDWHITE); effectCurrent = 0; break; - case IR44_YELLOW : colorFromUint24(COLOR_YELLOW); break; - case IR44_AQUA : colorFromUint24(COLOR_AQUA); break; - case IR44_PINK : colorFromUint24(COLOR_PINK); break; - case IR44_COLDWHITE2 : colorFromUint32(COLOR_COLDWHITE2); effectCurrent = 0; break; - case IR44_REDPLUS : relativeChange(&effectCurrent, 1); break; - case IR44_REDMINUS : relativeChange(&effectCurrent, -1, 0); break; - case IR44_GREENPLUS : relativeChange(&effectPalette, 1); break; - case IR44_GREENMINUS : relativeChange(&effectPalette, -1, 0); break; - case IR44_BLUEPLUS : relativeChange(&effectIntensity, 10); break; - case IR44_BLUEMINUS : relativeChange(&effectIntensity, -10, 5); break; - case IR44_QUICK : relativeChange(&effectSpeed, 10); break; - case IR44_SLOW : relativeChange(&effectSpeed, -10, 5); break; - case IR44_DIY1 : if (!applyPreset(1)) effectCurrent = FX_MODE_STATIC; break; - case IR44_DIY2 : if (!applyPreset(2)) effectCurrent = FX_MODE_BREATH; break; - case IR44_DIY3 : if (!applyPreset(3)) effectCurrent = FX_MODE_FIRE_FLICKER; break; - case IR44_DIY4 : if (!applyPreset(4)) effectCurrent = FX_MODE_RAINBOW; break; - case IR44_DIY5 : if (!applyPreset(5)) effectCurrent = FX_MODE_METEOR_SMOOTH; break; - case IR44_DIY6 : if (!applyPreset(6)) effectCurrent = FX_MODE_RAIN; break; - case IR44_AUTO : effectCurrent = FX_MODE_STATIC; break; - case IR44_FLASH : effectCurrent = FX_MODE_PALETTE; break; - case IR44_JUMP3 : bri = 63; break; - case IR44_JUMP7 : bri = 127; break; - case IR44_FADE3 : bri = 191; break; - case IR44_FADE7 : bri = 255; break; + case IR44_BPLUS : relativeChange(&bri, 10); break; + case IR44_BMINUS : relativeChange(&bri, -10, 5); break; + case IR44_OFF : briLast = bri; bri = 0; break; + case IR44_ON : bri = briLast; break; + case IR44_RED : colorFromUint24(COLOR_RED); break; + case IR44_GREEN : colorFromUint24(COLOR_GREEN); break; + case IR44_BLUE : colorFromUint24(COLOR_BLUE); break; + case IR44_WHITE : { + if (col[3] > 0) col[3] = 0; + else colorFromUint32(COLOR_NEUTRALWHITE); effectCurrent = 0; } break; + case IR44_REDDISH : colorFromUint24(COLOR_REDDISH); break; + case IR44_GREENISH : colorFromUint24(COLOR_GREENISH); break; + case IR44_DEEPBLUE : colorFromUint24(COLOR_DEEPBLUE); break; + case IR44_WARMWHITE2 : colorFromUint32(COLOR_WARMWHITE2); effectCurrent = 0; break; + case IR44_ORANGE : colorFromUint24(COLOR_ORANGE); break; + case IR44_TURQUOISE : colorFromUint24(COLOR_TURQUOISE); break; + case IR44_PURPLE : colorFromUint24(COLOR_PURPLE); break; + case IR44_WARMWHITE : colorFromUint32(COLOR_WARMWHITE); effectCurrent = 0; break; + case IR44_YELLOWISH : colorFromUint24(COLOR_YELLOWISH); break; + case IR44_CYAN : colorFromUint24(COLOR_CYAN); break; + case IR44_MAGENTA : colorFromUint24(COLOR_MAGENTA); break; + case IR44_COLDWHITE : colorFromUint32(COLOR_COLDWHITE); effectCurrent = 0; break; + case IR44_YELLOW : colorFromUint24(COLOR_YELLOW); break; + case IR44_AQUA : colorFromUint24(COLOR_AQUA); break; + case IR44_PINK : colorFromUint24(COLOR_PINK); break; + case IR44_COLDWHITE2 : colorFromUint32(COLOR_COLDWHITE2); effectCurrent = 0; break; + case IR44_REDPLUS : relativeChange(&effectCurrent, 1); break; + case IR44_REDMINUS : relativeChange(&effectCurrent, -1, 0); break; + case IR44_GREENPLUS : relativeChange(&effectPalette, 1); break; + case IR44_GREENMINUS : relativeChange(&effectPalette, -1, 0); break; + case IR44_BLUEPLUS : relativeChange(&effectIntensity, 10); break; + case IR44_BLUEMINUS : relativeChange(&effectIntensity, -10, 5); break; + case IR44_QUICK : relativeChange(&effectSpeed, 10); break; + case IR44_SLOW : relativeChange(&effectSpeed, -10, 5); break; + case IR44_DIY1 : if (!applyPreset(1)) effectCurrent = FX_MODE_STATIC; effectPalette = 0; break; + case IR44_DIY2 : if (!applyPreset(2)) effectCurrent = FX_MODE_BREATH; effectPalette = 0; break; + case IR44_DIY3 : if (!applyPreset(3)) effectCurrent = FX_MODE_FIRE_FLICKER; effectPalette = 0; break; + case IR44_DIY4 : if (!applyPreset(4)) effectCurrent = FX_MODE_RAINBOW; effectPalette = 0; break; + case IR44_DIY5 : if (!applyPreset(5)) effectCurrent = FX_MODE_METEOR_SMOOTH; effectPalette = 0; break; + case IR44_DIY6 : if (!applyPreset(6)) effectCurrent = FX_MODE_RAIN; effectPalette = 0; break; + case IR44_AUTO : effectCurrent = FX_MODE_STATIC; break; + case IR44_FLASH : effectCurrent = FX_MODE_PALETTE; break; + case IR44_JUMP3 : bri = 63; break; + case IR44_JUMP7 : bri = 127; break; + case IR44_FADE3 : bri = 191; break; + case IR44_FADE7 : bri = 255; break; } lastValidCode = code; colorUpdated(2); //for notifier, IR is considered a button input From 0e4bca255009afbb91c594df003e0208126dc253 Mon Sep 17 00:00:00 2001 From: Unknown Date: Sun, 15 Dec 2019 20:14:57 +0100 Subject: [PATCH 12/21] order of PINs alligned to hardware --- wled00/NpbWrapper.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wled00/NpbWrapper.h b/wled00/NpbWrapper.h index 0f1c510d34..af597a72c7 100644 --- a/wled00/NpbWrapper.h +++ b/wled00/NpbWrapper.h @@ -34,11 +34,11 @@ #define WPIN 14 //W pin for analog LED strip (W1: 14, W2: 04) #define W2PIN 04 //W2 pin for analog LED strip #else - //PWM pins - PINs 5,12,13,15 are used with Magic Home LED Controller - #define RPIN 5 //R pin for analog LED strip + //PWM pins - PINs 12,5,13,15 are used with Magic Home LED Controller #define GPIN 12 //G pin for analog LED strip + #define RPIN 5 //R pin for analog LED strip + #define WPIN 13 //W pin for analog LED strip #define BPIN 15 //B pin for analog LED strip - #define WPIN 13 //W pin for analog LED strip (W1: 14, W2: 04) #endif #endif From 915ecc1e5cc79e2adc4f19e40fda66d1aea208ad Mon Sep 17 00:00:00 2001 From: Def3nder <33399267+Def3nder@users.noreply.github.com> Date: Mon, 16 Dec 2019 15:35:58 +0100 Subject: [PATCH 13/21] Update readme.md --- readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index e3910d3f0f..bfc0001057 100644 --- a/readme.md +++ b/readme.md @@ -9,12 +9,12 @@ The Mod enables **analog RGBW stripes** instead of digital ones. -### All the acknowledgement goes to Aircoookie, the author of WLED. +### All the acknowledgement goes to Aircoookie, the author of WLED A fast and feature-rich implementation of an ESP8266/ESP32 webserver to control NeoPixel (WS2812B, WS2811, SK6812, APA102) LEDs! ### Features: -- WS2812FX library integrated for 80+ special effects +- WS2812FX library integrated for 80+ special effects - FastLED noise effects and palettes - Customizable Mobile and desktop UI with color and effect controls - Settings page - configuration over network From fbe35deee2e9064891122e66a83b29b8be9154ad Mon Sep 17 00:00:00 2001 From: Def3nder Date: Mon, 16 Dec 2019 15:39:38 +0100 Subject: [PATCH 14/21] correct initialization of variable rgb[] --- wled00/src/dependencies/espalexa/EspalexaDevice.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wled00/src/dependencies/espalexa/EspalexaDevice.cpp b/wled00/src/dependencies/espalexa/EspalexaDevice.cpp index 517689862d..de525fa675 100644 --- a/wled00/src/dependencies/espalexa/EspalexaDevice.cpp +++ b/wled00/src/dependencies/espalexa/EspalexaDevice.cpp @@ -122,7 +122,7 @@ uint32_t EspalexaDevice::getKelvin() uint32_t EspalexaDevice::getRGB() { if (_rgb != 0) return _rgb; //color has not changed - uint8_t rgb[4]; + byte rgb[4]{0, 0, 0, 0}; float r, g, b, w; if (_mode == EspalexaColorMode::none) return 0; From 59f900471d7b748cfbc5ed01de693d01b3deab3f Mon Sep 17 00:00:00 2001 From: Def3nder Date: Mon, 16 Dec 2019 15:48:46 +0100 Subject: [PATCH 15/21] SunRise Effect NightLight used to brighten the light combined with fading from the actual (primary) color to the secondary color --- wled00/wled00.ino | 1 + wled00/wled08_led.ino | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/wled00/wled00.ino b/wled00/wled00.ino index 0ca367ddf7..e82cbe316a 100644 --- a/wled00/wled00.ino +++ b/wled00/wled00.ino @@ -296,6 +296,7 @@ uint32_t nightlightDelayMs = 10; uint8_t nightlightDelayMinsDefault = nightlightDelayMins; unsigned long nightlightStartTime; byte briNlT = 0; //current nightlight brightness +byte colNlT[]{0, 0, 0, 0}; //current nightlight color //brightness unsigned long lastOnTime = 0; diff --git a/wled00/wled08_led.ino b/wled00/wled08_led.ino index 540619a7da..7890478976 100644 --- a/wled00/wled08_led.ino +++ b/wled00/wled08_led.ino @@ -193,11 +193,20 @@ void handleNightlight() nightlightDelayMs = (int)(nightlightDelayMins*60000); nightlightActiveOld = true; briNlT = bri; + for (byte i=0; i<4; i++) + { + colNlT[i] = col[i]; // remember starting color + } + } float nper = (millis() - nightlightStartTime)/((float)nightlightDelayMs); if (nightlightFade) { bri = briNlT + ((nightlightTargetBri - briNlT)*nper); + for (byte i=0; i<4; i++) + { + col[i] = colNlT[i]+ ((colSec[i] - colNlT[i])*nper); // fading from actual color to secondary color + } colorUpdated(5); } if (nper >= 1) From 56159427f47501f05cd4a221e31c4d67f1d188a2 Mon Sep 17 00:00:00 2001 From: Def3nder Date: Mon, 16 Dec 2019 16:35:13 +0100 Subject: [PATCH 16/21] Fixed headline RLYPIN definition dependant on WLED_USE_ANALOG_LEDS Corrected list-item indents (readme.md) updated to match upstream master (briLast in wled00.ino) --- readme.md | 53 +++++++++++++++++++++++---------------------- wled00/NpbWrapper.h | 6 ++++- wled00/wled00.ino | 4 ++-- 3 files changed, 34 insertions(+), 29 deletions(-) diff --git a/readme.md b/readme.md index bfc0001057..285bc5e4b5 100644 --- a/readme.md +++ b/readme.md @@ -5,7 +5,7 @@ [![](https://img.shields.io/badge/quick_start-wiki-blue.svg?style=flat-square)](https://github.com/Aircoookie/WLED/wiki) [![](https://img.shields.io/badge/app-wled-blue.svg?style=flat-square)](https://github.com/Aircoookie/WLED-App) -## Welcome to the modded version of the brilliant project WLED! +## Welcome to the modded version of the brilliant project WLED The Mod enables **analog RGBW stripes** instead of digital ones. @@ -14,33 +14,34 @@ The Mod enables **analog RGBW stripes** instead of digital ones. A fast and feature-rich implementation of an ESP8266/ESP32 webserver to control NeoPixel (WS2812B, WS2811, SK6812, APA102) LEDs! ### Features: -- WS2812FX library integrated for 80+ special effects -- FastLED noise effects and palettes -- Customizable Mobile and desktop UI with color and effect controls -- Settings page - configuration over network -- Access Point and station mode - automatic failsafe AP -- Support for RGBW strips -- 25 user presets to save and load colors/effects easily, supports cycling through them. -- Macro functions to automatically execute API calls -- Nightlight function (gradually dims down) -- Full OTA software updatability (HTTP + ArduinoOTA), password protectable -- Configurable analog clock + support for the Cronixie kit by Diamex -- Configurable Auto Brightness limit for safer operation + - WS2812FX library integrated for almost 90 special effects + - FastLED noise effects and palettes + - Modern UI with color, effect and segment controls + - Segments to set different effects and colors to parts of the LEDs + - Settings page - configuration over network + - Access Point and station mode - automatic failsafe AP + - Support for RGBW strips + - 16 user presets to save and load colors/effects easily, supports cycling through them. + - Macro functions to automatically execute API calls + - Nightlight function (gradually dims down) + - Full OTA software updatability (HTTP + ArduinoOTA), password protectable + - Configurable analog clock + support for the Cronixie kit by Diamex + - Configurable Auto Brightness limit for safer operation ### Supported light control interfaces: -- WLED app for Android and iOS -- JSON and HTTP request APIs -- MQTT -- Blynk IoT -- E1.31 -- Hyperion -- UDP realtime -- Alexa voice control (including dimming and color) -- Sync to Philips hue lights -- Adalight (PC ambilight via serial) -- Sync color of multiple WLED devices (UDP notifier) -- Infrared remotes (24-key RGB, receiver required) -- Simple timers/schedules (time from NTP, timezones/DST supported) + - WLED app for Android and iOS + - JSON and HTTP request APIs + - MQTT + - Blynk IoT + - E1.31 + - Hyperion + - UDP realtime + - Alexa voice control (including dimming and color) + - Sync to Philips hue lights + - Adalight (PC ambilight via serial) + - Sync color of multiple WLED devices (UDP notifier) + - Infrared remotes (24-key RGB, receiver required) + - Simple timers/schedules (time from NTP, timezones/DST supported) ### Quick start guide and documentation: diff --git a/wled00/NpbWrapper.h b/wled00/NpbWrapper.h index af597a72c7..f048f983c8 100644 --- a/wled00/NpbWrapper.h +++ b/wled00/NpbWrapper.h @@ -12,7 +12,11 @@ #define BTNPIN 0 //button pin. Needs to have pullup (gpio0 recommended) #define IR_PIN 4 //infrared pin (-1 to disable) MagicHome: 4, H801 Wifi: 0 #endif -#define RLYPIN -1 //pin for relay, will be set HIGH if LEDs are on (-1 to disable). Also usable for standby leds, triggers,... +#ifdef WLED_USE_ANALOG_LEDS + #define RLYPIN -1 //disable RLYPIN as it will be used for the RGB-PINs +#else + #define RLYPIN 12 //pin for relay, will be set HIGH if LEDs are on (-1 to disable). Also usable for standby leds, triggers,... +#endif #define AUXPIN -1 //debug auxiliary output pin (-1 to disable) #define RLYMDE 1 //mode for relay, 0: LOW if LEDs are on 1: HIGH if LEDs are on diff --git a/wled00/wled00.ino b/wled00/wled00.ino index 0ca367ddf7..465c74b52d 100644 --- a/wled00/wled00.ino +++ b/wled00/wled00.ino @@ -304,9 +304,9 @@ byte bri = briS; byte briOld = 0; byte briT = 0; byte briIT = 0; -byte briLast = 127; //brightness before turned off. Used for toggle function +byte briLast = 128; //brightness before turned off. Used for toggle function byte white = 0; -byte whiteLast = 127; //white level before turned off. Used for toggle function +byte whiteLast = 128; //white level before turned off. Used for toggle function //button bool buttonPressedBefore = false; From 57c2c825333eeab2562297bf4fec728dc2c56e79 Mon Sep 17 00:00:00 2001 From: Def3nder Date: Mon, 16 Dec 2019 16:35:13 +0100 Subject: [PATCH 17/21] Updates to adopt to upstream master RLYPIN definition dependant on WLED_USE_ANALOG_LEDS Fixed headline and corrected list-item indents (readme.md) updated to match upstream master (briLast in wled00.ino) --- readme.md | 53 +++++++++++++++++++++++---------------------- wled00/NpbWrapper.h | 6 ++++- wled00/wled00.ino | 4 ++-- 3 files changed, 34 insertions(+), 29 deletions(-) diff --git a/readme.md b/readme.md index bfc0001057..285bc5e4b5 100644 --- a/readme.md +++ b/readme.md @@ -5,7 +5,7 @@ [![](https://img.shields.io/badge/quick_start-wiki-blue.svg?style=flat-square)](https://github.com/Aircoookie/WLED/wiki) [![](https://img.shields.io/badge/app-wled-blue.svg?style=flat-square)](https://github.com/Aircoookie/WLED-App) -## Welcome to the modded version of the brilliant project WLED! +## Welcome to the modded version of the brilliant project WLED The Mod enables **analog RGBW stripes** instead of digital ones. @@ -14,33 +14,34 @@ The Mod enables **analog RGBW stripes** instead of digital ones. A fast and feature-rich implementation of an ESP8266/ESP32 webserver to control NeoPixel (WS2812B, WS2811, SK6812, APA102) LEDs! ### Features: -- WS2812FX library integrated for 80+ special effects -- FastLED noise effects and palettes -- Customizable Mobile and desktop UI with color and effect controls -- Settings page - configuration over network -- Access Point and station mode - automatic failsafe AP -- Support for RGBW strips -- 25 user presets to save and load colors/effects easily, supports cycling through them. -- Macro functions to automatically execute API calls -- Nightlight function (gradually dims down) -- Full OTA software updatability (HTTP + ArduinoOTA), password protectable -- Configurable analog clock + support for the Cronixie kit by Diamex -- Configurable Auto Brightness limit for safer operation + - WS2812FX library integrated for almost 90 special effects + - FastLED noise effects and palettes + - Modern UI with color, effect and segment controls + - Segments to set different effects and colors to parts of the LEDs + - Settings page - configuration over network + - Access Point and station mode - automatic failsafe AP + - Support for RGBW strips + - 16 user presets to save and load colors/effects easily, supports cycling through them. + - Macro functions to automatically execute API calls + - Nightlight function (gradually dims down) + - Full OTA software updatability (HTTP + ArduinoOTA), password protectable + - Configurable analog clock + support for the Cronixie kit by Diamex + - Configurable Auto Brightness limit for safer operation ### Supported light control interfaces: -- WLED app for Android and iOS -- JSON and HTTP request APIs -- MQTT -- Blynk IoT -- E1.31 -- Hyperion -- UDP realtime -- Alexa voice control (including dimming and color) -- Sync to Philips hue lights -- Adalight (PC ambilight via serial) -- Sync color of multiple WLED devices (UDP notifier) -- Infrared remotes (24-key RGB, receiver required) -- Simple timers/schedules (time from NTP, timezones/DST supported) + - WLED app for Android and iOS + - JSON and HTTP request APIs + - MQTT + - Blynk IoT + - E1.31 + - Hyperion + - UDP realtime + - Alexa voice control (including dimming and color) + - Sync to Philips hue lights + - Adalight (PC ambilight via serial) + - Sync color of multiple WLED devices (UDP notifier) + - Infrared remotes (24-key RGB, receiver required) + - Simple timers/schedules (time from NTP, timezones/DST supported) ### Quick start guide and documentation: diff --git a/wled00/NpbWrapper.h b/wled00/NpbWrapper.h index af597a72c7..f048f983c8 100644 --- a/wled00/NpbWrapper.h +++ b/wled00/NpbWrapper.h @@ -12,7 +12,11 @@ #define BTNPIN 0 //button pin. Needs to have pullup (gpio0 recommended) #define IR_PIN 4 //infrared pin (-1 to disable) MagicHome: 4, H801 Wifi: 0 #endif -#define RLYPIN -1 //pin for relay, will be set HIGH if LEDs are on (-1 to disable). Also usable for standby leds, triggers,... +#ifdef WLED_USE_ANALOG_LEDS + #define RLYPIN -1 //disable RLYPIN as it will be used for the RGB-PINs +#else + #define RLYPIN 12 //pin for relay, will be set HIGH if LEDs are on (-1 to disable). Also usable for standby leds, triggers,... +#endif #define AUXPIN -1 //debug auxiliary output pin (-1 to disable) #define RLYMDE 1 //mode for relay, 0: LOW if LEDs are on 1: HIGH if LEDs are on diff --git a/wled00/wled00.ino b/wled00/wled00.ino index 0ca367ddf7..465c74b52d 100644 --- a/wled00/wled00.ino +++ b/wled00/wled00.ino @@ -304,9 +304,9 @@ byte bri = briS; byte briOld = 0; byte briT = 0; byte briIT = 0; -byte briLast = 127; //brightness before turned off. Used for toggle function +byte briLast = 128; //brightness before turned off. Used for toggle function byte white = 0; -byte whiteLast = 127; //white level before turned off. Used for toggle function +byte whiteLast = 128; //white level before turned off. Used for toggle function //button bool buttonPressedBefore = false; From 53328113a4586593554f71107535b94afabcc231 Mon Sep 17 00:00:00 2001 From: Def3nder Date: Thu, 9 Jan 2020 12:44:12 +0100 Subject: [PATCH 18/21] Sync with upstream master --- wled00/FX.cpp | 970 ++++++++++++++---- wled00/FX.h | 88 +- wled00/FX_fcn.cpp | 89 +- wled00/NpbWrapper.h | 223 ++-- wled00/html_settings.h | 5 +- wled00/ir_codes.h | 48 +- wled00/src/dependencies/espalexa/Espalexa.h | 14 +- .../dependencies/espalexa/EspalexaDevice.cpp | 54 +- .../dependencies/espalexa/EspalexaDevice.h | 5 +- wled00/wled00.ino | 26 +- wled00/wled01_eeprom.ino | 7 + wled00/wled03_set.ino | 32 +- wled00/wled05_init.ino | 1 + wled00/wled07_notify.ino | 2 - wled00/wled08_led.ino | 10 +- wled00/wled10_ntp.ino | 21 +- wled00/wled11_ol.ino | 32 +- wled00/wled12_alexa.ino | 3 +- wled00/wled13_cronixie.ino | 2 - wled00/wled14_colors.ino | 17 +- wled00/wled18_server.ino | 2 +- wled00/wled19_json.ino | 6 +- wled00/wled20_ir.ino | 81 +- 23 files changed, 1104 insertions(+), 634 deletions(-) diff --git a/wled00/FX.cpp b/wled00/FX.cpp index fc13c60d9b..2c6bc116a3 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -116,7 +116,7 @@ uint16_t WS2812FX::mode_strobe_rainbow(void) { * if (bool rev == true) then LEDs are turned off in reverse order */ uint16_t WS2812FX::color_wipe(bool rev, bool useRandomColors) { - uint32_t cycleTime = 1000 + (255 - SEGMENT.speed)*200; + uint32_t cycleTime = 750 + (255 - SEGMENT.speed)*150; uint32_t perc = now % cycleTime; uint16_t prog = (perc * 65535) / cycleTime; bool back = (prog > 32767); @@ -151,7 +151,7 @@ uint16_t WS2812FX::color_wipe(bool rev, bool useRandomColors) { uint32_t col1 = useRandomColors? color_wheel(SEGENV.aux1) : SEGCOLOR(1); for (uint16_t i = SEGMENT.start; i < SEGMENT.stop; i++) { - uint16_t index = (rev && back)? SEGMENT.stop -1 -i : i; + uint16_t index = (rev && back)? SEGMENT.stop -1 -i +SEGMENT.start : i; uint32_t col0 = useRandomColors? color_wheel(SEGENV.aux0) : color_from_palette(index, true, PALETTE_SOLID_WRAP, 0); if (i - SEGMENT.start < ledIndex) @@ -236,22 +236,24 @@ uint16_t WS2812FX::mode_random_color(void) { // * to new random colors. */ uint16_t WS2812FX::mode_dynamic(void) { + if (!SEGENV.allocateData(SEGLEN)) return mode_static(); //allocation failed + if(SEGENV.call == 0) { - for(uint16_t i=SEGMENT.start; i < SEGMENT.stop; i++) _locked[i] = random8(); + for (uint16_t i = 0; i < SEGLEN; i++) SEGENV.data[i] = random8(); } uint32_t cycleTime = 50 + (255 - SEGMENT.speed)*15; uint32_t it = now / cycleTime; - if (it != SEGENV.step) //new color + if (it != SEGENV.step && SEGMENT.speed != 0) //new color { - for(uint16_t i=SEGMENT.start; i < SEGMENT.stop; i++) { - if (random8() <= SEGMENT.intensity) _locked[i] = random8(); + for (uint16_t i = 0; i < SEGLEN; i++) { + if (random8() <= SEGMENT.intensity) SEGENV.data[i] = random8(); } SEGENV.step = it; } - for(uint16_t i=SEGMENT.start; i < SEGMENT.stop; i++) { - setPixelColor(i, color_wheel(_locked[i])); + for (uint16_t i = 0; i < SEGLEN; i++) { + setPixelColor(SEGMENT.start + i, color_wheel(SEGENV.data[i])); } return FRAMETIME; } @@ -298,29 +300,33 @@ uint16_t WS2812FX::mode_fade(void) { */ uint16_t WS2812FX::scan(bool dual) { - if(SEGENV.step > (SEGLEN * 2) - 3) { - SEGENV.step = 0; - } + uint32_t cycleTime = 750 + (255 - SEGMENT.speed)*150; + uint32_t perc = now % cycleTime; + uint16_t prog = (perc * 65535) / cycleTime; + uint16_t size = 1 + ((SEGMENT.intensity * SEGLEN) >>9); + uint16_t ledIndex = (prog * ((SEGLEN *2) - size *2)) >> 16; fill(SEGCOLOR(1)); - int led_offset = SEGENV.step - (SEGLEN - 1); + int led_offset = ledIndex - (SEGLEN - size); led_offset = abs(led_offset); - uint16_t i = SEGMENT.start + led_offset; - setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); - if (dual) { - uint16_t i2 = SEGMENT.start + SEGLEN - led_offset - 1; - setPixelColor(i2, color_from_palette(i2, true, PALETTE_SOLID_WRAP, 0)); + for (uint16_t j = led_offset; j < led_offset + size; j++) { + uint16_t i2 = SEGMENT.stop -1 -j; + setPixelColor(i2, color_from_palette(i2, true, PALETTE_SOLID_WRAP, (SEGCOLOR(2))? 2:0)); + } } - SEGENV.step++; - return SPEED_FORMULA_L; + for (uint16_t j = led_offset; j < led_offset + size; j++) { + uint16_t i = SEGMENT.start + j; + setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); + } + + return FRAMETIME; } -//NOTE: add intensity (more than 1 pixel lit) /* * Runs a single pixel back and forth. */ @@ -410,7 +416,6 @@ uint16_t WS2812FX::mode_theater_chase(void) { * Inspired by the Adafruit examples. */ uint16_t WS2812FX::mode_theater_chase_rainbow(void) { - SEGENV.step = (SEGENV.step + 1) & 0xFF; return theater_chase(color_wheel(SEGENV.step), SEGCOLOR(1), false); } @@ -461,16 +466,34 @@ uint16_t WS2812FX::mode_saw(void) { * Inspired by www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/ */ uint16_t WS2812FX::mode_twinkle(void) { - if(SEGENV.step == 0) { - fill(SEGCOLOR(1)); - SEGENV.step = map(SEGMENT.intensity, 0, 255, 1, SEGLEN); // make sure, at least one LED is on + fill(SEGCOLOR(1)); + + uint32_t cycleTime = 20 + (255 - SEGMENT.speed)*5; + uint32_t it = now / cycleTime; + if (it != SEGENV.step) + { + uint16_t maxOn = map(SEGMENT.intensity, 0, 255, 1, SEGLEN); // make sure at least one LED is on + if (SEGENV.aux0 >= maxOn) + { + SEGENV.aux0 = 0; + SEGENV.aux1 = random16(); //new seed for our PRNG + } + SEGENV.aux0++; + SEGENV.step = it; } + + uint16_t PRNG16 = SEGENV.aux1; - uint16_t i = SEGMENT.start + random16(SEGLEN); - setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); + for (uint16_t i = 0; i < SEGENV.aux0; i++) + { + PRNG16 = (uint16_t)(PRNG16 * 2053) + 13849; // next 'random' number + uint32_t p = (uint32_t)SEGLEN * (uint32_t)PRNG16; + uint16_t mapped = p >> 16; + uint16_t j = SEGMENT.start + mapped; + setPixelColor(j, color_from_palette(j, true, PALETTE_SOLID_WRAP, 0)); + } - SEGENV.step--; - return 20 + (5 * (uint16_t)(255 - SEGMENT.speed)); + return FRAMETIME; } @@ -507,7 +530,7 @@ uint16_t WS2812FX::dissolve(uint32_t color) { SEGENV.call = 0; } - return 20; + return FRAMETIME; } @@ -592,6 +615,7 @@ uint16_t WS2812FX::mode_multi_strobe(void) { for(uint16_t i=SEGMENT.start; i < SEGMENT.stop; i++) { setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 1)); } + //blink(SEGCOLOR(0), SEGCOLOR(1), true, true); uint16_t delay = 50 + 20*(uint16_t)(255-SEGMENT.speed); uint16_t count = 2 * ((SEGMENT.speed / 10) + 1); @@ -669,9 +693,11 @@ uint16_t WS2812FX::mode_android(void) { * color2 and color3 = colors of two adjacent leds */ uint16_t WS2812FX::chase(uint32_t color1, uint32_t color2, uint32_t color3, bool dopalette) { - uint16_t a = SEGENV.step; - uint16_t b = (a + 1) % SEGLEN; - uint16_t c = (b + 1) % SEGLEN; + uint16_t counter = now * (SEGMENT.speed >> 3) + 1; + uint16_t a = counter * SEGLEN >> 16; + // Use intensity setting to vary chase up to 1/2 string length + uint16_t b = (a + 1 + (SEGMENT.intensity * SEGLEN >> 10)) % SEGLEN; + uint16_t c = (b + 1 + (SEGMENT.intensity * SEGLEN >> 10)) % SEGLEN; if (dopalette) color1 = color_from_palette(SEGMENT.start + a, true, PALETTE_SOLID_WRAP, 1); @@ -679,8 +705,7 @@ uint16_t WS2812FX::chase(uint32_t color1, uint32_t color2, uint32_t color3, bool setPixelColor(SEGMENT.start + b, color2); setPixelColor(SEGMENT.start + c, color3); - SEGENV.step = (SEGENV.step + 1) % SEGLEN; - return SPEED_FORMULA_L; + return FRAMETIME; } @@ -729,33 +754,40 @@ uint16_t WS2812FX::mode_colorful(void) { cols[3] = 0x0077F0F0; for (uint8_t i = 4; i < 7; i++) cols[i] = cols[i-4]; } - int i = SEGMENT.start; - for (i; i < SEGMENT.stop ; i+=4) + + uint32_t cycleTime = 50 + (15 * (uint32_t)(255 - SEGMENT.speed)); + uint32_t it = now / cycleTime; + if (it != SEGENV.step) + { + if (SEGMENT.speed > 0) SEGENV.aux0++; + if (SEGENV.aux0 > 3) SEGENV.aux0 = 0; + SEGENV.step = it; + } + + uint16_t i = SEGMENT.start; + for (i; i < SEGMENT.stop -3; i+=4) { - setPixelColor(i, cols[SEGENV.step]); - setPixelColor(i+1, cols[SEGENV.step+1]); - setPixelColor(i+2, cols[SEGENV.step+2]); - setPixelColor(i+3, cols[SEGENV.step+3]); + setPixelColor(i, cols[SEGENV.aux0]); + setPixelColor(i+1, cols[SEGENV.aux0+1]); + setPixelColor(i+2, cols[SEGENV.aux0+2]); + setPixelColor(i+3, cols[SEGENV.aux0+3]); } - i+=4; if(i < SEGMENT.stop) { - setPixelColor(i, cols[SEGENV.step]); + setPixelColor(i, cols[SEGENV.aux0]); if(i+1 < SEGMENT.stop) { - setPixelColor(i+1, cols[SEGENV.step+1]); + setPixelColor(i+1, cols[SEGENV.aux0+1]); if(i+2 < SEGMENT.stop) { - setPixelColor(i+2, cols[SEGENV.step+2]); + setPixelColor(i+2, cols[SEGENV.aux0+2]); } } } - if (SEGMENT.speed > 0) SEGENV.step++; //static if lowest speed - if (SEGENV.step >3) SEGENV.step = 0; - return 50 + (15 * (uint32_t)(255 - SEGMENT.speed)); + return FRAMETIME; } @@ -768,7 +800,7 @@ uint16_t WS2812FX::mode_traffic_light(void) { uint32_t mdelay = 500; for (int i = SEGMENT.start; i < SEGMENT.stop-2 ; i+=3) { - switch (SEGENV.step) + switch (SEGENV.aux0) { case 0: setPixelColor(i, 0x00FF0000); mdelay = 150 + (100 * (uint32_t)(255 - SEGMENT.speed));break; case 1: setPixelColor(i, 0x00FF0000); mdelay = 150 + (20 * (uint32_t)(255 - SEGMENT.speed)); setPixelColor(i+1, 0x00EECC00); break; @@ -777,9 +809,14 @@ uint16_t WS2812FX::mode_traffic_light(void) { } } - SEGENV.step++; - if (SEGENV.step >3) SEGENV.step = 0; - return mdelay; + if (now - SEGENV.step > mdelay) + { + SEGENV.aux0++; + if (SEGENV.aux0 > 3) SEGENV.aux0 = 0; + SEGENV.step = now; + } + + return FRAMETIME; } @@ -925,6 +962,10 @@ uint16_t WS2812FX::mode_halloween(void) { * Random colored pixels running. */ uint16_t WS2812FX::mode_running_random(void) { + uint32_t cycleTime = 25 + (3 * (uint32_t)(255 - SEGMENT.speed)); + uint32_t it = now / cycleTime; + if (SEGENV.aux1 == it) return FRAMETIME; + for(uint16_t i=SEGLEN-1; i > 0; i--) { setPixelColor(SEGMENT.start + i, getPixelColor(SEGMENT.start + i - 1)); } @@ -939,26 +980,49 @@ uint16_t WS2812FX::mode_running_random(void) { { SEGENV.step = 0; } - return SPEED_FORMULA_L; + + SEGENV.aux1 = it; + return FRAMETIME; } /* * K.I.T.T. */ -uint16_t WS2812FX::mode_larson_scanner(void) { +uint16_t WS2812FX::mode_larson_scanner(void){ + return larson_scanner(false); +} + +uint16_t WS2812FX::larson_scanner(bool dual) { + uint16_t counter = now * ((SEGMENT.speed >> 2) +8); + uint16_t index = counter * SEGLEN >> 16; + fade_out(SEGMENT.intensity); - uint16_t index = 0; - if(SEGENV.step < SEGLEN) { - index = SEGMENT.start + SEGENV.step; - } else { - index = SEGMENT.start + ((SEGLEN * 2) - SEGENV.step) - 2; + if (SEGENV.step > index && SEGENV.step - index > SEGLEN/2) { + SEGENV.aux0 = !SEGENV.aux0; + } + + for (uint16_t i = SEGENV.step; i < index; i++) { + uint16_t j = (SEGENV.aux0)?i:SEGLEN-1-i; + setPixelColor(SEGMENT.start + j, color_from_palette(j, true, PALETTE_SOLID_WRAP, 0)); } - setPixelColor(index, color_from_palette(index, true, PALETTE_SOLID_WRAP, 0)); + if (dual) { + uint32_t c; + if (SEGCOLOR(2) != 0) { + c = SEGCOLOR(2); + } else { + c = color_from_palette(index, true, PALETTE_SOLID_WRAP, 0); + } - SEGENV.step = (SEGENV.step + 1) % ((SEGLEN * 2) - 2); - return SPEED_FORMULA_L; + for (uint16_t i = SEGENV.step; i < index; i++) { + uint16_t j = (SEGENV.aux0)?SEGLEN-1-i:i; + setPixelColor(SEGMENT.start + j, c); + } + } + + SEGENV.step = index; + return FRAMETIME; } @@ -966,13 +1030,14 @@ uint16_t WS2812FX::mode_larson_scanner(void) { * Firing comets from one end. */ uint16_t WS2812FX::mode_comet(void) { + uint16_t counter = now * (SEGMENT.speed >>3) +1; + uint16_t index = counter * SEGLEN >> 16; + fade_out(SEGMENT.intensity); - uint16_t index = SEGMENT.start + SEGENV.step; - setPixelColor(index, color_from_palette(index, true, PALETTE_SOLID_WRAP, 0)); + setPixelColor(SEGMENT.start + index, color_from_palette(index, true, PALETTE_SOLID_WRAP, 0)); - SEGENV.step = (SEGENV.step + 1) % SEGLEN; - return SPEED_FORMULA_L; + return FRAMETIME; } @@ -1002,14 +1067,14 @@ uint16_t WS2812FX::mode_fireworks() { SEGENV.aux0 = index; } } - return 22; + return FRAMETIME; } //Twinkling LEDs running. Inspired by https://github.com/kitesurfer1404/WS2812FX/blob/master/src/custom/Rain.h uint16_t WS2812FX::mode_rain() { - SEGENV.step += 22; + SEGENV.step += FRAMETIME; if (SEGENV.step > SPEED_FORMULA_L) { SEGENV.step = 0; //shift all leds right @@ -1033,6 +1098,10 @@ uint16_t WS2812FX::mode_rain() * Fire flicker function */ uint16_t WS2812FX::mode_fire_flicker(void) { + uint32_t cycleTime = 40 + (255 - SEGMENT.speed); + uint32_t it = now / cycleTime; + if (SEGENV.step == it) return FRAMETIME; + byte w = (SEGCOLOR(0) >> 24) & 0xFF; byte r = (SEGCOLOR(0) >> 16) & 0xFF; byte g = (SEGCOLOR(0) >> 8) & 0xFF; @@ -1047,7 +1116,9 @@ uint16_t WS2812FX::mode_fire_flicker(void) { setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 0, 255 - flicker)); } } - return 20 + random((255 - SEGMENT.speed),(2 * (uint16_t)(255 - SEGMENT.speed))); + + SEGENV.step = it; + return FRAMETIME; } @@ -1055,15 +1126,18 @@ uint16_t WS2812FX::mode_fire_flicker(void) { * Gradient run base function */ uint16_t WS2812FX::gradient_base(bool loading) { + uint16_t counter = now * (SEGMENT.speed >> 3) + 1; + SEGENV.step = counter * SEGLEN >> 16; + if (SEGMENT.speed == 0) SEGENV.step = SEGMENT.start + (SEGLEN >> 1); if (SEGENV.call == 0) SEGENV.step = 0; float per,val; //0.0 = sec 1.0 = pri float brd = SEGMENT.intensity; - if (!loading) brd = SEGMENT.intensity/2; + if (!loading) brd = SEGMENT.intensity/2; if (brd <1.0) brd = 1.0; int pp = SEGENV.step; int p1 = pp-SEGLEN; int p2 = pp+SEGLEN; - + for(uint16_t i=SEGMENT.start; i < SEGMENT.stop; i++) { if (loading) @@ -1074,13 +1148,10 @@ uint16_t WS2812FX::gradient_base(bool loading) { } per = val/brd; if (per >1.0) per = 1.0; - setPixelColor(SEGMENT.start + i, color_blend(SEGCOLOR(0), color_from_palette(SEGMENT.start + i, true, PALETTE_SOLID_WRAP, 1), per*255)); + setPixelColor(i, color_blend(SEGCOLOR(0), color_from_palette(i, true, PALETTE_SOLID_WRAP, 1), per*255)); } - - SEGENV.step++; - if (SEGENV.step >= SEGMENT.stop) SEGENV.step = SEGMENT.start; - if (SEGMENT.speed == 0) SEGENV.step = SEGMENT.start + (SEGLEN >> 1); - return SPEED_FORMULA_L; + + return FRAMETIME; } @@ -1157,19 +1228,22 @@ uint16_t WS2812FX::mode_two_dots() * Tricolor chase function */ uint16_t WS2812FX::tricolor_chase(uint32_t color1, uint32_t color2) { - uint16_t index = SEGENV.step % 6; + uint32_t cycleTime = 50 + (255 - SEGMENT.speed)*2; + uint32_t it = now / cycleTime; + uint8_t width = (1 + SEGMENT.intensity/32) * 3; //value of 1-8 for each colour + uint8_t index = it % width; + for(uint16_t i=0; i < SEGLEN; i++, index++) { - if(index > 5) index = 0; + if(index > width-1) index = 0; uint32_t color = color1; - if(index > 3) color = color_from_palette(i, true, PALETTE_SOLID_WRAP, 1); - else if(index > 1) color = color2; + if(index > width*2/3-1) color = color_from_palette(i, true, PALETTE_SOLID_WRAP, 1); + else if(index > width/3-1) color = color2; setPixelColor(SEGMENT.stop - i -1, color); } - SEGENV.step++; - return 35 + ((350 * (uint32_t)(255 - SEGMENT.speed)) / 255); + return FRAMETIME; } @@ -1199,7 +1273,7 @@ uint16_t WS2812FX::mode_icu(void) { byte pindex = map(dest, 0, SEGLEN/2, 0, 255); uint32_t col = color_from_palette(pindex, false, false, 0); - + setPixelColor(SEGMENT.start + dest, col); setPixelColor(SEGMENT.start + dest + SEGLEN/2, col); @@ -1233,20 +1307,38 @@ uint16_t WS2812FX::mode_icu(void) { */ uint16_t WS2812FX::mode_tricolor_wipe(void) { - if(SEGENV.step < SEGLEN) { - uint32_t led_offset = SEGENV.step; - setPixelColor(SEGMENT.start + led_offset, SEGCOLOR(0)); - } else if (SEGENV.step < SEGLEN*2) { - uint32_t led_offset = SEGENV.step - SEGLEN; - setPixelColor(SEGMENT.start + led_offset, SEGCOLOR(1)); - } else + uint32_t cycleTime = 1000 + (255 - SEGMENT.speed)*200; + uint32_t perc = now % cycleTime; + uint16_t prog = (perc * 65535) / cycleTime; + uint16_t ledIndex = (prog * SEGLEN * 3) >> 16; + uint16_t ledOffset = ledIndex; + + for (uint16_t i = SEGMENT.start; i < SEGMENT.stop; i++) + { + setPixelColor(i, color_from_palette(i, true, PALETTE_SOLID_WRAP, 2)); + } + + if(ledIndex < SEGLEN) { //wipe from 0 to 1 + for (uint16_t i = SEGMENT.start; i < SEGMENT.stop; i++) + { + setPixelColor(i, (i - SEGMENT.start > ledOffset)? SEGCOLOR(0) : SEGCOLOR(1)); + } + } else if (ledIndex < SEGLEN*2) { //wipe from 1 to 2 + ledOffset = ledIndex - SEGLEN; + for (uint16_t i = SEGMENT.start +ledOffset +1; i < SEGMENT.stop; i++) + { + setPixelColor(i, SEGCOLOR(1)); + } + } else //wipe from 2 to 0 { - uint32_t led_offset = SEGENV.step - SEGLEN*2; - setPixelColor(SEGMENT.start + led_offset, color_from_palette(SEGMENT.start + led_offset, true, PALETTE_SOLID_WRAP, 2)); + ledOffset = ledIndex - SEGLEN*2; + for (uint16_t i = SEGMENT.start; i <= SEGMENT.start +ledOffset; i++) + { + setPixelColor(i, SEGCOLOR(0)); + } } - SEGENV.step = (SEGENV.step + 1) % (SEGLEN * 3); - return SPEED_FORMULA_L; + return FRAMETIME; } @@ -1257,14 +1349,17 @@ uint16_t WS2812FX::mode_tricolor_wipe(void) */ uint16_t WS2812FX::mode_tricolor_fade(void) { + uint16_t counter = now * ((SEGMENT.speed >> 3) +1); + uint32_t prog = (counter * 768) >> 16; + uint32_t color1 = 0, color2 = 0; byte stage = 0; - if(SEGENV.step < 256) { + if(prog < 256) { color1 = SEGCOLOR(0); color2 = SEGCOLOR(1); stage = 0; - } else if(SEGENV.step < 512) { + } else if(prog < 512) { color1 = SEGCOLOR(1); color2 = SEGCOLOR(2); stage = 1; @@ -1274,23 +1369,20 @@ uint16_t WS2812FX::mode_tricolor_fade(void) stage = 2; } - byte stp = SEGENV.step % 256; + byte stp = prog; // % 256 uint32_t color = 0; for(uint16_t i=SEGMENT.start; i < SEGMENT.stop; i++) { if (stage == 2) { - color = color_blend(color_from_palette(i, true, PALETTE_SOLID_WRAP, 2), color2, stp); + color = color_blend(color_from_palette(i, true, PALETTE_SOLID_WRAP, 2), color2, stp); } else if (stage == 1) { - color = color_blend(color1, color_from_palette(i, true, PALETTE_SOLID_WRAP, 2), stp); + color = color_blend(color1, color_from_palette(i, true, PALETTE_SOLID_WRAP, 2), stp); } else { color = color_blend(color1, color2, stp); } setPixelColor(i, color); } - SEGENV.step += 4; - if(SEGENV.step >= 768) SEGENV.step = 0; - - return 5 + ((uint32_t)(255 - SEGMENT.speed) / 10); + return FRAMETIME; } @@ -1300,6 +1392,10 @@ uint16_t WS2812FX::mode_tricolor_fade(void) */ uint16_t WS2812FX::mode_multi_comet(void) { + uint32_t cycleTime = 20 + (2 * (uint32_t)(255 - SEGMENT.speed)); + uint32_t it = now / cycleTime; + if (SEGENV.step == it) return FRAMETIME; + fade_out(SEGMENT.intensity); static uint16_t comets[] = {UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX, UINT16_MAX}; @@ -1321,7 +1417,9 @@ uint16_t WS2812FX::mode_multi_comet(void) } } } - return SPEED_FORMULA_L; + + SEGENV.step = it; + return FRAMETIME; } @@ -1330,31 +1428,7 @@ uint16_t WS2812FX::mode_multi_comet(void) * Custom mode by Keith Lord: https://github.com/kitesurfer1404/WS2812FX/blob/master/src/custom/DualLarson.h */ uint16_t WS2812FX::mode_dual_larson_scanner(void){ - if (SEGENV.aux0) - { - SEGENV.step--; - } else - { - SEGENV.step++; - } - - fade_out(SEGMENT.intensity); - - uint16_t index = SEGMENT.start + SEGENV.step; - setPixelColor(index, color_from_palette(index, true, PALETTE_SOLID_WRAP, 0)); - index = SEGMENT.stop - SEGENV.step -1; - if (SEGCOLOR(2) != 0) - { - setPixelColor(index, SEGCOLOR(2)); - } else - { - setPixelColor(index, color_from_palette(index, true, PALETTE_SOLID_WRAP, 0)); - } - - if(SEGENV.step >= SEGLEN -1 || SEGENV.step <= 0) - SEGENV.aux0 = !SEGENV.aux0; - - return SPEED_FORMULA_L; + return larson_scanner(true); } @@ -1364,6 +1438,10 @@ uint16_t WS2812FX::mode_dual_larson_scanner(void){ */ uint16_t WS2812FX::mode_random_chase(void) { + uint32_t cycleTime = 25 + (3 * (uint32_t)(255 - SEGMENT.speed)); + uint32_t it = now / cycleTime; + if (SEGENV.step == it) return FRAMETIME; + for(uint16_t i=SEGMENT.stop -1; i>SEGMENT.start; i--) { setPixelColor(i, getPixelColor(i-1)); } @@ -1374,7 +1452,8 @@ uint16_t WS2812FX::mode_random_chase(void) uint8_t b = random8(6) != 0 ? (color & 0xFF) : random8(); setPixelColor(SEGMENT.start, r, g, b); - return SPEED_FORMULA_L; + SEGENV.step = it; + return FRAMETIME; } @@ -1385,38 +1464,57 @@ typedef struct Oscillator { int8_t speed; } oscillator; +/* +/ Oscillating bars of color, updated with standard framerate +*/ uint16_t WS2812FX::mode_oscillate(void) { - static oscillator oscillators[2] = { - {SEGLEN/4, SEGLEN/8, 1, 1}, - {SEGLEN/4*2, SEGLEN/8, -1, 1} - //{SEGLEN/4*3, SEGLEN/8, 1, 2} - }; - - for(int8_t i=0; i < sizeof(oscillators)/sizeof(oscillators[0]); i++) { - oscillators[i].pos += oscillators[i].dir * oscillators[i].speed; + uint8_t numOscillators = 3; + uint16_t dataSize = sizeof(oscillator) * numOscillators; + + if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed + + Oscillator* oscillators = reinterpret_cast(SEGENV.data); + + if (SEGENV.call == 0) + { + oscillators[0] = {SEGLEN/4, SEGLEN/8, 1, 1}; + oscillators[1] = {SEGLEN/4*3, SEGLEN/8, 1, 2}; + oscillators[2] = {SEGLEN/4*2, SEGLEN/8, -1, 1}; + } + + uint32_t cycleTime = 20 + (2 * (uint32_t)(255 - SEGMENT.speed)); + uint32_t it = now / cycleTime; + + for(uint8_t i=0; i < numOscillators; i++) { + // if the counter has increased, move the oscillator by the random step + if (it != SEGENV.step) oscillators[i].pos += oscillators[i].dir * oscillators[i].speed; + oscillators[i].size = SEGLEN/(3+SEGMENT.intensity/8); if((oscillators[i].dir == -1) && (oscillators[i].pos <= 0)) { oscillators[i].pos = 0; oscillators[i].dir = 1; - oscillators[i].speed = random8(1, 3); + // make bigger steps for faster speeds + oscillators[i].speed = SEGMENT.speed > 100 ? random8(2, 4):random8(1, 3); } if((oscillators[i].dir == 1) && (oscillators[i].pos >= (SEGLEN - 1))) { oscillators[i].pos = SEGLEN - 1; oscillators[i].dir = -1; - oscillators[i].speed = random8(1, 3); + oscillators[i].speed = SEGMENT.speed > 100 ? random8(2, 4):random8(1, 3); } } - for(int16_t i=0; i < SEGLEN; i++) { + for(uint16_t i=0; i < SEGLEN; i++) { uint32_t color = BLACK; - for(int8_t j=0; j < sizeof(oscillators)/sizeof(oscillators[0]); j++) { + for(uint8_t j=0; j < numOscillators; j++) { if(i >= oscillators[j].pos - oscillators[j].size && i <= oscillators[j].pos + oscillators[j].size) { color = (color == BLACK) ? SEGMENT.colors[j] : color_blend(color, SEGMENT.colors[j], 128); } } setPixelColor(SEGMENT.start + i, color); } - return 15 + (uint32_t)(255 - SEGMENT.speed); + + SEGENV.step = it; + return FRAMETIME; } @@ -1424,17 +1522,17 @@ uint16_t WS2812FX::mode_lightning(void) { uint16_t ledstart = SEGMENT.start + random16(SEGLEN); // Determine starting location of flash uint16_t ledlen = random16(SEGMENT.stop -1 -ledstart); // Determine length of flash (not to go beyond NUM_LEDS-1) - uint8_t bri = 255/random8(1, 3); + uint8_t bri = 255/random8(1, 3); if (SEGENV.step == 0) { SEGENV.aux0 = random8(3, 3 + SEGMENT.intensity/20); //number of flashes - bri = 52; + bri = 52; SEGENV.aux1 = 1; } fill(SEGCOLOR(1)); - + if (SEGENV.aux1) { for (int i = ledstart; i < ledstart + ledlen; i++) { @@ -1468,7 +1566,7 @@ uint16_t WS2812FX::mode_pride_2015(void) uint16_t duration = 10 + SEGMENT.speed; uint16_t sPseudotime = SEGENV.step; uint16_t sHue16 = SEGENV.aux0; - + uint8_t sat8 = beatsin88( 87, 220, 250); uint8_t brightdepth = beatsin88( 341, 96, 224); uint16_t brightnessthetainc16 = beatsin88( 203, (25 * 256), (40 * 256)); @@ -1476,12 +1574,12 @@ uint16_t WS2812FX::mode_pride_2015(void) uint16_t hue16 = sHue16;//gHue * 256; uint16_t hueinc16 = beatsin88(113, 1, 3000); - + sPseudotime += duration * msmultiplier; sHue16 += duration * beatsin88( 400, 5,9); uint16_t brightnesstheta16 = sPseudotime; CRGB fastled_col; - + for( uint16_t i = SEGMENT.start ; i < SEGMENT.stop; i++) { hue16 += hueinc16; uint8_t hue8 = hue16 >> 8; @@ -1492,16 +1590,16 @@ uint16_t WS2812FX::mode_pride_2015(void) uint16_t bri16 = (uint32_t)((uint32_t)b16 * (uint32_t)b16) / 65536; uint8_t bri8 = (uint32_t)(((uint32_t)bri16) * brightdepth) / 65536; bri8 += (255 - brightdepth); - + CRGB newcolor = CHSV( hue8, sat8, bri8); fastled_col = col_to_crgb(getPixelColor(i)); - + nblend( fastled_col, newcolor, 64); setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); } SEGENV.step = sPseudotime; SEGENV.aux0 = sHue16; - return 20; + return FRAMETIME; } @@ -1511,13 +1609,13 @@ uint16_t WS2812FX::mode_juggle(void){ CRGB fastled_col; byte dothue = 0; for ( byte i = 0; i < 8; i++) { - uint16_t index = SEGMENT.start + beatsin16(i + 7, 0, SEGLEN -1); + uint16_t index = SEGMENT.start + beatsin88((128 + SEGMENT.speed)*(i + 7), 0, SEGLEN -1); fastled_col = col_to_crgb(getPixelColor(index)); fastled_col |= (SEGMENT.palette==0)?CHSV(dothue, 220, 255):ColorFromPalette(currentPalette, dothue, 255); setPixelColor(index, fastled_col.red, fastled_col.green, fastled_col.blue); dothue += 32; } - return 10 + (uint16_t)(255 - SEGMENT.speed)/4; + return FRAMETIME; } @@ -1577,30 +1675,34 @@ uint16_t WS2812FX::mode_fire_2012() { uint32_t it = now >> 5; //div 32 + if (!SEGENV.allocateData(SEGLEN)) return mode_static(); //allocation failed + + byte* heat = SEGENV.data; + if (it != SEGENV.step) { // Step 1. Cool down every cell a little - for( int i = SEGMENT.start; i < SEGMENT.stop; i++) { - _locked[i] = qsub8(_locked[i], random8(0, (((20 + SEGMENT.speed /3) * 10) / SEGLEN) + 2)); + for (uint16_t i = 0; i < SEGLEN; i++) { + SEGENV.data[i] = qsub8(heat[i], random8(0, (((20 + SEGMENT.speed /3) * 10) / SEGLEN) + 2)); } // Step 2. Heat from each cell drifts 'up' and diffuses a little - for( int k= SEGMENT.stop -1; k >= SEGMENT.start + 2; k--) { - _locked[k] = (_locked[k - 1] + _locked[k - 2] + _locked[k - 2] ) / 3; + for (uint16_t k= SEGLEN -1; k > 1; k--) { + heat[k] = (heat[k - 1] + heat[k - 2] + heat[k - 2] ) / 3; } // Step 3. Randomly ignite new 'sparks' of heat near the bottom - if( random8() <= SEGMENT.intensity ) { - int y = SEGMENT.start + random8(7); - if (y < SEGMENT.stop) _locked[y] = qadd8(_locked[y], random8(160,255) ); + if (random8() <= SEGMENT.intensity) { + uint8_t y = random8(7); + if (y < SEGLEN) heat[y] = qadd8(heat[y], random8(160,255)); } SEGENV.step = it; } // Step 4. Map from heat cells to LED colors - for( int j = SEGMENT.start; j < SEGMENT.stop; j++) { - CRGB color = ColorFromPalette( currentPalette, min(_locked[j],240), 255, LINEARBLEND); - setPixelColor(j, color.red, color.green, color.blue); + for (uint16_t j = 0; j < SEGLEN; j++) { + CRGB color = ColorFromPalette(currentPalette, min(heat[j],240), 255, LINEARBLEND); + setPixelColor(SEGMENT.start + j, color.red, color.green, color.blue); } return FRAMETIME; } @@ -1652,7 +1754,7 @@ uint16_t WS2812FX::mode_colorwaves() } SEGENV.step = sPseudotime; SEGENV.aux0 = sHue16; - return 20; + return FRAMETIME; } @@ -1681,7 +1783,7 @@ uint16_t WS2812FX::mode_fillnoise8() } SEGENV.step += beatsin8(SEGMENT.speed, 1, 6); //10,1,4 - return 20; + return FRAMETIME; } uint16_t WS2812FX::mode_noise16_1() @@ -1708,7 +1810,7 @@ uint16_t WS2812FX::mode_noise16_1() setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); } - return 20; + return FRAMETIME; } @@ -1733,7 +1835,7 @@ uint16_t WS2812FX::mode_noise16_2() setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); } - return 20; + return FRAMETIME; } @@ -1760,7 +1862,7 @@ uint16_t WS2812FX::mode_noise16_3() setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); } - return 20; + return FRAMETIME; } @@ -1768,8 +1870,7 @@ uint16_t WS2812FX::mode_noise16_3() uint16_t WS2812FX::mode_noise16_4() { CRGB fastled_col; - SEGENV.step += SEGMENT.speed; - uint32_t stp = (now / 160) * SEGMENT.speed; + uint32_t stp = (now * SEGMENT.speed) >> 7; for (uint16_t i = SEGMENT.start; i < SEGMENT.stop; i++) { int16_t index = inoise16(uint32_t(i - SEGMENT.start) << 12, stp); fastled_col = ColorFromPalette(currentPalette, index); @@ -1782,18 +1883,25 @@ uint16_t WS2812FX::mode_noise16_4() //based on https://gist.github.com/kriegsman/5408ecd397744ba0393e uint16_t WS2812FX::mode_colortwinkle() { + uint16_t dataSize = (SEGLEN+7) >> 3; //1 bit per LED + if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed + CRGB fastled_col, prev; fract8 fadeUpAmount = 8 + (SEGMENT.speed/4), fadeDownAmount = 5 + (SEGMENT.speed/7); - for( uint16_t i = SEGMENT.start; i < SEGMENT.stop; i++) { + for (uint16_t i = SEGMENT.start; i < SEGMENT.stop; i++) { fastled_col = col_to_crgb(getPixelColor(i)); prev = fastled_col; - if(_locked[i]) { + uint16_t index = (i - SEGMENT.start) >> 3; + uint8_t bitNum = (i - SEGMENT.start) & 0x07; + bool fadeUp = bitRead(SEGENV.data[index], bitNum); + + if (fadeUp) { CRGB incrementalColor = fastled_col; incrementalColor.nscale8_video( fadeUpAmount); fastled_col += incrementalColor; - if( fastled_col.red == 255 || fastled_col.green == 255 || fastled_col.blue == 255) { - _locked[i] = false; + if (fastled_col.red == 255 || fastled_col.green == 255 || fastled_col.blue == 255) { + bitWrite(SEGENV.data[index], bitNum, false); } setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); @@ -1810,20 +1918,22 @@ uint16_t WS2812FX::mode_colortwinkle() for (uint16_t j = 0; j <= SEGLEN / 50; j++) { - if ( random8() <= SEGMENT.intensity ) { + if (random8() <= SEGMENT.intensity) { for (uint8_t times = 0; times < 5; times++) //attempt to spawn a new pixel 5 times { int i = SEGMENT.start + random16(SEGLEN); if(getPixelColor(i) == 0) { fastled_col = ColorFromPalette(currentPalette, random8(), 64, NOBLEND); - _locked[i] = true; + uint16_t index = (i - SEGMENT.start) >> 3; + uint8_t bitNum = (i - SEGMENT.start) & 0x07; + bitWrite(SEGENV.data[index], bitNum, true); setPixelColor(i, fastled_col.red, fastled_col.green, fastled_col.blue); break; //only spawn 1 new pixel per frame per 50 LEDs } } } } - return 20; + return FRAMETIME; } @@ -1850,32 +1960,36 @@ uint16_t WS2812FX::mode_lake() { // send a meteor from begining to to the end of the strip with a trail that randomly decays. // adapted from https://www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/#LEDStripEffectMeteorRain uint16_t WS2812FX::mode_meteor() { + if (!SEGENV.allocateData(SEGLEN)) return mode_static(); //allocation failed + + byte* trail = SEGENV.data; + byte meteorSize= 1+ SEGLEN / 10; - uint16_t in = SEGMENT.start + SEGENV.step; + uint16_t counter = now * ((SEGMENT.speed >> 2) +8); + uint16_t in = counter * SEGLEN >> 16; // fade all leds to colors[1] in LEDs one step - for (uint16_t i = SEGMENT.start; i < SEGMENT.stop; i++) { + for (uint16_t i = 0; i < SEGLEN; i++) { if (random8() <= 255 - SEGMENT.intensity) { byte meteorTrailDecay = 128 + random8(127); - _locked[i] = scale8(_locked[i], meteorTrailDecay); - setPixelColor(i, color_from_palette(_locked[i], false, true, 255)); + trail[i] = scale8(trail[i], meteorTrailDecay); + setPixelColor(SEGMENT.start + i, color_from_palette(trail[i], false, true, 255)); } } - + // draw meteor - for(int j = 0; j < meteorSize; j++) { - uint16_t index = in + j; - if(in + j >= SEGMENT.stop) { - index = SEGMENT.start + (in + j - SEGMENT.stop); + for(int j = 0; j < meteorSize; j++) { + uint16_t index = in + j; + if(index >= SEGLEN) { + index = (in + j - SEGLEN); } - _locked[index] = 240; - setPixelColor(index, color_from_palette(_locked[index], false, true, 255)); + trail[index] = 240; + setPixelColor(SEGMENT.start + index, color_from_palette(trail[index], false, true, 255)); } - SEGENV.step = (SEGENV.step + 1) % (SEGLEN); - return SPEED_FORMULA_L; + return FRAMETIME; } @@ -1883,33 +1997,37 @@ uint16_t WS2812FX::mode_meteor() { // send a meteor from begining to to the end of the strip with a trail that randomly decays. // adapted from https://www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/#LEDStripEffectMeteorRain uint16_t WS2812FX::mode_meteor_smooth() { + if (!SEGENV.allocateData(SEGLEN)) return mode_static(); //allocation failed + + byte* trail = SEGENV.data; + byte meteorSize= 1+ SEGLEN / 10; - uint16_t in = map((SEGENV.step >> 6 & 0xFF), 0, 255, SEGMENT.start, SEGMENT.stop -1); + uint16_t in = map((SEGENV.step >> 6 & 0xFF), 0, 255, 0, SEGLEN -1); // fade all leds to colors[1] in LEDs one step - for (uint16_t i = SEGMENT.start; i < SEGMENT.stop; i++) { - if (_locked[i] != 0 && random8() <= 255 - SEGMENT.intensity) + for (uint16_t i = 0; i < SEGLEN; i++) { + if (trail[i] != 0 && random8() <= 255 - SEGMENT.intensity) { int change = 3 - random8(12); //change each time between -8 and +3 - _locked[i] += change; - if (_locked[i] > 245) _locked[i] = 0; - if (_locked[i] > 240) _locked[i] = 240; - setPixelColor(i, color_from_palette(_locked[i], false, true, 255)); + trail[i] += change; + if (trail[i] > 245) trail[i] = 0; + if (trail[i] > 240) trail[i] = 240; + setPixelColor(SEGMENT.start + i, color_from_palette(trail[i], false, true, 255)); } } // draw meteor for(int j = 0; j < meteorSize; j++) { uint16_t index = in + j; - if(in + j >= SEGMENT.stop) { - index = SEGMENT.start + (in + j - SEGMENT.stop); + if(in + j >= SEGLEN) { + index = (in + j - SEGLEN); } - setPixelColor(index, color_blend(getPixelColor(index), color_from_palette(240, false, true, 255), 48)); - _locked[index] = 240; + setPixelColor(SEGMENT.start + index, color_blend(getPixelColor(SEGMENT.start + index), color_from_palette(240, false, true, 255), 48)); + trail[index] = 240; } SEGENV.step += SEGMENT.speed +1; - return 20; + return FRAMETIME; } @@ -1947,23 +2065,35 @@ uint16_t WS2812FX::mode_railway() //Water ripple //propagation velocity from speed //drop rate from intensity + +//4 bytes +typedef struct Ripple { + uint8_t state; + uint8_t color; + uint16_t pos; +} ripple; + uint16_t WS2812FX::mode_ripple() { - uint16_t maxripples = SEGLEN / 4; - if (maxripples == 0) return mode_static(); + uint16_t maxRipples = 1 + (SEGLEN >> 2); + if (maxRipples > 100) maxRipples = 100; + uint16_t dataSize = sizeof(ripple) * maxRipples; + + if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed + + Ripple* ripples = reinterpret_cast(SEGENV.data); fill(SEGCOLOR(1)); //draw wave - for (uint16_t rippleI = 0; rippleI < maxripples; rippleI++) + for (uint16_t i = 0; i < maxRipples; i++) { - uint16_t storeI = SEGMENT.start + 4*rippleI; - uint16_t ripplestate = _locked[storeI]; + uint16_t ripplestate = ripples[i].state; if (ripplestate) { uint8_t rippledecay = (SEGMENT.speed >> 4) +1; //faster decay if faster propagation - uint16_t rippleorigin = (_locked[storeI+1] << 8) + _locked[storeI+2]; - uint32_t col = color_from_palette(_locked[storeI+3], false, false, 255); + uint16_t rippleorigin = ripples[i].pos; + uint32_t col = color_from_palette(ripples[i].color, false, false, 255); uint16_t propagation = ((ripplestate/rippledecay -1) * SEGMENT.speed); int16_t propI = propagation >> 8; uint8_t propF = propagation & 0xFF; @@ -1973,7 +2103,7 @@ uint16_t WS2812FX::mode_ripple() for (int16_t v = left; v < left +4; v++) { uint8_t mag = scale8(cubicwave8((propF>>2)+(v-left)*64), amp); - if (v >= SEGMENT.start) + if (v < SEGMENT.stop && v >= SEGMENT.start) { setPixelColor(v, color_blend(getPixelColor(v), col, mag)); } @@ -1984,20 +2114,18 @@ uint16_t WS2812FX::mode_ripple() } } ripplestate += rippledecay; - _locked[storeI] = (ripplestate > 254) ? 0 : ripplestate; + ripples[i].state = (ripplestate > 254) ? 0 : ripplestate; } else //randomly create new wave { if (random16(IBN + 10000) <= SEGMENT.intensity) { - _locked[storeI] = 1; - uint16_t origin = SEGMENT.start + random16(SEGLEN); - _locked[storeI+1] = origin >> 8; - _locked[storeI+2] = origin & 0xFF; - _locked[storeI+3] = random8(); //color + ripples[i].state = 1; + ripples[i].pos = SEGMENT.start + random16(SEGLEN); + ripples[i].color = random8(); //color } } } - return 20; + return FRAMETIME; } @@ -2288,6 +2416,110 @@ uint16_t WS2812FX::mode_spots_fade() } +//each needs 12 bytes +//Spark type is used for popcorn and 1D fireworks +typedef struct Ball { + unsigned long lastBounceTime; + float impactVelocity; + float height; +} ball; + +/* +* Bouncing Balls Effect +*/ +uint16_t WS2812FX::mode_bouncing_balls(void) { + //allocate segment data + uint16_t maxNumBalls = 16; + uint16_t dataSize = sizeof(ball) * maxNumBalls; + if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed + + Ball* balls = reinterpret_cast(SEGENV.data); + + // number of balls based on intensity setting to max of 7 (cycles colors) + // non-chosen color is a random color + uint8_t numBalls = int(((SEGMENT.intensity * (maxNumBalls - 0.8f)) / 255) + 1); + + float gravity = -9.81; // standard value of gravity + float impactVelocityStart = sqrt( -2 * gravity); + + unsigned long time = millis(); + + if (SEGENV.call == 0) { + for (uint8_t i = 0; i < maxNumBalls; i++) balls[i].lastBounceTime = time; + } + + bool hasCol2 = SEGCOLOR(2); + fill(hasCol2 ? BLACK : SEGCOLOR(1)); + + for (uint8_t i = 0; i < numBalls; i++) { + float timeSinceLastBounce = (time - balls[i].lastBounceTime)/((255-SEGMENT.speed)*8/256 +1); + balls[i].height = 0.5 * gravity * pow(timeSinceLastBounce/1000 , 2.0) + balls[i].impactVelocity * timeSinceLastBounce/1000; + + if (balls[i].height < 0) { //start bounce + balls[i].height = 0; + //damping for better effect using multiple balls + float dampening = 0.90 - float(i)/pow(numBalls,2); + balls[i].impactVelocity = dampening * balls[i].impactVelocity; + balls[i].lastBounceTime = time; + + if (balls[i].impactVelocity < 0.015) { + balls[i].impactVelocity = impactVelocityStart; + } + } + + uint32_t color = SEGCOLOR(0); + if (SEGMENT.palette) { + color = color_wheel(i*(256/max(numBalls, 8))); + } else if (hasCol2) { + color = SEGCOLOR(i % NUM_COLORS); + } + + uint16_t pos = round(balls[i].height * (SEGLEN - 1)); + setPixelColor(SEGMENT.start + pos, color); + } + + return FRAMETIME; +} + + +/* +* Sinelon stolen from FASTLED examples +*/ +uint16_t WS2812FX::sinelon_base(bool dual, bool rainbow=false) { + fade_out(SEGMENT.intensity); + int pos = beatsin16(SEGMENT.speed/10,0,SEGLEN-1); + + uint32_t color1 = color_from_palette(pos, true, false, 0); + if (rainbow) { + color1 = color_wheel((pos & 0x07) * 32); + } + setPixelColor(SEGMENT.start + pos, color1); + + if (dual) { + uint32_t color2 = SEGCOLOR(2); + + if (!color2) color2 = color_from_palette(pos, true, false, 0); + if (rainbow) color2 = color1; //rainbow + + setPixelColor(SEGMENT.start + SEGLEN-1-pos, color2); + } + + return FRAMETIME; +} + +uint16_t WS2812FX::mode_sinelon(void) { + return sinelon_base(false); +} + +uint16_t WS2812FX::mode_sinelon_dual(void) { + return sinelon_base(true); +} + +uint16_t WS2812FX::mode_sinelon_rainbow(void) { + return sinelon_base(true, true); +} + + //Rainbow with glitter, inspired by https://gist.github.com/kriegsman/062e10f7f07ba8518af6 uint16_t WS2812FX::mode_glitter() { @@ -2302,6 +2534,72 @@ uint16_t WS2812FX::mode_glitter() } + +//each needs 12 bytes +//Spark type is used for popcorn and 1D fireworks +typedef struct Spark { + float pos; + float vel; + uint16_t col; + uint8_t colIndex; +} spark; + +/* +* POPCORN +* modified from https://github.com/kitesurfer1404/WS2812FX/blob/master/src/custom/Popcorn.h +*/ +uint16_t WS2812FX::mode_popcorn(void) { + //allocate segment data + uint16_t maxNumPopcorn = 24; + uint16_t dataSize = sizeof(spark) * maxNumPopcorn; + if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed + + Spark* popcorn = reinterpret_cast(SEGENV.data); + + float gravity = -0.0001 - (SEGMENT.speed/200000.0); // m/s/s + gravity *= SEGLEN; + + bool hasCol2 = SEGCOLOR(2); + fill(hasCol2 ? BLACK : SEGCOLOR(1)); + + uint8_t numPopcorn = SEGMENT.intensity*maxNumPopcorn/255; + if (numPopcorn == 0) numPopcorn = 1; + + for(uint8_t i = 0; i < numPopcorn; i++) { + bool isActive = popcorn[i].pos >= 0.0f; + + if(isActive) { // if kernel is active, update its position + popcorn[i].pos += popcorn[i].vel; + popcorn[i].vel += gravity; + uint32_t col = color_wheel(popcorn[i].colIndex); + if (!SEGMENT.palette && popcorn[i].colIndex < NUM_COLORS) col = SEGCOLOR(popcorn[i].colIndex); + + uint16_t ledIndex = SEGMENT.start + popcorn[i].pos; + if(ledIndex >= SEGMENT.start && ledIndex < SEGMENT.stop) setPixelColor(ledIndex, col); + } else { // if kernel is inactive, randomly pop it + if(random8() < 2) { // POP!!! + popcorn[i].pos = 0.01f; + + uint16_t peakHeight = 128 + random8(128); //0-255 + peakHeight = (peakHeight * (SEGLEN -1)) >> 8; + popcorn[i].vel = sqrt(-2.0 * gravity * peakHeight); + + if (SEGMENT.palette) + { + popcorn[i].colIndex = random8(); + } else { + byte col = random8(0, NUM_COLORS); + if (!hasCol2 || !SEGCOLOR(col)) col = 0; + popcorn[i].colIndex = col; + } + } + } + } + + return FRAMETIME; +} + + //values close to 100 produce 5Hz flicker, which looks very candle-y //Inspired by https://github.com/avanhanegem/ArduinoCandleEffectNeoPixel //and https://cpldcpu.wordpress.com/2016/01/05/reverse-engineering-a-real-candle/ @@ -2349,3 +2647,239 @@ uint16_t WS2812FX::mode_candle() return FRAMETIME; } + + +/* +/ Fireworks in starburst effect +/ based on the video: https://www.reddit.com/r/arduino/comments/c3sd46/i_made_this_fireworks_effect_for_my_led_strips/ +/ Speed sets frequency of new starbursts, intensity is the intensity of the burst +*/ +#define STARBURST_MAX_FRAG 12 + +//each needs 64 byte +typedef struct particle { + CRGB color; + uint32_t birth =0; + uint32_t last =0; + float vel =0; + uint16_t pos =-1; + float fragment[STARBURST_MAX_FRAG]; +} star; + +uint16_t WS2812FX::mode_starburst(void) { + uint8_t numStars = 1 + (SEGLEN >> 3); + if (numStars > 15) numStars = 15; + uint16_t dataSize = sizeof(star) * numStars; + + if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed + + uint32_t it = millis(); + + star* stars = reinterpret_cast(SEGENV.data); + + float maxSpeed = 375.0f; // Max velocity + float particleIgnition = 250.0f; // How long to "flash" + float particleFadeTime = 1500.0f; // Fade out time + + for (int j = 0; j < numStars; j++) + { + // speed to adjust chance of a burst, max is nearly always. + if (random8((144-(SEGMENT.speed >> 1))) == 0 && stars[j].birth == 0) + { + // Pick a random color and location. + uint16_t startPos = random16(SEGLEN-1); + float multiplier = (float)(random8())/255.0 * 1.0; + + stars[j].color = col_to_crgb(color_wheel(random8())); + stars[j].pos = startPos; + stars[j].vel = maxSpeed * (float)(random8())/255.0 * multiplier; + stars[j].birth = it; + stars[j].last = it; + // more fragments means larger burst effect + int num = random8(3,6 + (SEGMENT.intensity >> 5)); + + for (int i=0; i < STARBURST_MAX_FRAG; i++) { + if (i < num) stars[j].fragment[i] = startPos; + else stars[j].fragment[i] = -1; + } + } + } + + fill(SEGCOLOR(1)); + + for (int j=0; j> 1; + + if (stars[j].fragment[i] > 0) { + //all fragments travel right, will be mirrored on other side + stars[j].fragment[i] += stars[j].vel * dt * (float)var/3.0; + } + } + stars[j].last = it; + stars[j].vel -= 3*stars[j].vel*dt; + } + + CRGB c = stars[j].color; + + // If the star is brand new, it flashes white briefly. + // Otherwise it just fades over time. + float fade = 0.0f; + float age = it-stars[j].birth; + + if (age < particleIgnition) { + c = col_to_crgb(color_blend(WHITE, crgb_to_col(c), 254.5f*((age / particleIgnition)))); + } else { + // Figure out how much to fade and shrink the star based on + // its age relative to its lifetime + if (age > particleIgnition + particleFadeTime) { + fade = 1.0f; // Black hole, all faded out + stars[j].birth = 0; + c = col_to_crgb(SEGCOLOR(1)); + } else { + age -= particleIgnition; + fade = (age / particleFadeTime); // Fading star + byte f = 254.5f*fade; + c = col_to_crgb(color_blend(crgb_to_col(c), SEGCOLOR(1), f)); + } + } + + float particleSize = (1.0 - fade) * 2; + + for (uint8_t index=0; index < STARBURST_MAX_FRAG*2; index++) { + bool mirrored = index & 0x1; + uint8_t i = index >> 1; + if (stars[j].fragment[i] > 0) { + float loc = stars[j].fragment[i]; + if (mirrored) loc -= (loc-stars[j].pos)*2; + int start = loc - particleSize; + int end = loc + particleSize; + if (start < 0) start = 0; + if (start == end) end++; + if (end > SEGLEN) end = SEGLEN; + for (int p = start; p < end; p++) { + setPixelColor(SEGMENT.start+p, c.r, c.g, c.b); + } + } + } + } + return FRAMETIME; +} + + +/* + * Exploding fireworks effect + * adapted from: http://www.anirama.com/1000leds/1d-fireworks/ + */ + +uint16_t WS2812FX::mode_exploding_fireworks(void) +{ + //allocate segment data + uint16_t numSparks = 2 + (SEGLEN >> 1); + if (numSparks > 80) numSparks = 80; + uint16_t dataSize = sizeof(spark) * numSparks; + if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed + + fill(BLACK); + + bool actuallyReverse = SEGMENT.getOption(1); + //have fireworks start in either direction based on intensity + SEGMENT.setOption(1, SEGENV.step); + + Spark* sparks = reinterpret_cast(SEGENV.data); + Spark* flare = sparks; //first spark is flare data + + float gravity = -0.0004 - (SEGMENT.speed/800000.0); // m/s/s + gravity *= SEGLEN; + + if (SEGENV.aux0 < 2) { //FLARE + if (SEGENV.aux0 == 0) { //init flare + flare->pos = 0; + uint16_t peakHeight = 75 + random8(180); //0-255 + peakHeight = (peakHeight * (SEGLEN -1)) >> 8; + flare->vel = sqrt(-2.0 * gravity * peakHeight); + flare->col = 255; //brightness + + SEGENV.aux0 = 1; + } + + // launch + if (flare->vel > 12 * gravity) { + // flare + setPixelColor(SEGMENT.start + int(flare->pos),flare->col,flare->col,flare->col); + + flare->pos += flare->vel; + flare->pos = constrain(flare->pos, 0, SEGLEN-1); + flare->vel += gravity; + flare->col -= 2; + } else { + SEGENV.aux0 = 2; // ready to explode + } + } else if (SEGENV.aux0 < 4) { + /* + * Explode! + * + * Explosion happens where the flare ended. + * Size is proportional to the height. + */ + int nSparks = flare->pos; + nSparks = constrain(nSparks, 0, numSparks); + static float dying_gravity; + + // initialize sparks + if (SEGENV.aux0 == 2) { + for (int i = 1; i < nSparks; i++) { + sparks[i].pos = flare->pos; + sparks[i].vel = (float(random16(0, 20000)) / 10000.0) - 0.9; // from -0.9 to 1.1 + sparks[i].col = 345;//abs(sparks[i].vel * 750.0); // set colors before scaling velocity to keep them bright + //sparks[i].col = constrain(sparks[i].col, 0, 345); + sparks[i].colIndex = random8(); + sparks[i].vel *= flare->pos/SEGLEN; // proportional to height + sparks[i].vel *= -gravity *50; + } + //sparks[1].col = 345; // this will be our known spark + dying_gravity = gravity/2; + SEGENV.aux0 = 3; + } + + if (sparks[1].col > 4) {//&& sparks[1].pos > 0) { // as long as our known spark is lit, work with all the sparks + for (int i = 1; i < nSparks; i++) { + sparks[i].pos += sparks[i].vel; + sparks[i].vel += dying_gravity; + if (sparks[i].col > 3) sparks[i].col -= 4; + + if (sparks[i].pos > 0 && sparks[i].pos < SEGLEN) { + uint16_t prog = sparks[i].col; + uint32_t spColor = (SEGMENT.palette) ? color_wheel(sparks[i].colIndex) : SEGCOLOR(0); + CRGB c = CRGB::Black; //HeatColor(sparks[i].col); + if (prog > 300) { //fade from white to spark color + c = col_to_crgb(color_blend(spColor, WHITE, (prog - 300)*5)); + } else if (prog > 45) { //fade from spark color to black + c = col_to_crgb(color_blend(BLACK, spColor, prog - 45)); + uint8_t cooling = (300 - prog) >> 5; + c.g = qsub8(c.g, cooling); + c.b = qsub8(c.b, cooling * 2); + } + setPixelColor(SEGMENT.start + int(sparks[i].pos), c.red, c.green, c.blue); + } + } + dying_gravity *= .99; // as sparks burn out they fall slower + } else { + SEGENV.aux0 = 6 + random8(10); //wait for this many frames + } + } else { + SEGENV.aux0--; + if (SEGENV.aux0 < 4) { + SEGENV.aux0 = 0; //back to flare + SEGENV.step = (SEGMENT.intensity > random8()); //decide firing side + } + } + + SEGMENT.setOption(1, actuallyReverse); + + return FRAMETIME; +} diff --git a/wled00/FX.h b/wled00/FX.h index e877a055e9..fdbbfb5546 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -44,10 +44,17 @@ #define WLED_FPS 42 #define FRAMETIME (1000/WLED_FPS) -/* each segment uses 37 bytes of SRAM memory, so if you're application fails because of +/* each segment uses 52 bytes of SRAM memory, so if you're application fails because of insufficient memory, decreasing MAX_NUM_SEGMENTS may help */ #define MAX_NUM_SEGMENTS 10 +/* How much data bytes all segments combined may allocate */ +#ifdef ESP8266 +#define MAX_SEGMENT_DATA 2048 +#else +#define MAX_SEGMENT_DATA 8192 +#endif + #define NUM_COLORS 3 /* number of colors per segment */ #define SEGMENT _segments[_segment_index] #define SEGCOLOR(x) gamma32(_segments[_segment_index].colors[x]) @@ -84,7 +91,7 @@ #define IS_REVERSE ((SEGMENT.options & REVERSE ) == REVERSE ) #define IS_SELECTED ((SEGMENT.options & SELECTED) == SELECTED ) -#define MODE_COUNT 89 +#define MODE_COUNT 96 #define FX_MODE_STATIC 0 #define FX_MODE_BLINK 1 @@ -175,10 +182,20 @@ #define FX_MODE_SPOTS_FADE 86 #define FX_MODE_GLITTER 87 #define FX_MODE_CANDLE 88 +#define FX_MODE_STARBURST 89 +#define FX_MODE_EXPLODING_FIREWORKS 90 +#define FX_MODE_BOUNCINGBALLS 91 +#define FX_MODE_SINELON 92 +#define FX_MODE_SINELON_DUAL 93 +#define FX_MODE_SINELON_RAINBOW 94 +#define FX_MODE_POPCORN 95 class WS2812FX { typedef uint16_t (WS2812FX::*mode_ptr)(void); + + // pre show callback + typedef void (*show_callback) (void); // segment parameters public: @@ -221,13 +238,33 @@ class WS2812FX { } segment; // segment runtime parameters - typedef struct Segment_runtime { // 16 bytes + typedef struct Segment_runtime { // 28 bytes unsigned long next_time; uint32_t step; uint32_t call; uint16_t aux0; uint16_t aux1; - void reset(){next_time = 0; step = 0; call = 0; aux0 = 0; aux1 = 0;}; + byte* data = nullptr; + bool allocateData(uint16_t len){ + if (data && _dataLen == len) return true; //already allocated + deallocateData(); + if (WS2812FX::_usedSegmentData + len > MAX_SEGMENT_DATA) return false; //not enough memory + data = new (std::nothrow) byte[len]; + if (!data) return false; //allocation failed + WS2812FX::_usedSegmentData += len; + _dataLen = len; + memset(data, 0, len); + return true; + } + void deallocateData(){ + delete[] data; + data = nullptr; + WS2812FX::_usedSegmentData -= _dataLen; + _dataLen = 0; + } + void reset(){next_time = 0; step = 0; call = 0; aux0 = 0; aux1 = 0; deallocateData();} + private: + uint16_t _dataLen = 0; } segment_runtime; WS2812FX() { @@ -321,6 +358,13 @@ class WS2812FX { _mode[FX_MODE_SPOTS_FADE] = &WS2812FX::mode_spots_fade; _mode[FX_MODE_GLITTER] = &WS2812FX::mode_glitter; _mode[FX_MODE_CANDLE] = &WS2812FX::mode_candle; + _mode[FX_MODE_STARBURST] = &WS2812FX::mode_starburst; + _mode[FX_MODE_EXPLODING_FIREWORKS] = &WS2812FX::mode_exploding_fireworks; + _mode[FX_MODE_BOUNCINGBALLS] = &WS2812FX::mode_bouncing_balls; + _mode[FX_MODE_SINELON] = &WS2812FX::mode_sinelon; + _mode[FX_MODE_SINELON_DUAL] = &WS2812FX::mode_sinelon_dual; + _mode[FX_MODE_SINELON_RAINBOW] = &WS2812FX::mode_sinelon_rainbow; + _mode[FX_MODE_POPCORN] = &WS2812FX::mode_popcorn; _brightness = DEFAULT_BRIGHTNESS; currentPalette = CRGBPalette16(CRGB::Black); @@ -328,8 +372,6 @@ class WS2812FX { ablMilliampsMax = 850; currentMilliamps = 0; timebase = 0; - _locked = nullptr; - _modeUsesLock = false; bus = new NeoPixelWrapper(); resetSegments(); } @@ -346,13 +388,8 @@ class WS2812FX { driverModeCronixie(bool b), setCronixieDigits(byte* d), setCronixieBacklight(bool b), - setIndividual(uint16_t i, uint32_t col), setRange(uint16_t i, uint16_t i2, uint32_t col), - lock(uint16_t i), - lockRange(uint16_t i, uint16_t i2), - unlock(uint16_t i), - unlockRange(uint16_t i, uint16_t i2), - unlockAll(void), + setShowCallback(show_callback cb), setTransitionMode(bool t), trigger(void), setSegment(uint8_t n, uint16_t start, uint16_t stop), @@ -503,7 +540,14 @@ class WS2812FX { mode_spots(void), mode_spots_fade(void), mode_glitter(void), - mode_candle(void); + mode_candle(void), + mode_starburst(void), + mode_exploding_fireworks(void), + mode_bouncing_balls(void), + mode_sinelon(void), + mode_sinelon_dual(void), + mode_sinelon_rainbow(void), + mode_popcorn(void); private: @@ -518,24 +562,24 @@ class WS2812FX { uint16_t _length, _lengthRaw, _usableCount; uint16_t _rand16seed; uint8_t _brightness; + static uint16_t _usedSegmentData; void handle_palette(void); void fill(uint32_t); - bool modeUsesLock(uint8_t); bool - _modeUsesLock, _rgbwMode, _cronixieMode, _cronixieBacklightEnabled, _skipFirstMode, _triggered; - byte* _locked; byte _cronixieDigits[6]; mode_ptr _mode[MODE_COUNT]; // SRAM footprint: 4 bytes per element + show_callback _callback = nullptr; + // mode helper functions uint16_t blink(uint32_t, uint32_t, bool strobe, bool), @@ -543,6 +587,8 @@ class WS2812FX { scan(bool), theater_chase(uint32_t, uint32_t, bool), running_base(bool), + larson_scanner(bool), + sinelon_base(bool,bool), dissolve(uint32_t), chase(uint32_t, uint32_t, uint32_t, bool), gradient_base(bool), @@ -563,21 +609,23 @@ class WS2812FX { // start, stop, speed, intensity, palette, mode, options, 3 unused bytes (group, spacing, opacity), color[] { 0, 7, DEFAULT_SPEED, 128, 0, DEFAULT_MODE, NO_OPTIONS, 1, 0, 255, {DEFAULT_COLOR}} }; - segment_runtime _segment_runtimes[MAX_NUM_SEGMENTS]; // SRAM footprint: 16 bytes per element + segment_runtime _segment_runtimes[MAX_NUM_SEGMENTS]; // SRAM footprint: 28 bytes per element + friend class Segment_runtime; }; //10 names per line const char JSON_mode_names[] PROGMEM = R"=====([ "Solid","Blink","Breathe","Wipe","Wipe Random","Random Colors","Sweep","Dynamic","Colorloop","Rainbow", -"Scan","Dual Scan","Fade","Theater","Theater Rainbow","Running","Saw","Twinkle","Dissolve","Dissolve Rnd", +"Scan","Scan Dual","Fade","Theater","Theater Rainbow","Running","Saw","Twinkle","Dissolve","Dissolve Rnd", "Sparkle","Sparkle Dark","Sparkle+","Strobe","Strobe Rainbow","Strobe Mega","Blink Rainbow","Android","Chase","Chase Random", "Chase Rainbow","Chase Flash","Chase Flash Rnd","Rainbow Runner","Colorful","Traffic Light","Sweep Random","Running 2","Red & Blue","Stream", "Scanner","Lighthouse","Fireworks","Rain","Merry Christmas","Fire Flicker","Gradient","Loading","Police","Police All", "Two Dots","Two Areas","Circus","Halloween","Tri Chase","Tri Wipe","Tri Fade","Lightning","ICU","Multi Comet", -"Scanner Dual ","Stream 2","Oscillate","Pride 2015","Juggle","Palette","Fire 2012","Colorwaves","Bpm","Fill Noise", +"Scanner Dual","Stream 2","Oscillate","Pride 2015","Juggle","Palette","Fire 2012","Colorwaves","Bpm","Fill Noise", "Noise 1","Noise 2","Noise 3","Noise 4","Colortwinkles","Lake","Meteor","Meteor Smooth","Railway","Ripple", -"Twinklefox","Twinklecat","Halloween Eyes","Solid Pattern","Solid Pattern Tri","Spots","Spots Fade","Glitter","Candle" +"Twinklefox","Twinklecat","Halloween Eyes","Solid Pattern","Solid Pattern Tri","Spots","Spots Fade","Glitter","Candle","Fireworks Starburst", +"Fireworks 1D","Bouncing Balls","Sinelon","Sinelon Dual","Sinelon Rainbow","Popcorn" ])====="; diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index 2b7d6ec1da..3081c2be5c 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -32,7 +32,7 @@ void WS2812FX::init(bool supportWhite, uint16_t countPixels, bool skipFirst, uint8_t disableNLeds) { - if (supportWhite == _rgbwMode && countPixels == _length && _locked != NULL && disableNLeds == _disableNLeds) return; + if (supportWhite == _rgbwMode && countPixels == _length && disableNLeds == _disableNLeds) return; RESET_RUNTIME; _rgbwMode = supportWhite; _skipFirstMode = skipFirst; @@ -59,13 +59,9 @@ void WS2812FX::init(bool supportWhite, uint16_t countPixels, bool skipFirst, uin bus->Begin((NeoPixelType)ty, _lengthRaw); - delete[] _locked; - _locked = new byte[_length]; - _segments[0].start = 0; _segments[0].stop = _usableCount; - - unlockAll(); + setBrightness(_brightness); } @@ -96,14 +92,6 @@ void WS2812FX::service() { _triggered = false; } -bool WS2812FX::modeUsesLock(uint8_t m) -{ - if (m == FX_MODE_FIRE_2012 || m == FX_MODE_COLORTWINKLE || - m == FX_MODE_METEOR || m == FX_MODE_METEOR_SMOOTH || - m == FX_MODE_RIPPLE || m == FX_MODE_DYNAMIC ) return true; - return false; -} - void WS2812FX::setPixelColor(uint16_t n, uint32_t c) { uint8_t w = (c >> 24); uint8_t r = (c >> 16); @@ -115,7 +103,6 @@ void WS2812FX::setPixelColor(uint16_t n, uint32_t c) { void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w) { i = i * (_disableNLeds+1); - if (_locked[i] && !_modeUsesLock) return; if (IS_REVERSE) i = SEGMENT.stop -1 -i + SEGMENT.start; //reverse just individual segment byte tmpg = g; switch (colorOrder) //0 = Grb, default @@ -208,6 +195,8 @@ void WS2812FX::setCronixieDigits(byte d[]) //you can set it to 0 if the ESP is powered by USB and the LEDs by external void WS2812FX::show(void) { + if (_callback) _callback(); + //power limit calculation //each LED can draw up 195075 "power units" (approx. 53mA) //one PU is the power it takes to have 1 channel 1 step brighter per brightness step @@ -273,7 +262,6 @@ void WS2812FX::trigger() { void WS2812FX::setMode(uint8_t segid, uint8_t m) { if (segid >= MAX_NUM_SEGMENTS) return; - bool anyUsedLock = _modeUsesLock, anyUseLock = false; if (m >= MODE_COUNT) m = MODE_COUNT - 1; if (_segments[segid].mode != m) @@ -281,13 +269,6 @@ void WS2812FX::setMode(uint8_t segid, uint8_t m) { _segment_runtimes[segid].reset(); _segments[segid].mode = m; } - - for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++) - { - if (modeUsesLock(_segments[i].mode)) anyUseLock = true; - } - if (anyUsedLock && !anyUseLock) unlockAll(); - _modeUsesLock = anyUseLock; } uint8_t WS2812FX::getModeCount() @@ -454,12 +435,7 @@ void WS2812FX::setSegment(uint8_t n, uint16_t i1, uint16_t i2) { if (n >= MAX_NUM_SEGMENTS) return; Segment& seg = _segments[n]; if (seg.start == i1 && seg.stop == i2) return; - if (seg.isActive() && modeUsesLock(seg.mode)) - { - _modeUsesLock = false; - unlockRange(seg.start, seg.stop); - _modeUsesLock = true; - } + _segment_index = n; fill(0); //turn old segment range off if (i2 <= i1) //disable segment { @@ -473,7 +449,7 @@ void WS2812FX::setSegment(uint8_t n, uint16_t i1, uint16_t i2) { void WS2812FX::resetSegments() { memset(_segments, 0, sizeof(_segments)); - memset(_segment_runtimes, 0, sizeof(_segment_runtimes)); + //memset(_segment_runtimes, 0, sizeof(_segment_runtimes)); _segment_index = 0; _segments[0].mode = DEFAULT_MODE; _segments[0].colors[0] = DEFAULT_COLOR; @@ -484,64 +460,25 @@ void WS2812FX::resetSegments() { for (uint16_t i = 1; i < MAX_NUM_SEGMENTS; i++) { _segments[i].colors[0] = color_wheel(i*51); + _segment_runtimes[i].reset(); } -} - -void WS2812FX::setIndividual(uint16_t i, uint32_t col) -{ - if (modeUsesLock(SEGMENT.mode)) return; - if (i >= 0 && i < _length) - { - _locked[i] = false; - setPixelColor(i, col); - _locked[i] = true; - } + _segment_runtimes[0].reset(); } void WS2812FX::setRange(uint16_t i, uint16_t i2, uint32_t col) { if (i2 >= i) { - for (uint16_t x = i; x <= i2; x++) setIndividual(x,col); + for (uint16_t x = i; x <= i2; x++) setPixelColor(x, col); } else { - for (uint16_t x = i2; x <= i; x++) setIndividual(x,col); - } -} - -void WS2812FX::lock(uint16_t i) -{ - if (_modeUsesLock) return; - if (i < _length) _locked[i] = true; -} - -void WS2812FX::lockRange(uint16_t i, uint16_t i2) -{ - if (_modeUsesLock) return; - for (uint16_t x = i; x < i2; x++) - { - if (x < _length) _locked[i] = true; + for (uint16_t x = i2; x <= i; x++) setPixelColor(x, col); } } -void WS2812FX::unlock(uint16_t i) +void WS2812FX::setShowCallback(show_callback cb) { - if (_modeUsesLock) return; - if (i < _length) _locked[i] = false; -} - -void WS2812FX::unlockRange(uint16_t i, uint16_t i2) -{ - if (_modeUsesLock) return; - for (uint16_t x = i; x < i2; x++) - { - if (x < _length) _locked[x] = false; - } -} - -void WS2812FX::unlockAll() -{ - for (int i=0; i < _length; i++) _locked[i] = false; + _callback = cb; } void WS2812FX::setTransitionMode(bool t) @@ -862,3 +799,5 @@ uint32_t WS2812FX::gamma32(uint32_t color) b = gammaT[b]; return ((w << 24) | (r << 16) | (g << 8) | (b)); } + +uint16_t WS2812FX::_usedSegmentData = 0; diff --git a/wled00/NpbWrapper.h b/wled00/NpbWrapper.h index 1f595df71b..463f429ec3 100644 --- a/wled00/NpbWrapper.h +++ b/wled00/NpbWrapper.h @@ -5,21 +5,18 @@ //PIN CONFIGURATION #define LEDPIN 2 //strip pin. Any for ESP32, gpio2 or 3 is recommended for ESP8266 (gpio2/3 are labeled D4/RX on NodeMCU and Wemos) //#define USE_APA102 // Uncomment for using APA102 LEDs. -#ifdef WLED_USE_H801 - #define BTNPIN -1 //button pin. Needs to have pullup (gpio0 recommended) - #define IR_PIN 0 //infrared pin (-1 to disable) MagicHome: 4, H801 Wifi: 0 -#else - #define BTNPIN 0 //button pin. Needs to have pullup (gpio0 recommended) - #define IR_PIN 4 //infrared pin (-1 to disable) MagicHome: 4, H801 Wifi: 0 -#endif -#ifdef WLED_USE_ANALOG_LEDS - #define RLYPIN -1 //disable RLYPIN as it will be used for the RGB-PINs -#else - #define RLYPIN 12 //pin for relay, will be set HIGH if LEDs are on (-1 to disable). Also usable for standby leds, triggers,... -#endif -#define AUXPIN -1 //debug auxiliary output pin (-1 to disable) +//#define WLED_USE_ANALOG_LEDS //Uncomment for using "dumb" PWM controlled LEDs (see pins below, default R: gpio5, G: 12, B: 15, W: 13) +//#define WLED_USE_H801 //H801 controller. Please uncomment #define WLED_USE_ANALOG_LEDS as well +//#define WLED_USE_5CH //5 Channel H801 for cold and warm white + +#define BTNPIN 0 //button pin. Needs to have pullup (gpio0 recommended) +#define IR_PIN 4 //infrared pin (-1 to disable) MagicHome: 4, H801 Wifi: 0 +#define RLYPIN 12 //pin for relay, will be set HIGH if LEDs are on (-1 to disable). Also usable for standby leds, triggers,... +#define AUXPIN -1 //debug auxiliary output pin (-1 to disable) -#define RLYMDE 1 //mode for relay, 0: LOW if LEDs are on 1: HIGH if LEDs are on +#define RLYMDE 1 //mode for relay, 0: LOW if LEDs are on 1: HIGH if LEDs are on + +//END CONFIGURATION #ifdef USE_APA102 #define CLKPIN 0 @@ -36,14 +33,19 @@ #define GPIN 13 //G pin for analog LED strip #define BPIN 12 //B pin for analog LED strip #define WPIN 14 //W pin for analog LED strip (W1: 14, W2: 04) - #define W2PIN 04 //W2 pin for analog LED strip + #define W2PIN 04 //W2 pin for analog LED strip + #undef BTNPIN + #undef IR_PIN + #define IR_PIN 0 //infrared pin (-1 to disable) MagicHome: 4, H801 Wifi: 0 #else - //PWM pins - PINs 12,5,13,15 are used with Magic Home LED Controller - #define GPIN 12 //G pin for analog LED strip + //PWM pins - PINs 5,12,13,15 are used with Magic Home LED Controller #define RPIN 5 //R pin for analog LED strip - #define WPIN 13 //W pin for analog LED strip + #define GPIN 12 //G pin for analog LED strip #define BPIN 15 //B pin for analog LED strip + #define WPIN 13 //W pin for analog LED strip (W1: 14, W2: 04) #endif + #undef RLYPIN + #define RLYPIN -1 //disable as pin 12 is used by analog LEDs #endif //automatically uses the right driver method for each platform @@ -129,41 +131,71 @@ class NeoPixelWrapper #endif _pGrbw->Begin(); break; - - #ifdef WLED_USE_ANALOG_LEDS - //init PWM pins - PINs 5,12,13,15 are used with Magic Home LED Controller - pinMode(RPIN, OUTPUT); - pinMode(GPIN, OUTPUT); - pinMode(BPIN, OUTPUT); - switch (_type) { - case NeoPixelType_Grb: break; - #ifdef WLED_USE_5CH_LEDS - case NeoPixelType_Grbw: pinMode(WPIN, OUTPUT); pinMode(W2PIN, OUTPUT); break; - #else - case NeoPixelType_Grbw: pinMode(WPIN, OUTPUT); break; - #endif - } - analogWriteRange(255); //same range as one RGB channel - analogWriteFreq(880); //PWM frequency proven as good for LEDs - #endif - } + + #ifdef WLED_USE_ANALOG_LEDS + #ifdef ARDUINO_ARCH_ESP32 + ledcSetup(0, 5000, 8); + ledcAttachPin(RPIN, 0); + ledcSetup(1, 5000, 8); + ledcAttachPin(GPIN, 1); + ledcSetup(2, 5000, 8); + ledcAttachPin(BPIN, 2); + if(_type == NeoPixelType_Grbw) + { + ledcSetup(3, 5000, 8); + ledcAttachPin(WPIN, 3); + #ifdef WLED_USE_5CH_LEDS + ledcSetup(4, 5000, 8); + ledcAttachPin(W2PIN, 4); + #endif + } + #else // ESP8266 + //init PWM pins - PINs 5,12,13,15 are used with Magic Home LED Controller + pinMode(RPIN, OUTPUT); + pinMode(GPIN, OUTPUT); + pinMode(BPIN, OUTPUT); + if(_type == NeoPixelType_Grbw) + { + pinMode(WPIN, OUTPUT); + #ifdef WLED_USE_5CH_LEDS + pinMode(W2PIN, OUTPUT); + #endif + } + analogWriteRange(255); //same range as one RGB channel + analogWriteFreq(880); //PWM frequency proven as good for LEDs + #endif + #endif } #ifdef WLED_USE_ANALOG_LEDS void SetRgbwPwm(uint8_t r, uint8_t g, uint8_t b, uint8_t w, uint8_t w2=0) { - analogWrite(RPIN, r); - analogWrite(GPIN, g); - analogWrite(BPIN, b); - switch (_type) { - case NeoPixelType_Grb: break; - #ifdef WLED_USE_5CH_LEDS - case NeoPixelType_Grbw: analogWrite(WPIN, w); analogWrite(W2PIN, w2); break; - #else - case NeoPixelType_Grbw: analogWrite(WPIN, w); break; - #endif - } + #ifdef ARDUINO_ARCH_ESP32 + ledcWrite(0, r); //RPIN + ledcWrite(1, g); //GPIN + ledcWrite(2, b); //BPIN + switch (_type) { + case NeoPixelType_Grb: break; + #ifdef WLED_USE_5CH_LEDS + case NeoPixelType_Grbw: ledcWrite(3, w); ledcWrite(4, w2); break; + #else + case NeoPixelType_Grbw: ledcWrite(3, w); break; + #endif + } + #else + analogWrite(RPIN, r); + analogWrite(GPIN, g); + analogWrite(BPIN, b); + switch (_type) { + case NeoPixelType_Grb: break; + #ifdef WLED_USE_5CH_LEDS + case NeoPixelType_Grbw: analogWrite(WPIN, w); analogWrite(W2PIN, w2); break; + #else + case NeoPixelType_Grbw: analogWrite(WPIN, w); break; + #endif + } + #endif } #endif @@ -172,66 +204,51 @@ class NeoPixelWrapper byte b; switch (_type) { + case NeoPixelType_Grb: _pGrb->Show(); break; + case NeoPixelType_Grbw: _pGrbw->Show(); break; + } + } + + void SetPixelColor(uint16_t indexPixel, RgbwColor color) + { + switch (_type) { case NeoPixelType_Grb: { - _pGrb->Show(); - #ifdef WLED_USE_ANALOG_LEDS - RgbColor color = _pGrb->GetPixelColor(0); - b = _pGrb->GetBrightness(); + _pGrb->SetPixelColor(indexPixel, RgbColor(color.R,color.G,color.B)); + #ifdef WLED_USE_ANALOG_LEDS + if (indexPixel != 0) return; //set analog LEDs from first pixel + byte b = _pGrb->GetBrightness(); SetRgbwPwm(color.R * b / 255, color.G * b / 255, color.B * b / 255, 0); #endif } break; case NeoPixelType_Grbw: { - _pGrbw->Show(); + _pGrbw->SetPixelColor(indexPixel, color); #ifdef WLED_USE_ANALOG_LEDS - RgbwColor colorW = _pGrbw->GetPixelColor(0); - b = _pGrbw->GetBrightness(); - // check color values for Warm / COld white mix (for RGBW) // EsplanexaDevice.cpp + if (indexPixel != 0) return; //set analog LEDs from first pixel + byte b = _pGrbw->GetBrightness(); + // check color values for Warm / Cold white mix (for RGBW) // EsplanexaDevice.cpp #ifdef WLED_USE_5CH_LEDS - if (colorW.R == 255 & colorW.G == 255 && colorW.B == 255 && colorW.W == 255) { - SetRgbwPwm(0, 0, 0, 0, colorW.W * b / 255); - } else if (colorW.R == 127 & colorW.G == 127 && colorW.B == 127 && colorW.W == 255) { - SetRgbwPwm(0, 0, 0, colorW.W * b / 512, colorW.W * b / 255); - } else if (colorW.R == 0 & colorW.G == 0 && colorW.B == 0 && colorW.W == 255) { - SetRgbwPwm(0, 0, 0, colorW.W * b / 255, 0); - } else if (colorW.R == 130 & colorW.G == 90 && colorW.B == 0 && colorW.W == 255) { - SetRgbwPwm(0, 0, 0, colorW.W * b / 255, colorW.W * b / 512); - } else if (colorW.R == 255 & colorW.G == 153 && colorW.B == 0 && colorW.W == 255) { - SetRgbwPwm(0, 0, 0, colorW.W * b / 255, 0); + if (color.R == 255 & color.G == 255 && color.B == 255 && color.W == 255) { + SetRgbwPwm(0, 0, 0, 0, color.W * b / 255); + } else if (color.R == 127 & color.G == 127 && color.B == 127 && color.W == 255) { + SetRgbwPwm(0, 0, 0, color.W * b / 512, colorW.W * b / 255); + } else if (color.R == 0 & color.G == 0 && color.B == 0 && color.W == 255) { + SetRgbwPwm(0, 0, 0, color.W * b / 255, 0); + } else if (color.R == 130 & color.G == 90 && color.B == 0 && color.W == 255) { + 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) { + SetRgbwPwm(0, 0, 0, color.W * b / 255, 0); } else { // not only white colors - SetRgbwPwm(colorW.R * b / 255, colorW.G * b / 255, colorW.B * b / 255, colorW.W * b / 255); + SetRgbwPwm(color.R * b / 255, colorW.G * b / 255, colorW.B * b / 255, color.W * b / 255); } #else - SetRgbwPwm(colorW.R * b / 255, colorW.G * b / 255, colorW.B * b / 255, colorW.W * b / 255); + SetRgbwPwm(color.R * b / 255, color.G * b / 255, color.B * b / 255, color.W * b / 255); #endif #endif } break; } - } - - bool CanShow() const - { - switch (_type) { - case NeoPixelType_Grb: _pGrb->CanShow(); break; - case NeoPixelType_Grbw: _pGrbw->CanShow(); break; - } - } - - void SetPixelColor(uint16_t indexPixel, RgbColor color) - { - switch (_type) { - case NeoPixelType_Grb: _pGrb->SetPixelColor(indexPixel, color); break; - case NeoPixelType_Grbw:_pGrbw->SetPixelColor(indexPixel, color); break; - } - } - - void SetPixelColor(uint16_t indexPixel, RgbwColor color) - { - switch (_type) { - case NeoPixelType_Grb: _pGrb->SetPixelColor(indexPixel, RgbColor(color.R,color.G,color.B)); break; - case NeoPixelType_Grbw: _pGrbw->SetPixelColor(indexPixel, color); break; - } + } void SetBrightness(byte b) @@ -242,15 +259,6 @@ class NeoPixelWrapper } } - RgbColor GetPixelColor(uint16_t indexPixel) const - { - switch (_type) { - case NeoPixelType_Grb: return _pGrb->GetPixelColor(indexPixel); break; - case NeoPixelType_Grbw: /*doesn't support it so we don't return it*/ break; - } - return 0; - } - // 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 @@ -262,21 +270,6 @@ class NeoPixelWrapper return 0; } - void ClearTo(RgbColor color) - { - switch (_type) { - case NeoPixelType_Grb: _pGrb->ClearTo(color); break; - case NeoPixelType_Grbw:_pGrbw->ClearTo(color); break; - } - } - - void ClearTo(RgbwColor color) - { - switch (_type) { - case NeoPixelType_Grb: break; - case NeoPixelType_Grbw:_pGrbw->ClearTo(color); break; - } - } private: NeoPixelType _type; diff --git a/wled00/html_settings.h b/wled00/html_settings.h index 3030dc8cc3..32d6bf4ec0 100644 --- a/wled00/html_settings.h +++ b/wled00/html_settings.h @@ -281,6 +281,7 @@ Time zone: +
UTC offset: seconds (max. 18 hours)
Current local time is unknown. @@ -367,10 +368,10 @@ HTTP traffic is unencrypted. An attacker in the same network can intercept form
Enable ArduinoOTA:

About

-WLED version 0.9.0-b1

+WLED version 0.9.0-b2

Contributors, dependencies and special thanks
A huge thank you to everyone who helped me create WLED!

-(c) 2016-2019 Christian Schwinne
+(c) 2016-2020 Christian Schwinne
Licensed under the MIT license

Server message: Response error!
diff --git a/wled00/ir_codes.h b/wled00/ir_codes.h index 3bd056028c..dda33e7b7a 100644 --- a/wled00/ir_codes.h +++ b/wled00/ir_codes.h @@ -170,25 +170,29 @@ #define IR44_FADE3 0xFF609F // #define IR44_FADE7 0xFFE01F // -// Color definitions -#define COLOR_RED 0xFF0000 -#define COLOR_REDDISH 0xFF7800 -#define COLOR_ORANGE 0xFFA000 -#define COLOR_YELLOWISH 0xFFC800 -#define COLOR_YELLOW 0xFFFF00 -#define COLOR_GREEN 0x00FF00 -#define COLOR_GREENISH 0x00FF78 -#define COLOR_TURQUOISE 0x00FFA0 -#define COLOR_CYAN 0x00FFDC -#define COLOR_AQUA 0x00C8FF -#define COLOR_BLUE 0x00A0FF -#define COLOR_DEEPBLUE 0x0000FF -#define COLOR_PURPLE 0xAA00FF -#define COLOR_MAGENTA 0xFF00DC -#define COLOR_PINK 0xFF00A0 -#define COLOR_WHITE 0xFFFFDC -#define COLOR_WARMWHITE2 0xFFFF9900 -#define COLOR_WARMWHITE 0xFF825A00 -#define COLOR_NEUTRALWHITE 0xFF000000 -#define COLOR_COLDWHITE 0xFF7F7F7F -#define COLOR_COLDWHITE2 0xFFFFFFFF \ No newline at end of file +#define COLOR_RED 0xFF0000 +#define COLOR_REDDISH 0xFF7800 +#define COLOR_ORANGE 0xFFA000 +#define COLOR_YELLOWISH 0xFFC800 +#define COLOR_YELLOW 0xFFFF00 +#define COLOR_GREEN 0x00FF00 +#define COLOR_GREENISH 0x00FF78 +#define COLOR_TURQUOISE 0x00FFA0 +#define COLOR_CYAN 0x00FFDC +#define COLOR_AQUA 0x00C8FF +#define COLOR_BLUE 0x00A0FF +#define COLOR_DEEPBLUE 0x0000FF +#define COLOR_PURPLE 0xAA00FF +#define COLOR_MAGENTA 0xFF00DC +#define COLOR_PINK 0xFF00A0 +#define COLOR_WHITE 0xFFFFDC +#define COLOR_WARMWHITE2 0xFFAA69 +#define COLOR_WARMWHITE 0xFFBF8E +#define COLOR_NEUTRALWHITE 0xFFD4B4 +#define COLOR_COLDWHITE 0xFFE9D9 +#define COLOR_COLDWHITE2 0xFFFFFF +#define COLOR2_WARMWHITE2 0xFFFF9900 +#define COLOR2_WARMWHITE 0xFF825A00 +#define COLOR2_NEUTRALWHITE 0xFF000000 +#define COLOR2_COLDWHITE 0xFF7F7F7F +#define COLOR2_COLDWHITE2 0xFFFFFFFF diff --git a/wled00/src/dependencies/espalexa/Espalexa.h b/wled00/src/dependencies/espalexa/Espalexa.h index 0c817dcf8f..49c9b6a9a5 100644 --- a/wled00/src/dependencies/espalexa/Espalexa.h +++ b/wled00/src/dependencies/espalexa/Espalexa.h @@ -10,7 +10,7 @@ */ /* * @title Espalexa library - * @version 2.4.3 + * @version 2.4.4 * @author Christian Schwinne * @license MIT * @contributors d-999 @@ -49,7 +49,7 @@ #include #ifdef ESPALEXA_DEBUG - #pragma message "Espalexa 2.4.3 debug mode" + #pragma message "Espalexa 2.4.4 debug mode" #define EA_DEBUG(x) Serial.print (x) #define EA_DEBUGLN(x) Serial.println (x) #else @@ -164,7 +164,7 @@ class Espalexa { json += "\",\"modelid\":\"" + modelidString(dev->getType()); json += "\",\"manufacturername\":\"Philips\",\"productname\":\"E" + String(static_cast(dev->getType())); json += "\",\"uniqueid\":\"" + String(encodeLightId(deviceId+1)); - json += "\",\"swversion\":\"espalexa-2.4.3\"}"; + json += "\",\"swversion\":\"espalexa-2.4.4\"}"; return json; } @@ -188,7 +188,7 @@ class Espalexa { } res += "\r\nFree Heap: " + (String)ESP.getFreeHeap(); res += "\r\nUptime: " + (String)millis(); - res += "\r\n\r\nEspalexa library v2.4.3 by Christian Schwinne 2019"; + res += "\r\n\r\nEspalexa library v2.4.4 by Christian Schwinne 2020"; server->send(200, "text/plain", res); } #endif @@ -298,7 +298,7 @@ class Espalexa { "SERVER: FreeRTOS/6.0.5, UPnP/1.0, IpBridge/1.17.0\r\n" // _modelName, _modelNumber "hue-bridgeid: "+ escapedMac +"\r\n" "ST: urn:schemas-upnp-org:device:basic:1\r\n" // _deviceType - "USN: uuid:2f402f80-da50-11e1-9b23-"+ escapedMac +"::upnp:rootdevice\r\n" // _uuid::_deviceType + "USN: uuid:2f402f80-da50-11e1-9b23-"+ escapedMac +"::ssdp:all\r\n" // _uuid::_deviceType "\r\n"; espalexaUdp.beginPacket(espalexaUdp.remoteIP(), espalexaUdp.remotePort()); @@ -372,7 +372,7 @@ class Espalexa { String request = packetBuffer; if(request.indexOf("M-SEARCH") >= 0) { EA_DEBUGLN(request); - if(request.indexOf("upnp:rootdevice") > 0 || request.indexOf("asic:1") > 0) { + if(request.indexOf("upnp:rootdevice") > 0 || request.indexOf("asic:1") > 0 || request.indexOf("ssdp:all") > 0) { EA_DEBUGLN("Responding search req..."); respondToSearch(); } @@ -584,4 +584,4 @@ class Espalexa { ~Espalexa(){delete devices;} //note: Espalexa is NOT meant to be destructed }; -#endif \ No newline at end of file +#endif diff --git a/wled00/src/dependencies/espalexa/EspalexaDevice.cpp b/wled00/src/dependencies/espalexa/EspalexaDevice.cpp index de525fa675..25d70bb0bb 100644 --- a/wled00/src/dependencies/espalexa/EspalexaDevice.cpp +++ b/wled00/src/dependencies/espalexa/EspalexaDevice.cpp @@ -95,18 +95,6 @@ float EspalexaDevice::getY() return _y; } -float EspalexaDevice::minf (float v, float w) -{ - if (w > v) return v; - return w; -} - -float EspalexaDevice::maxf (float v, float w) -{ - if (w > v) return w; - return v; -} - uint16_t EspalexaDevice::getCt() { if (_ct == 0) return 500; @@ -134,7 +122,7 @@ uint32_t EspalexaDevice::getRGB() float temp = 10000/ _ct; //kelvins = 1,000,000/mired (and that /100) float r, g, b; - // Cold white to warm white receiving from Alexa: _ct = 199 234 284 350 383 +// Cold white to warm white receiving from Alexa: _ct = 199, 234, 284, 350, 383 (from cold white to warm white) switch (_ct) { case 199: rgb[0]=255,rgb[1]=255,rgb[2]=255;rgb[3]=255;break; case 234: rgb[0]=127,rgb[1]=127,rgb[2]=127;rgb[3]=255;break; @@ -159,11 +147,10 @@ uint32_t EspalexaDevice::getRGB() g = 288.12217 * pow(g, -0.07551485 ); b = 255; } - + rgb[0] = (byte)constrain(r,0.1,255.1); rgb[1] = (byte)constrain(g,0.1,255.1); rgb[2] = (byte)constrain(b,0.1,255.1); - RGBtoRGBW(rgb); } } } else if (_mode == EspalexaColorMode::hs) @@ -183,7 +170,6 @@ uint32_t EspalexaDevice::getRGB() case 4: rgb[0]=t,rgb[1]=p,rgb[2]=255;break; case 5: rgb[0]=255,rgb[1]=p,rgb[2]=q; } - RGBtoRGBW(rgb); } else if (_mode == EspalexaColorMode::xy) { //Source: https://www.developers.meethue.com/documentation/color-conversions-rgb-xy @@ -239,12 +225,12 @@ uint32_t EspalexaDevice::getRGB() rgb[0] = 255.0*r; rgb[1] = 255.0*g; rgb[2] = 255.0*b; - RGBtoRGBW(rgb); } - _rgb = ((rgb[3] << 24) | (rgb[0] << 16) | (rgb[1] << 8) | (rgb[2])); + _rgb = ((rgb[3] << 24) | (rgb[0] << 16) | (rgb[1] << 8) | (rgb[2])); //white value is only >0 if Alexa did provide a CT value, RGB colors will not be touched. return _rgb; } +//white channel for RGBW lights. Always 0 unless colormode is ct uint8_t EspalexaDevice::getW() { return (getRGB() >> 24) & 0xFF; @@ -342,38 +328,6 @@ void EspalexaDevice::setColor(uint8_t r, uint8_t g, uint8_t b) _mode = EspalexaColorMode::xy; } -void EspalexaDevice::RGBtoRGBW(byte* rgb) //rgb to rgbw (http://codewelt.com/rgbw) -{ - // https://stackoverflow.com/questions/40312216/converting-rgb-to-rgbw - float Ri=rgb[0], Gi=rgb[1], Bi=rgb[2]; - //Get the maximum between R, G, and B - float tM = maxf(Ri, maxf(Gi, Bi)); - - //If the maximum value is 0, immediately return pure black. - if(tM == 0) rgb[3] = 0; - else - { - //This section serves to figure out what the color with 100% hue is - float multiplier = 255.0f / tM; - float hR = Ri * multiplier; - float hG = Gi * multiplier; - float hB = Bi * multiplier; - - //This calculates the Whiteness (not strictly speaking Luminance) of the color - float M = maxf(hR, maxf(hG, hB)); - float m = minf(hR, minf(hG, hB)); - float Luminance = ((M + m) / 2.0f - 127.5f) * (255.0f/127.5f) / multiplier; - - //Calculate and trim the output values - int Wo = (byte)constrain(Luminance,0.1,255.1); - int Bo = (byte)constrain(Bi - Luminance,0.1,255.1); - int Ro = (byte)constrain(Ri - Luminance,0.1,255.1); - int Go = (byte)constrain(Gi - Luminance,0.1,255.1); - - rgb[0]=Ro; rgb[1]=Go; rgb[2]=Bo; rgb[3]=Wo; - } -} - void EspalexaDevice::doCallback() { if (_callback != nullptr) {_callback(_val); return;} diff --git a/wled00/src/dependencies/espalexa/EspalexaDevice.h b/wled00/src/dependencies/espalexa/EspalexaDevice.h index e9f597023a..a66449165f 100644 --- a/wled00/src/dependencies/espalexa/EspalexaDevice.h +++ b/wled00/src/dependencies/espalexa/EspalexaDevice.h @@ -47,13 +47,11 @@ class EspalexaDevice { uint32_t getKelvin(); float getX(); float getY(); - float minf (float v, float w); - float maxf (float v, float w); uint32_t getRGB(); - uint8_t getW(); uint8_t getR(); uint8_t getG(); uint8_t getB(); + uint8_t getW(); EspalexaColorMode getColorMode(); EspalexaDeviceType getType(); @@ -66,7 +64,6 @@ class EspalexaDevice { void setColor(uint16_t hue, uint8_t sat); void setColorXY(float x, float y); void setColor(uint8_t r, uint8_t g, uint8_t b); - void RGBtoRGBW(byte* rgb); void doCallback(); diff --git a/wled00/wled00.ino b/wled00/wled00.ino index dfbc8f1ace..7d5c7ad23e 100644 --- a/wled00/wled00.ino +++ b/wled00/wled00.ino @@ -3,7 +3,7 @@ */ /* * @title WLED project sketch - * @version 0.9.0-b1 + * @version 0.9.0-b2 * @author Christian Schwinne */ @@ -32,12 +32,6 @@ //to toggle usb serial debug (un)comment the following line //#define WLED_DEBUG -//to toggle using analog RGB or RGBW led strips (un)comment the following line -//#define WLED_USE_ANALOG_LEDS - -//to toggle using 5CH analog RGBWS led strips (un)comment the following line -//#define WLED_USE_5CH_LEDS - //library inclusions #include #ifdef ESP8266 @@ -89,23 +83,15 @@ #endif #endif -#ifdef ARDUINO_ARCH_ESP32 - #undef WLED_USE_ANALOG_LEDS // Solid RGBW not implemented for ESP32 yet - /*#ifndef WLED_DISABLE_INFRARED - #include - #endif*/ //there are issues with ESP32 infrared, so it is disabled for now -#else #ifndef WLED_DISABLE_INFRARED #include #include #include #endif -#endif - //version code in format yymmddb (b = daily build) -#define VERSION 1912182 -char versionString[] = "0.9.0-b1"; +#define VERSION 2001071 +char versionString[] = "0.9.0-b2"; //AP and OTA default passwords (for maximum change them!) @@ -150,6 +136,7 @@ byte briS = 128; //default brightness byte nightlightTargetBri = 0; //brightness after nightlight is over byte nightlightDelayMins = 60; bool nightlightFade = true; //if enabled, light will gradually dim towards the target bri. Otherwise, it will instantly set after delay over +bool nightlightColorFade = false; //if enabled, light will gradually fade color from primary to secondary color. bool fadeTransition = true; //enable crossfading color transition bool enableSecTransition = true; //also enable transition for secondary color uint16_t transitionDelay = 750; //default crossfade duration in ms @@ -166,7 +153,7 @@ bool syncToggleReceive = false; //UIs which only have a single but //Sync CONFIG bool buttonEnabled = true; -byte irEnabled = 1; //Infrared receiver +byte irEnabled = 0; //Infrared receiver uint16_t udpPort = 21324; //WLED notifier default port uint16_t udpRgbPort = 19446; //Hyperion port @@ -295,6 +282,7 @@ byte briOld = 0; byte briT = 0; byte briIT = 0; byte briLast = 128; //brightness before turned off. Used for toggle function +byte whiteLast = 128; //white channel before turned off. Used for toggle function //button bool buttonPressedBefore = false; @@ -431,6 +419,7 @@ AsyncMqttClient* mqtt = NULL; void colorFromUint32(uint32_t,bool=false); void serveMessage(AsyncWebServerRequest*,uint16_t,String,String,byte); void handleE131Packet(e131_packet_t*, IPAddress); +void handleOverlayDraw(); #define E131_MAX_UNIVERSE_COUNT 9 @@ -513,6 +502,7 @@ void setup() { //main program loop void loop() { + handleIR(); //2nd call to function needed for ESP32 to return valid results -- should be good for ESP8266, too handleConnection(); handleSerial(); handleNotifications(); diff --git a/wled00/wled01_eeprom.ino b/wled00/wled01_eeprom.ino index 2f68703eac..8a43a79dbb 100644 --- a/wled00/wled01_eeprom.ino +++ b/wled00/wled01_eeprom.ino @@ -561,6 +561,7 @@ bool applyPreset(byte index, bool loadBri = true, bool loadCol = true, bool load col[j] = EEPROM.read(i+j+2); colSec[j] = EEPROM.read(i+j+6); } + strip.setColor(2, EEPROM.read(i+12), EEPROM.read(i+13), EEPROM.read(i+14), EEPROM.read(i+15)); //tertiary color } if (loadFX) { @@ -598,6 +599,12 @@ void savePreset(byte index) } EEPROM.write(i+10, effectCurrent); EEPROM.write(i+11, effectSpeed); + + uint32_t colTer = strip.getSegment(strip.getMainSegmentId()).colors[2]; + EEPROM.write(i+12, (colTer >> 16) & 0xFF); + EEPROM.write(i+13, (colTer >> 8) & 0xFF); + EEPROM.write(i+14, (colTer >> 0) & 0xFF); + EEPROM.write(i+15, (colTer >> 24) & 0xFF); EEPROM.write(i+16, effectIntensity); EEPROM.write(i+17, effectPalette); diff --git a/wled00/wled03_set.ino b/wled00/wled03_set.ino index 7e8f6fe94f..1de26719f8 100644 --- a/wled00/wled03_set.ino +++ b/wled00/wled03_set.ino @@ -200,7 +200,6 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage) if (request->hasArg("OL")){ overlayDefault = request->arg("OL").toInt(); - if (overlayCurrent != overlayDefault) strip.unlockAll(); overlayCurrent = overlayDefault; } @@ -459,29 +458,6 @@ bool handleSet(AsyncWebServerRequest *request, const String& req) pos = req.indexOf("OL="); if (pos > 0) { overlayCurrent = getNumVal(&req, pos); - strip.unlockAll(); - } - - //(un)lock pixel (ranges) - pos = req.indexOf("&L="); - if (pos > 0) { - uint16_t index = getNumVal(&req, pos); - pos = req.indexOf("L2="); - bool unlock = req.indexOf("UL") > 0; - if (pos > 0) { - uint16_t index2 = getNumVal(&req, pos); - if (unlock) { - strip.unlockRange(index, index2); - } else { - strip.lockRange(index, index2); - } - } else { - if (unlock) { - strip.unlock(index); - } else { - strip.lock(index); - } - } } //apply macro @@ -535,6 +511,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req) if (pos > 0) { nightlightFade = (req.charAt(pos+3) != '0'); + nightlightColorFade = (req.charAt(pos+3) == '2'); //NighLightColorFade can only be enabled via API or Macro with "NF=2" nightlightActiveOld = false; //re-init } @@ -622,6 +599,10 @@ bool handleSet(AsyncWebServerRequest *request, const String& req) //cronixie #ifndef WLED_DISABLE_CRONIXIE + //mode, 1 countdown + pos = req.indexOf("NM="); + if (pos > 0) countdownMode = (req.charAt(pos+3) != '0'); + pos = req.indexOf("NX="); //sets digits to code if (pos > 0) { strlcpy(cronixieDisplay, req.substring(pos + 3, pos + 9).c_str(), 6); @@ -636,9 +617,6 @@ bool handleSet(AsyncWebServerRequest *request, const String& req) overlayRefreshedTime = 0; } #endif - //mode, 1 countdown - pos = req.indexOf("NM="); - if (pos > 0) countdownMode = (req.charAt(pos+3) != '0'); pos = req.indexOf("U0="); //user var 0 if (pos > 0) { diff --git a/wled00/wled05_init.ino b/wled00/wled05_init.ino index 684893f1be..a347eb4dcf 100644 --- a/wled00/wled05_init.ino +++ b/wled00/wled05_init.ino @@ -96,6 +96,7 @@ void wledInit() void beginStrip() { // Initialize NeoPixel Strip and button + strip.setShowCallback(handleOverlayDraw); #ifdef BTNPIN pinMode(BTNPIN, INPUT_PULLUP); diff --git a/wled00/wled07_notify.ino b/wled00/wled07_notify.ino index 22370072cc..8bb739e05a 100644 --- a/wled00/wled07_notify.ino +++ b/wled00/wled07_notify.ino @@ -79,7 +79,6 @@ void arlsLock(uint32_t timeoutMs) { strip.setPixelColor(i,0,0,0,0); } - strip.unlockAll(); realtimeActive = true; } realtimeTimeout = millis() + timeoutMs; @@ -127,7 +126,6 @@ void handleNotifications() //unlock strip when realtime UDP times out if (realtimeActive && millis() > realtimeTimeout) { - //strip.unlockAll(); strip.setBrightness(bri); realtimeActive = false; //strip.setMode(effectCurrent); diff --git a/wled00/wled08_led.ino b/wled00/wled08_led.ino index d9cf8778a2..786049a081 100644 --- a/wled00/wled08_led.ino +++ b/wled00/wled08_led.ino @@ -217,19 +217,15 @@ void handleNightlight() nightlightDelayMs = (int)(nightlightDelayMins*60000); nightlightActiveOld = true; briNlT = bri; - for (byte i=0; i<4; i++) - { - colNlT[i] = col[i]; // remember starting color - } - + for (byte i=0; i<4; i++) colNlT[i] = col[i]; // remember starting color } float nper = (millis() - nightlightStartTime)/((float)nightlightDelayMs); if (nightlightFade) { bri = briNlT + ((nightlightTargetBri - briNlT)*nper); - for (byte i=0; i<4; i++) + if (nightlightColorFade) // color fading only is enabled with "NF=2" { - col[i] = colNlT[i]+ ((colSec[i] - colNlT[i])*nper); // fading from actual color to secondary color + for (byte i=0; i<4; i++) col[i] = colNlT[i]+ ((colSec[i] - colNlT[i])*nper); // fading from actual color to secondary color } colorUpdated(5); } diff --git a/wled00/wled10_ntp.ino b/wled00/wled10_ntp.ino index d665943d6c..bf8df064df 100644 --- a/wled00/wled10_ntp.ino +++ b/wled00/wled10_ntp.ino @@ -25,6 +25,8 @@ TimeChangeRule CDT = {Second, Sun, Mar, 2, -300 }; //Daylight time = UTC - 5 TimeChangeRule CST = {First, Sun, Nov, 2, -360 }; //Standard time = UTC - 6 hours Timezone tzUSCentral(CDT, CST); +Timezone tzCASaskatchewan(CST, CST); //Central without DST + TimeChangeRule MDT = {Second, Sun, Mar, 2, -360 }; //Daylight time = UTC - 6 hours TimeChangeRule MST = {First, Sun, Nov, 2, -420 }; //Standard time = UTC - 7 hours Timezone tzUSMountain(MDT, MST); @@ -55,7 +57,7 @@ Timezone tzNK(NKST, NKST); TimeChangeRule IST = {Last, Sun, Mar, 1, 330}; // India Standard Time = UTC + 5.5 hours Timezone tzIndia(IST, IST); -Timezone* timezones[] = {&tzUTC, &tzUK, &tzEUCentral, &tzEUEastern, &tzUSEastern, &tzUSCentral, &tzUSMountain, &tzUSArizona, &tzUSPacific, &tzChina, &tzJapan, &tzAUEastern, &tzNZ, &tzNK, &tzIndia}; +Timezone* timezones[] = {&tzUTC, &tzUK, &tzEUCentral, &tzEUEastern, &tzUSEastern, &tzUSCentral, &tzUSMountain, &tzUSArizona, &tzUSPacific, &tzChina, &tzJapan, &tzAUEastern, &tzNZ, &tzNK, &tzIndia, &tzCASaskatchewan}; void handleNetworkTime() { @@ -161,13 +163,16 @@ void setCountdown() //returns true if countdown just over bool checkCountdown() { - long diff = countdownTime - now(); - local = abs(diff); - if (diff <0 && !countdownOverTriggered) - { - if (macroCountdown != 0) applyMacro(macroCountdown); - countdownOverTriggered = true; - return true; + unsigned long n = now(); + local = countdownTime - n; + if (n > countdownTime) { + local = n - countdownTime; + if (!countdownOverTriggered) + { + if (macroCountdown != 0) applyMacro(macroCountdown); + countdownOverTriggered = true; + return true; + } } return false; } diff --git a/wled00/wled11_ol.ino b/wled00/wled11_ol.ino index fc3a47d8b4..cfe8a1f9fd 100644 --- a/wled00/wled11_ol.ino +++ b/wled00/wled11_ol.ino @@ -1,6 +1,7 @@ /* * Used to draw clock overlays over the strip */ + void initCronixie() { if (overlayCurrent == 3 && !cronixieInit) @@ -24,14 +25,8 @@ void handleOverlays() initCronixie(); updateLocalTime(); checkTimers(); - switch (overlayCurrent) - { - case 0: break;//no overlay - case 1: _overlayAnalogClock(); break;//2 analog clock - case 2: break;//nixie 1-digit, removed - case 3: _overlayCronixie();//Diamex cronixie clock kit - } - if (!countdownMode || overlayCurrent < 3) checkCountdown(); //countdown macro activation must work + checkCountdown(); + if (overlayCurrent == 3) _overlayCronixie();//Diamex cronixie clock kit overlayRefreshedTime = millis(); } } @@ -40,7 +35,6 @@ void handleOverlays() void _overlayAnalogClock() { int overlaySize = overlayMax - overlayMin +1; - strip.unlockAll(); if (countdownMode) { _overlayAnalogCountdown(); return; @@ -73,23 +67,19 @@ void _overlayAnalogClock() { pix = analogClock12pixel + round((overlaySize / 12.0) *i); if (pix > overlayMax) pix -= overlaySize; - strip.setIndividual(pix, 0x00FFAA); + strip.setPixelColor(pix, 0x00FFAA); } } - if (!analogClockSecondsTrail) strip.setIndividual(secondPixel, 0xFF0000); - strip.setIndividual(minutePixel, 0x00FF00); - strip.setIndividual(hourPixel, 0x0000FF); + if (!analogClockSecondsTrail) strip.setPixelColor(secondPixel, 0xFF0000); + strip.setPixelColor(minutePixel, 0x00FF00); + strip.setPixelColor(hourPixel, 0x0000FF); overlayRefreshMs = 998; } void _overlayAnalogCountdown() { - strip.unlockAll(); - if (now() >= countdownTime) - { - checkCountdown(); - } else + if (now() < countdownTime) { long diff = countdownTime - now(); double pval = 60; @@ -127,3 +117,9 @@ void _overlayAnalogCountdown() } overlayRefreshMs = 998; } + + +void handleOverlayDraw() { + if (overlayCurrent != 1) return; //only analog clock + _overlayAnalogClock(); +} diff --git a/wled00/wled12_alexa.ino b/wled00/wled12_alexa.ino index 3c2c1cb5c7..c3bc01ab02 100644 --- a/wled00/wled12_alexa.ino +++ b/wled00/wled12_alexa.ino @@ -62,10 +62,11 @@ void onAlexaChange(EspalexaDevice* dev) } else //color { uint32_t color = espalexaDevice->getRGB(); - col[3] = ((color >> 24) & 0xFF); + col[3] = ((color >> 24) & 0xFF); // white color from Alexa is "pure white only" col[0] = ((color >> 16) & 0xFF); col[1] = ((color >> 8) & 0xFF); col[2] = (color & 0xFF); + if (useRGBW && col[3] == 0) colorRGBtoRGBW(col); // do not touch white value if EspalexaDevice.cpp did set the white channel colorUpdated(10); } } diff --git a/wled00/wled13_cronixie.ino b/wled00/wled13_cronixie.ino index dac3247512..de89aede21 100644 --- a/wled00/wled13_cronixie.ino +++ b/wled00/wled13_cronixie.ino @@ -145,9 +145,7 @@ void setCronixie() void _overlayCronixie() { - if (countdownMode) checkCountdown(); #ifndef WLED_DISABLE_CRONIXIE - byte h = hour(local); byte h0 = h; byte m = minute(local); diff --git a/wled00/wled14_colors.ino b/wled00/wled14_colors.ino index bfc3ecb09d..8b0414627f 100644 --- a/wled00/wled14_colors.ino +++ b/wled00/wled14_colors.ino @@ -17,11 +17,18 @@ void colorFromUint32(uint32_t in, bool secondary) } } -void colorFromUint24(uint32_t in) +//load a color without affecting the white channel +void colorFromUint24(uint32_t in, bool secondary = false) { - col[0] = in >> 16 & 0xFF; - col[1] = in >> 8 & 0xFF; - col[2] = in & 0xFF; + if (secondary) { + colSec[0] = in >> 16 & 0xFF; + colSec[1] = in >> 8 & 0xFF; + colSec[2] = in & 0xFF; + } else { + col[0] = in >> 16 & 0xFF; + col[1] = in >> 8 & 0xFF; + col[2] = in & 0xFF; + } } //relatively change white brightness, minumum A=5 @@ -181,6 +188,6 @@ void colorRGBtoRGBW(byte* rgb) //rgb to rgbw (http://codewelt.com/rgbw) float low = minf(rgb[0],minf(rgb[1],rgb[2])); float high = maxf(rgb[0],maxf(rgb[1],rgb[2])); if (high < 0.1f) return; - 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); } diff --git a/wled00/wled18_server.ino b/wled00/wled18_server.ino index e101c997e0..f7162d3e5e 100644 --- a/wled00/wled18_server.ino +++ b/wled00/wled18_server.ino @@ -104,7 +104,7 @@ void initServer() AsyncCallbackJsonWebHandler* handler = new AsyncCallbackJsonWebHandler("/json", [](AsyncWebServerRequest *request) { bool verboseResponse = false; - if (1) { //scope JsonDocument so it releases its buffer + { //scope JsonDocument so it releases its buffer DynamicJsonDocument jsonBuffer(8192); DeserializationError error = deserializeJson(jsonBuffer, (uint8_t*)(request->_tempObject)); JsonObject root = jsonBuffer.as(); diff --git a/wled00/wled19_json.ino b/wled00/wled19_json.ino index 3e135d4064..12339db43e 100644 --- a/wled00/wled19_json.ino +++ b/wled00/wled19_json.ino @@ -243,7 +243,7 @@ void serializeInfo(JsonObject root) leds_pin.add(LEDPIN); leds["pwr"] = strip.currentMilliamps; - leds["maxpwr"] = strip.ablMilliampsMax; + leds["maxpwr"] = (strip.currentMilliamps)? strip.ablMilliampsMax : 0; leds["maxseg"] = strip.getMaxSegments(); leds["seglock"] = false; //will be used in the future to prevent modifications to segment config @@ -257,7 +257,9 @@ void serializeInfo(JsonObject root) JsonObject wifi_info = root.createNestedObject("wifi"); wifi_info["bssid"] = WiFi.BSSIDstr(); - wifi_info["signal"] = getSignalQuality(WiFi.RSSI()); + int qrssi = WiFi.RSSI(); + wifi_info["rssi"] = qrssi; + wifi_info["signal"] = getSignalQuality(qrssi); wifi_info["channel"] = WiFi.channel(); #ifdef ARDUINO_ARCH_ESP32 diff --git a/wled00/wled20_ir.ino b/wled00/wled20_ir.ino index 29df7f8bb3..d602e4e122 100644 --- a/wled00/wled20_ir.ino +++ b/wled00/wled20_ir.ino @@ -1,8 +1,8 @@ /* - * Infrared sensor support for generic 24 key RGB remote + * Infrared sensor support for generic 24/40/44 key RGB remotes */ -#if defined(WLED_DISABLE_INFRARED) || defined(ARDUINO_ARCH_ESP32) +#if defined(WLED_DISABLE_INFRARED) void handleIR(){} #else @@ -48,11 +48,11 @@ void decodeIR(uint32_t code) if (code == 0xFFFFFFFF) //repeated code, continue brightness up/down { irTimesRepeated++; - if (lastValidCode == IR24_BRIGHTER | lastValidCode == IR40_BPLUS ) + if (lastValidCode == IR24_BRIGHTER || lastValidCode == IR40_BPLUS ) { relativeChange(&bri, 10); colorUpdated(2); } - else if (lastValidCode == IR24_DARKER | lastValidCode == IR40_BMINUS ) + else if (lastValidCode == IR24_DARKER || lastValidCode == IR40_BMINUS ) { relativeChange(&bri, -10, 5); colorUpdated(2); } @@ -64,7 +64,7 @@ void decodeIR(uint32_t code) { relativeChangeWhite(-10, 5); colorUpdated(2); } - else if ((lastValidCode == IR24_ON | lastValidCode == IR44_ON) && irTimesRepeated > 7 ) + else if ((lastValidCode == IR24_ON || lastValidCode == IR40_ON) && irTimesRepeated > 7 ) { nightlightActive = true; nightlightStartTime = millis(); @@ -123,7 +123,6 @@ void decodeIR24(uint32_t code) colorUpdated(2); //for notifier, IR is considered a button input } - void decodeIR24OLD(uint32_t code) { switch (code) { @@ -216,11 +215,21 @@ void decodeIR40(uint32_t code) case IR40_PURPLE : colorFromUint24(COLOR_PURPLE); break; case IR40_MAGENTA : colorFromUint24(COLOR_MAGENTA); break; case IR40_PINK : colorFromUint24(COLOR_PINK); break; - case IR40_WARMWHITE2 : colorFromUint32(COLOR_WARMWHITE2); effectCurrent = 0; break; - case IR40_WARMWHITE : colorFromUint32(COLOR_WARMWHITE); effectCurrent = 0; break; - case IR40_WHITE : colorFromUint32(COLOR_NEUTRALWHITE); effectCurrent = 0; break; - case IR40_COLDWHITE : colorFromUint32(COLOR_COLDWHITE); effectCurrent = 0; break; - case IR40_COLDWHITE2 : colorFromUint32(COLOR_COLDWHITE2); effectCurrent = 0; break; + case IR40_WARMWHITE2 : { + if (useRGBW) { colorFromUint32(COLOR2_WARMWHITE2); effectCurrent = 0; } + else colorFromUint24(COLOR_WARMWHITE2); } break; + case IR40_WARMWHITE : { + if (useRGBW) { colorFromUint32(COLOR2_WARMWHITE); effectCurrent = 0; } + else colorFromUint24(COLOR_WARMWHITE); } break; + case IR40_WHITE : { + if (useRGBW) { colorFromUint32(COLOR2_NEUTRALWHITE); effectCurrent = 0; } + else colorFromUint24(COLOR_NEUTRALWHITE); } break; + case IR40_COLDWHITE : { + if (useRGBW) { colorFromUint32(COLOR2_COLDWHITE); effectCurrent = 0; } + else colorFromUint24(COLOR_COLDWHITE); } break; + case IR40_COLDWHITE2 : { + if (useRGBW) { colorFromUint32(COLOR2_COLDWHITE2); effectCurrent = 0; } + else colorFromUint24(COLOR_COLDWHITE2); } break; case IR40_WPLUS : relativeChangeWhite(10); break; case IR40_WMINUS : relativeChangeWhite(-10, 5); break; case IR40_WOFF : whiteLast = col[3]; col[3] = 0; break; @@ -242,7 +251,6 @@ void decodeIR40(uint32_t code) colorUpdated(2); //for notifier, IR is considered a button input } - void decodeIR44(uint32_t code) { switch (code) { @@ -251,27 +259,37 @@ void decodeIR44(uint32_t code) case IR44_OFF : briLast = bri; bri = 0; break; case IR44_ON : bri = briLast; break; case IR44_RED : colorFromUint24(COLOR_RED); break; - case IR44_GREEN : colorFromUint24(COLOR_GREEN); break; - case IR44_BLUE : colorFromUint24(COLOR_BLUE); break; - case IR44_WHITE : { - if (col[3] > 0) col[3] = 0; - else colorFromUint32(COLOR_NEUTRALWHITE); effectCurrent = 0; } break; case IR44_REDDISH : colorFromUint24(COLOR_REDDISH); break; - case IR44_GREENISH : colorFromUint24(COLOR_GREENISH); break; - case IR44_DEEPBLUE : colorFromUint24(COLOR_DEEPBLUE); break; - case IR44_WARMWHITE2 : colorFromUint32(COLOR_WARMWHITE2); effectCurrent = 0; break; case IR44_ORANGE : colorFromUint24(COLOR_ORANGE); break; - case IR44_TURQUOISE : colorFromUint24(COLOR_TURQUOISE); break; - case IR44_PURPLE : colorFromUint24(COLOR_PURPLE); break; - case IR44_WARMWHITE : colorFromUint32(COLOR_WARMWHITE); effectCurrent = 0; break; case IR44_YELLOWISH : colorFromUint24(COLOR_YELLOWISH); break; - case IR44_CYAN : colorFromUint24(COLOR_CYAN); break; - case IR44_MAGENTA : colorFromUint24(COLOR_MAGENTA); break; - case IR44_COLDWHITE : colorFromUint32(COLOR_COLDWHITE); effectCurrent = 0; break; case IR44_YELLOW : colorFromUint24(COLOR_YELLOW); break; + case IR44_GREEN : colorFromUint24(COLOR_GREEN); break; + case IR44_GREENISH : colorFromUint24(COLOR_GREENISH); break; + case IR44_TURQUOISE : colorFromUint24(COLOR_TURQUOISE); break; + case IR44_CYAN : colorFromUint24(COLOR_CYAN); break; case IR44_AQUA : colorFromUint24(COLOR_AQUA); break; + case IR44_BLUE : colorFromUint24(COLOR_BLUE); break; + case IR44_DEEPBLUE : colorFromUint24(COLOR_DEEPBLUE); break; + case IR44_PURPLE : colorFromUint24(COLOR_PURPLE); break; + case IR44_MAGENTA : colorFromUint24(COLOR_MAGENTA); break; case IR44_PINK : colorFromUint24(COLOR_PINK); break; - case IR44_COLDWHITE2 : colorFromUint32(COLOR_COLDWHITE2); effectCurrent = 0; break; + case IR44_WHITE : { + if (useRGBW) { + if (col[3] > 0) col[3] = 0; + else { colorFromUint32(COLOR2_NEUTRALWHITE); effectCurrent = 0; } + } else colorFromUint24(COLOR_NEUTRALWHITE); } break; + case IR44_WARMWHITE2 : { + if (useRGBW) { colorFromUint32(COLOR2_WARMWHITE2); effectCurrent = 0; } + else colorFromUint24(COLOR_WARMWHITE2); } break; + case IR44_WARMWHITE : { + if (useRGBW) { colorFromUint32(COLOR2_WARMWHITE); effectCurrent = 0; } + else colorFromUint24(COLOR_WARMWHITE); } break; + case IR44_COLDWHITE : { + if (useRGBW) { colorFromUint32(COLOR2_COLDWHITE); effectCurrent = 0; } + else colorFromUint24(COLOR_COLDWHITE); } break; + case IR44_COLDWHITE2 : { + if (useRGBW) { colorFromUint32(COLOR2_COLDWHITE2); effectCurrent = 0; } + else colorFromUint24(COLOR_COLDWHITE2); } break; case IR44_REDPLUS : relativeChange(&effectCurrent, 1); break; case IR44_REDMINUS : relativeChange(&effectCurrent, -1, 0); break; case IR44_GREENPLUS : relativeChange(&effectPalette, 1); break; @@ -322,9 +340,12 @@ void handleIR() if (irrecv->decode(&results)) { - Serial.print("IR recv\r\n0x"); - Serial.println((uint32_t)results.value, HEX); - Serial.println(); + if (results.value != 0) // only print results if anything is received ( != 0 ) + { + Serial.print("IR recv\r\n0x"); + Serial.println((uint32_t)results.value, HEX); + Serial.println(); + } decodeIR(results.value); irrecv->resume(); } From 0daf78e3e9e3a92d557ebe273be9307f76966397 Mon Sep 17 00:00:00 2001 From: Def3nder Date: Thu, 9 Jan 2020 15:47:55 +0100 Subject: [PATCH 19/21] PIO ini correction --- platformio.ini | 42 ------------------------------------------ 1 file changed, 42 deletions(-) diff --git a/platformio.ini b/platformio.ini index a3e73eef0c..095992ea82 100644 --- a/platformio.ini +++ b/platformio.ini @@ -131,48 +131,6 @@ build_flags = lib_deps = ${common.lib_deps_external} -[env:esp8285_4CH_H801] -board = esp8285 -platform = ${common:esp8266_1M.platform} -monitor_speed = ${common.monitor_speed} -upload_speed = ${common.upload_speed} -framework = ${common.framework} -build_flags = - ${common.build_flags} - ${common:esp8266_1M.build_flags} - -D WLED_USE_ANALOG_LEDS - -D WLED_USE_H801 -lib_deps = - ${common.lib_deps_external} - -[env:esp8285_4CH_MagicHome] -board = esp8285 -platform = ${common:esp8266_1M.platform} -monitor_speed = ${common.monitor_speed} -upload_speed = ${common.upload_speed} -framework = ${common.framework} -build_flags = - ${common.build_flags} - ${common:esp8266_1M.build_flags} - -D WLED_USE_ANALOG_LEDS -lib_deps = - ${common.lib_deps_external} - -[env:esp8285_5CH_H801] -board = esp8285 -platform = ${common:esp8266_1M.platform} -monitor_speed = ${common.monitor_speed} -upload_speed = ${common.upload_speed} -framework = ${common.framework} -build_flags = - ${common.build_flags} - ${common:esp8266_1M.build_flags} - -D WLED_USE_ANALOG_LEDS - -D WLED_USE_5CH_LEDS - -D WLED_USE_H801 -lib_deps = - ${common.lib_deps_external} - [env:esp01_1m] board = esp01_1m platform = ${common:esp8266_1M.platform} From fbaea16f7ac57de7394bc83051db16f5442c764f Mon Sep 17 00:00:00 2001 From: Def3nder Date: Fri, 10 Jan 2020 15:11:26 +0100 Subject: [PATCH 20/21] Author of IRremoteESP8266 has created new branch for us ... ...where the used functions can be controlled with -D build_flags. This saves 21024 bytes of program space :smile: --- platformio.ini | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/platformio.ini b/platformio.ini index 095992ea82..6cfa3da8dc 100644 --- a/platformio.ini +++ b/platformio.ini @@ -27,6 +27,18 @@ build_flags = -w ; supresses all C/C++ warnings ; -D VERSION=0.8.5 ; -D DEBUG + #build_flags for the IRremoteESP8266 library (enabled decoders have to appear here) + -D _IR_ENABLE_DEFAULT_=false + -D DECODE_HASH=true + -D DECODE_NEC=true + -D DECODE_SONY=true + -D DECODE_PANASONIC=true + -D DECODE_JVC=true + -D DECODE_SAMSUNG=true + -D DECODE_LG=true + -D DECODE_SANYO=true + -D DECODE_SHARP=true + -D DECODE_DENON=true # TODO replace libs in /lib with managed libs in here if possible. # If they are not changed it's just a matter of setting the correct version and change the import statement lib_deps_external = @@ -40,6 +52,8 @@ lib_deps_external = Esp Async WebServer@1.2.0 #ArduinoJson@5.13.5 IRremoteESP8266@2.7.2 + #For saving 20k program space the brnach "compile_flags" will be used: + #https://github.com/crankyoldgit/IRremoteESP8266.git#compile_flags #Time@1.5 #Timezone@1.2.1 #For use SSD1306 0.91" OLED display uncomment following From 13e84b06986ae2eba39818a9e7c99d4e94964736 Mon Sep 17 00:00:00 2001 From: Def3nder Date: Fri, 10 Jan 2020 15:18:10 +0100 Subject: [PATCH 21/21] Author of IRremoteESP8266 has created new branch for us ... ...where the used functions can be controlled with -D build_flags. This saves 21024 bytes of program space :smile: changed to the new branch version (this was the prove test with the old v2.7.2) --- platformio.ini | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/platformio.ini b/platformio.ini index 095992ea82..f9c3575d04 100644 --- a/platformio.ini +++ b/platformio.ini @@ -27,6 +27,18 @@ build_flags = -w ; supresses all C/C++ warnings ; -D VERSION=0.8.5 ; -D DEBUG + #build_flags for the IRremoteESP8266 library (enabled decoders have to appear here) + -D _IR_ENABLE_DEFAULT_=false + -D DECODE_HASH=true + -D DECODE_NEC=true + -D DECODE_SONY=true + -D DECODE_PANASONIC=true + -D DECODE_JVC=true + -D DECODE_SAMSUNG=true + -D DECODE_LG=true + -D DECODE_SANYO=true + -D DECODE_SHARP=true + -D DECODE_DENON=true # TODO replace libs in /lib with managed libs in here if possible. # If they are not changed it's just a matter of setting the correct version and change the import statement lib_deps_external = @@ -39,7 +51,9 @@ lib_deps_external = AsyncTCP@1.0.3 Esp Async WebServer@1.2.0 #ArduinoJson@5.13.5 - IRremoteESP8266@2.7.2 + #IRremoteESP8266@2.7.2 + #For saving 20k program space the brnach "compile_flags" will be used: + https://github.com/crankyoldgit/IRremoteESP8266.git#compile_flags #Time@1.5 #Timezone@1.2.1 #For use SSD1306 0.91" OLED display uncomment following