diff --git a/platformio.ini b/platformio.ini index c23047e681..b6633d86cd 100644 --- a/platformio.ini +++ b/platformio.ini @@ -1,64 +1,21 @@ ; PlatformIO Project Configuration File -; Please visit documentation: https://docs.platformio.org/page/projectconf.html +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html [platformio] -# ------------------------------------------------------------------------------ -# ENVIRONMENTS -# -# Please uncomment one of the lines below to select your board(s) -# ------------------------------------------------------------------------------ - -# Travis CI binaries (comment this out with a ';' when building for your own board) -default_envs = travis_esp8266, travis_esp32 - -# Release binaries -; default_envs = nodemcuv2, esp01_1m_full, esp32dev, custom_WS2801, custom_APA102, custom_LEDPIN_16, custom_LEDPIN_4, custom_LEDPIN_3, custom32_LEDPIN_16 - -# Single binaries (uncomment your board) -; default_envs = nodemcuv2 -; default_envs = esp01 -; default_envs = esp01_1m_ota -; default_envs = esp01_1m_full -; default_envs = esp07 -; default_envs = d1_mini -; default_envs = heltec_wifi_kit_8 -; default_envs = h803wf -; default_envs = d1_mini_debug -; default_envs = d1_mini_ota -; default_envs = esp32dev -; default_envs = esp8285_4CH_MagicHome -; default_envs = esp8285_4CH_H801 -; default_envs = esp8285_5CH_H801 -; default_envs = d1_mini_5CH_Shojo_PCB -; default_envs = wemos_shield_esp32 -; default_envs = m5atom -; default_envs = esp32_poe - -src_dir = ./wled00 +src_dir = ./wled00 data_dir = ./wled00/data +lib_dir = ./wled00/src build_cache_dir = ~/.buildcache extra_configs = - platformio_override.ini - -[common] -# ------------------------------------------------------------------------------ -# PLATFORM: -# !! DO NOT confuse platformio's ESP8266 development platform with Arduino core for ESP8266 -# -# arduino core 2.6.3 = platformIO 2.3.2 -# arduino core 2.7.0 = platformIO 2.5.0 -# ------------------------------------------------------------------------------ -arduino_core_2_6_3 = espressif8266@2.3.3 -arduino_core_2_7_4 = espressif8266@2.6.2 - -# Development platforms -arduino_core_develop = https://github.com/platformio/platform-espressif8266#develop -arduino_core_git = https://github.com/platformio/platform-espressif8266#feature/stage - -# Platform to use for ESP8266 -platform_wled_default = ${common.arduino_core_2_7_4} -# We use 2.7.4.7 for all, includes PWM flicker fix and Wstring optimization -platform_packages = tasmota/framework-arduinoespressif8266 @ 3.20704.7 + platformio_override.ini +default_envs = nodemcu-32s # ------------------------------------------------------------------------------ # FLAGS: DEBUG @@ -68,31 +25,6 @@ debug_flags = -D DEBUG=1 -D WLED_DEBUG -DDEBUG_ESP_WIFI -DDEBUG_ESP_HTTP_CLIENT #if needed (for memleaks etc) also add; -DDEBUG_ESP_OOM -include "umm_malloc/umm_malloc_cfg.h" #-DDEBUG_ESP_CORE is not working right now -# ------------------------------------------------------------------------------ -# FLAGS: ldscript (available ldscripts at https://github.com/esp8266/Arduino/tree/master/tools/sdk/ld) -# ldscript_512k ( 512 KB) = 487 KB sketch, 4 KB eeprom, no spiffs, 16 KB reserved -# ldscript_1m0m (1024 KB) = 999 KB sketch, 4 KB eeprom, no spiffs, 16 KB reserved -# ldscript_2m1m (2048 KB) = 1019 KB sketch, 4 KB eeprom, 1004 KB spiffs, 16 KB reserved -# ldscript_4m1m (4096 KB) = 1019 KB sketch, 4 KB eeprom, 1002 KB spiffs, 16 KB reserved, 2048 KB empty/ota? -# ldscript_4m3m (4096 KB) = 1019 KB sketch, 4 KB eeprom, 3040 KB spiffs, 16 KB reserved -# -# Available lwIP variants (macros): -# -DPIO_FRAMEWORK_ARDUINO_LWIP_HIGHER_BANDWIDTH = v1.4 Higher Bandwidth (default) -# -DPIO_FRAMEWORK_ARDUINO_LWIP2_LOW_MEMORY = v2 Lower Memory -# -DPIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH = v2 Higher Bandwidth -# -DPIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH_LOW_FLASH -# -# BearSSL performance: -# When building with -DSECURE_CLIENT=SECURE_CLIENT_BEARSSL, please add `board_build.f_cpu = 160000000` to the environment configuration -# -# BearSSL ciphers: -# When building on core >= 2.5, you can add the build flag -DBEARSSL_SSL_BASIC in order to build BearSSL with a limited set of ciphers: -# TLS_RSA_WITH_AES_128_CBC_SHA256 / AES128-SHA256 -# TLS_RSA_WITH_AES_256_CBC_SHA256 / AES256-SHA256 -# TLS_RSA_WITH_AES_128_CBC_SHA / AES128-SHA -# TLS_RSA_WITH_AES_256_CBC_SHA / AES256-SHA -# This reduces the OTA size with ~45KB, so it's especially useful on low memory boards (512k/1m). -# ------------------------------------------------------------------------------ build_flags = -Wno-switch -Wno-deprecated-declarations @@ -167,15 +99,13 @@ extra_scripts = pio/name-firmware.py pio/strip-floats.py pio/user_config_copy.py -# ------------------------------------------------------------------------------ -# COMMON SETTINGS: -# ------------------------------------------------------------------------------ [env] framework = arduino board_build.flash_mode = dout monitor_speed = 115200 upload_speed = 115200 - +lib_extra_dirs = + ${common.shared_libdeps_dir} # ------------------------------------------------------------------------------ # LIBRARIES: required dependencies # Please note that we don't always use the latest version of a library. @@ -207,309 +137,25 @@ lib_ignore = extra_scripts = ${scripts_defaults.extra_scripts} -# ------------------------------------------------------------------------------ -# WLED BUILDS -# ------------------------------------------------------------------------------ - -[env:nodemcuv2] -board = nodemcuv2 -platform = ${common.platform_wled_default} -platform_packages = ${common.platform_packages} -board_build.ldscript = ${common.ldscript_4m1m} -build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp8266} - -# Unsupported environment due to insufficient flash -[env:esp01] -board = esp01 -platform = ${common.platform_wled_default} -platform_packages = ${common.platform_packages} -board_build.ldscript = ${common.ldscript_512k} -build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp8266} -D WLED_DISABLE_OTA -D WLED_DISABLE_ALEXA -D WLED_DISABLE_BLYNK - -D WLED_DISABLE_CRONIXIE -D WLED_DISABLE_HUESYNC -D WLED_DISABLE_INFRARED -D WLED_DISABLE_MQTT -D WLED_DISABLE_WEBSOCKETS - -# Unsupported environment due to insufficient flash -[env:esp01_1m_ota] -board = esp01_1m -platform = ${common.platform_wled_default} -platform_packages = ${common.platform_packages} -board_build.ldscript = ${common.ldscript_1m0m} -build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp8266} -D WLED_DISABLE_ALEXA -D WLED_DISABLE_BLYNK -D WLED_DISABLE_CRONIXIE - -D WLED_DISABLE_HUESYNC -D WLED_DISABLE_INFRARED -D WLED_DISABLE_MQTT -D WLED_DISABLE_WEBSOCKETS - -[env:esp01_1m_full] -board = esp01_1m -platform = ${common.platform_wled_default} -platform_packages = ${common.platform_packages} -board_build.ldscript = ${common.ldscript_1m128k} -build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp8266} -D WLED_DISABLE_OTA - -[env:esp07] -board = esp07 -platform = ${common.platform_wled_default} -platform_packages = ${common.platform_packages} -board_build.ldscript = ${common.ldscript_4m1m} -build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp8266} - -[env:d1_mini] -board = d1_mini -platform = ${common.platform_wled_default} -platform_packages = ${common.platform_packages} -upload_speed = 921600 -board_build.ldscript = ${common.ldscript_4m1m} -build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp8266} -monitor_filters = esp8266_exception_decoder - -[env:heltec_wifi_kit_8] -board = d1_mini -platform = ${common.platform_wled_default} -platform_packages = ${common.platform_packages} -board_build.ldscript = ${common.ldscript_4m1m} -build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp8266} - -[env:h803wf] -board = d1_mini -platform = ${common.platform_wled_default} -platform_packages = ${common.platform_packages} -board_build.ldscript = ${common.ldscript_4m1m} -build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp8266} -D LEDPIN=1 -D WLED_DISABLE_INFRARED - -[env:esp32dev] -board = esp32dev -platform = espressif32@2.0 -build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp32} -lib_ignore = - ESPAsyncTCP - ESPAsyncUDP - -[env:esp32_poe] -board = esp32-poe -platform = espressif32@2.0 -upload_speed = 921600 -build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp32} -D RLYPIN=-1 -D WLED_USE_ETHERNET -lib_ignore = - ESPAsyncTCP - ESPAsyncUDP - -[env:esp8285_4CH_MagicHome] -board = esp8285 -platform = ${common.platform_wled_default} -platform_packages = ${common.platform_packages} -board_build.ldscript = ${common.ldscript_1m0m} -build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp8266} -D WLED_DISABLE_HUESYNC -D WLED_USE_ANALOG_LEDS -[env:esp8285_4CH_H801] -board = esp8285 -platform = ${common.platform_wled_default} -platform_packages = ${common.platform_packages} -board_build.ldscript = ${common.ldscript_1m0m} -build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp8266} -D WLED_DISABLE_HUESYNC -D WLED_USE_ANALOG_LEDS -D WLED_USE_H801 -[env:esp8285_5CH_H801] -board = esp8285 -platform = ${common.platform_wled_default} -platform_packages = ${common.platform_packages} -board_build.ldscript = ${common.ldscript_1m0m} -build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp8266} -D WLED_DISABLE_HUESYNC -D WLED_USE_ANALOG_LEDS -D WLED_USE_H801 -D WLED_ENABLE_5CH_LEDS +; [env:esp32dev] +; board = esp32dev +; platform = espressif32@1.12.4 +; build_flags = ${common.build_flags_esp32} +; lib_ignore = +; ESPAsyncTCP +; ESPAsyncUDP -[env:d1_mini_5CH_Shojo_PCB] -board = d1_mini -platform = ${common.platform_wled_default} -platform_packages = ${common.platform_packages} -board_build.ldscript = ${common.ldscript_4m1m} -build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp8266} -D WLED_USE_ANALOG_LEDS -D WLED_USE_SHOJO_PCB -D WLED_ENABLE_5CH_LEDS - -# ------------------------------------------------------------------------------ -# DEVELOPMENT BOARDS -# ------------------------------------------------------------------------------ - -[env:d1_mini_debug] -board = d1_mini -build_type = debug -platform = ${common.platform_wled_default} -platform_packages = ${common.platform_packages} -board_build.ldscript = ${common.ldscript_4m1m} -build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp8266} ${common.debug_flags} - -[env:d1_mini_ota] -board = d1_mini +[env:nodemcu-32s] +board = nodemcu-32s +platform = espressif32@1.12.4 upload_protocol = espota -# exchange for your WLED IP -upload_port = "10.10.1.27" -platform = ${common.platform_wled_default} -platform_packages = ${common.platform_packages} -board_build.ldscript = ${common.ldscript_4m1m} -build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp8266} - -# ------------------------------------------------------------------------------ -# custom board configurations -# ------------------------------------------------------------------------------ - -[env:custom_LEDPIN_4] -board = d1_mini -platform = ${common.platform_wled_default} -platform_packages = ${common.platform_packages} -board_build.ldscript = ${common.ldscript_4m1m} -build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp8266} -D LEDPIN=4 -D IRPIN=5 - -[env:custom_LEDPIN_16] -board = d1_mini -platform = ${common.platform_wled_default} -platform_packages = ${common.platform_packages} -board_build.ldscript = ${common.ldscript_4m1m} -build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp8266} -D LEDPIN=16 - - -[env:custom_LEDPIN_3] -board = d1_mini -platform = ${common.platform_wled_default} -platform_packages = ${common.platform_packages} -board_build.ldscript = ${common.ldscript_4m1m} -build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp8266} -D LEDPIN=3 - -[env:custom_APA102] -board = d1_mini -platform = ${common.platform_wled_default} -platform_packages = ${common.platform_packages} -board_build.ldscript = ${common.ldscript_4m1m} -build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp8266} -D USE_APA102 - -[env:custom_WS2801] -board = d1_mini -platform = ${common.platform_wled_default} -platform_packages = ${common.platform_packages} -board_build.ldscript = ${common.ldscript_4m1m} -build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp8266} -D USE_WS2801 - -[env:custom32_LEDPIN_16] -board = esp32dev -platform = espressif32@2.0 -build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp32} -D LEDPIN=16 -lib_ignore = - ESPAsyncTCP - ESPAsyncUDP - -[env:custom32_TOUCHPIN_T0] -board = esp32dev -platform = espressif32@2.0 -build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp32} -D TOUCHPIN=T0 -lib_ignore = - ESPAsyncTCP - ESPAsyncUDP - -[env:wemos_shield_esp32] -board = esp32dev -platform = espressif32@2.0 -upload_port = /dev/cu.SLAB_USBtoUART -monitor_port = /dev/cu.SLAB_USBtoUART -upload_speed = 460800 -build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp32} -D LEDPIN=16 -D RLYPIN=19 -D BTNPIN=17 -lib_ignore = - ESPAsyncTCP - ESPAsyncUDP - -[env:m5atom] -board = esp32dev -build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp32} -D LEDPIN=27 -D BTNPIN=39 +upload_port = "10.0.0.8" +#upload_port = "4.3.2.1" +; upload_port = COM3 +; moniter_port = COM3 +build_flags = ${common.build_flags_esp32} lib_ignore = ESPAsyncTCP ESPAsyncUDP -platform = espressif32@2.0 - -[env:sp501e] -board = esp_wroom_02 -platform = ${common.platform_wled_default} -board_build.ldscript = ${common.ldscript_2m1m} -build_flags = ${common.build_flags_esp8266} -D LEDPIN=3 -D BTNPIN=1 - -# ------------------------------------------------------------------------------ -# travis test board configurations -# ------------------------------------------------------------------------------ - -[env:travis_esp8266] -extends = env:d1_mini -build_type = debug -build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp8266} ${common.debug_flags} ${common.build_flags_all_features} - -[env:travis_esp32] -extends = env:esp32dev -; build_type = debug -build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp32} ${common.debug_flags} ${common.build_flags_all_features} - -# ------------------------------------------------------------------------------ -# codm pixel controller board configurations -# ------------------------------------------------------------------------------ - -[env:codm-controller-0.4] -board = esp_wroom_02 -platform = ${common.platform_wled_default} -platform_packages = ${common.platform_packages} -board_build.ldscript = ${common.ldscript_2m1m} -build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp8266} -D LEDPIN=3 - -[env:codm-controller-0.4-WS2801] -board = esp_wroom_02 -platform = ${common.platform_wled_default} -platform_packages = ${common.platform_packages} -board_build.ldscript = ${common.ldscript_2m1m} -build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp8266} -D USE_WS2801 -D CLKPIN=13 -D DATAPIN=3 - -[env:codm-controller-0.4-APA102] -board = esp_wroom_02 -platform = ${common.platform_wled_default} -platform_packages = ${common.platform_packages} -board_build.ldscript = ${common.ldscript_2m1m} -build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp8266} -D USE_APA102 -D CLKPIN=13 -D DATAPIN=3 - -[env:codm-controller-0.5] -board = esp_wroom_02 -platform = ${common.platform_wled_default} -platform_packages = ${common.platform_packages} -board_build.ldscript = ${common.ldscript_2m1m} -build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp8266} - -[env:codm-controller-0.5-WS2801] -board = esp_wroom_02 -platform = ${common.platform_wled_default} -platform_packages = ${common.platform_packages} -board_build.ldscript = ${common.ldscript_2m1m} -build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp8266} -D USE_WS2801 #-D CLKPIN=0 -D DATAPIN=2 - -[env:codm-controller-0.5-APA102] -board = esp_wroom_02 -platform = ${common.platform_wled_default} -platform_packages = ${common.platform_packages} -board_build.ldscript = ${common.ldscript_2m1m} -build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp8266} -D USE_APA102 #-D CLKPIN=0 -D DATAPIN=2 diff --git a/readme.md b/readme.md index 866db4aaf3..98f365256d 100644 --- a/readme.md +++ b/readme.md @@ -1,3 +1,11 @@ +### This is a temporary proof of concept fork of WLED that implements multi-pin output. Up to 8-pin output is working. RGBW Strips will not work currently. Only RGB like ws2812b. + +### In NpbWrapper.h adjust: NUM_STRIPS to the total pins you want to output on. Set the qty of LEDS per strip (STRIPx_LEDCOUNT). Set what GPIO pin# to output on. Then build using Platformio. Then set the WLED gui LED count to the total LED count in your system. +# +# +# +# +

diff --git a/tools/cdata.js b/tools/cdata.js index aa473deb11..e2c1b3f33d 100644 --- a/tools/cdata.js +++ b/tools/cdata.js @@ -305,6 +305,20 @@ const char PAGE_settings_dmx[] PROGMEM = R"=====()====="; .replace(/\.*\<\/style\>/gms, "%CSS%%SCSS%") .replace(/function GetV().*\<\/script\>/gms, "function GetV() {\n"), }, + { + file: "settings_clock.htm", + name: "PAGE_settings_clock", + prepend: "=====(", + append: ")=====", + method: "plaintext", + filter: "html-minify", + mangle: (str) => + str + .replace(/\/gms, "") + .replace(/\.*\<\/style\>/gms, "%CSS%%SCSS%") + .replace(/function GetV().*\<\/script\>/gms, "function GetV() {var d=document;\n"), + + }, { file: "settings_sec.htm", name: "PAGE_settings_sec", diff --git a/wled00/FX.h b/wled00/FX.h index 8e27d2a72e..2af40d845e 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -451,6 +451,9 @@ class WS2812FX { void init(bool supportWhite, uint16_t countPixels, bool skipFirst), service(void), + + Print_Time(String,bool,bool), + blur(uint8_t), fill(uint32_t), fade_out(uint8_t r), diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index 099f77cd03..4fe2653a25 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -26,69 +26,137 @@ #include "FX.h" #include "palettes.h" - +//Outside Count +#define OC 198 +//Inside Count +#define IC 166 +//Tower Outside Count +#define TOC 36 +//Tower Inside Count +#define TIC 28 +//Center Tower Count +#define CTC 57 +//Matrix Count +#define MC 256 //enable custom per-LED mapping. This can allow for better effects on matrices or special displays //#define WLED_CUSTOM_LED_MAPPING #ifdef WLED_CUSTOM_LED_MAPPING //this is just an example (30 LEDs). It will first set all even, then all uneven LEDs. const uint16_t customMappingTable[] = { - 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, - 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29}; + 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, + 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29}; //another example. Switches direction every 5 LEDs. /*const uint16_t customMappingTable[] = { 0, 1, 2, 3, 4, 9, 8, 7, 6, 5, 10, 11, 12, 13, 14, 19, 18, 17, 16, 15, 20, 21, 22, 23, 24, 29, 28, 27, 26, 25};*/ -const uint16_t customMappingSize = sizeof(customMappingTable)/sizeof(uint16_t); //30 in example +const uint16_t customMappingSize = sizeof(customMappingTable) / sizeof(uint16_t); //30 in example #endif void WS2812FX::init(bool supportWhite, uint16_t countPixels, bool skipFirst) { - if (supportWhite == _useRgbw && countPixels == _length && _skipFirstMode == skipFirst) return; + if (supportWhite == _useRgbw && countPixels == _length && _skipFirstMode == skipFirst) + return; RESET_RUNTIME; _useRgbw = supportWhite; _length = countPixels; _skipFirstMode = skipFirst; uint8_t ty = 1; - if (supportWhite) ty = 2; + if (supportWhite) + ty = 2; _lengthRaw = _length; - if (_skipFirstMode) { + if (_skipFirstMode) + { _lengthRaw += LED_SKIP_AMOUNT; } bus->Begin((NeoPixelType)ty, _lengthRaw); - - _segments[0].start = 0; - _segments[0].stop = _length; + + // _segments[0].start = 0; + // _segments[0].stop = _length; + +#ifdef MIRROR + uint8_t _num_segments = 0; + if (_length == OC + IC + TOC + TIC + CTC) + { + _num_segments = 5; + + //Outside + setSegment(0, 0, OC - 1, 0, 0); + //Inside + setSegment(1, OC, OC + IC - 1, 0, 0); + //Towers Outside + setSegment(2, OC + IC, OC + IC + TOC - 1, 0, 0); + //Towers Inside + setSegment(3, OC + IC + TOC, OC + IC + TOC + TIC - 1, 0, 0); + //Center Tower + setSegment(4, OC + IC + TOC + TIC, OC + IC + TOC + TIC + CTC - 1, 0, 0); + for (size_t i = 0; i < _num_segments; i++) + { + _segments[i].setOption(0, 1); //select + } + } + else // (_length == OC + IC + ((TOC + TIC) * 2) + CTC) + { + + _num_segments = 7; + + //Outside + setSegment(0, 0, OC - 1, 0, 0); + //Inside + setSegment(1, OC, OC + IC - 1, 0, 0); + //Left Tower Outside + setSegment(2, OC + IC, OC + IC + TOC - 1, 0, 0); + //Left Tower Inside + setSegment(3, OC + IC + TOC, OC + IC + TOC + TIC - 1, 0, 0); + //Right Tower Outside + setSegment(4, OC + IC + TOC + TIC, OC + IC + TOC + TIC + TOC - 1, 0, 0); + //Right Tower Inside + setSegment(5, OC + IC + TOC + TIC + TOC, OC + IC + ((TOC + TIC) * 2) - 1, 0, 0); + //Center Tower + setSegment(6, OC + IC + ((TOC + TIC) * 2), OC + IC + ((TOC + TIC) * 2) + CTC - 1, 0, 0); + + for (size_t i = 0; i < _num_segments; i++) + { + _segments[i].setOption(0, 1); //select + } + } + +#endif // MIRROR setBrightness(_brightness); } -void WS2812FX::service() { +void WS2812FX::service() +{ uint32_t nowUp = millis(); // Be aware, millis() rolls over every 49 days now = nowUp + timebase; - if (nowUp - _lastShow < MIN_SHOW_DELAY) return; + if (nowUp - _lastShow < MIN_SHOW_DELAY) + return; bool doShow = false; - for(uint8_t i=0; i < MAX_NUM_SEGMENTS; i++) + for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++) { _segment_index = i; if (SEGMENT.isActive()) { - if(nowUp > SEGENV.next_time || _triggered || (doShow && SEGMENT.mode == 0)) //last is temporary + if (nowUp > SEGENV.next_time || _triggered || (doShow && SEGMENT.mode == 0)) //last is temporary { - if (SEGMENT.grouping == 0) SEGMENT.grouping = 1; //sanity check + if (SEGMENT.grouping == 0) + SEGMENT.grouping = 1; //sanity check doShow = true; uint16_t delay = FRAMETIME; - if (!SEGMENT.getOption(SEG_OPTION_FREEZE)) { //only run effect function if not frozen + if (!SEGMENT.getOption(SEG_OPTION_FREEZE)) + { //only run effect function if not frozen _virtualSegmentLength = SEGMENT.virtualLength(); handle_palette(); delay = (this->*_mode[SEGMENT.mode])(); //effect function - if (SEGMENT.mode != FX_MODE_HALLOWEEN_EYES) SEGENV.call++; + if (SEGMENT.mode != FX_MODE_HALLOWEEN_EYES) + SEGENV.call++; } SEGENV.next_time = nowUp + delay; @@ -96,40 +164,48 @@ void WS2812FX::service() { } } _virtualSegmentLength = 0; - if(doShow) { + if (doShow) + { yield(); show(); } _triggered = false; } -void WS2812FX::setPixelColor(uint16_t n, uint32_t c) { +void WS2812FX::setPixelColor(uint16_t n, uint32_t c) +{ uint8_t w = (c >> 24); uint8_t r = (c >> 16); - uint8_t g = (c >> 8); - uint8_t b = c ; + uint8_t g = (c >> 8); + uint8_t b = c; setPixelColor(n, r, g, b, w); } #define REV(i) (_length - 1 - (i)) //used to map from segment index to physical pixel, taking into account grouping, offsets, reverse and mirroring -uint16_t WS2812FX::realPixelIndex(uint16_t i) { +uint16_t WS2812FX::realPixelIndex(uint16_t i) +{ int16_t iGroup = i * SEGMENT.groupLength(); /* reverse just an individual segment */ int16_t realIndex = iGroup; - if (IS_REVERSE) { - if (IS_MIRROR) { - realIndex = (SEGMENT.length() -1) / 2 - iGroup; //only need to index half the pixels - } else { + if (IS_REVERSE) + { + if (IS_MIRROR) + { + realIndex = (SEGMENT.length() - 1) / 2 - iGroup; //only need to index half the pixels + } + else + { realIndex = SEGMENT.length() - iGroup - 1; } } realIndex += SEGMENT.start; /* Reverse the whole string */ - if (reverseMode) realIndex = REV(realIndex); + if (reverseMode) + realIndex = REV(realIndex); return realIndex; } @@ -137,45 +213,77 @@ uint16_t WS2812FX::realPixelIndex(uint16_t i) { void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w) { //auto calculate white channel value if enabled - if (_useRgbw) { + if (_useRgbw) + { if (rgbwMode == RGBW_MODE_AUTO_BRIGHTER || (w == 0 && (rgbwMode == RGBW_MODE_DUAL || rgbwMode == RGBW_MODE_LEGACY))) { //white value is set to lowest RGB channel //thank you to @Def3nder! w = r < g ? (r < b ? r : b) : (g < b ? g : b); - } else if (rgbwMode == RGBW_MODE_AUTO_ACCURATE && w == 0) + } + else if (rgbwMode == RGBW_MODE_AUTO_ACCURATE && w == 0) { w = r < g ? (r < b ? r : b) : (g < b ? g : b); - r -= w; g -= w; b -= w; + r -= w; + g -= w; + b -= w; } } - + //reorder channels to selected order RgbwColor col; switch (colorOrder) { - case 0: col.G = g; col.R = r; col.B = b; break; //0 = GRB, default - case 1: col.G = r; col.R = g; col.B = b; break; //1 = RGB, common for WS2811 - case 2: col.G = b; col.R = r; col.B = g; break; //2 = BRG - case 3: col.G = r; col.R = b; col.B = g; break; //3 = RBG - case 4: col.G = b; col.R = g; col.B = r; break; //4 = BGR - default: col.G = g; col.R = b; col.B = r; break; //5 = GBR + case 0: + col.G = g; + col.R = r; + col.B = b; + break; //0 = GRB, default + case 1: + col.G = r; + col.R = g; + col.B = b; + break; //1 = RGB, common for WS2811 + case 2: + col.G = b; + col.R = r; + col.B = g; + break; //2 = BRG + case 3: + col.G = r; + col.R = b; + col.B = g; + break; //3 = RBG + case 4: + col.G = b; + col.R = g; + col.B = r; + break; //4 = BGR + default: + col.G = g; + col.R = b; + col.B = r; + break; //5 = GBR } col.W = w; - + uint16_t skip = _skipFirstMode ? LED_SKIP_AMOUNT : 0; - if (SEGLEN) {//from segment + if (SEGLEN) + { //from segment //color_blend(getpixel, col, SEGMENT.opacity); (pseudocode for future blending of segments) if (IS_SEGMENT_ON) { - if (SEGMENT.opacity < 255) { + if (SEGMENT.opacity < 255) + { col.R = scale8(col.R, SEGMENT.opacity); col.G = scale8(col.G, SEGMENT.opacity); col.B = scale8(col.B, SEGMENT.opacity); col.W = scale8(col.W, SEGMENT.opacity); } - } else { + } + else + { col = BLACK; } @@ -183,39 +291,52 @@ void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w) bool reversed = reverseMode ^ IS_REVERSE; uint16_t realIndex = realPixelIndex(i); - for (uint16_t j = 0; j < SEGMENT.grouping; j++) { + for (uint16_t j = 0; j < SEGMENT.grouping; j++) + { int16_t indexSet = realIndex + (reversed ? -j : j); int16_t indexSetRev = indexSet; - if (reverseMode) indexSetRev = REV(indexSet); - #ifdef WLED_CUSTOM_LED_MAPPING - if (indexSet < customMappingSize) indexSet = customMappingTable[indexSet]; - #endif - if (indexSetRev >= SEGMENT.start && indexSetRev < SEGMENT.stop) { + if (reverseMode) + indexSetRev = REV(indexSet); +#ifdef WLED_CUSTOM_LED_MAPPING + if (indexSet < customMappingSize) + indexSet = customMappingTable[indexSet]; +#endif + if (indexSetRev >= SEGMENT.start && indexSetRev < SEGMENT.stop) + { bus->SetPixelColor(indexSet + skip, col); - if (IS_MIRROR) { //set the corresponding mirrored pixel - if (reverseMode) { + if (IS_MIRROR) + { //set the corresponding mirrored pixel + if (reverseMode) + { bus->SetPixelColor(REV(SEGMENT.start) - indexSet + skip + REV(SEGMENT.stop) + 1, col); - } else { + } + else + { bus->SetPixelColor(SEGMENT.stop - indexSet + skip + SEGMENT.start - 1, col); } } } } - } else { //live data, etc. - if (reverseMode) i = REV(i); - #ifdef WLED_CUSTOM_LED_MAPPING - if (i < customMappingSize) i = customMappingTable[i]; - #endif + } + else + { //live data, etc. + if (reverseMode) + i = REV(i); +#ifdef WLED_CUSTOM_LED_MAPPING + if (i < customMappingSize) + i = customMappingTable[i]; +#endif bus->SetPixelColor(i + skip, col); } - if (skip && i == 0) { - for (uint16_t j = 0; j < skip; j++) { + if (skip && i == 0) + { + for (uint16_t j = 0; j < skip; j++) + { bus->SetPixelColor(j, RgbwColor(0, 0, 0, 0)); } } } - //DISCLAIMER //The following function attemps to calculate the current LED power usage, //and will limit the brightness to stay below a set amperage threshold. @@ -223,13 +344,15 @@ void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w) //Stay safe with high amperage and have a reasonable safety margin! //I am NOT to be held liable for burned down garages! -//fine tune power estimation constants for your setup -#define MA_FOR_ESP 100 //how much mA does the ESP use (Wemos D1 about 80mA, ESP32 about 120mA) - //you can set it to 0 if the ESP is powered by USB and the LEDs by external +//fine tune power estimation constants for your setup +#define MA_FOR_ESP 100 //how much mA does the ESP use (Wemos D1 about 80mA, ESP32 about 120mA) \ + //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(); -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 @@ -237,7 +360,8 @@ void WS2812FX::show(void) { bool useWackyWS2815PowerModel = false; byte actualMilliampsPerLed = milliampsPerLed; - if(milliampsPerLed == 255) { + if (milliampsPerLed == 255) + { useWackyWS2815PowerModel = true; actualMilliampsPerLed = 12; // from testing an actual strip } @@ -246,10 +370,11 @@ void WS2812FX::show(void) { { uint32_t puPerMilliamp = 195075 / actualMilliampsPerLed; uint32_t powerBudget = (ablMilliampsMax - MA_FOR_ESP) * puPerMilliamp; //100mA for ESP power - if (powerBudget > puPerMilliamp * _length) //each LED uses about 1mA in standby, exclude that from power budget + if (powerBudget > puPerMilliamp * _length) //each LED uses about 1mA in standby, exclude that from power budget { powerBudget -= puPerMilliamp * _length; - } else + } + else { powerBudget = 0; } @@ -260,18 +385,17 @@ void WS2812FX::show(void) { { RgbwColor c = bus->GetPixelColorRgbw(i); - if(useWackyWS2815PowerModel) + if (useWackyWS2815PowerModel) { // ignore white component on WS2815 power calculation - powerSum += (MAX(MAX(c.R,c.G),c.B)) * 3; + powerSum += (MAX(MAX(c.R, c.G), c.B)) * 3; } - else + else { powerSum += (c.R + c.G + c.B + c.W); } } - if (_useRgbw) //RGBW led total output with white LEDs enabled is still 50mA, so each channel uses less { powerSum *= 3; @@ -280,7 +404,7 @@ void WS2812FX::show(void) { uint32_t powerSum0 = powerSum; powerSum *= _brightness; - + if (powerSum > powerBudget) //scale brightness down to stay in current limit { float scale = (float)powerBudget / (float)powerSum; @@ -289,32 +413,39 @@ void WS2812FX::show(void) { uint8_t newBri = scale8(_brightness, scaleB); bus->SetBrightness(newBri); currentMilliamps = (powerSum0 * newBri) / puPerMilliamp; - } else + } + else { currentMilliamps = powerSum / puPerMilliamp; bus->SetBrightness(_brightness); } currentMilliamps += MA_FOR_ESP; //add power of ESP back to estimate - currentMilliamps += _length; //add standby power back to estimate - } else { + currentMilliamps += _length; //add standby power back to estimate + } + else + { currentMilliamps = 0; bus->SetBrightness(_brightness); } - + bus->Show(); _lastShow = millis(); } -void WS2812FX::trigger() { +void WS2812FX::trigger() +{ _triggered = true; } -void WS2812FX::setMode(uint8_t segid, uint8_t m) { - if (segid >= MAX_NUM_SEGMENTS) return; - - if (m >= MODE_COUNT) m = MODE_COUNT - 1; +void WS2812FX::setMode(uint8_t segid, uint8_t m) +{ + if (segid >= MAX_NUM_SEGMENTS) + return; + + if (m >= MODE_COUNT) + m = MODE_COUNT - 1; - if (_segments[segid].mode != m) + if (_segments[segid].mode != m) { _segment_runtimes[segid].reset(); _segments[segid].mode = m; @@ -333,15 +464,16 @@ uint8_t WS2812FX::getPaletteCount() //TODO transitions - -bool WS2812FX::setEffectConfig(uint8_t m, uint8_t s, uint8_t in, uint8_t p) { +bool WS2812FX::setEffectConfig(uint8_t m, uint8_t s, uint8_t in, uint8_t p) +{ uint8_t mainSeg = getMainSegmentId(); - Segment& seg = _segments[getMainSegmentId()]; + Segment &seg = _segments[getMainSegmentId()]; uint8_t modePrev = seg.mode, speedPrev = seg.speed, intensityPrev = seg.intensity, palettePrev = seg.palette; bool applied = false; - - if (applyToAllSelected) { + + if (applyToAllSelected) + { for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++) { if (_segments[i].isSelected()) @@ -353,78 +485,97 @@ bool WS2812FX::setEffectConfig(uint8_t m, uint8_t s, uint8_t in, uint8_t p) { applied = true; } } - } - - if (!applyToAllSelected || !applied) { + } + + if (!applyToAllSelected || !applied) + { seg.speed = s; seg.intensity = in; seg.palette = p; setMode(mainSegment, m); } - - if (seg.mode != modePrev || seg.speed != speedPrev || seg.intensity != intensityPrev || seg.palette != palettePrev) return true; + + if (seg.mode != modePrev || seg.speed != speedPrev || seg.intensity != intensityPrev || seg.palette != palettePrev) + return true; return false; } -void WS2812FX::setColor(uint8_t slot, uint8_t r, uint8_t g, uint8_t b, uint8_t w) { - setColor(slot, ((uint32_t)w << 24) |((uint32_t)r << 16) | ((uint32_t)g << 8) | b); +void WS2812FX::setColor(uint8_t slot, uint8_t r, uint8_t g, uint8_t b, uint8_t w) +{ + setColor(slot, ((uint32_t)w << 24) | ((uint32_t)r << 16) | ((uint32_t)g << 8) | b); } -void WS2812FX::setColor(uint8_t slot, uint32_t c) { - if (slot >= NUM_COLORS) return; +void WS2812FX::setColor(uint8_t slot, uint32_t c) +{ + if (slot >= NUM_COLORS) + return; bool applied = false; - - if (applyToAllSelected) { + + if (applyToAllSelected) + { for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++) { - if (_segments[i].isSelected()) _segments[i].colors[slot] = c; + if (_segments[i].isSelected()) + _segments[i].colors[slot] = c; } } - if (!applyToAllSelected || !applied) { + if (!applyToAllSelected || !applied) + { _segments[getMainSegmentId()].colors[slot] = c; } } -void WS2812FX::setBrightness(uint8_t b) { - if (_brightness == b) return; +void WS2812FX::setBrightness(uint8_t b) +{ + if (_brightness == b) + return; _brightness = (gammaCorrectBri) ? gamma8(b) : b; _segment_index = 0; - if (b == 0) { //unfreeze all segments on power off + if (b == 0) + { //unfreeze all segments on power off for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++) { _segments[i].setOption(SEG_OPTION_FREEZE, false); } - #if LEDPIN == LED_BUILTIN - if (!shouldStartBus) - shouldStartBus = true; - #endif - } else { - #if LEDPIN == LED_BUILTIN - if (shouldStartBus) { - shouldStartBus = false; - const uint8_t ty = _useRgbw ? 2 : 1; - bus->Begin((NeoPixelType)ty, _lengthRaw); - } - #endif +#if LEDPIN == LED_BUILTIN + if (!shouldStartBus) + shouldStartBus = true; +#endif + } + else + { +#if LEDPIN == LED_BUILTIN + if (shouldStartBus) + { + shouldStartBus = false; + const uint8_t ty = _useRgbw ? 2 : 1; + bus->Begin((NeoPixelType)ty, _lengthRaw); + } +#endif } - if (SEGENV.next_time > millis() + 22 && millis() - _lastShow > MIN_SHOW_DELAY) show();//apply brightness change immediately if no refresh soon + if (SEGENV.next_time > millis() + 22 && millis() - _lastShow > MIN_SHOW_DELAY) + show(); //apply brightness change immediately if no refresh soon } -uint8_t WS2812FX::getMode(void) { +uint8_t WS2812FX::getMode(void) +{ return _segments[getMainSegmentId()].mode; } -uint8_t WS2812FX::getSpeed(void) { +uint8_t WS2812FX::getSpeed(void) +{ return _segments[getMainSegmentId()].speed; } -uint8_t WS2812FX::getBrightness(void) { +uint8_t WS2812FX::getBrightness(void) +{ return _brightness; } -uint8_t WS2812FX::getMaxSegments(void) { +uint8_t WS2812FX::getMaxSegments(void) +{ return MAX_NUM_SEGMENTS; } @@ -441,79 +592,103 @@ uint8_t WS2812FX::getMaxSegments(void) { return 0; }*/ -uint8_t WS2812FX::getMainSegmentId(void) { - if (mainSegment >= MAX_NUM_SEGMENTS) return 0; - if (_segments[mainSegment].isActive()) return mainSegment; +uint8_t WS2812FX::getMainSegmentId(void) +{ + if (mainSegment >= MAX_NUM_SEGMENTS) + return 0; + if (_segments[mainSegment].isActive()) + return mainSegment; for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++) //get first active { - if (_segments[i].isActive()) return i; + if (_segments[i].isActive()) + return i; } return 0; } -uint32_t WS2812FX::getColor(void) { +uint32_t WS2812FX::getColor(void) +{ return _segments[getMainSegmentId()].colors[0]; } uint32_t WS2812FX::getPixelColor(uint16_t i) { i = realPixelIndex(i); - - #ifdef WLED_CUSTOM_LED_MAPPING - if (i < customMappingSize) i = customMappingTable[i]; - #endif - - if (_skipFirstMode) i += LED_SKIP_AMOUNT; - - if (i >= _lengthRaw) return 0; - + +#ifdef WLED_CUSTOM_LED_MAPPING + if (i < customMappingSize) + i = customMappingTable[i]; +#endif + + if (_skipFirstMode) + i += LED_SKIP_AMOUNT; + + if (i >= _lengthRaw) + return 0; + RgbwColor col = bus->GetPixelColorRgbw(i); switch (colorOrder) { - // W G R B - case 0: return ((col.W << 24) | (col.G << 8) | (col.R << 16) | (col.B)); //0 = GRB, default - case 1: return ((col.W << 24) | (col.R << 8) | (col.G << 16) | (col.B)); //1 = RGB, common for WS2811 - case 2: return ((col.W << 24) | (col.B << 8) | (col.R << 16) | (col.G)); //2 = BRG - case 3: return ((col.W << 24) | (col.B << 8) | (col.G << 16) | (col.R)); //3 = RBG - case 4: return ((col.W << 24) | (col.R << 8) | (col.B << 16) | (col.G)); //4 = BGR - case 5: return ((col.W << 24) | (col.G << 8) | (col.B << 16) | (col.R)); //5 = GBR + // W G R B + case 0: + return ((col.W << 24) | (col.G << 8) | (col.R << 16) | (col.B)); //0 = GRB, default + case 1: + return ((col.W << 24) | (col.R << 8) | (col.G << 16) | (col.B)); //1 = RGB, common for WS2811 + case 2: + return ((col.W << 24) | (col.B << 8) | (col.R << 16) | (col.G)); //2 = BRG + case 3: + return ((col.W << 24) | (col.B << 8) | (col.G << 16) | (col.R)); //3 = RBG + case 4: + return ((col.W << 24) | (col.R << 8) | (col.B << 16) | (col.G)); //4 = BGR + case 5: + return ((col.W << 24) | (col.G << 8) | (col.B << 16) | (col.R)); //5 = GBR } return 0; } -WS2812FX::Segment& WS2812FX::getSegment(uint8_t id) { - if (id >= MAX_NUM_SEGMENTS) return _segments[0]; +WS2812FX::Segment &WS2812FX::getSegment(uint8_t id) +{ + if (id >= MAX_NUM_SEGMENTS) + return _segments[0]; return _segments[id]; } -WS2812FX::Segment_runtime WS2812FX::getSegmentRuntime(void) { +WS2812FX::Segment_runtime WS2812FX::getSegmentRuntime(void) +{ return SEGENV; } -WS2812FX::Segment* WS2812FX::getSegments(void) { +WS2812FX::Segment *WS2812FX::getSegments(void) +{ return _segments; } -uint32_t WS2812FX::getLastShow(void) { +uint32_t WS2812FX::getLastShow(void) +{ return _lastShow; } -void WS2812FX::setSegment(uint8_t n, uint16_t i1, uint16_t i2, uint8_t grouping, uint8_t spacing) { - if (n >= MAX_NUM_SEGMENTS) return; - Segment& seg = _segments[n]; +void WS2812FX::setSegment(uint8_t n, uint16_t i1, uint16_t i2, uint8_t grouping, uint8_t spacing) +{ + if (n >= MAX_NUM_SEGMENTS) + return; + Segment &seg = _segments[n]; //return if neither bounds nor grouping have changed - if (seg.start == i1 && seg.stop == i2 && (!grouping || (seg.grouping == grouping && seg.spacing == spacing))) return; + if (seg.start == i1 && seg.stop == i2 && (!grouping || (seg.grouping == grouping && seg.spacing == spacing))) + return; - if (seg.stop) setRange(seg.start, seg.stop -1, 0); //turn old segment range off - if (i2 <= i1) //disable segment + if (seg.stop) + setRange(seg.start, seg.stop - 1, 0); //turn old segment range off + if (i2 <= i1) //disable segment { - seg.stop = 0; + seg.stop = 0; if (n == mainSegment) //if main segment is deleted, set first active as main segment { for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++) { - if (_segments[i].isActive()) { + if (_segments[i].isActive()) + { mainSegment = i; return; } @@ -522,17 +697,21 @@ void WS2812FX::setSegment(uint8_t n, uint16_t i1, uint16_t i2, uint8_t grouping, } return; } - if (i1 < _length) seg.start = i1; + if (i1 < _length) + seg.start = i1; seg.stop = i2; - if (i2 > _length) seg.stop = _length; - if (grouping) { + if (i2 > _length) + seg.stop = _length; + if (grouping) + { seg.grouping = grouping; seg.spacing = spacing; } _segment_runtimes[n].reset(); } -void WS2812FX::resetSegments() { +void WS2812FX::resetSegments() +{ mainSegment = 0; memset(_segments, 0, sizeof(_segments)); //memset(_segment_runtimes, 0, sizeof(_segment_runtimes)); @@ -550,7 +729,7 @@ void WS2812FX::resetSegments() { for (uint16_t i = 1; i < MAX_NUM_SEGMENTS; i++) { - _segments[i].colors[0] = color_wheel(i*51); + _segments[i].colors[0] = color_wheel(i * 51); _segments[i].grouping = 1; _segments[i].setOption(SEG_OPTION_ON, 1); _segments[i].opacity = 255; @@ -564,10 +743,13 @@ void WS2812FX::resetSegments() { //After this function is called, setPixelColor() will use that segment (offsets, grouping, ... will apply) void WS2812FX::setPixelSegment(uint8_t n) { - if (n < MAX_NUM_SEGMENTS) { + if (n < MAX_NUM_SEGMENTS) + { _segment_index = n; _virtualSegmentLength = SEGMENT.length(); - } else { + } + else + { _segment_index = 0; _virtualSegmentLength = 0; } @@ -577,10 +759,13 @@ void WS2812FX::setRange(uint16_t i, uint16_t i2, uint32_t col) { if (i2 >= i) { - for (uint16_t x = i; x <= i2; x++) setPixelColor(x, col); - } else + for (uint16_t x = i; x <= i2; x++) + setPixelColor(x, col); + } + else { - for (uint16_t x = i2; x <= i; x++) setPixelColor(x, col); + for (uint16_t x = i2; x <= i; x++) + setPixelColor(x, col); } } @@ -597,26 +782,30 @@ void WS2812FX::setTransitionMode(bool t) _segment_index = i; SEGMENT.setOption(SEG_OPTION_TRANSITIONAL, t); - if (t && SEGMENT.mode == FX_MODE_STATIC && SEGENV.next_time > waitMax) SEGENV.next_time = waitMax; + if (t && SEGMENT.mode == FX_MODE_STATIC && SEGENV.next_time > waitMax) + SEGENV.next_time = waitMax; } } /* * color blend function */ -uint32_t WS2812FX::color_blend(uint32_t color1, uint32_t color2, uint8_t blend) { - if(blend == 0) return color1; - if(blend == 255) return color2; +uint32_t WS2812FX::color_blend(uint32_t color1, uint32_t color2, uint8_t blend) +{ + if (blend == 0) + return color1; + if (blend == 255) + return color2; uint32_t w1 = (color1 >> 24) & 0xff; uint32_t r1 = (color1 >> 16) & 0xff; - uint32_t g1 = (color1 >> 8) & 0xff; - uint32_t b1 = color1 & 0xff; + uint32_t g1 = (color1 >> 8) & 0xff; + uint32_t b1 = color1 & 0xff; uint32_t w2 = (color2 >> 24) & 0xff; uint32_t r2 = (color2 >> 16) & 0xff; - uint32_t g2 = (color2 >> 8) & 0xff; - uint32_t b2 = color2 & 0xff; + uint32_t g2 = (color2 >> 8) & 0xff; + uint32_t b2 = color2 & 0xff; uint32_t w3 = ((w2 * blend) + (w1 * (255 - blend))) >> 8; uint32_t r3 = ((r2 * blend) + (r1 * (255 - blend))) >> 8; @@ -629,8 +818,10 @@ uint32_t WS2812FX::color_blend(uint32_t color1, uint32_t color2, uint8_t blend) /* * Fills segment with color */ -void WS2812FX::fill(uint32_t c) { - for(uint16_t i = 0; i < SEGLEN; i++) { +void WS2812FX::fill(uint32_t c) +{ + for (uint16_t i = 0; i < SEGLEN; i++) + { setPixelColor(i, c); } } @@ -646,22 +837,24 @@ void WS2812FX::blendPixelColor(uint16_t n, uint32_t color, uint8_t blend) /* * fade out function, higher rate = quicker fade */ -void WS2812FX::fade_out(uint8_t rate) { - rate = (255-rate) >> 1; - float mappedRate = float(rate) +1.1; +void WS2812FX::fade_out(uint8_t rate) +{ + rate = (255 - rate) >> 1; + float mappedRate = float(rate) + 1.1; uint32_t color = SEGCOLOR(1); // target color int w2 = (color >> 24) & 0xff; int r2 = (color >> 16) & 0xff; - int g2 = (color >> 8) & 0xff; - int b2 = color & 0xff; + int g2 = (color >> 8) & 0xff; + int b2 = color & 0xff; - for(uint16_t i = 0; i < SEGLEN; i++) { + for (uint16_t i = 0; i < SEGLEN; i++) + { color = getPixelColor(i); int w1 = (color >> 24) & 0xff; int r1 = (color >> 16) & 0xff; - int g1 = (color >> 8) & 0xff; - int b1 = color & 0xff; + int g1 = (color >> 8) & 0xff; + int b1 = color & 0xff; int wdelta = (w2 - w1) / mappedRate; int rdelta = (r2 - r1) / mappedRate; @@ -686,29 +879,31 @@ void WS2812FX::blur(uint8_t blur_amount) uint8_t keep = 255 - blur_amount; uint8_t seep = blur_amount >> 1; CRGB carryover = CRGB::Black; - for(uint16_t i = 0; i < SEGLEN; i++) + for (uint16_t i = 0; i < SEGLEN; i++) { CRGB cur = col_to_crgb(getPixelColor(i)); CRGB part = cur; part.nscale8(seep); cur.nscale8(keep); cur += carryover; - if(i > 0) { - uint32_t c = getPixelColor(i-1); + if (i > 0) + { + uint32_t c = getPixelColor(i - 1); uint8_t r = (c >> 16 & 0xFF); - uint8_t g = (c >> 8 & 0xFF); - uint8_t b = (c & 0xFF); - setPixelColor(i-1, qadd8(r, part.red), qadd8(g, part.green), qadd8(b, part.blue)); + uint8_t g = (c >> 8 & 0xFF); + uint8_t b = (c & 0xFF); + setPixelColor(i - 1, qadd8(r, part.red), qadd8(g, part.green), qadd8(b, part.blue)); } - setPixelColor(i,cur.red, cur.green, cur.blue); + setPixelColor(i, cur.red, cur.green, cur.blue); carryover = part; } } uint16_t WS2812FX::triwave16(uint16_t in) { - if (in < 0x8000) return in *2; - return 0xFFFF - (in - 0x8000)*2; + if (in < 0x8000) + return in * 2; + return 0xFFFF - (in - 0x8000) * 2; } /* @@ -718,21 +913,26 @@ uint16_t WS2812FX::triwave16(uint16_t in) * @param attdec attac & decay, max. pulsewidth / 2 * @returns signed waveform value */ -int8_t WS2812FX::tristate_square8(uint8_t x, uint8_t pulsewidth, uint8_t attdec) { +int8_t WS2812FX::tristate_square8(uint8_t x, uint8_t pulsewidth, uint8_t attdec) +{ int8_t a = 127; - if (x > 127) { + if (x > 127) + { a = -127; x -= 127; } - if (x < attdec) { //inc to max - return (int16_t) x * a / attdec; + if (x < attdec) + { //inc to max + return (int16_t)x * a / attdec; } - else if (x < pulsewidth - attdec) { //max + else if (x < pulsewidth - attdec) + { //max return a; - } - else if (x < pulsewidth) { //dec to 0 - return (int16_t) (pulsewidth - x) * a / attdec; + } + else if (x < pulsewidth) + { //dec to 0 + return (int16_t)(pulsewidth - x) * a / attdec; } return 0; } @@ -742,15 +942,22 @@ int8_t WS2812FX::tristate_square8(uint8_t x, uint8_t pulsewidth, uint8_t attdec) * The colours are a transition r -> g -> b -> back to r * Inspired by the Adafruit examples. */ -uint32_t WS2812FX::color_wheel(uint8_t pos) { - if (SEGMENT.palette) return color_from_palette(pos, false, true, 0); +uint32_t WS2812FX::color_wheel(uint8_t pos) +{ + if (SEGMENT.palette) + return color_from_palette(pos, false, true, 0); pos = 255 - pos; - if(pos < 85) { + if (pos < 85) + { return ((uint32_t)(255 - pos * 3) << 16) | ((uint32_t)(0) << 8) | (pos * 3); - } else if(pos < 170) { + } + else if (pos < 170) + { pos -= 85; return ((uint32_t)(0) << 16) | ((uint32_t)(pos * 3) << 8) | (255 - pos * 3); - } else { + } + else + { pos -= 170; return ((uint32_t)(pos * 3) << 16) | ((uint32_t)(255 - pos * 3) << 8) | (0); } @@ -759,10 +966,12 @@ uint32_t WS2812FX::color_wheel(uint8_t pos) { /* * Returns a new, random wheel index with a minimum distance of 42 from pos. */ -uint8_t WS2812FX::get_random_wheel_index(uint8_t pos) { +uint8_t WS2812FX::get_random_wheel_index(uint8_t pos) +{ uint8_t r = 0, x = 0, y = 0, d = 0; - while(d < 42) { + while (d < 42) + { r = random8(); x = abs(pos - r); y = 255 - x; @@ -771,32 +980,28 @@ uint8_t WS2812FX::get_random_wheel_index(uint8_t pos) { return r; } - uint32_t WS2812FX::crgb_to_col(CRGB fastled) { return (((uint32_t)fastled.red << 16) | ((uint32_t)fastled.green << 8) | fastled.blue); } - CRGB WS2812FX::col_to_crgb(uint32_t color) { CRGB fastled_col; - fastled_col.red = (color >> 16 & 0xFF); - fastled_col.green = (color >> 8 & 0xFF); - fastled_col.blue = (color & 0xFF); + fastled_col.red = (color >> 16 & 0xFF); + fastled_col.green = (color >> 8 & 0xFF); + fastled_col.blue = (color & 0xFF); return fastled_col; } - void WS2812FX::load_gradient_palette(uint8_t index) { - byte i = constrain(index, 0, GRADIENT_PALETTE_COUNT -1); + byte i = constrain(index, 0, GRADIENT_PALETTE_COUNT - 1); byte tcp[72]; //support gradient palettes with up to 18 entries - memcpy_P(tcp, (byte*)pgm_read_dword(&(gGradientPalettes[i])), 72); + memcpy_P(tcp, (byte *)pgm_read_dword(&(gGradientPalettes[i])), 72); targetPalette.loadDynamicGradientPalette(tcp); } - /* * FastLED palette modes helper function. Limitation: Due to memory reasons, multiple active segments with FastLED will disable the Palette transitions */ @@ -810,88 +1015,135 @@ void WS2812FX::handle_palette(void) { switch (SEGMENT.mode) { - case FX_MODE_FIRE_2012 : paletteIndex = 35; break; //heat palette - case FX_MODE_COLORWAVES : paletteIndex = 26; break; //landscape 33 - case FX_MODE_FILLNOISE8 : paletteIndex = 9; break; //ocean colors - case FX_MODE_NOISE16_1 : paletteIndex = 20; break; //Drywet - case FX_MODE_NOISE16_2 : paletteIndex = 43; break; //Blue cyan yellow - case FX_MODE_NOISE16_3 : paletteIndex = 35; break; //heat palette - case FX_MODE_NOISE16_4 : paletteIndex = 26; break; //landscape 33 - case FX_MODE_GLITTER : paletteIndex = 11; break; //rainbow colors - case FX_MODE_SUNRISE : paletteIndex = 35; break; //heat palette - case FX_MODE_FLOW : paletteIndex = 6; break; //party + case FX_MODE_FIRE_2012: + paletteIndex = 35; + break; //heat palette + case FX_MODE_COLORWAVES: + paletteIndex = 26; + break; //landscape 33 + case FX_MODE_FILLNOISE8: + paletteIndex = 9; + break; //ocean colors + case FX_MODE_NOISE16_1: + paletteIndex = 20; + break; //Drywet + case FX_MODE_NOISE16_2: + paletteIndex = 43; + break; //Blue cyan yellow + case FX_MODE_NOISE16_3: + paletteIndex = 35; + break; //heat palette + case FX_MODE_NOISE16_4: + paletteIndex = 26; + break; //landscape 33 + case FX_MODE_GLITTER: + paletteIndex = 11; + break; //rainbow colors + case FX_MODE_SUNRISE: + paletteIndex = 35; + break; //heat palette + case FX_MODE_FLOW: + paletteIndex = 6; + break; //party } } - if (SEGMENT.mode >= FX_MODE_METEOR && paletteIndex == 0) paletteIndex = 4; - + if (SEGMENT.mode >= FX_MODE_METEOR && paletteIndex == 0) + paletteIndex = 4; + switch (paletteIndex) { - case 0: //default palette. Exceptions for specific effects above - targetPalette = PartyColors_p; break; - case 1: {//periodically replace palette with a random one. Doesn't work with multiple FastLED segments - if (!singleSegmentMode) - { - targetPalette = PartyColors_p; break; //fallback - } - if (millis() - _lastPaletteChange > 1000 + ((uint32_t)(255-SEGMENT.intensity))*100) - { - targetPalette = CRGBPalette16( - CHSV(random8(), 255, random8(128, 255)), - CHSV(random8(), 255, random8(128, 255)), - CHSV(random8(), 192, random8(128, 255)), - CHSV(random8(), 255, random8(128, 255))); - _lastPaletteChange = millis(); - } break;} - case 2: {//primary color only - CRGB prim = col_to_crgb(SEGCOLOR(0)); - targetPalette = CRGBPalette16(prim); break;} - case 3: {//primary + secondary - CRGB prim = col_to_crgb(SEGCOLOR(0)); - CRGB sec = col_to_crgb(SEGCOLOR(1)); - targetPalette = CRGBPalette16(prim,prim,sec,sec); break;} - case 4: {//primary + secondary + tertiary - CRGB prim = col_to_crgb(SEGCOLOR(0)); - CRGB sec = col_to_crgb(SEGCOLOR(1)); - CRGB ter = col_to_crgb(SEGCOLOR(2)); - targetPalette = CRGBPalette16(ter,sec,prim); break;} - case 5: {//primary + secondary (+tert if not off), more distinct - CRGB prim = col_to_crgb(SEGCOLOR(0)); - CRGB sec = col_to_crgb(SEGCOLOR(1)); - if (SEGCOLOR(2)) { - CRGB ter = col_to_crgb(SEGCOLOR(2)); - targetPalette = CRGBPalette16(prim,prim,prim,prim,prim,sec,sec,sec,sec,sec,ter,ter,ter,ter,ter,prim); - } else { - targetPalette = CRGBPalette16(prim,prim,prim,prim,prim,prim,prim,prim,sec,sec,sec,sec,sec,sec,sec,sec); - } - break;} - case 6: //Party colors - targetPalette = PartyColors_p; break; - case 7: //Cloud colors - targetPalette = CloudColors_p; break; - case 8: //Lava colors - targetPalette = LavaColors_p; break; - case 9: //Ocean colors - targetPalette = OceanColors_p; break; - case 10: //Forest colors - targetPalette = ForestColors_p; break; - case 11: //Rainbow colors - targetPalette = RainbowColors_p; break; - case 12: //Rainbow stripe colors - targetPalette = RainbowStripeColors_p; break; - default: //progmem palettes - load_gradient_palette(paletteIndex -13); - } - + case 0: //default palette. Exceptions for specific effects above + targetPalette = PartyColors_p; + break; + case 1: + { //periodically replace palette with a random one. Doesn't work with multiple FastLED segments + if (!singleSegmentMode) + { + targetPalette = PartyColors_p; + break; //fallback + } + if (millis() - _lastPaletteChange > 1000 + ((uint32_t)(255 - SEGMENT.intensity)) * 100) + { + targetPalette = CRGBPalette16( + CHSV(random8(), 255, random8(128, 255)), + CHSV(random8(), 255, random8(128, 255)), + CHSV(random8(), 192, random8(128, 255)), + CHSV(random8(), 255, random8(128, 255))); + _lastPaletteChange = millis(); + } + break; + } + case 2: + { //primary color only + CRGB prim = col_to_crgb(SEGCOLOR(0)); + targetPalette = CRGBPalette16(prim); + break; + } + case 3: + { //primary + secondary + CRGB prim = col_to_crgb(SEGCOLOR(0)); + CRGB sec = col_to_crgb(SEGCOLOR(1)); + targetPalette = CRGBPalette16(prim, prim, sec, sec); + break; + } + case 4: + { //primary + secondary + tertiary + CRGB prim = col_to_crgb(SEGCOLOR(0)); + CRGB sec = col_to_crgb(SEGCOLOR(1)); + CRGB ter = col_to_crgb(SEGCOLOR(2)); + targetPalette = CRGBPalette16(ter, sec, prim); + break; + } + case 5: + { //primary + secondary (+tert if not off), more distinct + CRGB prim = col_to_crgb(SEGCOLOR(0)); + CRGB sec = col_to_crgb(SEGCOLOR(1)); + if (SEGCOLOR(2)) + { + CRGB ter = col_to_crgb(SEGCOLOR(2)); + targetPalette = CRGBPalette16(prim, prim, prim, prim, prim, sec, sec, sec, sec, sec, ter, ter, ter, ter, ter, prim); + } + else + { + targetPalette = CRGBPalette16(prim, prim, prim, prim, prim, prim, prim, prim, sec, sec, sec, sec, sec, sec, sec, sec); + } + break; + } + case 6: //Party colors + targetPalette = PartyColors_p; + break; + case 7: //Cloud colors + targetPalette = CloudColors_p; + break; + case 8: //Lava colors + targetPalette = LavaColors_p; + break; + case 9: //Ocean colors + targetPalette = OceanColors_p; + break; + case 10: //Forest colors + targetPalette = ForestColors_p; + break; + case 11: //Rainbow colors + targetPalette = RainbowColors_p; + break; + case 12: //Rainbow stripe colors + targetPalette = RainbowStripeColors_p; + break; + default: //progmem palettes + load_gradient_palette(paletteIndex - 13); + } + if (singleSegmentMode && paletteFade && SEGENV.call > 0) //only blend if just one segment uses FastLED mode { nblendPaletteTowardPalette(currentPalette, targetPalette, 48); - } else + } + else { currentPalette = targetPalette; } } - /* * Gets a single color from the currently selected palette. * @param i Palette Index (if mapping is true, the full palette will be SEGLEN long, if false, 255). Will wrap around automatically. @@ -903,66 +1155,90 @@ void WS2812FX::handle_palette(void) */ uint32_t WS2812FX::color_from_palette(uint16_t i, bool mapping, bool wrap, uint8_t mcol, uint8_t pbri) { - if (SEGMENT.palette == 0 && mcol < 3) return SEGCOLOR(mcol); //WS2812FX default + if (SEGMENT.palette == 0 && mcol < 3) + return SEGCOLOR(mcol); //WS2812FX default uint8_t paletteIndex = i; - if (mapping) paletteIndex = (i*255)/(SEGLEN -1); - if (!wrap) paletteIndex = scale8(paletteIndex, 240); //cut off blend at palette "end" + if (mapping) + paletteIndex = (i * 255) / (SEGLEN - 1); + if (!wrap) + paletteIndex = scale8(paletteIndex, 240); //cut off blend at palette "end" CRGB fastled_col; - fastled_col = ColorFromPalette( currentPalette, paletteIndex, pbri, (paletteBlend == 3)? NOBLEND:LINEARBLEND); - return fastled_col.r*65536 + fastled_col.g*256 + fastled_col.b; + fastled_col = ColorFromPalette(currentPalette, paletteIndex, pbri, (paletteBlend == 3) ? NOBLEND : LINEARBLEND); + return fastled_col.r * 65536 + fastled_col.g * 256 + fastled_col.b; } //@returns `true` if color, mode, speed, intensity and palette match -bool WS2812FX::segmentsAreIdentical(Segment* a, Segment* b) +bool WS2812FX::segmentsAreIdentical(Segment *a, Segment *b) { //if (a->start != b->start) return false; //if (a->stop != b->stop) return false; for (uint8_t i = 0; i < NUM_COLORS; i++) { - if (a->colors[i] != b->colors[i]) return false; + if (a->colors[i] != b->colors[i]) + return false; } - if (a->mode != b->mode) return false; - if (a->speed != b->speed) return false; - if (a->intensity != b->intensity) return false; - if (a->palette != b->palette) return false; + if (a->mode != b->mode) + return false; + if (a->speed != b->speed) + return false; + if (a->intensity != b->intensity) + return false; + if (a->palette != b->palette) + return false; //if (a->getOption(SEG_OPTION_REVERSED) != b->getOption(SEG_OPTION_REVERSED)) return false; return true; } -#ifdef WLED_USE_ANALOG_LEDS -void WS2812FX::setRgbwPwm(void) { +#ifdef WLED_USE_ANALOG_LEDS +void WS2812FX::setRgbwPwm(void) +{ uint32_t nowUp = millis(); // Be aware, millis() rolls over every 49 days - if (nowUp - _analogLastShow < MIN_SHOW_DELAY) return; + if (nowUp - _analogLastShow < MIN_SHOW_DELAY) + return; _analogLastShow = nowUp; RgbwColor color = bus->GetPixelColorRgbw(0); byte b = getBrightness(); - if (color == _analogLastColor && b == _analogLastBri) return; - - // check color values for Warm / Cold white mix (for RGBW) // EsplanexaDevice.cpp - #ifdef WLED_USE_5CH_LEDS - if (color.R == 255 && color.G == 255 && color.B == 255 && color.W == 255) { - bus->SetRgbwPwm(0, 0, 0, 0, color.W * b / 255); - } else if (color.R == 127 && color.G == 127 && color.B == 127 && color.W == 255) { - bus->SetRgbwPwm(0, 0, 0, color.W * b / 512, color.W * b / 255); - } else if (color.R == 0 && color.G == 0 && color.B == 0 && color.W == 255) { - bus->SetRgbwPwm(0, 0, 0, color.W * b / 255, 0); - } else if (color.R == 130 && color.G == 90 && color.B == 0 && color.W == 255) { - bus->SetRgbwPwm(0, 0, 0, color.W * b / 255, color.W * b / 512); - } else if (color.R == 255 && color.G == 153 && color.B == 0 && color.W == 255) { - bus->SetRgbwPwm(0, 0, 0, color.W * b / 255, 0); - } else { // not only white colors - bus->SetRgbwPwm(color.R * b / 255, color.G * b / 255, color.B * b / 255, color.W * b / 255); - } - #else + if (color == _analogLastColor && b == _analogLastBri) + return; + +// check color values for Warm / Cold white mix (for RGBW) // EsplanexaDevice.cpp +#ifdef WLED_USE_5CH_LEDS + if (color.R == 255 && color.G == 255 && color.B == 255 && color.W == 255) + { + bus->SetRgbwPwm(0, 0, 0, 0, color.W * b / 255); + } + else if (color.R == 127 && color.G == 127 && color.B == 127 && color.W == 255) + { + bus->SetRgbwPwm(0, 0, 0, color.W * b / 512, color.W * b / 255); + } + else if (color.R == 0 && color.G == 0 && color.B == 0 && color.W == 255) + { + bus->SetRgbwPwm(0, 0, 0, color.W * b / 255, 0); + } + else if (color.R == 130 && color.G == 90 && color.B == 0 && color.W == 255) + { + bus->SetRgbwPwm(0, 0, 0, color.W * b / 255, color.W * b / 512); + } + else if (color.R == 255 && color.G == 153 && color.B == 0 && color.W == 255) + { + bus->SetRgbwPwm(0, 0, 0, color.W * b / 255, 0); + } + else + { // not only white colors bus->SetRgbwPwm(color.R * b / 255, color.G * b / 255, color.B * b / 255, color.W * b / 255); - #endif + } +#else + bus->SetRgbwPwm(color.R * b / 255, color.G * b / 255, color.B * b / 255, color.W * b / 255); +#endif _analogLastColor = color; _analogLastBri = b; } #else -void WS2812FX::setRgbwPwm() {} +void WS2812FX::setRgbwPwm() +{ +} #endif //gamma 2.8 lookup table used for color correction @@ -1002,11 +1278,12 @@ uint8_t WS2812FX::gamma8(uint8_t b) uint32_t WS2812FX::gamma32(uint32_t color) { - if (!gammaCorrectCol) return color; + if (!gammaCorrectCol) + return color; uint8_t w = (color >> 24); uint8_t r = (color >> 16); - uint8_t g = (color >> 8); - uint8_t b = color; + uint8_t g = (color >> 8); + uint8_t b = color; w = gammaT[w]; r = gammaT[r]; g = gammaT[g]; diff --git a/wled00/NpbWrapper.h b/wled00/NpbWrapper.h index d867ef86b3..459dd06492 100644 --- a/wled00/NpbWrapper.h +++ b/wled00/NpbWrapper.h @@ -1,9 +1,12 @@ //this code is a modified version of https://github.com/Makuna/NeoPixelBus/issues/103 + + #ifndef NpbWrapper_h #define NpbWrapper_h //PIN CONFIGURATION #ifndef LEDPIN +//LEDPIN variable is ignored in multipin mod. configure strip number output PIN variables instead: STRIP1_PIN, STRIP2_PIN, etc. #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) #endif //#define USE_APA102 // Uncomment for using APA102 LEDs. @@ -26,11 +29,11 @@ #endif #ifndef IR_PIN -#define IR_PIN 4 //infrared pin (-1 to disable) MagicHome: 4, H801 Wifi: 0 +#define IR_PIN -1 //infrared pin (-1 to disable) MagicHome: 4, H801 Wifi: 0 #endif #ifndef RLYPIN -#define RLYPIN 12 //pin for relay, will be set HIGH if LEDs are on (-1 to disable). Also usable for standby leds, triggers,... +#define RLYPIN -1 //pin for relay, will be set HIGH if LEDs are on (-1 to disable). Also usable for standby leds, triggers,... #endif #ifndef AUXPIN @@ -41,8 +44,117 @@ #define RLYMDE 1 //mode for relay, 0: LOW if LEDs are on 1: HIGH if LEDs are on #endif +// How many strips will be connected. currently up to 8 strips is possible. +#define NUM_STRIPS 7 +#define SHOW_CLOCK +// multipin mod configuration: + +//Outside Count +#define OC 198 +//Inside Count +#define IC 166 +//Tower Outside Count +#define TOC 36 +//Tower Inside Count +#define TIC 28 +//Center Tower Count +#define CTC 57 +//Matrix Count +#define MC 256 + +// What pins to use: +#define STRIP1_PIN 12 //Outside +#define STRIP2_PIN 14 //Inside +#define STRIP3_PIN 27 //Left Tower Outside +#define STRIP4_PIN 26 //Left Tower Inside +#define STRIP5_PIN 15 //Right Tower Outside +#define STRIP6_PIN 2 //Right Tower Inside +#define STRIP7_PIN 0 //Center Tower +#define STRIP8_PIN 4 //Matrix + +// How many LEDs are on each strip: +#define STRIP1_LEDCOUNT OC +#define STRIP2_LEDCOUNT IC +#define STRIP3_LEDCOUNT TOC +#define STRIP4_LEDCOUNT TIC +#define STRIP5_LEDCOUNT TOC +#define STRIP6_LEDCOUNT TIC +#define STRIP7_LEDCOUNT CTC +#define STRIP8_LEDCOUNT MC + +// What pixelmethod to use on each strip? +#define STRIP1_PIXELMETHOD NeoEsp32Rmt0Ws2812xMethod // the board specific PIXELMETHOD variable is being ignored now, so make sure it's set here! +#define STRIP2_PIXELMETHOD NeoEsp32Rmt1Ws2812xMethod // define what method you want to use to drive each strip. For esp32 RMT 0-7 works best. +#define STRIP3_PIXELMETHOD NeoEsp32Rmt2Ws2812xMethod +#define STRIP4_PIXELMETHOD NeoEsp32Rmt3Ws2812xMethod +#define STRIP5_PIXELMETHOD NeoEsp32Rmt4Ws2812xMethod +#define STRIP6_PIXELMETHOD NeoEsp32Rmt5Ws2812xMethod +#define STRIP7_PIXELMETHOD NeoEsp32Rmt6Ws2812xMethod +#define STRIP8_PIXELMETHOD NeoEsp32Rmt7Ws2812xMethod + + //END CONFIGURATION +// do calculations to find the starting LED index position of each strip: +#define STRIP1_STARTLED 0 +#define STRIP2_STARTLED STRIP1_STARTLED + STRIP1_LEDCOUNT +#define STRIP3_STARTLED STRIP2_STARTLED + STRIP2_LEDCOUNT +#define STRIP4_STARTLED STRIP3_STARTLED + STRIP3_LEDCOUNT +#define STRIP5_STARTLED STRIP4_STARTLED + STRIP4_LEDCOUNT +#define STRIP6_STARTLED STRIP5_STARTLED + STRIP5_LEDCOUNT +#define STRIP7_STARTLED STRIP6_STARTLED + STRIP6_LEDCOUNT +#define STRIP8_STARTLED STRIP7_STARTLED + STRIP7_LEDCOUNT +#define STRIP9_STARTLED STRIP8_STARTLED + STRIP8_LEDCOUNT // using this for calculation of strip8's end led + +// calculate the ending LED index of each strip: +#define STRIP1_ENDLED STRIP2_STARTLED - 1 +#define STRIP2_ENDLED STRIP3_STARTLED - 1 +#define STRIP3_ENDLED STRIP4_STARTLED - 1 +#define STRIP4_ENDLED STRIP5_STARTLED - 1 +#define STRIP5_ENDLED STRIP6_STARTLED - 1 +#define STRIP6_ENDLED STRIP7_STARTLED - 1 +#define STRIP7_ENDLED STRIP8_STARTLED - 1 +#define STRIP8_ENDLED STRIP9_STARTLED - 1 + + + + +// find the total number of LEDs available in the physical system by reusing the math done above, then do strip 8 math +#if NUM_STRIPS == 1 +#define NUM_LEDS STRIP2_STARTLED +#endif + +#if NUM_STRIPS == 2 +#define NUM_LEDS STRIP3_STARTLED +#endif + +#if NUM_STRIPS == 3 +#define NUM_LEDS STRIP4_STARTLED +#endif + +#if NUM_STRIPS == 4 +#define NUM_LEDS STRIP5_STARTLED +#endif + +#if NUM_STRIPS == 5 +#define NUM_LEDS STRIP6_STARTLED +#endif + +#if NUM_STRIPS == 6 +#define NUM_LEDS STRIP7_STARTLED +#endif + +#if NUM_STRIPS == 7 +#define NUM_LEDS STRIP8_STARTLED +#endif + +#if NUM_STRIPS == 8 +#define NUM_LEDS STRIP9_STARTLED +#endif + + +//END calculations + #if defined(USE_APA102) || defined(USE_WS2801) || defined(USE_LPD8806) || defined(USE_P9813) #ifndef CLKPIN #define CLKPIN 0 @@ -182,11 +294,53 @@ class NeoPixelWrapper public: NeoPixelWrapper() : // initialize each member to null - _pGrb(NULL), - _pGrbw(NULL), + _pGrb(NULL), // strip1 + #if NUM_STRIPS > 1 + _pGrb2(NULL), // strip2 + #endif + #if NUM_STRIPS > 2 + _pGrb3(NULL), // strip3 + #endif + #if NUM_STRIPS > 3 + _pGrb4(NULL), // strip4 + #endif + #if NUM_STRIPS > 4 + _pGrb5(NULL), // strip5 + #endif + #if NUM_STRIPS > 5 + _pGrb6(NULL), // strip6 + #endif + #if NUM_STRIPS > 6 + _pGrb7(NULL), // strip7 + #endif + #if NUM_STRIPS > 7 + _pGrb8(NULL), // strip8 + #endif + _pGrbw(NULL), // strip1 + #if NUM_STRIPS > 1 + _pGrbw2(NULL), // strip2 + #endif + #if NUM_STRIPS > 2 + _pGrbw3(NULL), // strip3 + #endif + #if NUM_STRIPS > 3 + _pGrbw4(NULL), // strip4 + #endif + #if NUM_STRIPS > 4 + _pGrbw5(NULL), // strip5 + #endif + #if NUM_STRIPS > 5 + _pGrbw6(NULL), // strip6 + #endif + #if NUM_STRIPS > 6 + _pGrbw7(NULL), // strip7 + #endif + #if NUM_STRIPS > 7 + _pGrbw8(NULL), // strip8 + #endif _type(NeoPixelType_None) { - + } ~NeoPixelWrapper() @@ -194,10 +348,13 @@ class NeoPixelWrapper cleanup(); } + + void Begin(NeoPixelType type, uint16_t countPixels) { cleanup(); _type = type; + //MatrixBegin(); switch (_type) { @@ -205,18 +362,76 @@ class NeoPixelWrapper #if defined(USE_APA102) || defined(USE_WS2801) || defined(USE_LPD8806) || defined(USE_P9813) _pGrb = new NeoPixelBrightnessBus(countPixels, CLKPIN, DATAPIN); #else - _pGrb = new NeoPixelBrightnessBus(countPixels, LEDPIN); + _pGrb = new NeoPixelBrightnessBus(STRIP1_LEDCOUNT, STRIP1_PIN); // strip1 + _pGrb->Begin(); // strip1 + #if NUM_STRIPS > 1 + _pGrb2 = new NeoPixelBrightnessBus(STRIP2_LEDCOUNT, STRIP2_PIN); // strip2 + _pGrb2->Begin(); // strip2 + #endif + #if NUM_STRIPS > 2 + _pGrb3 = new NeoPixelBrightnessBus(STRIP3_LEDCOUNT, STRIP3_PIN); // strip3 + _pGrb3->Begin(); // strip3 + #endif + #if NUM_STRIPS > 3 + _pGrb4 = new NeoPixelBrightnessBus(STRIP4_LEDCOUNT, STRIP4_PIN); // strip4 + _pGrb4->Begin(); // strip4 + #endif + #if NUM_STRIPS > 4 + _pGrb5 = new NeoPixelBrightnessBus(STRIP5_LEDCOUNT, STRIP5_PIN); // strip5 + _pGrb5->Begin(); // strip5 + #endif + #if NUM_STRIPS > 5 + _pGrb6 = new NeoPixelBrightnessBus(STRIP6_LEDCOUNT, STRIP6_PIN); // strip6 + _pGrb6->Begin(); // strip6 + #endif + #if NUM_STRIPS > 6 + _pGrb7 = new NeoPixelBrightnessBus(STRIP7_LEDCOUNT, STRIP7_PIN); // strip7 + _pGrb7->Begin(); // strip7 + #endif + #if NUM_STRIPS > 7 + _pGrb8 = new NeoPixelBrightnessBus(STRIP8_LEDCOUNT, STRIP8_PIN); // strip8 + _pGrb8->Begin(); // strip8 + #endif #endif - _pGrb->Begin(); break; case NeoPixelType_Grbw: #if defined(USE_APA102) || defined(USE_WS2801) || defined(USE_LPD8806) || defined(USE_P9813) _pGrbw = new NeoPixelBrightnessBus(countPixels, CLKPIN, DATAPIN); #else - _pGrbw = new NeoPixelBrightnessBus(countPixels, LEDPIN); + // _pGrbw = new NeoPixelBrightnessBus(countPixels, LEDPIN); + _pGrbw = new NeoPixelBrightnessBus(STRIP1_LEDCOUNT, STRIP1_PIN); // strip1 + _pGrbw->Begin(); // strip1 + #if NUM_STRIPS > 1 + _pGrbw2 = new NeoPixelBrightnessBus(STRIP2_LEDCOUNT, STRIP2_PIN); // strip2 + _pGrbw2->Begin(); // strip2 + #endif + #if NUM_STRIPS > 2 + _pGrbw3 = new NeoPixelBrightnessBus(STRIP3_LEDCOUNT, STRIP3_PIN); // strip3 + _pGrbw3->Begin(); // strip3 + #endif + #if NUM_STRIPS > 3 + _pGrbw4 = new NeoPixelBrightnessBus(STRIP4_LEDCOUNT, STRIP4_PIN); // strip4 + _pGrbw4->Begin(); // strip4 + #endif + #if NUM_STRIPS > 4 + _pGrbw5 = new NeoPixelBrightnessBus(STRIP5_LEDCOUNT, STRIP5_PIN); // strip5 + _pGrbw5->Begin(); // strip5 + #endif + #if NUM_STRIPS > 5 + _pGrbw6 = new NeoPixelBrightnessBus(STRIP6_LEDCOUNT, STRIP6_PIN); // strip6 + _pGrbw6->Begin(); // strip6 + #endif + #if NUM_STRIPS > 6 + _pGrbw7 = new NeoPixelBrightnessBus(STRIP7_LEDCOUNT, STRIP7_PIN); // strip7 + _pGrbw7->Begin(); // strip7 + #endif + #if NUM_STRIPS > 7 + _pGrbw8 = new NeoPixelBrightnessBus(STRIP8_LEDCOUNT, STRIP8_PIN); // strip8 + _pGrbw8->Begin(); // strip8 + #endif #endif - _pGrbw->Begin(); + //_pGrbw->Begin(); break; } @@ -291,8 +506,57 @@ class NeoPixelWrapper byte b; switch (_type) { - case NeoPixelType_Grb: _pGrb->Show(); break; - case NeoPixelType_Grbw: _pGrbw->Show(); break; + case NeoPixelType_Grb: { + _pGrb->Show(); //strip1 + #if NUM_STRIPS > 1 + _pGrb2->Show(); //strip2 + #endif + #if NUM_STRIPS > 2 + _pGrb3->Show(); //strip3 + #endif + #if NUM_STRIPS > 3 + _pGrb4->Show(); //strip4 + #endif + #if NUM_STRIPS > 4 + _pGrb5->Show(); //strip5 + #endif + #if NUM_STRIPS > 5 + _pGrb6->Show(); //strip6 + #endif + #if NUM_STRIPS > 6 + _pGrb7->Show(); //strip7 + #endif + #if NUM_STRIPS > 7 + _pGrb8->Show(); //strip8 + #endif + break; + } + //case NeoPixelType_Grbw: _pGrbw->Show(); break; + case NeoPixelType_Grbw: { + _pGrbw->Show(); //strip1 + #if NUM_STRIPS > 1 + _pGrbw2->Show(); //strip2 + #endif + #if NUM_STRIPS > 2 + _pGrbw3->Show(); //strip3 + #endif + #if NUM_STRIPS > 3 + _pGrbw4->Show(); //strip4 + #endif + #if NUM_STRIPS > 4 + _pGrbw5->Show(); //strip5 + #endif + #if NUM_STRIPS > 5 + _pGrbw6->Show(); //strip6 + #endif + #if NUM_STRIPS > 6 + _pGrbw7->Show(); //strip7 + #endif + #if NUM_STRIPS > 7 + _pGrbw8->Show(); //strip8 + #endif + break; + } } } @@ -300,16 +564,137 @@ class NeoPixelWrapper { switch (_type) { case NeoPixelType_Grb: { - _pGrb->SetPixelColor(indexPixel, RgbColor(color.R,color.G,color.B)); + // using the preprocessor math variables, assign the color to the correct LED on the correct strip based on its index + // calculate the strip specific location from the indexPixel provided, again re-using the math variables. + switch (indexPixel) { + case STRIP1_STARTLED ... STRIP1_ENDLED: + _pGrb->SetPixelColor(indexPixel, RgbColor(color.R,color.G,color.B)); + break; + #if NUM_STRIPS > 1 + case STRIP2_STARTLED ... STRIP2_ENDLED: + _pGrb2->SetPixelColor((indexPixel -= STRIP2_STARTLED), RgbColor(color.R,color.G,color.B)); + break; + #endif + #if NUM_STRIPS > 2 + case STRIP3_STARTLED ... STRIP3_ENDLED: + _pGrb3->SetPixelColor((indexPixel -= STRIP3_STARTLED), RgbColor(color.R,color.G,color.B)); + break; + #endif + #if NUM_STRIPS > 3 + case STRIP4_STARTLED ... STRIP4_ENDLED: + _pGrb4->SetPixelColor((indexPixel -= STRIP4_STARTLED), RgbColor(color.R,color.G,color.B)); + break; + #endif + #if NUM_STRIPS > 4 + case STRIP5_STARTLED ... STRIP5_ENDLED: + _pGrb5->SetPixelColor((indexPixel -= STRIP5_STARTLED), RgbColor(color.R,color.G,color.B)); + break; + #endif + #if NUM_STRIPS > 5 + case STRIP6_STARTLED ... STRIP6_ENDLED: + _pGrb6->SetPixelColor((indexPixel -= STRIP6_STARTLED), RgbColor(color.R,color.G,color.B)); + break; + #endif + #if NUM_STRIPS > 6 + case STRIP7_STARTLED ... STRIP7_ENDLED: + _pGrb7->SetPixelColor((indexPixel -= STRIP7_STARTLED), RgbColor(color.R,color.G,color.B)); + break; + #endif + #if NUM_STRIPS > 7 + case STRIP8_STARTLED ... STRIP8_ENDLED: + _pGrb8->SetPixelColor((indexPixel -= STRIP8_STARTLED), RgbColor(color.R,color.G,color.B)); + break; + #endif + } } break; case NeoPixelType_Grbw: { #if defined(USE_LPD8806) || defined(USE_WS2801) - _pGrbw->SetPixelColor(indexPixel, RgbColor(color.R,color.G,color.B)); + // _pGrbw->SetPixelColor(indexPixel, RgbColor(color.R,color.G,color.B)); + switch (indexPixel) { + case STRIP1_STARTLED ... STRIP1_ENDLED: + _pGrbw->SetPixelColor(indexPixel, RgbColor(color.R,color.G,color.B)); + break; + #if NUM_STRIPS > 1 + case STRIP2_STARTLED ... STRIP2_ENDLED: + _pGrbw2->SetPixelColor((indexPixel -= STRIP2_STARTLED), RgbColor(color.R,color.G,color.B)); + break; + #endif + #if NUM_STRIPS > 2 + case STRIP3_STARTLED ... STRIP3_ENDLED: + _pGrbw3->SetPixelColor((indexPixel -= STRIP3_STARTLED), RgbColor(color.R,color.G,color.B)); + break; + #endif + #if NUM_STRIPS > 3 + case STRIP4_STARTLED ... STRIP4_ENDLED: + _pGrbw4->SetPixelColor((indexPixel -= STRIP4_STARTLED), RgbColor(color.R,color.G,color.B)); + break; + #endif + #if NUM_STRIPS > 4 + case STRIP5_STARTLED ... STRIP5_ENDLED: + _pGrbw5->SetPixelColor((indexPixel -= STRIP5_STARTLED), RgbColor(color.R,color.G,color.B)); + break; + #endif + #if NUM_STRIPS > 5 + case STRIP6_STARTLED ... STRIP6_ENDLED: + _pGrbw6->SetPixelColor((indexPixel -= STRIP6_STARTLED), RgbColor(color.R,color.G,color.B)); + break; + #endif + #if NUM_STRIPS > 6 + case STRIP7_STARTLED ... STRIP7_ENDLED: + _pGrbw7->SetPixelColor((indexPixel -= STRIP7_STARTLED), RgbColor(color.R,color.G,color.B)); + break; + #endif + #if NUM_STRIPS > 7 + case STRIP8_STARTLED ... STRIP8_ENDLED: + _pGrbw8->SetPixelColor((indexPixel -= STRIP8_STARTLED), RgbColor(color.R,color.G,color.B)); + break; + #endif + } #else - _pGrbw->SetPixelColor(indexPixel, color); - #endif + // _pGrbw->SetPixelColor(indexPixel, color); + switch (indexPixel) { + case STRIP1_STARTLED ... STRIP1_ENDLED: + _pGrbw->SetPixelColor(indexPixel, color); + break; + #if NUM_STRIPS > 1 + case STRIP2_STARTLED ... STRIP2_ENDLED: + _pGrbw2->SetPixelColor((indexPixel -= STRIP2_STARTLED), color); + break; + #endif + #if NUM_STRIPS > 2 + case STRIP3_STARTLED ... STRIP3_ENDLED: + _pGrbw3->SetPixelColor((indexPixel -= STRIP3_STARTLED), color); + break; + #endif + #if NUM_STRIPS > 3 + case STRIP4_STARTLED ... STRIP4_ENDLED: + _pGrbw4->SetPixelColor((indexPixel -= STRIP4_STARTLED), color); + break; + #endif + #if NUM_STRIPS > 4 + case STRIP5_STARTLED ... STRIP5_ENDLED: + _pGrbw5->SetPixelColor((indexPixel -= STRIP5_STARTLED), color); + break; + #endif + #if NUM_STRIPS > 5 + case STRIP6_STARTLED ... STRIP6_ENDLED: + _pGrbw6->SetPixelColor((indexPixel -= STRIP6_STARTLED), color); + break; + #endif + #if NUM_STRIPS > 6 + case STRIP7_STARTLED ... STRIP7_ENDLED: + _pGrbw7->SetPixelColor((indexPixel -= STRIP7_STARTLED), color); + break; + #endif + #if NUM_STRIPS > 7 + case STRIP8_STARTLED ... STRIP8_ENDLED: + _pGrbw8->SetPixelColor((indexPixel -= STRIP8_STARTLED), color); + break; + #endif + } } + #endif break; } @@ -318,8 +703,57 @@ class NeoPixelWrapper void SetBrightness(byte b) { switch (_type) { - case NeoPixelType_Grb: _pGrb->SetBrightness(b); break; - case NeoPixelType_Grbw:_pGrbw->SetBrightness(b); break; + case NeoPixelType_Grb: { + _pGrb->SetBrightness(b); //strip1 + #if NUM_STRIPS > 1 + _pGrb2->SetBrightness(b); //strip2 + #endif + #if NUM_STRIPS > 2 + _pGrb3->SetBrightness(b); //strip3 + #endif + #if NUM_STRIPS > 3 + _pGrb4->SetBrightness(b); //strip4 + #endif + #if NUM_STRIPS > 4 + _pGrb5->SetBrightness(b); //strip5 + #endif + #if NUM_STRIPS > 5 + _pGrb6->SetBrightness(b); //strip6 + #endif + #if NUM_STRIPS > 6 + _pGrb7->SetBrightness(b); //strip7 + #endif + #if NUM_STRIPS > 7 + _pGrb8->SetBrightness(b); //strip8 + #endif + break; + } + //case NeoPixelType_Grbw:_pGrbw->SetBrightness(b); break; + case NeoPixelType_Grbw: { + _pGrbw->SetBrightness(b); //strip1 + #if NUM_STRIPS > 1 + _pGrbw2->SetBrightness(b); //strip2 + #endif + #if NUM_STRIPS > 2 + _pGrbw3->SetBrightness(b); //strip3 + #endif + #if NUM_STRIPS > 3 + _pGrbw4->SetBrightness(b); //strip4 + #endif + #if NUM_STRIPS > 4 + _pGrbw5->SetBrightness(b); //strip5 + #endif + #if NUM_STRIPS > 5 + _pGrbw6->SetBrightness(b); //strip6 + #endif + #if NUM_STRIPS > 6 + _pGrbw7->SetBrightness(b); //strip7 + #endif + #if NUM_STRIPS > 7 + _pGrbw8->SetBrightness(b); //strip8 + #endif + break; + } } } @@ -328,13 +762,94 @@ class NeoPixelWrapper RgbwColor GetPixelColorRgbw(uint16_t indexPixel) const { switch (_type) { - case NeoPixelType_Grb: return _pGrb->GetPixelColor(indexPixel); break; - case NeoPixelType_Grbw: return _pGrbw->GetPixelColor(indexPixel); break; + case NeoPixelType_Grb: + switch (indexPixel) { + case STRIP1_STARTLED ... STRIP1_ENDLED: + return _pGrb->GetPixelColor(indexPixel); + break; + #if NUM_STRIPS > 1 + case STRIP2_STARTLED ... STRIP2_ENDLED: + return _pGrb2->GetPixelColor((indexPixel -= STRIP2_STARTLED)); + break; + #endif + #if NUM_STRIPS > 2 + case STRIP3_STARTLED ... STRIP3_ENDLED: + return _pGrb3->GetPixelColor((indexPixel -= STRIP3_STARTLED)); + break; + #endif + #if NUM_STRIPS > 3 + case STRIP4_STARTLED ... STRIP4_ENDLED: + return _pGrb4->GetPixelColor((indexPixel -= STRIP4_STARTLED)); + break; + #endif + #if NUM_STRIPS > 4 + case STRIP5_STARTLED ... STRIP5_ENDLED: + return _pGrb5->GetPixelColor((indexPixel -= STRIP5_STARTLED)); + break; + #endif + #if NUM_STRIPS > 5 + case STRIP6_STARTLED ... STRIP6_ENDLED: + return _pGrb6->GetPixelColor((indexPixel -= STRIP6_STARTLED)); + break; + #endif + #if NUM_STRIPS > 6 + case STRIP7_STARTLED ... STRIP7_ENDLED: + return _pGrb7->GetPixelColor((indexPixel -= STRIP7_STARTLED)); + break; + #endif + #if NUM_STRIPS > 7 + case STRIP8_STARTLED ... STRIP8_ENDLED: + return _pGrb8->GetPixelColor((indexPixel -= STRIP8_STARTLED)); + break; + #endif + } + // case NeoPixelType_Grbw: return _pGrbw->GetPixelColor(indexPixel); break; + case NeoPixelType_Grbw: + switch (indexPixel) { + case STRIP1_STARTLED ... STRIP1_ENDLED: + return _pGrbw->GetPixelColor(indexPixel); + break; + #if NUM_STRIPS > 1 + case STRIP2_STARTLED ... STRIP2_ENDLED: + return _pGrbw2->GetPixelColor((indexPixel -= STRIP2_STARTLED)); + break; + #endif + #if NUM_STRIPS > 2 + case STRIP3_STARTLED ... STRIP3_ENDLED: + return _pGrbw3->GetPixelColor((indexPixel -= STRIP3_STARTLED)); + break; + #endif + #if NUM_STRIPS > 3 + case STRIP4_STARTLED ... STRIP4_ENDLED: + return _pGrbw4->GetPixelColor((indexPixel -= STRIP4_STARTLED)); + break; + #endif + #if NUM_STRIPS > 4 + case STRIP5_STARTLED ... STRIP5_ENDLED: + return _pGrbw5->GetPixelColor((indexPixel -= STRIP5_STARTLED)); + break; + #endif + #if NUM_STRIPS > 5 + case STRIP6_STARTLED ... STRIP6_ENDLED: + return _pGrbw6->GetPixelColor((indexPixel -= STRIP6_STARTLED)); + break; + #endif + #if NUM_STRIPS > 6 + case STRIP7_STARTLED ... STRIP7_ENDLED: + return _pGrbw7->GetPixelColor((indexPixel -= STRIP7_STARTLED)); + break; + #endif + #if NUM_STRIPS > 7 + case STRIP8_STARTLED ... STRIP8_ENDLED: + return _pGrbw8->GetPixelColor((indexPixel -= STRIP8_STARTLED)); + break; + #endif + } } return 0; } - uint8_t* GetPixels(void) + uint8_t* GetPixels(void)//GetPixels function wont work correctly in multistrip mod, as it will only return strip1's pixels! { switch (_type) { case NeoPixelType_Grb: return _pGrb->Pixels(); break; @@ -347,15 +862,109 @@ class NeoPixelWrapper private: NeoPixelType _type; + // have a member for every possible type - NeoPixelBrightnessBus* _pGrb; - NeoPixelBrightnessBus* _pGrbw; + NeoPixelBrightnessBus* _pGrb; //strip1 + #if NUM_STRIPS > 1 + NeoPixelBrightnessBus* _pGrb2; //strip2 + #endif + #if NUM_STRIPS > 2 + NeoPixelBrightnessBus* _pGrb3; //strip3 + #endif + #if NUM_STRIPS > 3 + NeoPixelBrightnessBus* _pGrb4; //strip4 + #endif + #if NUM_STRIPS > 4 + NeoPixelBrightnessBus* _pGrb5; //strip5 + #endif + #if NUM_STRIPS > 5 + NeoPixelBrightnessBus* _pGrb6; //strip6 + #endif + #if NUM_STRIPS > 6 + NeoPixelBrightnessBus* _pGrb7; //strip7 + #endif + #if NUM_STRIPS > 7 + NeoPixelBrightnessBus* _pGrb8; //strip8 + #endif + // NeoPixelBrightnessBus* _pGrbw; + NeoPixelBrightnessBus* _pGrbw; //strip1 + #if NUM_STRIPS > 1 + NeoPixelBrightnessBus* _pGrbw2; //strip2 + #endif + #if NUM_STRIPS > 2 + NeoPixelBrightnessBus* _pGrbw3; //strip3 + #endif + #if NUM_STRIPS > 3 + NeoPixelBrightnessBus* _pGrbw4; //strip4 + #endif + #if NUM_STRIPS > 4 + NeoPixelBrightnessBus* _pGrbw5; //strip5 + #endif + #if NUM_STRIPS > 5 + NeoPixelBrightnessBus* _pGrbw6; //strip6 + #endif + #if NUM_STRIPS > 6 + NeoPixelBrightnessBus* _pGrbw7; //strip7 + #endif + #if NUM_STRIPS > 7 + NeoPixelBrightnessBus* _pGrbw8; //strip8 + #endif void cleanup() { + switch (_type) { - case NeoPixelType_Grb: delete _pGrb ; _pGrb = NULL; break; - case NeoPixelType_Grbw: delete _pGrbw; _pGrbw = NULL; break; + case NeoPixelType_Grb: { + delete _pGrb ; _pGrb = NULL; //strip1 + #if NUM_STRIPS > 1 + delete _pGrb2 ; _pGrb2 = NULL; //strip2 + #endif + #if NUM_STRIPS > 2 + delete _pGrb3 ; _pGrb3 = NULL; //strip3 + #endif + #if NUM_STRIPS > 3 + delete _pGrb4 ; _pGrb4 = NULL; //strip4 + #endif + #if NUM_STRIPS > 4 + delete _pGrb5 ; _pGrb5 = NULL; //strip5 + #endif + #if NUM_STRIPS > 5 + delete _pGrb6 ; _pGrb6 = NULL; //strip6 + #endif + #if NUM_STRIPS > 6 + delete _pGrb7 ; _pGrb7 = NULL; //strip7 + #endif + #if NUM_STRIPS > 7 + delete _pGrb8 ; _pGrb8 = NULL; //strip8 + #endif + break; + } + // case NeoPixelType_Grbw: delete _pGrbw; _pGrbw = NULL; break; + case NeoPixelType_Grbw: { + delete _pGrbw ; _pGrbw = NULL; //strip1 + #if NUM_STRIPS > 1 + delete _pGrbw2 ; _pGrbw2 = NULL; //strip2 + #endif + #if NUM_STRIPS > 2 + delete _pGrbw3 ; _pGrbw3 = NULL; //strip3 + #endif + #if NUM_STRIPS > 3 + delete _pGrbw4 ; _pGrbw4 = NULL; //strip4 + #endif + #if NUM_STRIPS > 4 + delete _pGrbw5 ; _pGrbw5 = NULL; //strip5 + #endif + #if NUM_STRIPS > 5 + delete _pGrbw6 ; _pGrbw6 = NULL; //strip6 + #endif + #if NUM_STRIPS > 6 + delete _pGrbw7 ; _pGrbw7 = NULL; //strip7 + #endif + #if NUM_STRIPS > 7 + delete _pGrbw8 ; _pGrbw8 = NULL; //strip8 + #endif + break; + } } } }; diff --git a/wled00/colors.cpp b/wled00/colors.cpp index 0996de07f0..4b866d0fe3 100644 --- a/wled00/colors.cpp +++ b/wled00/colors.cpp @@ -198,6 +198,35 @@ void colorFromDecOrHexString(byte* rgb, char* in) rgb[2] = c & 0xFF; } +uint16_t color16bitFromDecOrHexString(char* in) +{ + if (in[0] == 0) return 0; + char first = in[0]; + uint32_t c = 0; + + if (first == '#' || first == 'h' || first == 'H') //is HEX encoded + { + c = strtoul(in +1, NULL, 16); + } else + { + c = strtoul(in, NULL, 10); + } +byte rgb[4]; + + rgb[3] = (c >> 24) & 0xFF; + rgb[0] = (c >> 16) & 0xFF; + rgb[1] = (c >> 8) & 0xFF; + rgb[2] = c & 0xFF; + + return color16bit(rgb[0],rgb[1],rgb[2]); +} +// Downgrade 24-bit color to 16-bit (add reverse gamma lookup here?) +uint16_t color16bit(uint8_t r, uint8_t g, uint8_t b) +{ + return ((uint16_t)(r & 0xF8) << 8) | + ((uint16_t)(g & 0xFC) << 3) | + (b >> 3); +} //contrary to the colorFromDecOrHexString() function, this uses the more standard RRGGBB / RRGGBBWW order bool colorFromHexString(byte* rgb, const char* in) { if (in == nullptr) return false; diff --git a/wled00/const.h b/wled00/const.h index 8dc1a28601..bfe7208ff4 100644 --- a/wled00/const.h +++ b/wled00/const.h @@ -146,6 +146,9 @@ #define NL_MODE_COLORFADE 2 //Fade to target brightness and secondary color gradually #define NL_MODE_SUN 3 //Sunrise/sunset. Target brightness is set immediately, then Sunrise effect is started. Max 60 min. +//EEPROM size +//#define EEPSIZE 2560 //Maximum is 4096 +#define EEPSIZE 3072 //Maximum is 4096 #define NTP_PACKET_SIZE 48 diff --git a/wled00/data/settings.htm b/wled00/data/settings.htm index 425c3295b7..5ec6f278a3 100644 --- a/wled00/data/settings.htm +++ b/wled00/data/settings.htm @@ -41,6 +41,7 @@

+
\ No newline at end of file diff --git a/wled00/data/settings_clock.htm b/wled00/data/settings_clock.htm new file mode 100644 index 0000000000..c309c356ff --- /dev/null +++ b/wled00/data/settings_clock.htm @@ -0,0 +1,80 @@ + + + + + + + Clock + + + + + +
+
+ +
+

Clock Settings

+ Turn on Clock:
+ Clock brightness: + (0-255)

+ Clock Hex Color:

+ +

Options

+ Show time:
+ Show date:
+ Show greeting:

+ Option alternating speed: (1-240 + seconds)

+ Text scroll speed: (10-2500 + milliseconds)

+ +

Dimming

+ Dim lights when turned off:
+ Dimmed brightness: (0-255)
+ Auto dim at night:
+ -or-
+ Dim clock from: + to:

+ +

Formatting

+ Time Format: +
+ + Date Format: +

+ + + +
+ +
+ + + \ No newline at end of file diff --git a/wled00/data/usermod.htm b/wled00/data/usermod.htm index 3f7734a724..c4a954c390 100644 --- a/wled00/data/usermod.htm +++ b/wled00/data/usermod.htm @@ -1,6 +1,42 @@ - -No usermod custom web page set. - + + + + Misc Settings + + + + +
+
+
+

Clock Settings

+ Turn on Clock:
+ Dim lights when turned off:
+ Dimmed brightness:
+ Clock Hex Color:
+
+ +
+ \ No newline at end of file diff --git a/wled00/fcn_declare.h b/wled00/fcn_declare.h index 52f2ff344e..6eb844a4e8 100644 --- a/wled00/fcn_declare.h +++ b/wled00/fcn_declare.h @@ -45,6 +45,8 @@ void colorRGBtoXY(byte* rgb, float* xy); // only defined if huesync disabled TOD void colorFromDecOrHexString(byte* rgb, char* in); bool colorFromHexString(byte* rgb, const char* in); void colorRGBtoRGBW(byte* rgb); //rgb to rgbw (http://codewelt.com/rgbw). (RGBW_MODE_LEGACY) +uint16_t color16bit(uint8_t r, uint8_t g, uint8_t b); +uint16_t color16bitFromDecOrHexString(char* in); //dmx.cpp void initDMX(); @@ -230,6 +232,10 @@ void registerUsermods(); void userSetup(); void userConnected(); void userLoop(); +void setClockColor(uint16_t color); +void setClockBrightness(uint8_t brightness); +void turnOffClock(); +tmElements_t timeFromString(String t); //wled_eeprom.cpp void applyMacro(byte index); diff --git a/wled00/html_other.h b/wled00/html_other.h index 1e51b21371..169a10f4eb 100644 --- a/wled00/html_other.h +++ b/wled00/html_other.h @@ -6,7 +6,19 @@ */ // Autogenerated from wled00/data/usermod.htm, do not edit!! -const char PAGE_usermod[] PROGMEM = R"=====(No usermod custom web page set.)====="; +const char PAGE_usermod[] PROGMEM = R"=====(Misc Settings +

Clock Settings

+Turn on Clock:
+Dim lights when turned off:
+Dimmed brightness:
Clock Hex Color:

)====="; // Autogenerated from wled00/data/msg.htm, do not edit!! diff --git a/wled00/html_settings.h b/wled00/html_settings.h index 183a9e11c3..80c1548f16 100644 --- a/wled00/html_settings.h +++ b/wled00/html_settings.h @@ -22,7 +22,8 @@ LED Preferences
%DMXMENU%
+ action="/settings/clock">
)====="; @@ -335,6 +336,39 @@ required>

Time-controlled presets

)====="; +// Autogenerated from wled00/data/settings_clock.htm, do not edit!! +const char PAGE_settings_clock[] PROGMEM = R"=====(Clock")); }