Merge pull request #3280 from Aircoookie/alt-buffer
Bus-level global buffering
This commit is contained in:
commit
93853613bd
@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
# CI binaries
|
# CI binaries
|
||||||
; default_envs = nodemcuv2, esp8266_2m, esp01_1m_full, esp32dev, esp32_eth # ESP32 variant builds are temporarily excluded from CI due to toolchain issues on the GitHub Actions Linux environment
|
; default_envs = nodemcuv2, esp8266_2m, esp01_1m_full, esp32dev, esp32_eth # ESP32 variant builds are temporarily excluded from CI due to toolchain issues on the GitHub Actions Linux environment
|
||||||
default_envs = nodemcuv2, esp8266_2m, esp01_1m_full, esp32dev, esp32_eth, lolin_s2_mini, esp32c3dev, esp32s3dev_8MB
|
default_envs = nodemcuv2, esp8266_2m, esp01_1m_full, esp32dev, esp32_eth, lolin_s2_mini, esp32c3dev, esp32s3dev_8MB, esp32s3dev_8MB_PSRAM_opi
|
||||||
|
|
||||||
# Release binaries
|
# Release binaries
|
||||||
; default_envs = nodemcuv2, esp8266_2m, esp01_1m_full, esp32dev, esp32_eth, lolin_s2_mini, esp32c3dev, esp32s3dev_8MB
|
; default_envs = nodemcuv2, esp8266_2m, esp01_1m_full, esp32dev, esp32_eth, lolin_s2_mini, esp32c3dev, esp32s3dev_8MB
|
||||||
@ -175,7 +175,7 @@ upload_speed = 115200
|
|||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
lib_compat_mode = strict
|
lib_compat_mode = strict
|
||||||
lib_deps =
|
lib_deps =
|
||||||
fastled/FastLED @ 3.5.0
|
fastled/FastLED @ 3.6.0
|
||||||
IRremoteESP8266 @ 2.8.2
|
IRremoteESP8266 @ 2.8.2
|
||||||
makuna/NeoPixelBus @ 2.7.5
|
makuna/NeoPixelBus @ 2.7.5
|
||||||
https://github.com/Aircoookie/ESPAsyncWebServer.git @ ~2.0.7
|
https://github.com/Aircoookie/ESPAsyncWebServer.git @ ~2.0.7
|
||||||
@ -201,7 +201,7 @@ build_flags =
|
|||||||
-DESP8266
|
-DESP8266
|
||||||
-DFP_IN_IROM
|
-DFP_IN_IROM
|
||||||
;-Wno-deprecated-declarations
|
;-Wno-deprecated-declarations
|
||||||
-Wno-register ;; leaves some warnings when compiling C files: command-line option '-Wno-register' is valid for C++/ObjC++ but not for C
|
;-Wno-register ;; leaves some warnings when compiling C files: command-line option '-Wno-register' is valid for C++/ObjC++ but not for C
|
||||||
;-Dregister= # remove warnings in C++17 due to use of deprecated register keyword by the FastLED library ;; warning: this can be dangerous
|
;-Dregister= # remove warnings in C++17 due to use of deprecated register keyword by the FastLED library ;; warning: this can be dangerous
|
||||||
-Wno-misleading-indentation
|
-Wno-misleading-indentation
|
||||||
; NONOSDK22x_190703 = 2.2.2-dev(38a443e)
|
; NONOSDK22x_190703 = 2.2.2-dev(38a443e)
|
||||||
@ -249,9 +249,8 @@ lib_deps =
|
|||||||
;;
|
;;
|
||||||
;; please note that you can NOT update existing ESP32 installs with a "V4" build. Also updating by OTA will not work properly.
|
;; please note that you can NOT update existing ESP32 installs with a "V4" build. Also updating by OTA will not work properly.
|
||||||
;; You need to completely erase your device (esptool erase_flash) first, then install the "V4" build from VSCode+platformio.
|
;; You need to completely erase your device (esptool erase_flash) first, then install the "V4" build from VSCode+platformio.
|
||||||
platform = espressif32@5.2.0
|
platform = espressif32@5.3.0
|
||||||
platform_packages =
|
platform_packages =
|
||||||
toolchain-riscv32-esp @ 8.4.0+2021r2-patch5 ; required for platform version < 5.3.0, remove this line when upgrading to platform >=5.3.0
|
|
||||||
build_flags = -g
|
build_flags = -g
|
||||||
-Wshadow=compatible-local ;; emit warning in case a local variable "shadows" another local one
|
-Wshadow=compatible-local ;; emit warning in case a local variable "shadows" another local one
|
||||||
-DARDUINO_ARCH_ESP32 -DESP32
|
-DARDUINO_ARCH_ESP32 -DESP32
|
||||||
@ -265,9 +264,8 @@ lib_deps =
|
|||||||
|
|
||||||
[esp32s2]
|
[esp32s2]
|
||||||
;; generic definitions for all ESP32-S2 boards
|
;; generic definitions for all ESP32-S2 boards
|
||||||
platform = espressif32@5.2.0
|
platform = espressif32@5.3.0
|
||||||
platform_packages =
|
platform_packages =
|
||||||
toolchain-riscv32-esp @ 8.4.0+2021r2-patch5 ; required for platform version < 5.3.0, remove this line when upgrading to platform >=5.3.0
|
|
||||||
build_flags = -g
|
build_flags = -g
|
||||||
-DARDUINO_ARCH_ESP32
|
-DARDUINO_ARCH_ESP32
|
||||||
-DARDUINO_ARCH_ESP32S2
|
-DARDUINO_ARCH_ESP32S2
|
||||||
@ -285,9 +283,8 @@ lib_deps =
|
|||||||
|
|
||||||
[esp32c3]
|
[esp32c3]
|
||||||
;; generic definitions for all ESP32-C3 boards
|
;; generic definitions for all ESP32-C3 boards
|
||||||
platform = espressif32@5.2.0
|
platform = espressif32@5.3.0
|
||||||
platform_packages =
|
platform_packages =
|
||||||
toolchain-riscv32-esp @ 8.4.0+2021r2-patch5 ; required for platform version < 5.3.0, remove this line when upgrading to platform >=5.3.0
|
|
||||||
build_flags = -g
|
build_flags = -g
|
||||||
-DARDUINO_ARCH_ESP32
|
-DARDUINO_ARCH_ESP32
|
||||||
-DARDUINO_ARCH_ESP32C3
|
-DARDUINO_ARCH_ESP32C3
|
||||||
@ -304,9 +301,8 @@ lib_deps =
|
|||||||
|
|
||||||
[esp32s3]
|
[esp32s3]
|
||||||
;; generic definitions for all ESP32-S3 boards
|
;; generic definitions for all ESP32-S3 boards
|
||||||
platform = espressif32@5.2.0
|
platform = espressif32@5.3.0
|
||||||
platform_packages =
|
platform_packages =
|
||||||
toolchain-riscv32-esp @ 8.4.0+2021r2-patch5 ; required for platform version < 5.3.0, remove this line when upgrading to platform >=5.3.0
|
|
||||||
build_flags = -g
|
build_flags = -g
|
||||||
-DESP32
|
-DESP32
|
||||||
-DARDUINO_ARCH_ESP32
|
-DARDUINO_ARCH_ESP32
|
||||||
@ -450,6 +446,7 @@ board_build.flash_mode = qio
|
|||||||
upload_speed = 460800
|
upload_speed = 460800
|
||||||
build_unflags = ${common.build_unflags}
|
build_unflags = ${common.build_unflags}
|
||||||
build_flags = ${common.build_flags} ${esp32s2.build_flags} #-D WLED_RELEASE_NAME=S2_saola
|
build_flags = ${common.build_flags} ${esp32s2.build_flags} #-D WLED_RELEASE_NAME=S2_saola
|
||||||
|
;-DLOLIN_WIFI_FIX ;; try this in case Wifi does not work
|
||||||
-DARDUINO_USB_CDC_ON_BOOT=1
|
-DARDUINO_USB_CDC_ON_BOOT=1
|
||||||
lib_deps = ${esp32s2.lib_deps}
|
lib_deps = ${esp32s2.lib_deps}
|
||||||
|
|
||||||
@ -462,6 +459,7 @@ board = esp32-c3-devkitm-1
|
|||||||
board_build.partitions = tools/WLED_ESP32_4MB_1MB_FS.csv
|
board_build.partitions = tools/WLED_ESP32_4MB_1MB_FS.csv
|
||||||
build_flags = ${common.build_flags} ${esp32c3.build_flags} #-D WLED_RELEASE_NAME=ESP32-C3
|
build_flags = ${common.build_flags} ${esp32c3.build_flags} #-D WLED_RELEASE_NAME=ESP32-C3
|
||||||
-D WLED_WATCHDOG_TIMEOUT=0
|
-D WLED_WATCHDOG_TIMEOUT=0
|
||||||
|
-DLOLIN_WIFI_FIX ; seems to work much better with this
|
||||||
-DARDUINO_USB_CDC_ON_BOOT=1 ;; for virtual CDC USB
|
-DARDUINO_USB_CDC_ON_BOOT=1 ;; for virtual CDC USB
|
||||||
;-DARDUINO_USB_CDC_ON_BOOT=0 ;; for serial-to-USB chip
|
;-DARDUINO_USB_CDC_ON_BOOT=0 ;; for serial-to-USB chip
|
||||||
upload_speed = 460800
|
upload_speed = 460800
|
||||||
@ -478,7 +476,7 @@ build_unflags = ${common.build_unflags}
|
|||||||
build_flags = ${common.build_flags} ${esp32s3.build_flags}
|
build_flags = ${common.build_flags} ${esp32s3.build_flags}
|
||||||
-D CONFIG_LITTLEFS_FOR_IDF_3_2 -D WLED_WATCHDOG_TIMEOUT=0
|
-D CONFIG_LITTLEFS_FOR_IDF_3_2 -D WLED_WATCHDOG_TIMEOUT=0
|
||||||
-D ARDUINO_USB_CDC_ON_BOOT=0 ;; -D ARDUINO_USB_MODE=1 ;; for boards with serial-to-USB chip
|
-D ARDUINO_USB_CDC_ON_BOOT=0 ;; -D ARDUINO_USB_MODE=1 ;; for boards with serial-to-USB chip
|
||||||
;-D ARDUINO_USB_CDC_ON_BOOT=1 ;; -D ARDUINO_USB_MODE=0 ;; for boards with USB-OTG connector only (USBCDC or "TinyUSB")
|
;-D ARDUINO_USB_CDC_ON_BOOT=1 ;; -D ARDUINO_USB_MODE=1 ;; for boards with USB-OTG connector only (USBCDC or "TinyUSB")
|
||||||
;-D WLED_DEBUG
|
;-D WLED_DEBUG
|
||||||
lib_deps = ${esp32s3.lib_deps}
|
lib_deps = ${esp32s3.lib_deps}
|
||||||
board_build.partitions = tools/WLED_ESP32_8MB.csv
|
board_build.partitions = tools/WLED_ESP32_8MB.csv
|
||||||
@ -487,11 +485,10 @@ board_build.flash_mode = qio
|
|||||||
; board_build.flash_mode = dio ;; try this if you have problems at startup
|
; board_build.flash_mode = dio ;; try this if you have problems at startup
|
||||||
monitor_filters = esp32_exception_decoder
|
monitor_filters = esp32_exception_decoder
|
||||||
|
|
||||||
[env:esp32s3dev_8MB_PSRAM]
|
[env:esp32s3dev_8MB_PSRAM_opi]
|
||||||
;; ESP32-TinyS3 development board, with 8MB FLASH and 8MB PSRAM (memory_type: qio_opi, qio_qspi, or opi_opi)
|
;; ESP32-S3 development board, with 8MB FLASH and >= 8MB PSRAM (memory_type: qio_opi)
|
||||||
;board = um_tinys3 ; -> needs workaround from https://github.com/Aircoookie/WLED/pull/2905#issuecomment-1328049860
|
board = esp32-s3-devkitc-1 ;; generic dev board; the next line adds PSRAM support
|
||||||
;board = esp32s3box ; -> error: 'esp32_adc2gpio' was not declared in this scope
|
board_build.arduino.memory_type = qio_opi ;; use with PSRAM: 8MB or 16MB
|
||||||
board = esp32-s3-devkitc-1 ; -> compiles, but does not support PSRAM
|
|
||||||
platform = ${esp32s3.platform}
|
platform = ${esp32s3.platform}
|
||||||
platform_packages = ${esp32s3.platform_packages}
|
platform_packages = ${esp32s3.platform_packages}
|
||||||
upload_speed = 921600
|
upload_speed = 921600
|
||||||
@ -499,7 +496,7 @@ build_unflags = ${common.build_unflags}
|
|||||||
build_flags = ${common.build_flags} ${esp32s3.build_flags}
|
build_flags = ${common.build_flags} ${esp32s3.build_flags}
|
||||||
-D CONFIG_LITTLEFS_FOR_IDF_3_2 -D WLED_WATCHDOG_TIMEOUT=0
|
-D CONFIG_LITTLEFS_FOR_IDF_3_2 -D WLED_WATCHDOG_TIMEOUT=0
|
||||||
;-D ARDUINO_USB_CDC_ON_BOOT=0 ;; -D ARDUINO_USB_MODE=1 ;; for boards with serial-to-USB chip
|
;-D ARDUINO_USB_CDC_ON_BOOT=0 ;; -D ARDUINO_USB_MODE=1 ;; for boards with serial-to-USB chip
|
||||||
-D ARDUINO_USB_CDC_ON_BOOT=1 ;; -D ARDUINO_USB_MODE=0 ;; for boards with USB-OTG connector only (USBCDC or "TinyUSB")
|
-D ARDUINO_USB_CDC_ON_BOOT=1 -D ARDUINO_USB_MODE=1 ;; for boards with USB-OTG connector only (USBCDC or "TinyUSB")
|
||||||
; -D WLED_RELEASE_NAME=ESP32-S3_PSRAM
|
; -D WLED_RELEASE_NAME=ESP32-S3_PSRAM
|
||||||
-D WLED_USE_PSRAM -DBOARD_HAS_PSRAM ; tells WLED that PSRAM shall be used
|
-D WLED_USE_PSRAM -DBOARD_HAS_PSRAM ; tells WLED that PSRAM shall be used
|
||||||
lib_deps = ${esp32s3.lib_deps}
|
lib_deps = ${esp32s3.lib_deps}
|
||||||
@ -508,6 +505,13 @@ board_build.f_flash = 80000000L
|
|||||||
board_build.flash_mode = qio
|
board_build.flash_mode = qio
|
||||||
monitor_filters = esp32_exception_decoder
|
monitor_filters = esp32_exception_decoder
|
||||||
|
|
||||||
|
[env:esp32s3dev_8MB_PSRAM_qspi]
|
||||||
|
;; ESP32-TinyS3 development board, with 8MB FLASH and PSRAM (memory_type: qio_qspi)
|
||||||
|
extends = env:esp32s3dev_8MB_PSRAM_opi
|
||||||
|
;board = um_tinys3 ; -> needs workaround from https://github.com/Aircoookie/WLED/pull/2905#issuecomment-1328049860
|
||||||
|
board = esp32-s3-devkitc-1 ;; generic dev board; the next line adds PSRAM support
|
||||||
|
board_build.arduino.memory_type = qio_qspi ;; use with PSRAM: 2MB or 4MB
|
||||||
|
|
||||||
[env:esp8285_4CH_MagicHome]
|
[env:esp8285_4CH_MagicHome]
|
||||||
board = esp8285
|
board = esp8285
|
||||||
platform = ${common.platform_wled_default}
|
platform = ${common.platform_wled_default}
|
||||||
|
8
tools/WLED_ESP32_16MB_9MB_FS.csv
Normal file
8
tools/WLED_ESP32_16MB_9MB_FS.csv
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# Name, Type, SubType, Offset, Size, Flags
|
||||||
|
nvs, data, nvs, 0x9000, 0x5000,
|
||||||
|
otadata, data, ota, 0xe000, 0x2000,
|
||||||
|
app0, app, ota_0, 0x10000, 0x300000,
|
||||||
|
app1, app, ota_1, 0x310000,0x300000,
|
||||||
|
spiffs, data, spiffs, 0x610000,0x9E0000,
|
||||||
|
coredump, data, coredump,,64K
|
||||||
|
# to create/use ffat, see https://github.com/marcmerlin/esp32_fatfsimage
|
|
@ -3,4 +3,5 @@ nvs, data, nvs, 0x9000, 0x5000,
|
|||||||
otadata, data, ota, 0xe000, 0x2000,
|
otadata, data, ota, 0xe000, 0x2000,
|
||||||
app0, app, ota_0, 0x10000, 0x200000,
|
app0, app, ota_0, 0x10000, 0x200000,
|
||||||
app1, app, ota_1, 0x210000,0x200000,
|
app1, app, ota_1, 0x210000,0x200000,
|
||||||
spiffs, data, spiffs, 0x410000,0x3F0000,
|
spiffs, data, spiffs, 0x410000,0x3E0000,
|
||||||
|
coredump, data, coredump,,64K
|
||||||
|
|
@ -289,7 +289,6 @@ uint16_t mode_dynamic(void) {
|
|||||||
if (!SEGENV.allocateData(SEGLEN)) return mode_static(); //allocation failed
|
if (!SEGENV.allocateData(SEGLEN)) return mode_static(); //allocation failed
|
||||||
|
|
||||||
if(SEGENV.call == 0) {
|
if(SEGENV.call == 0) {
|
||||||
//SEGMENT.setUpLeds(); //lossless getPixelColor()
|
|
||||||
//SEGMENT.fill(BLACK);
|
//SEGMENT.fill(BLACK);
|
||||||
for (int i = 0; i < SEGLEN; i++) SEGENV.data[i] = random8();
|
for (int i = 0; i < SEGLEN; i++) SEGENV.data[i] = random8();
|
||||||
}
|
}
|
||||||
@ -607,7 +606,6 @@ static const char _data_FX_MODE_TWINKLE[] PROGMEM = "Twinkle@!,!;!,!;!;;m12=0";
|
|||||||
uint16_t dissolve(uint32_t color) {
|
uint16_t dissolve(uint32_t color) {
|
||||||
//bool wa = (SEGCOLOR(1) != 0 && strip.getBrightness() < 255); //workaround, can't compare getPixel to color if not full brightness
|
//bool wa = (SEGCOLOR(1) != 0 && strip.getBrightness() < 255); //workaround, can't compare getPixel to color if not full brightness
|
||||||
if (SEGENV.call == 0) {
|
if (SEGENV.call == 0) {
|
||||||
SEGMENT.setUpLeds(); //lossless getPixelColor()
|
|
||||||
SEGMENT.fill(SEGCOLOR(1));
|
SEGMENT.fill(SEGCOLOR(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1206,7 +1204,6 @@ uint16_t mode_fireworks() {
|
|||||||
const uint16_t height = SEGMENT.virtualHeight();
|
const uint16_t height = SEGMENT.virtualHeight();
|
||||||
|
|
||||||
if (SEGENV.call == 0) {
|
if (SEGENV.call == 0) {
|
||||||
SEGMENT.setUpLeds(); //lossless getPixelColor()
|
|
||||||
SEGMENT.fill(SEGCOLOR(1));
|
SEGMENT.fill(SEGCOLOR(1));
|
||||||
SEGENV.aux0 = UINT16_MAX;
|
SEGENV.aux0 = UINT16_MAX;
|
||||||
SEGENV.aux1 = UINT16_MAX;
|
SEGENV.aux1 = UINT16_MAX;
|
||||||
@ -1215,19 +1212,21 @@ uint16_t mode_fireworks() {
|
|||||||
|
|
||||||
bool valid1 = (SEGENV.aux0 < width*height);
|
bool valid1 = (SEGENV.aux0 < width*height);
|
||||||
bool valid2 = (SEGENV.aux1 < width*height);
|
bool valid2 = (SEGENV.aux1 < width*height);
|
||||||
|
uint8_t x = SEGENV.aux0%width, y = SEGENV.aux0/width; // 2D coordinates stored in upper and lower byte
|
||||||
uint32_t sv1 = 0, sv2 = 0;
|
uint32_t sv1 = 0, sv2 = 0;
|
||||||
if (valid1) sv1 = SEGMENT.is2D() ? SEGMENT.getPixelColorXY(SEGENV.aux0%width, SEGENV.aux0/width) : SEGMENT.getPixelColor(SEGENV.aux0); // get spark color
|
if (valid1) sv1 = SEGMENT.is2D() ? SEGMENT.getPixelColorXY(x, y) : SEGMENT.getPixelColor(SEGENV.aux0); // get spark color
|
||||||
if (valid2) sv2 = SEGMENT.is2D() ? SEGMENT.getPixelColorXY(SEGENV.aux1%width, SEGENV.aux1/width) : SEGMENT.getPixelColor(SEGENV.aux1);
|
if (valid2) sv2 = SEGMENT.is2D() ? SEGMENT.getPixelColorXY(x, y) : SEGMENT.getPixelColor(SEGENV.aux1);
|
||||||
if (!SEGENV.step) SEGMENT.blur(16);
|
if (!SEGENV.step) SEGMENT.blur(16);
|
||||||
if (valid1) { if (SEGMENT.is2D()) SEGMENT.setPixelColorXY(SEGENV.aux0%width, SEGENV.aux0/width, sv1); else SEGMENT.setPixelColor(SEGENV.aux0, sv1); } // restore spark color after blur
|
if (valid1) { if (SEGMENT.is2D()) SEGMENT.setPixelColorXY(x, y, sv1); else SEGMENT.setPixelColor(SEGENV.aux0, sv1); } // restore spark color after blur
|
||||||
if (valid2) { if (SEGMENT.is2D()) SEGMENT.setPixelColorXY(SEGENV.aux1%width, SEGENV.aux1/width, sv2); else SEGMENT.setPixelColor(SEGENV.aux1, sv2); } // restore old spark color after blur
|
if (valid2) { if (SEGMENT.is2D()) SEGMENT.setPixelColorXY(x, y, sv2); else SEGMENT.setPixelColor(SEGENV.aux1, sv2); } // restore old spark color after blur
|
||||||
|
|
||||||
for (int i=0; i<MAX(1, width/20); i++) {
|
for (int i=0; i<MAX(1, width/20); i++) {
|
||||||
if (random8(129 - (SEGMENT.intensity >> 1)) == 0) {
|
if (random8(129 - (SEGMENT.intensity >> 1)) == 0) {
|
||||||
uint16_t index = random16(width*height);
|
uint16_t index = random16(width*height);
|
||||||
uint16_t j = index % width, k = index / width;
|
x = index % width;
|
||||||
|
y = index / width;
|
||||||
uint32_t col = SEGMENT.color_from_palette(random8(), false, false, 0);
|
uint32_t col = SEGMENT.color_from_palette(random8(), false, false, 0);
|
||||||
if (SEGMENT.is2D()) SEGMENT.setPixelColorXY(j, k, col);
|
if (SEGMENT.is2D()) SEGMENT.setPixelColorXY(x, y, col);
|
||||||
else SEGMENT.setPixelColor(index, col);
|
else SEGMENT.setPixelColor(index, col);
|
||||||
SEGENV.aux1 = SEGENV.aux0; // old spark
|
SEGENV.aux1 = SEGENV.aux0; // old spark
|
||||||
SEGENV.aux0 = index; // remember where spark occured
|
SEGENV.aux0 = index; // remember where spark occured
|
||||||
@ -1905,7 +1904,6 @@ static const char _data_FX_MODE_PRIDE_2015[] PROGMEM = "Pride 2015@!;;";
|
|||||||
uint16_t mode_juggle(void) {
|
uint16_t mode_juggle(void) {
|
||||||
if (SEGLEN == 1) return mode_static();
|
if (SEGLEN == 1) return mode_static();
|
||||||
if (SEGENV.call == 0) {
|
if (SEGENV.call == 0) {
|
||||||
SEGMENT.setUpLeds(); //lossless getPixelColor()
|
|
||||||
SEGMENT.fill(BLACK);
|
SEGMENT.fill(BLACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4586,7 +4584,6 @@ uint16_t mode_2DBlackHole(void) { // By: Stepko https://editor.soulma
|
|||||||
|
|
||||||
// initialize on first call
|
// initialize on first call
|
||||||
if (SEGENV.call == 0) {
|
if (SEGENV.call == 0) {
|
||||||
SEGMENT.setUpLeds();
|
|
||||||
SEGMENT.fill(BLACK);
|
SEGMENT.fill(BLACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4596,22 +4593,22 @@ uint16_t mode_2DBlackHole(void) { // By: Stepko https://editor.soulma
|
|||||||
for (size_t i = 0; i < 8; i++) {
|
for (size_t i = 0; i < 8; i++) {
|
||||||
x = beatsin8(SEGMENT.custom1>>3, 0, cols - 1, 0, ((i % 2) ? 128 : 0) + t * i);
|
x = beatsin8(SEGMENT.custom1>>3, 0, cols - 1, 0, ((i % 2) ? 128 : 0) + t * i);
|
||||||
y = beatsin8(SEGMENT.intensity>>3, 0, rows - 1, 0, ((i % 2) ? 192 : 64) + t * i);
|
y = beatsin8(SEGMENT.intensity>>3, 0, rows - 1, 0, ((i % 2) ? 192 : 64) + t * i);
|
||||||
SEGMENT.addPixelColorXY(x, y, CHSV(i*32, 255, 255));
|
SEGMENT.addPixelColorXY(x, y, SEGMENT.color_from_palette(i*32, false, PALETTE_SOLID_WRAP, SEGMENT.check1?0:255));
|
||||||
}
|
}
|
||||||
// inner stars
|
// inner stars
|
||||||
for (size_t i = 0; i < 4; i++) {
|
for (size_t i = 0; i < 4; i++) {
|
||||||
x = beatsin8(SEGMENT.custom2>>3, cols/4, cols - 1 - cols/4, 0, ((i % 2) ? 128 : 0) + t * i);
|
x = beatsin8(SEGMENT.custom2>>3, cols/4, cols - 1 - cols/4, 0, ((i % 2) ? 128 : 0) + t * i);
|
||||||
y = beatsin8(SEGMENT.custom3 , rows/4, rows - 1 - rows/4, 0, ((i % 2) ? 192 : 64) + t * i);
|
y = beatsin8(SEGMENT.custom3 , rows/4, rows - 1 - rows/4, 0, ((i % 2) ? 192 : 64) + t * i);
|
||||||
SEGMENT.addPixelColorXY(x, y, CHSV(i*32, 255, 255));
|
SEGMENT.addPixelColorXY(x, y, SEGMENT.color_from_palette(255-i*64, false, PALETTE_SOLID_WRAP, SEGMENT.check1?0:255));
|
||||||
}
|
}
|
||||||
// central white dot
|
// central white dot
|
||||||
SEGMENT.setPixelColorXY(cols/2, rows/2, CHSV(0, 0, 255));
|
SEGMENT.setPixelColorXY(cols/2, rows/2, WHITE);
|
||||||
// blur everything a bit
|
// blur everything a bit
|
||||||
SEGMENT.blur(16);
|
SEGMENT.blur(16);
|
||||||
|
|
||||||
return FRAMETIME;
|
return FRAMETIME;
|
||||||
} // mode_2DBlackHole()
|
} // mode_2DBlackHole()
|
||||||
static const char _data_FX_MODE_2DBLACKHOLE[] PROGMEM = "Black Hole@Fade rate,Outer Y freq.,Outer X freq.,Inner X freq.,Inner Y freq.;;;2";
|
static const char _data_FX_MODE_2DBLACKHOLE[] PROGMEM = "Black Hole@Fade rate,Outer Y freq.,Outer X freq.,Inner X freq.,Inner Y freq.,Solid;!;!;2;pal=11";
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////
|
////////////////////////////
|
||||||
@ -4624,7 +4621,6 @@ uint16_t mode_2DColoredBursts() { // By: ldirko https://editor.so
|
|||||||
const uint16_t rows = SEGMENT.virtualHeight();
|
const uint16_t rows = SEGMENT.virtualHeight();
|
||||||
|
|
||||||
if (SEGENV.call == 0) {
|
if (SEGENV.call == 0) {
|
||||||
SEGMENT.setUpLeds();
|
|
||||||
SEGMENT.fill(BLACK);
|
SEGMENT.fill(BLACK);
|
||||||
SEGENV.aux0 = 0; // start with red hue
|
SEGENV.aux0 = 0; // start with red hue
|
||||||
}
|
}
|
||||||
@ -4678,7 +4674,6 @@ uint16_t mode_2Ddna(void) { // dna originally by by ldirko at https://pa
|
|||||||
const uint16_t rows = SEGMENT.virtualHeight();
|
const uint16_t rows = SEGMENT.virtualHeight();
|
||||||
|
|
||||||
if (SEGENV.call == 0) {
|
if (SEGENV.call == 0) {
|
||||||
SEGMENT.setUpLeds();
|
|
||||||
SEGMENT.fill(BLACK);
|
SEGMENT.fill(BLACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4705,7 +4700,6 @@ uint16_t mode_2DDNASpiral() { // By: ldirko https://editor.soulma
|
|||||||
const uint16_t rows = SEGMENT.virtualHeight();
|
const uint16_t rows = SEGMENT.virtualHeight();
|
||||||
|
|
||||||
if (SEGENV.call == 0) {
|
if (SEGENV.call == 0) {
|
||||||
SEGMENT.setUpLeds();
|
|
||||||
SEGMENT.fill(BLACK);
|
SEGMENT.fill(BLACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4751,7 +4745,6 @@ uint16_t mode_2DDrift() { // By: Stepko https://editor.soulmateli
|
|||||||
const uint16_t rows = SEGMENT.virtualHeight();
|
const uint16_t rows = SEGMENT.virtualHeight();
|
||||||
|
|
||||||
if (SEGENV.call == 0) {
|
if (SEGENV.call == 0) {
|
||||||
SEGMENT.setUpLeds();
|
|
||||||
SEGMENT.fill(BLACK);
|
SEGMENT.fill(BLACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4783,7 +4776,6 @@ uint16_t mode_2Dfirenoise(void) { // firenoise2d. By Andrew Tuline
|
|||||||
const uint16_t rows = SEGMENT.virtualHeight();
|
const uint16_t rows = SEGMENT.virtualHeight();
|
||||||
|
|
||||||
if (SEGENV.call == 0) {
|
if (SEGENV.call == 0) {
|
||||||
SEGMENT.setUpLeds();
|
|
||||||
SEGMENT.fill(BLACK);
|
SEGMENT.fill(BLACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4818,7 +4810,6 @@ uint16_t mode_2DFrizzles(void) { // By: Stepko https://editor.so
|
|||||||
const uint16_t rows = SEGMENT.virtualHeight();
|
const uint16_t rows = SEGMENT.virtualHeight();
|
||||||
|
|
||||||
if (SEGENV.call == 0) {
|
if (SEGENV.call == 0) {
|
||||||
SEGMENT.setUpLeds();
|
|
||||||
SEGMENT.fill(BLACK);
|
SEGMENT.fill(BLACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4857,8 +4848,6 @@ uint16_t mode_2Dgameoflife(void) { // Written by Ewoud Wijma, inspired by https:
|
|||||||
|
|
||||||
CRGB backgroundColor = SEGCOLOR(1);
|
CRGB backgroundColor = SEGCOLOR(1);
|
||||||
|
|
||||||
if (SEGENV.call == 0) SEGMENT.setUpLeds();
|
|
||||||
|
|
||||||
if (SEGENV.call == 0 || strip.now - SEGMENT.step > 3000) {
|
if (SEGENV.call == 0 || strip.now - SEGMENT.step > 3000) {
|
||||||
SEGENV.step = strip.now;
|
SEGENV.step = strip.now;
|
||||||
SEGENV.aux0 = 0;
|
SEGENV.aux0 = 0;
|
||||||
@ -4915,7 +4904,7 @@ uint16_t mode_2Dgameoflife(void) { // Written by Ewoud Wijma, inspired by https:
|
|||||||
} // i,j
|
} // i,j
|
||||||
|
|
||||||
// Rules of Life
|
// Rules of Life
|
||||||
uint32_t col = prevLeds[XY(x,y)];
|
uint32_t col = uint32_t(prevLeds[XY(x,y)]) & 0x00FFFFFF; // uint32_t operator returns RGBA, we want RGBW -> cut off "alpha" byte
|
||||||
uint32_t bgc = RGBW32(backgroundColor.r, backgroundColor.g, backgroundColor.b, 0);
|
uint32_t bgc = RGBW32(backgroundColor.r, backgroundColor.g, backgroundColor.b, 0);
|
||||||
if ((col != bgc) && (neighbors < 2)) SEGMENT.setPixelColorXY(x,y, bgc); // Loneliness
|
if ((col != bgc) && (neighbors < 2)) SEGMENT.setPixelColorXY(x,y, bgc); // Loneliness
|
||||||
else if ((col != bgc) && (neighbors > 3)) SEGMENT.setPixelColorXY(x,y, bgc); // Overpopulation
|
else if ((col != bgc) && (neighbors > 3)) SEGMENT.setPixelColorXY(x,y, bgc); // Overpopulation
|
||||||
@ -5124,7 +5113,6 @@ uint16_t mode_2Dmatrix(void) { // Matrix2D. By Jeremy Williams.
|
|||||||
const uint16_t rows = SEGMENT.virtualHeight();
|
const uint16_t rows = SEGMENT.virtualHeight();
|
||||||
|
|
||||||
if (SEGENV.call == 0) {
|
if (SEGENV.call == 0) {
|
||||||
SEGMENT.setUpLeds();
|
|
||||||
SEGMENT.fill(BLACK);
|
SEGMENT.fill(BLACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5269,7 +5257,6 @@ uint16_t mode_2DPlasmaball(void) { // By: Stepko https://edito
|
|||||||
const uint16_t rows = SEGMENT.virtualHeight();
|
const uint16_t rows = SEGMENT.virtualHeight();
|
||||||
|
|
||||||
if (SEGENV.call == 0) {
|
if (SEGENV.call == 0) {
|
||||||
SEGMENT.setUpLeds();
|
|
||||||
SEGMENT.fill(BLACK);
|
SEGMENT.fill(BLACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5317,7 +5304,6 @@ uint16_t mode_2DPolarLights(void) { // By: Kostyantyn Matviyevskyy https
|
|||||||
CRGBPalette16 auroraPalette = {0x000000, 0x003300, 0x006600, 0x009900, 0x00cc00, 0x00ff00, 0x33ff00, 0x66ff00, 0x99ff00, 0xccff00, 0xffff00, 0xffcc00, 0xff9900, 0xff6600, 0xff3300, 0xff0000};
|
CRGBPalette16 auroraPalette = {0x000000, 0x003300, 0x006600, 0x009900, 0x00cc00, 0x00ff00, 0x33ff00, 0x66ff00, 0x99ff00, 0xccff00, 0xffff00, 0xffcc00, 0xff9900, 0xff6600, 0xff3300, 0xff0000};
|
||||||
|
|
||||||
if (SEGENV.call == 0) {
|
if (SEGENV.call == 0) {
|
||||||
SEGMENT.setUpLeds();
|
|
||||||
SEGMENT.fill(BLACK);
|
SEGMENT.fill(BLACK);
|
||||||
SEGENV.step = 0;
|
SEGENV.step = 0;
|
||||||
}
|
}
|
||||||
@ -5367,7 +5353,6 @@ uint16_t mode_2DPulser(void) { // By: ldirko https://edi
|
|||||||
const uint16_t rows = SEGMENT.virtualHeight();
|
const uint16_t rows = SEGMENT.virtualHeight();
|
||||||
|
|
||||||
if (SEGENV.call == 0) {
|
if (SEGENV.call == 0) {
|
||||||
SEGMENT.setUpLeds();
|
|
||||||
SEGMENT.fill(BLACK);
|
SEGMENT.fill(BLACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5395,7 +5380,6 @@ uint16_t mode_2DSindots(void) { // By: ldirko http
|
|||||||
const uint16_t rows = SEGMENT.virtualHeight();
|
const uint16_t rows = SEGMENT.virtualHeight();
|
||||||
|
|
||||||
if (SEGENV.call == 0) {
|
if (SEGENV.call == 0) {
|
||||||
SEGMENT.setUpLeds();
|
|
||||||
SEGMENT.fill(BLACK);
|
SEGMENT.fill(BLACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5427,7 +5411,6 @@ uint16_t mode_2Dsquaredswirl(void) { // By: Mark Kriegsman. https://g
|
|||||||
const uint16_t rows = SEGMENT.virtualHeight();
|
const uint16_t rows = SEGMENT.virtualHeight();
|
||||||
|
|
||||||
if (SEGENV.call == 0) {
|
if (SEGENV.call == 0) {
|
||||||
SEGMENT.setUpLeds();
|
|
||||||
SEGMENT.fill(BLACK);
|
SEGMENT.fill(BLACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5470,7 +5453,6 @@ uint16_t mode_2DSunradiation(void) { // By: ldirko https://edi
|
|||||||
byte *bump = reinterpret_cast<byte*>(SEGENV.data);
|
byte *bump = reinterpret_cast<byte*>(SEGENV.data);
|
||||||
|
|
||||||
if (SEGENV.call == 0) {
|
if (SEGENV.call == 0) {
|
||||||
SEGMENT.setUpLeds();
|
|
||||||
SEGMENT.fill(BLACK);
|
SEGMENT.fill(BLACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5518,7 +5500,6 @@ uint16_t mode_2Dtartan(void) { // By: Elliott Kember https://editor.so
|
|||||||
const uint16_t rows = SEGMENT.virtualHeight();
|
const uint16_t rows = SEGMENT.virtualHeight();
|
||||||
|
|
||||||
if (SEGENV.call == 0) {
|
if (SEGENV.call == 0) {
|
||||||
SEGMENT.setUpLeds();
|
|
||||||
SEGMENT.fill(BLACK);
|
SEGMENT.fill(BLACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5558,7 +5539,6 @@ uint16_t mode_2Dspaceships(void) { //// Space ships by stepko (c)05.02.21 [ht
|
|||||||
const uint16_t rows = SEGMENT.virtualHeight();
|
const uint16_t rows = SEGMENT.virtualHeight();
|
||||||
|
|
||||||
if (SEGENV.call == 0) {
|
if (SEGENV.call == 0) {
|
||||||
SEGMENT.setUpLeds();
|
|
||||||
SEGMENT.fill(BLACK);
|
SEGMENT.fill(BLACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5627,7 +5607,6 @@ uint16_t mode_2Dcrazybees(void) {
|
|||||||
bee_t *bee = reinterpret_cast<bee_t*>(SEGENV.data);
|
bee_t *bee = reinterpret_cast<bee_t*>(SEGENV.data);
|
||||||
|
|
||||||
if (SEGENV.call == 0) {
|
if (SEGENV.call == 0) {
|
||||||
SEGMENT.setUpLeds();
|
|
||||||
SEGMENT.fill(BLACK);
|
SEGMENT.fill(BLACK);
|
||||||
for (size_t i = 0; i < n; i++) {
|
for (size_t i = 0; i < n; i++) {
|
||||||
bee[i].posX = random8(0, cols);
|
bee[i].posX = random8(0, cols);
|
||||||
@ -5697,7 +5676,6 @@ uint16_t mode_2Dghostrider(void) {
|
|||||||
|
|
||||||
const size_t maxLighters = min(cols + rows, LIGHTERS_AM);
|
const size_t maxLighters = min(cols + rows, LIGHTERS_AM);
|
||||||
|
|
||||||
if (SEGENV.call == 0) SEGMENT.setUpLeds();
|
|
||||||
if (SEGENV.aux0 != cols || SEGENV.aux1 != rows) {
|
if (SEGENV.aux0 != cols || SEGENV.aux1 != rows) {
|
||||||
SEGENV.aux0 = cols;
|
SEGENV.aux0 = cols;
|
||||||
SEGENV.aux1 = rows;
|
SEGENV.aux1 = rows;
|
||||||
@ -5782,7 +5760,6 @@ uint16_t mode_2Dfloatingblobs(void) {
|
|||||||
if (!SEGENV.allocateData(sizeof(blob_t))) return mode_static(); //allocation failed
|
if (!SEGENV.allocateData(sizeof(blob_t))) return mode_static(); //allocation failed
|
||||||
blob_t *blob = reinterpret_cast<blob_t*>(SEGENV.data);
|
blob_t *blob = reinterpret_cast<blob_t*>(SEGENV.data);
|
||||||
|
|
||||||
if (SEGENV.call == 0) SEGMENT.setUpLeds();
|
|
||||||
if (SEGENV.aux0 != cols || SEGENV.aux1 != rows) {
|
if (SEGENV.aux0 != cols || SEGENV.aux1 != rows) {
|
||||||
SEGENV.aux0 = cols; // re-initialise if virtual size changes
|
SEGENV.aux0 = cols; // re-initialise if virtual size changes
|
||||||
SEGENV.aux1 = rows;
|
SEGENV.aux1 = rows;
|
||||||
@ -5948,7 +5925,6 @@ uint16_t mode_2Ddriftrose(void) {
|
|||||||
const float L = min(cols, rows) / 2.f;
|
const float L = min(cols, rows) / 2.f;
|
||||||
|
|
||||||
if (SEGENV.call == 0) {
|
if (SEGENV.call == 0) {
|
||||||
SEGMENT.setUpLeds();
|
|
||||||
SEGMENT.fill(BLACK);
|
SEGMENT.fill(BLACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6103,7 +6079,6 @@ uint16_t mode_2DSwirl(void) {
|
|||||||
const uint16_t rows = SEGMENT.virtualHeight();
|
const uint16_t rows = SEGMENT.virtualHeight();
|
||||||
|
|
||||||
if (SEGENV.call == 0) {
|
if (SEGENV.call == 0) {
|
||||||
SEGMENT.setUpLeds();
|
|
||||||
SEGMENT.fill(BLACK);
|
SEGMENT.fill(BLACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6150,7 +6125,6 @@ uint16_t mode_2DWaverly(void) {
|
|||||||
const uint16_t rows = SEGMENT.virtualHeight();
|
const uint16_t rows = SEGMENT.virtualHeight();
|
||||||
|
|
||||||
if (SEGENV.call == 0) {
|
if (SEGENV.call == 0) {
|
||||||
SEGMENT.setUpLeds();
|
|
||||||
SEGMENT.fill(BLACK);
|
SEGMENT.fill(BLACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6379,7 +6353,6 @@ uint16_t mode_matripix(void) { // Matripix. By Andrew Tuline.
|
|||||||
int16_t volumeRaw = *(int16_t*)um_data->u_data[1];
|
int16_t volumeRaw = *(int16_t*)um_data->u_data[1];
|
||||||
|
|
||||||
if (SEGENV.call == 0) {
|
if (SEGENV.call == 0) {
|
||||||
SEGMENT.setUpLeds();
|
|
||||||
SEGMENT.fill(BLACK);
|
SEGMENT.fill(BLACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6507,7 +6480,6 @@ uint16_t mode_pixelwave(void) { // Pixelwave. By Andrew Tuline.
|
|||||||
// even with 1D effect we have to take logic for 2D segments for allocation as fill_solid() fills whole segment
|
// even with 1D effect we have to take logic for 2D segments for allocation as fill_solid() fills whole segment
|
||||||
|
|
||||||
if (SEGENV.call == 0) {
|
if (SEGENV.call == 0) {
|
||||||
SEGMENT.setUpLeds();
|
|
||||||
SEGMENT.fill(BLACK);
|
SEGMENT.fill(BLACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6733,7 +6705,6 @@ uint16_t mode_DJLight(void) { // Written by ??? Adapted by Wil
|
|||||||
uint8_t *fftResult = (uint8_t*)um_data->u_data[2];
|
uint8_t *fftResult = (uint8_t*)um_data->u_data[2];
|
||||||
|
|
||||||
if (SEGENV.call == 0) {
|
if (SEGENV.call == 0) {
|
||||||
SEGMENT.setUpLeds();
|
|
||||||
SEGMENT.fill(BLACK);
|
SEGMENT.fill(BLACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6802,7 +6773,6 @@ uint16_t mode_freqmatrix(void) { // Freqmatrix. By Andreas Plesch
|
|||||||
float volumeSmth = *(float*)um_data->u_data[0];
|
float volumeSmth = *(float*)um_data->u_data[0];
|
||||||
|
|
||||||
if (SEGENV.call == 0) {
|
if (SEGENV.call == 0) {
|
||||||
SEGMENT.setUpLeds();
|
|
||||||
SEGMENT.fill(BLACK);
|
SEGMENT.fill(BLACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6904,7 +6874,6 @@ uint16_t mode_freqwave(void) { // Freqwave. By Andreas Pleschun
|
|||||||
float volumeSmth = *(float*)um_data->u_data[0];
|
float volumeSmth = *(float*)um_data->u_data[0];
|
||||||
|
|
||||||
if (SEGENV.call == 0) {
|
if (SEGENV.call == 0) {
|
||||||
SEGMENT.setUpLeds();
|
|
||||||
SEGMENT.fill(BLACK);
|
SEGMENT.fill(BLACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7089,7 +7058,6 @@ uint16_t mode_waterfall(void) { // Waterfall. By: Andrew Tulin
|
|||||||
if (FFT_MajorPeak < 1) FFT_MajorPeak = 1; // log10(0) is "forbidden" (throws exception)
|
if (FFT_MajorPeak < 1) FFT_MajorPeak = 1; // log10(0) is "forbidden" (throws exception)
|
||||||
|
|
||||||
if (SEGENV.call == 0) {
|
if (SEGENV.call == 0) {
|
||||||
SEGMENT.setUpLeds();
|
|
||||||
SEGMENT.fill(BLACK);
|
SEGMENT.fill(BLACK);
|
||||||
SEGENV.aux0 = 255;
|
SEGENV.aux0 = 255;
|
||||||
SEGMENT.custom1 = *binNum;
|
SEGMENT.custom1 = *binNum;
|
||||||
@ -7206,7 +7174,6 @@ uint16_t mode_2DFunkyPlank(void) { // Written by ??? Adapted by Wil
|
|||||||
uint8_t *fftResult = (uint8_t*)um_data->u_data[2];
|
uint8_t *fftResult = (uint8_t*)um_data->u_data[2];
|
||||||
|
|
||||||
if (SEGENV.call == 0) {
|
if (SEGENV.call == 0) {
|
||||||
SEGMENT.setUpLeds();
|
|
||||||
SEGMENT.fill(BLACK);
|
SEGMENT.fill(BLACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7419,7 +7386,6 @@ uint16_t mode_2Dsoap() {
|
|||||||
|
|
||||||
// init
|
// init
|
||||||
if (SEGENV.call == 0) {
|
if (SEGENV.call == 0) {
|
||||||
SEGMENT.setUpLeds();
|
|
||||||
*noise32_x = random16();
|
*noise32_x = random16();
|
||||||
*noise32_y = random16();
|
*noise32_y = random16();
|
||||||
*noise32_z = random16();
|
*noise32_z = random16();
|
||||||
@ -7537,12 +7503,12 @@ uint16_t mode_2Doctopus() {
|
|||||||
SEGENV.aux1 = rows;
|
SEGENV.aux1 = rows;
|
||||||
*offsX = SEGMENT.custom1;
|
*offsX = SEGMENT.custom1;
|
||||||
*offsY = SEGMENT.custom2;
|
*offsY = SEGMENT.custom2;
|
||||||
const uint8_t C_X = cols / 2 + (SEGMENT.custom1 - 128)*cols/255;
|
const int C_X = (cols / 2) + ((SEGMENT.custom1 - 128)*cols)/255;
|
||||||
const uint8_t C_Y = rows / 2 + (SEGMENT.custom2 - 128)*rows/255;
|
const int C_Y = (rows / 2) + ((SEGMENT.custom2 - 128)*rows)/255;
|
||||||
for (int x = 0; x < cols; x++) {
|
for (int x = 0; x < cols; x++) {
|
||||||
for (int y = 0; y < rows; y++) {
|
for (int y = 0; y < rows; y++) {
|
||||||
rMap[XY(x, y)].angle = 40.7436f * atan2f(y - C_Y, x - C_X); // avoid 128*atan2()/PI
|
rMap[XY(x, y)].angle = 40.7436f * atan2f((y - C_Y), (x - C_X)); // avoid 128*atan2()/PI
|
||||||
rMap[XY(x, y)].radius = hypotf(x - C_X, y - C_Y) * mapp; //thanks Sutaburosu
|
rMap[XY(x, y)].radius = hypotf((x - C_X), (y - C_Y)) * mapp; //thanks Sutaburosu
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
53
wled00/FX.h
53
wled00/FX.h
@ -329,7 +329,7 @@ typedef enum mapping1D2D {
|
|||||||
M12_pCorner = 3
|
M12_pCorner = 3
|
||||||
} mapping1D2D_t;
|
} mapping1D2D_t;
|
||||||
|
|
||||||
// segment, 72 bytes
|
// segment, 80 bytes
|
||||||
typedef struct Segment {
|
typedef struct Segment {
|
||||||
public:
|
public:
|
||||||
uint16_t start; // start index / start X coordinate 2D (left)
|
uint16_t start; // start index / start X coordinate 2D (left)
|
||||||
@ -379,8 +379,6 @@ typedef struct Segment {
|
|||||||
uint16_t aux0; // custom var
|
uint16_t aux0; // custom var
|
||||||
uint16_t aux1; // custom var
|
uint16_t aux1; // custom var
|
||||||
byte *data; // effect data pointer
|
byte *data; // effect data pointer
|
||||||
CRGB* leds; // local leds[] array (may be a pointer to global)
|
|
||||||
static CRGB *_globalLeds; // global leds[] array
|
|
||||||
static uint16_t maxWidth, maxHeight; // these define matrix width & height (max. segment dimensions)
|
static uint16_t maxWidth, maxHeight; // these define matrix width & height (max. segment dimensions)
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -397,7 +395,7 @@ typedef struct Segment {
|
|||||||
uint16_t _dataLen;
|
uint16_t _dataLen;
|
||||||
static uint16_t _usedSegmentData;
|
static uint16_t _usedSegmentData;
|
||||||
|
|
||||||
// transition data, valid only if transitional==true, holds values during transition
|
// transition data, valid only if transitional==true, holds values during transition (72 bytes)
|
||||||
struct Transition {
|
struct Transition {
|
||||||
uint32_t _colorT[NUM_COLORS];
|
uint32_t _colorT[NUM_COLORS];
|
||||||
uint8_t _briT; // temporary brightness
|
uint8_t _briT; // temporary brightness
|
||||||
@ -408,7 +406,7 @@ typedef struct Segment {
|
|||||||
//uint16_t _aux0, _aux1; // previous mode/effect runtime data
|
//uint16_t _aux0, _aux1; // previous mode/effect runtime data
|
||||||
//uint32_t _step, _call; // previous mode/effect runtime data
|
//uint32_t _step, _call; // previous mode/effect runtime data
|
||||||
//byte *_data; // previous mode/effect runtime data
|
//byte *_data; // previous mode/effect runtime data
|
||||||
uint32_t _start;
|
unsigned long _start; // must accommodate millis()
|
||||||
uint16_t _dur;
|
uint16_t _dur;
|
||||||
Transition(uint16_t dur=750)
|
Transition(uint16_t dur=750)
|
||||||
: _briT(255)
|
: _briT(255)
|
||||||
@ -463,7 +461,6 @@ typedef struct Segment {
|
|||||||
aux0(0),
|
aux0(0),
|
||||||
aux1(0),
|
aux1(0),
|
||||||
data(nullptr),
|
data(nullptr),
|
||||||
leds(nullptr),
|
|
||||||
_capabilities(0),
|
_capabilities(0),
|
||||||
_dataLen(0),
|
_dataLen(0),
|
||||||
_t(nullptr)
|
_t(nullptr)
|
||||||
@ -484,12 +481,10 @@ typedef struct Segment {
|
|||||||
//Serial.print(F("Destroying segment:"));
|
//Serial.print(F("Destroying segment:"));
|
||||||
//if (name) Serial.printf(" %s (%p)", name, name);
|
//if (name) Serial.printf(" %s (%p)", name, name);
|
||||||
//if (data) Serial.printf(" %d (%p)", (int)_dataLen, data);
|
//if (data) Serial.printf(" %d (%p)", (int)_dataLen, data);
|
||||||
//if (leds) Serial.printf(" [%u]", length()*sizeof(CRGB));
|
|
||||||
//Serial.println();
|
//Serial.println();
|
||||||
//#endif
|
//#endif
|
||||||
if (!Segment::_globalLeds && leds) { free(leds); leds = nullptr;} // reset to nullptr, to avoid race conditions
|
if (name) { delete[] name; name = nullptr; }
|
||||||
if (name) delete[] name;
|
if (_t) { transitional = false; delete _t; _t = nullptr; }
|
||||||
if (_t) delete _t;
|
|
||||||
deallocateData();
|
deallocateData();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -497,7 +492,7 @@ typedef struct Segment {
|
|||||||
Segment& operator= (Segment &&orig) noexcept; // move assignment
|
Segment& operator= (Segment &&orig) noexcept; // move assignment
|
||||||
|
|
||||||
#ifdef WLED_DEBUG
|
#ifdef WLED_DEBUG
|
||||||
size_t getSize() const { return sizeof(Segment) + (data?_dataLen:0) + (name?strlen(name):0) + (_t?sizeof(Transition):0) + (!Segment::_globalLeds && leds?sizeof(CRGB)*length():0); }
|
size_t getSize() const { return sizeof(Segment) + (data?_dataLen:0) + (name?strlen(name):0) + (_t?sizeof(Transition):0); }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
inline bool getOption(uint8_t n) const { return ((options >> n) & 0x01); }
|
inline bool getOption(uint8_t n) const { return ((options >> n) & 0x01); }
|
||||||
@ -507,8 +502,8 @@ typedef struct Segment {
|
|||||||
inline bool hasRGB(void) const { return _isRGB; }
|
inline bool hasRGB(void) const { return _isRGB; }
|
||||||
inline bool hasWhite(void) const { return _hasW; }
|
inline bool hasWhite(void) const { return _hasW; }
|
||||||
inline bool isCCT(void) const { return _isCCT; }
|
inline bool isCCT(void) const { return _isCCT; }
|
||||||
inline uint16_t width(void) const { return (stop > start) ? (stop - start) : 0; } // segment width in physical pixels (length if 1D)
|
inline uint16_t width(void) const { return isActive() ? (stop - start) : 0; } // segment width in physical pixels (length if 1D)
|
||||||
inline uint16_t height(void) const { return (stopY > startY) ? (stopY - startY) : 0; } // segment height (if 2D) in physical pixels // softhack007: make sure its always > 0
|
inline uint16_t height(void) const { return stopY - startY; } // segment height (if 2D) in physical pixels (it *is* always >=1)
|
||||||
inline uint16_t length(void) const { return width() * height(); } // segment length (count) in physical pixels
|
inline uint16_t length(void) const { return width() * height(); } // segment length (count) in physical pixels
|
||||||
inline uint16_t groupLength(void) const { return grouping + spacing; }
|
inline uint16_t groupLength(void) const { return grouping + spacing; }
|
||||||
inline uint8_t getLightCapabilities(void) const { return _capabilities; }
|
inline uint8_t getLightCapabilities(void) const { return _capabilities; }
|
||||||
@ -516,7 +511,7 @@ typedef struct Segment {
|
|||||||
static uint16_t getUsedSegmentData(void) { return _usedSegmentData; }
|
static uint16_t getUsedSegmentData(void) { return _usedSegmentData; }
|
||||||
static void addUsedSegmentData(int len) { _usedSegmentData += len; }
|
static void addUsedSegmentData(int len) { _usedSegmentData += len; }
|
||||||
|
|
||||||
void setUp(uint16_t i1, uint16_t i2, uint8_t grp=1, uint8_t spc=0, uint16_t ofs=UINT16_MAX, uint16_t i1Y=0, uint16_t i2Y=1);
|
void setUp(uint16_t i1, uint16_t i2, uint8_t grp=1, uint8_t spc=0, uint16_t ofs=UINT16_MAX, uint16_t i1Y=0, uint16_t i2Y=1, uint8_t segId = 255);
|
||||||
bool setColor(uint8_t slot, uint32_t c); //returns true if changed
|
bool setColor(uint8_t slot, uint32_t c); //returns true if changed
|
||||||
void setCCT(uint16_t k);
|
void setCCT(uint16_t k);
|
||||||
void setOpacity(uint8_t o);
|
void setOpacity(uint8_t o);
|
||||||
@ -538,7 +533,6 @@ typedef struct Segment {
|
|||||||
* Safe to call from interrupts and network requests.
|
* Safe to call from interrupts and network requests.
|
||||||
*/
|
*/
|
||||||
inline void markForReset(void) { reset = true; } // setOption(SEG_OPTION_RESET, true)
|
inline void markForReset(void) { reset = true; } // setOption(SEG_OPTION_RESET, true)
|
||||||
void setUpLeds(void); // set up leds[] array for loseless getPixelColor()
|
|
||||||
|
|
||||||
// transition functions
|
// transition functions
|
||||||
void startTransition(uint16_t dur); // transition has to start before actual segment values change
|
void startTransition(uint16_t dur); // transition has to start before actual segment values change
|
||||||
@ -579,7 +573,7 @@ typedef struct Segment {
|
|||||||
uint16_t virtualHeight(void) const;
|
uint16_t virtualHeight(void) const;
|
||||||
uint16_t nrOfVStrips(void) const;
|
uint16_t nrOfVStrips(void) const;
|
||||||
#ifndef WLED_DISABLE_2D
|
#ifndef WLED_DISABLE_2D
|
||||||
uint16_t XY(uint16_t x, uint16_t y); // support function to get relative index within segment (for leds[])
|
uint16_t XY(uint16_t x, uint16_t y); // support function to get relative index within segment
|
||||||
void setPixelColorXY(int x, int y, uint32_t c); // set relative pixel within segment with color
|
void setPixelColorXY(int x, int y, uint32_t c); // set relative pixel within segment with color
|
||||||
void setPixelColorXY(int x, int y, byte r, byte g, byte b, byte w = 0) { setPixelColorXY(x, y, RGBW32(r,g,b,w)); } // automatically inline
|
void setPixelColorXY(int x, int y, byte r, byte g, byte b, byte w = 0) { setPixelColorXY(x, y, RGBW32(r,g,b,w)); } // automatically inline
|
||||||
void setPixelColorXY(int x, int y, CRGB c) { setPixelColorXY(x, y, RGBW32(c.r,c.g,c.b,0)); } // automatically inline
|
void setPixelColorXY(int x, int y, CRGB c) { setPixelColorXY(x, y, RGBW32(c.r,c.g,c.b,0)); } // automatically inline
|
||||||
@ -692,7 +686,15 @@ class WS2812FX { // 96 bytes
|
|||||||
customMappingSize(0),
|
customMappingSize(0),
|
||||||
_lastShow(0),
|
_lastShow(0),
|
||||||
_segment_index(0),
|
_segment_index(0),
|
||||||
_mainSegment(0)
|
_mainSegment(0),
|
||||||
|
_queuedChangesSegId(255),
|
||||||
|
_qStart(0),
|
||||||
|
_qStop(0),
|
||||||
|
_qStartY(0),
|
||||||
|
_qStopY(0),
|
||||||
|
_qGrouping(0),
|
||||||
|
_qSpacing(0),
|
||||||
|
_qOffset(0)
|
||||||
{
|
{
|
||||||
WS2812FX::instance = this;
|
WS2812FX::instance = this;
|
||||||
_mode.reserve(_modeCount); // allocate memory to prevent initial fragmentation (does not increase size())
|
_mode.reserve(_modeCount); // allocate memory to prevent initial fragmentation (does not increase size())
|
||||||
@ -710,7 +712,6 @@ class WS2812FX { // 96 bytes
|
|||||||
panel.clear();
|
panel.clear();
|
||||||
#endif
|
#endif
|
||||||
customPalettes.clear();
|
customPalettes.clear();
|
||||||
if (useLedsArray && Segment::_globalLeds) {free(Segment::_globalLeds); Segment::_globalLeds = nullptr;} // reset to nullptr, to avoid race conditions
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static WS2812FX* getInstance(void) { return instance; }
|
static WS2812FX* getInstance(void) { return instance; }
|
||||||
@ -749,7 +750,7 @@ class WS2812FX { // 96 bytes
|
|||||||
inline void trigger(void) { _triggered = true; } // Forces the next frame to be computed on all active segments.
|
inline void trigger(void) { _triggered = true; } // Forces the next frame to be computed on all active segments.
|
||||||
inline void setShowCallback(show_callback cb) { _callback = cb; }
|
inline void setShowCallback(show_callback cb) { _callback = cb; }
|
||||||
inline void setTransition(uint16_t t) { _transitionDur = t; }
|
inline void setTransition(uint16_t t) { _transitionDur = t; }
|
||||||
inline void appendSegment(const Segment &seg = Segment()) { _segments.push_back(seg); }
|
inline void appendSegment(const Segment &seg = Segment()) { if (_segments.size() < getMaxSegments()) _segments.push_back(seg); }
|
||||||
|
|
||||||
bool
|
bool
|
||||||
checkSegmentAlignment(void),
|
checkSegmentAlignment(void),
|
||||||
@ -757,8 +758,7 @@ class WS2812FX { // 96 bytes
|
|||||||
hasCCTBus(void),
|
hasCCTBus(void),
|
||||||
// return true if the strip is being sent pixel updates
|
// return true if the strip is being sent pixel updates
|
||||||
isUpdating(void),
|
isUpdating(void),
|
||||||
deserializeMap(uint8_t n=0),
|
deserializeMap(uint8_t n=0);
|
||||||
useLedsArray = false;
|
|
||||||
|
|
||||||
inline bool isServicing(void) { return _isServicing; }
|
inline bool isServicing(void) { return _isServicing; }
|
||||||
inline bool hasWhiteChannel(void) {return _hasWhiteChannel;}
|
inline bool hasWhiteChannel(void) {return _hasWhiteChannel;}
|
||||||
@ -900,13 +900,20 @@ class WS2812FX { // 96 bytes
|
|||||||
uint16_t* customMappingTable;
|
uint16_t* customMappingTable;
|
||||||
uint16_t customMappingSize;
|
uint16_t customMappingSize;
|
||||||
|
|
||||||
uint32_t _lastShow;
|
unsigned long _lastShow;
|
||||||
|
|
||||||
uint8_t _segment_index;
|
uint8_t _segment_index;
|
||||||
uint8_t _mainSegment;
|
uint8_t _mainSegment;
|
||||||
|
uint8_t _queuedChangesSegId;
|
||||||
|
uint16_t _qStart, _qStop, _qStartY, _qStopY;
|
||||||
|
uint8_t _qGrouping, _qSpacing;
|
||||||
|
uint16_t _qOffset;
|
||||||
|
|
||||||
|
uint8_t
|
||||||
|
estimateCurrentAndLimitBri(void);
|
||||||
|
|
||||||
void
|
void
|
||||||
estimateCurrentAndLimitBri(void);
|
setUpSegmentFromQueuedChanges(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
extern const char JSON_mode_names[];
|
extern const char JSON_mode_names[];
|
||||||
|
@ -189,20 +189,16 @@ uint32_t WS2812FX::getPixelColorXY(uint16_t x, uint16_t y) {
|
|||||||
|
|
||||||
// XY(x,y) - gets pixel index within current segment (often used to reference leds[] array element)
|
// XY(x,y) - gets pixel index within current segment (often used to reference leds[] array element)
|
||||||
uint16_t /*IRAM_ATTR*/ Segment::XY(uint16_t x, uint16_t y) {
|
uint16_t /*IRAM_ATTR*/ Segment::XY(uint16_t x, uint16_t y) {
|
||||||
uint16_t width = virtualWidth(); // segment width in logical pixels
|
uint16_t width = virtualWidth(); // segment width in logical pixels (can be 0 if segment is inactive)
|
||||||
uint16_t height = virtualHeight(); // segment height in logical pixels
|
uint16_t height = virtualHeight(); // segment height in logical pixels (is always >= 1)
|
||||||
if (width == 0) return 0; // softhack007 avoid div/0
|
return isActive() ? (x%width) + (y%height) * width : 0;
|
||||||
if (height == 0) return (x%width); // softhack007 avoid div/0
|
|
||||||
return (x%width) + (y%height) * width;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void /*IRAM_ATTR*/ Segment::setPixelColorXY(int x, int y, uint32_t col)
|
void /*IRAM_ATTR*/ Segment::setPixelColorXY(int x, int y, uint32_t col)
|
||||||
{
|
{
|
||||||
if (Segment::maxHeight==1) return; // not a matrix set-up
|
if (!isActive()) return; // not active
|
||||||
if (x >= virtualWidth() || y >= virtualHeight() || x<0 || y<0) return; // if pixel would fall out of virtual segment just exit
|
if (x >= virtualWidth() || y >= virtualHeight() || x<0 || y<0) return; // if pixel would fall out of virtual segment just exit
|
||||||
|
|
||||||
if (leds) leds[XY(x,y)] = col;
|
|
||||||
|
|
||||||
uint8_t _bri_t = currentBri(on ? opacity : 0);
|
uint8_t _bri_t = currentBri(on ? opacity : 0);
|
||||||
if (_bri_t < 255) {
|
if (_bri_t < 255) {
|
||||||
byte r = scale8(R(col), _bri_t);
|
byte r = scale8(R(col), _bri_t);
|
||||||
@ -245,7 +241,7 @@ void /*IRAM_ATTR*/ Segment::setPixelColorXY(int x, int y, uint32_t col)
|
|||||||
// anti-aliased version of setPixelColorXY()
|
// anti-aliased version of setPixelColorXY()
|
||||||
void Segment::setPixelColorXY(float x, float y, uint32_t col, bool aa)
|
void Segment::setPixelColorXY(float x, float y, uint32_t col, bool aa)
|
||||||
{
|
{
|
||||||
if (Segment::maxHeight==1) return; // not a matrix set-up
|
if (!isActive()) return; // not active
|
||||||
if (x<0.0f || x>1.0f || y<0.0f || y>1.0f) return; // not normalized
|
if (x<0.0f || x>1.0f || y<0.0f || y>1.0f) return; // not normalized
|
||||||
|
|
||||||
const uint16_t cols = virtualWidth();
|
const uint16_t cols = virtualWidth();
|
||||||
@ -288,8 +284,8 @@ void Segment::setPixelColorXY(float x, float y, uint32_t col, bool aa)
|
|||||||
|
|
||||||
// returns RGBW values of pixel
|
// returns RGBW values of pixel
|
||||||
uint32_t Segment::getPixelColorXY(uint16_t x, uint16_t y) {
|
uint32_t Segment::getPixelColorXY(uint16_t x, uint16_t y) {
|
||||||
int i = XY(x,y);
|
if (!isActive()) return 0; // not active
|
||||||
if (leds) return RGBW32(leds[i].r, leds[i].g, leds[i].b, 0);
|
if (x >= virtualWidth() || y >= virtualHeight() || x<0 || y<0) return 0; // if pixel would fall out of virtual segment just exit
|
||||||
if (reverse ) x = virtualWidth() - x - 1;
|
if (reverse ) x = virtualWidth() - x - 1;
|
||||||
if (reverse_y) y = virtualHeight() - y - 1;
|
if (reverse_y) y = virtualHeight() - y - 1;
|
||||||
if (transpose) { uint16_t t = x; x = y; y = t; } // swap X & Y if segment transposed
|
if (transpose) { uint16_t t = x; x = y; y = t; } // swap X & Y if segment transposed
|
||||||
@ -306,6 +302,7 @@ void Segment::blendPixelColorXY(uint16_t x, uint16_t y, uint32_t color, uint8_t
|
|||||||
|
|
||||||
// Adds the specified color with the existing pixel color perserving color balance.
|
// Adds the specified color with the existing pixel color perserving color balance.
|
||||||
void Segment::addPixelColorXY(int x, int y, uint32_t color, bool fast) {
|
void Segment::addPixelColorXY(int x, int y, uint32_t color, bool fast) {
|
||||||
|
if (!isActive()) return; // not active
|
||||||
if (x >= virtualWidth() || y >= virtualHeight() || x<0 || y<0) return; // if pixel would fall out of virtual segment just exit
|
if (x >= virtualWidth() || y >= virtualHeight() || x<0 || y<0) return; // if pixel would fall out of virtual segment just exit
|
||||||
uint32_t col = getPixelColorXY(x,y);
|
uint32_t col = getPixelColorXY(x,y);
|
||||||
uint8_t r = R(col);
|
uint8_t r = R(col);
|
||||||
@ -325,12 +322,14 @@ void Segment::addPixelColorXY(int x, int y, uint32_t color, bool fast) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Segment::fadePixelColorXY(uint16_t x, uint16_t y, uint8_t fade) {
|
void Segment::fadePixelColorXY(uint16_t x, uint16_t y, uint8_t fade) {
|
||||||
|
if (!isActive()) return; // not active
|
||||||
CRGB pix = CRGB(getPixelColorXY(x,y)).nscale8_video(fade);
|
CRGB pix = CRGB(getPixelColorXY(x,y)).nscale8_video(fade);
|
||||||
setPixelColorXY(x, y, pix);
|
setPixelColorXY(x, y, pix);
|
||||||
}
|
}
|
||||||
|
|
||||||
// blurRow: perform a blur on a row of a rectangular matrix
|
// blurRow: perform a blur on a row of a rectangular matrix
|
||||||
void Segment::blurRow(uint16_t row, fract8 blur_amount) {
|
void Segment::blurRow(uint16_t row, fract8 blur_amount) {
|
||||||
|
if (!isActive()) return; // not active
|
||||||
const uint_fast16_t cols = virtualWidth();
|
const uint_fast16_t cols = virtualWidth();
|
||||||
const uint_fast16_t rows = virtualHeight();
|
const uint_fast16_t rows = virtualHeight();
|
||||||
|
|
||||||
@ -358,6 +357,7 @@ void Segment::blurRow(uint16_t row, fract8 blur_amount) {
|
|||||||
|
|
||||||
// blurCol: perform a blur on a column of a rectangular matrix
|
// blurCol: perform a blur on a column of a rectangular matrix
|
||||||
void Segment::blurCol(uint16_t col, fract8 blur_amount) {
|
void Segment::blurCol(uint16_t col, fract8 blur_amount) {
|
||||||
|
if (!isActive()) return; // not active
|
||||||
const uint_fast16_t cols = virtualWidth();
|
const uint_fast16_t cols = virtualWidth();
|
||||||
const uint_fast16_t rows = virtualHeight();
|
const uint_fast16_t rows = virtualHeight();
|
||||||
|
|
||||||
@ -385,6 +385,7 @@ void Segment::blurCol(uint16_t col, fract8 blur_amount) {
|
|||||||
|
|
||||||
// 1D Box blur (with added weight - blur_amount: [0=no blur, 255=max blur])
|
// 1D Box blur (with added weight - blur_amount: [0=no blur, 255=max blur])
|
||||||
void Segment::box_blur(uint16_t i, bool vertical, fract8 blur_amount) {
|
void Segment::box_blur(uint16_t i, bool vertical, fract8 blur_amount) {
|
||||||
|
if (!isActive()) return; // not active
|
||||||
const uint16_t cols = virtualWidth();
|
const uint16_t cols = virtualWidth();
|
||||||
const uint16_t rows = virtualHeight();
|
const uint16_t rows = virtualHeight();
|
||||||
const uint16_t dim1 = vertical ? rows : cols;
|
const uint16_t dim1 = vertical ? rows : cols;
|
||||||
@ -437,6 +438,7 @@ void Segment::blur1d(fract8 blur_amount) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Segment::moveX(int8_t delta, bool wrap) {
|
void Segment::moveX(int8_t delta, bool wrap) {
|
||||||
|
if (!isActive()) return; // not active
|
||||||
const uint16_t cols = virtualWidth();
|
const uint16_t cols = virtualWidth();
|
||||||
const uint16_t rows = virtualHeight();
|
const uint16_t rows = virtualHeight();
|
||||||
if (!delta || abs(delta) >= cols) return;
|
if (!delta || abs(delta) >= cols) return;
|
||||||
@ -454,6 +456,7 @@ void Segment::moveX(int8_t delta, bool wrap) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Segment::moveY(int8_t delta, bool wrap) {
|
void Segment::moveY(int8_t delta, bool wrap) {
|
||||||
|
if (!isActive()) return; // not active
|
||||||
const uint16_t cols = virtualWidth();
|
const uint16_t cols = virtualWidth();
|
||||||
const uint16_t rows = virtualHeight();
|
const uint16_t rows = virtualHeight();
|
||||||
if (!delta || abs(delta) >= rows) return;
|
if (!delta || abs(delta) >= rows) return;
|
||||||
@ -489,6 +492,7 @@ void Segment::move(uint8_t dir, uint8_t delta, bool wrap) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Segment::draw_circle(uint16_t cx, uint16_t cy, uint8_t radius, CRGB col) {
|
void Segment::draw_circle(uint16_t cx, uint16_t cy, uint8_t radius, CRGB col) {
|
||||||
|
if (!isActive()) return; // not active
|
||||||
// Bresenham’s Algorithm
|
// Bresenham’s Algorithm
|
||||||
int d = 3 - (2*radius);
|
int d = 3 - (2*radius);
|
||||||
int y = radius, x = 0;
|
int y = radius, x = 0;
|
||||||
@ -513,6 +517,7 @@ void Segment::draw_circle(uint16_t cx, uint16_t cy, uint8_t radius, CRGB col) {
|
|||||||
|
|
||||||
// by stepko, taken from https://editor.soulmatelights.com/gallery/573-blobs
|
// by stepko, taken from https://editor.soulmatelights.com/gallery/573-blobs
|
||||||
void Segment::fill_circle(uint16_t cx, uint16_t cy, uint8_t radius, CRGB col) {
|
void Segment::fill_circle(uint16_t cx, uint16_t cy, uint8_t radius, CRGB col) {
|
||||||
|
if (!isActive()) return; // not active
|
||||||
const uint16_t cols = virtualWidth();
|
const uint16_t cols = virtualWidth();
|
||||||
const uint16_t rows = virtualHeight();
|
const uint16_t rows = virtualHeight();
|
||||||
for (int16_t y = -radius; y <= radius; y++) {
|
for (int16_t y = -radius; y <= radius; y++) {
|
||||||
@ -526,6 +531,7 @@ void Segment::fill_circle(uint16_t cx, uint16_t cy, uint8_t radius, CRGB col) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Segment::nscale8(uint8_t scale) {
|
void Segment::nscale8(uint8_t scale) {
|
||||||
|
if (!isActive()) return; // not active
|
||||||
const uint16_t cols = virtualWidth();
|
const uint16_t cols = virtualWidth();
|
||||||
const uint16_t rows = virtualHeight();
|
const uint16_t rows = virtualHeight();
|
||||||
for(uint16_t y = 0; y < rows; y++) for (uint16_t x = 0; x < cols; x++) {
|
for(uint16_t y = 0; y < rows; y++) for (uint16_t x = 0; x < cols; x++) {
|
||||||
@ -535,6 +541,7 @@ void Segment::nscale8(uint8_t scale) {
|
|||||||
|
|
||||||
//line function
|
//line function
|
||||||
void Segment::drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint32_t c) {
|
void Segment::drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint32_t c) {
|
||||||
|
if (!isActive()) return; // not active
|
||||||
const uint16_t cols = virtualWidth();
|
const uint16_t cols = virtualWidth();
|
||||||
const uint16_t rows = virtualHeight();
|
const uint16_t rows = virtualHeight();
|
||||||
if (x0 >= cols || x1 >= cols || y0 >= rows || y1 >= rows) return;
|
if (x0 >= cols || x1 >= cols || y0 >= rows || y1 >= rows) return;
|
||||||
@ -559,6 +566,7 @@ void Segment::drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint3
|
|||||||
// draws a raster font character on canvas
|
// draws a raster font character on canvas
|
||||||
// only supports: 4x6=24, 5x8=40, 5x12=60, 6x8=48 and 7x9=63 fonts ATM
|
// only supports: 4x6=24, 5x8=40, 5x12=60, 6x8=48 and 7x9=63 fonts ATM
|
||||||
void Segment::drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, uint32_t color, uint32_t col2) {
|
void Segment::drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, uint32_t color, uint32_t col2) {
|
||||||
|
if (!isActive()) return; // not active
|
||||||
if (chr < 32 || chr > 126) return; // only ASCII 32-126 supported
|
if (chr < 32 || chr > 126) return; // only ASCII 32-126 supported
|
||||||
chr -= 32; // align with font table entries
|
chr -= 32; // align with font table entries
|
||||||
const uint16_t cols = virtualWidth();
|
const uint16_t cols = virtualWidth();
|
||||||
@ -594,6 +602,7 @@ void Segment::drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w,
|
|||||||
|
|
||||||
#define WU_WEIGHT(a,b) ((uint8_t) (((a)*(b)+(a)+(b))>>8))
|
#define WU_WEIGHT(a,b) ((uint8_t) (((a)*(b)+(a)+(b))>>8))
|
||||||
void Segment::wu_pixel(uint32_t x, uint32_t y, CRGB c) { //awesome wu_pixel procedure by reddit u/sutaburosu
|
void Segment::wu_pixel(uint32_t x, uint32_t y, CRGB c) { //awesome wu_pixel procedure by reddit u/sutaburosu
|
||||||
|
if (!isActive()) return; // not active
|
||||||
// extract the fractional parts and derive their inverses
|
// extract the fractional parts and derive their inverses
|
||||||
uint8_t xx = x & 0xff, yy = y & 0xff, ix = 255 - xx, iy = 255 - yy;
|
uint8_t xx = x & 0xff, yy = y & 0xff, ix = 255 - xx, iy = 255 - yy;
|
||||||
// calculate the intensities for each affected pixel
|
// calculate the intensities for each affected pixel
|
||||||
|
@ -74,7 +74,6 @@
|
|||||||
// Segment class implementation
|
// Segment class implementation
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
uint16_t Segment::_usedSegmentData = 0U; // amount of RAM all segments use for their data[]
|
uint16_t Segment::_usedSegmentData = 0U; // amount of RAM all segments use for their data[]
|
||||||
CRGB *Segment::_globalLeds = nullptr;
|
|
||||||
uint16_t Segment::maxWidth = DEFAULT_LED_COUNT;
|
uint16_t Segment::maxWidth = DEFAULT_LED_COUNT;
|
||||||
uint16_t Segment::maxHeight = 1;
|
uint16_t Segment::maxHeight = 1;
|
||||||
|
|
||||||
@ -82,22 +81,21 @@ uint16_t Segment::maxHeight = 1;
|
|||||||
Segment::Segment(const Segment &orig) {
|
Segment::Segment(const Segment &orig) {
|
||||||
//DEBUG_PRINTLN(F("-- Copy segment constructor --"));
|
//DEBUG_PRINTLN(F("-- Copy segment constructor --"));
|
||||||
memcpy((void*)this, (void*)&orig, sizeof(Segment));
|
memcpy((void*)this, (void*)&orig, sizeof(Segment));
|
||||||
|
transitional = false; // copied segment cannot be in transition
|
||||||
name = nullptr;
|
name = nullptr;
|
||||||
data = nullptr;
|
data = nullptr;
|
||||||
_dataLen = 0;
|
_dataLen = 0;
|
||||||
_t = nullptr;
|
_t = nullptr;
|
||||||
if (leds && !Segment::_globalLeds) leds = nullptr;
|
|
||||||
if (orig.name) { name = new char[strlen(orig.name)+1]; if (name) strcpy(name, orig.name); }
|
if (orig.name) { name = new char[strlen(orig.name)+1]; if (name) strcpy(name, orig.name); }
|
||||||
if (orig.data) { if (allocateData(orig._dataLen)) memcpy(data, orig.data, orig._dataLen); }
|
if (orig.data) { if (allocateData(orig._dataLen)) memcpy(data, orig.data, orig._dataLen); }
|
||||||
if (orig._t) { _t = new Transition(orig._t->_dur, orig._t->_briT, orig._t->_cctT, orig._t->_colorT); }
|
//if (orig._t) { _t = new Transition(orig._t->_dur, orig._t->_briT, orig._t->_cctT, orig._t->_colorT); }
|
||||||
if (orig.leds && !Segment::_globalLeds && length() > 0) { leds = (CRGB*)malloc(sizeof(CRGB)*length()); if (leds) memcpy(leds, orig.leds, sizeof(CRGB)*length()); }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// move constructor
|
// move constructor
|
||||||
Segment::Segment(Segment &&orig) noexcept {
|
Segment::Segment(Segment &&orig) noexcept {
|
||||||
//DEBUG_PRINTLN(F("-- Move segment constructor --"));
|
//DEBUG_PRINTLN(F("-- Move segment constructor --"));
|
||||||
memcpy((void*)this, (void*)&orig, sizeof(Segment));
|
memcpy((void*)this, (void*)&orig, sizeof(Segment));
|
||||||
orig.leds = nullptr;
|
orig.transitional = false; // old segment cannot be in transition any more
|
||||||
orig.name = nullptr;
|
orig.name = nullptr;
|
||||||
orig.data = nullptr;
|
orig.data = nullptr;
|
||||||
orig._dataLen = 0;
|
orig._dataLen = 0;
|
||||||
@ -109,23 +107,22 @@ Segment& Segment::operator= (const Segment &orig) {
|
|||||||
//DEBUG_PRINTLN(F("-- Copying segment --"));
|
//DEBUG_PRINTLN(F("-- Copying segment --"));
|
||||||
if (this != &orig) {
|
if (this != &orig) {
|
||||||
// clean destination
|
// clean destination
|
||||||
|
transitional = false; // copied segment cannot be in transition
|
||||||
if (name) delete[] name;
|
if (name) delete[] name;
|
||||||
if (_t) delete _t;
|
if (_t) delete _t;
|
||||||
if (leds && !Segment::_globalLeds) {free(leds); leds=nullptr;}
|
|
||||||
deallocateData();
|
deallocateData();
|
||||||
// copy source
|
// copy source
|
||||||
memcpy((void*)this, (void*)&orig, sizeof(Segment));
|
memcpy((void*)this, (void*)&orig, sizeof(Segment));
|
||||||
|
transitional = false;
|
||||||
// erase pointers to allocated data
|
// erase pointers to allocated data
|
||||||
name = nullptr;
|
name = nullptr;
|
||||||
data = nullptr;
|
data = nullptr;
|
||||||
_dataLen = 0;
|
_dataLen = 0;
|
||||||
_t = nullptr;
|
_t = nullptr;
|
||||||
if (!Segment::_globalLeds) leds = nullptr;
|
|
||||||
// copy source data
|
// copy source data
|
||||||
if (orig.name) { name = new char[strlen(orig.name)+1]; if (name) strcpy(name, orig.name); }
|
if (orig.name) { name = new char[strlen(orig.name)+1]; if (name) strcpy(name, orig.name); }
|
||||||
if (orig.data) { if (allocateData(orig._dataLen)) memcpy(data, orig.data, orig._dataLen); }
|
if (orig.data) { if (allocateData(orig._dataLen)) memcpy(data, orig.data, orig._dataLen); }
|
||||||
if (orig._t) { _t = new Transition(orig._t->_dur, orig._t->_briT, orig._t->_cctT, orig._t->_colorT); }
|
//if (orig._t) { _t = new Transition(orig._t->_dur, orig._t->_briT, orig._t->_cctT, orig._t->_colorT); }
|
||||||
if (orig.leds && !Segment::_globalLeds && length() > 0) { leds = (CRGB*)malloc(sizeof(CRGB)*length()); if (leds) memcpy(leds, orig.leds, sizeof(CRGB)*length()); }
|
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@ -134,16 +131,16 @@ Segment& Segment::operator= (const Segment &orig) {
|
|||||||
Segment& Segment::operator= (Segment &&orig) noexcept {
|
Segment& Segment::operator= (Segment &&orig) noexcept {
|
||||||
//DEBUG_PRINTLN(F("-- Moving segment --"));
|
//DEBUG_PRINTLN(F("-- Moving segment --"));
|
||||||
if (this != &orig) {
|
if (this != &orig) {
|
||||||
if (name) delete[] name; // free old name
|
transitional = false; // just temporary
|
||||||
|
if (name) { delete[] name; name = nullptr; } // free old name
|
||||||
deallocateData(); // free old runtime data
|
deallocateData(); // free old runtime data
|
||||||
if (_t) delete _t;
|
if (_t) { delete _t; _t = nullptr; }
|
||||||
if (leds && !Segment::_globalLeds) {free(leds); leds=nullptr;}
|
|
||||||
memcpy((void*)this, (void*)&orig, sizeof(Segment));
|
memcpy((void*)this, (void*)&orig, sizeof(Segment));
|
||||||
|
orig.transitional = false; // old segment cannot be in transition
|
||||||
orig.name = nullptr;
|
orig.name = nullptr;
|
||||||
orig.data = nullptr;
|
orig.data = nullptr;
|
||||||
orig._dataLen = 0;
|
orig._dataLen = 0;
|
||||||
orig._t = nullptr;
|
orig._t = nullptr;
|
||||||
orig.leds = nullptr;
|
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@ -153,11 +150,6 @@ bool Segment::allocateData(size_t len) {
|
|||||||
deallocateData();
|
deallocateData();
|
||||||
if (Segment::getUsedSegmentData() + len > MAX_SEGMENT_DATA) return false; //not enough memory
|
if (Segment::getUsedSegmentData() + len > MAX_SEGMENT_DATA) return false; //not enough memory
|
||||||
// do not use SPI RAM on ESP32 since it is slow
|
// do not use SPI RAM on ESP32 since it is slow
|
||||||
//#if defined(ARDUINO_ARCH_ESP32) && defined(BOARD_HAS_PSRAM) && defined(WLED_USE_PSRAM)
|
|
||||||
//if (psramFound())
|
|
||||||
// data = (byte*) ps_malloc(len);
|
|
||||||
//else
|
|
||||||
//#endif
|
|
||||||
data = (byte*) malloc(len);
|
data = (byte*) malloc(len);
|
||||||
if (!data) return false; //allocation failed
|
if (!data) return false; //allocation failed
|
||||||
Segment::addUsedSegmentData(len);
|
Segment::addUsedSegmentData(len);
|
||||||
@ -182,31 +174,11 @@ void Segment::deallocateData() {
|
|||||||
* may free that data buffer.
|
* may free that data buffer.
|
||||||
*/
|
*/
|
||||||
void Segment::resetIfRequired() {
|
void Segment::resetIfRequired() {
|
||||||
if (reset) {
|
if (!reset) return;
|
||||||
if (leds && !Segment::_globalLeds) { free(leds); leds = nullptr; }
|
|
||||||
//if (transitional && _t) { transitional = false; delete _t; _t = nullptr; }
|
|
||||||
deallocateData();
|
deallocateData();
|
||||||
next_time = 0; step = 0; call = 0; aux0 = 0; aux1 = 0;
|
next_time = 0; step = 0; call = 0; aux0 = 0; aux1 = 0;
|
||||||
reset = false; // setOption(SEG_OPTION_RESET, false);
|
reset = false;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Segment::setUpLeds() {
|
|
||||||
// deallocation happens in resetIfRequired() as it is called when segment changes or in destructor
|
|
||||||
if (Segment::_globalLeds)
|
|
||||||
#ifndef WLED_DISABLE_2D
|
|
||||||
leds = &Segment::_globalLeds[start + startY*Segment::maxWidth];
|
|
||||||
#else
|
|
||||||
leds = &Segment::_globalLeds[start];
|
|
||||||
#endif
|
|
||||||
else if (leds == nullptr && length() > 0) { //softhack007 quickfix - avoid malloc(0) which is undefined behaviour (should not happen, but i've seen it)
|
|
||||||
//#if defined(ARDUINO_ARCH_ESP32) && defined(WLED_USE_PSRAM)
|
|
||||||
//if (psramFound())
|
|
||||||
// leds = (CRGB*)ps_malloc(sizeof(CRGB)*length()); // softhack007 disabled; putting leds into psram leads to horrible slowdown on WROVER boards
|
|
||||||
//else
|
|
||||||
//#endif
|
|
||||||
leds = (CRGB*)malloc(sizeof(CRGB)*length());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CRGBPalette16 &Segment::loadPalette(CRGBPalette16 &targetPalette, uint8_t pal) {
|
CRGBPalette16 &Segment::loadPalette(CRGBPalette16 &targetPalette, uint8_t pal) {
|
||||||
@ -331,7 +303,7 @@ void Segment::startTransition(uint16_t dur) {
|
|||||||
// transition progression between 0-65535
|
// transition progression between 0-65535
|
||||||
uint16_t Segment::progress() {
|
uint16_t Segment::progress() {
|
||||||
if (!transitional || !_t) return 0xFFFFU;
|
if (!transitional || !_t) return 0xFFFFU;
|
||||||
uint32_t timeNow = millis();
|
unsigned long timeNow = millis();
|
||||||
if (timeNow - _t->_start > _t->_dur || _t->_dur == 0) return 0xFFFFU;
|
if (timeNow - _t->_start > _t->_dur || _t->_dur == 0) return 0xFFFFU;
|
||||||
return (timeNow - _t->_start) * 0xFFFFU / _t->_dur;
|
return (timeNow - _t->_start) * 0xFFFFU / _t->_dur;
|
||||||
}
|
}
|
||||||
@ -360,7 +332,7 @@ CRGBPalette16 &Segment::currentPalette(CRGBPalette16 &targetPalette, uint8_t pal
|
|||||||
// blend palettes
|
// blend palettes
|
||||||
// there are about 255 blend passes of 48 "blends" to completely blend two palettes (in _dur time)
|
// there are about 255 blend passes of 48 "blends" to completely blend two palettes (in _dur time)
|
||||||
// minimum blend time is 100ms maximum is 65535ms
|
// minimum blend time is 100ms maximum is 65535ms
|
||||||
uint32_t timeMS = millis() - _t->_start;
|
unsigned long timeMS = millis() - _t->_start;
|
||||||
uint16_t noOfBlends = (255U * timeMS / _t->_dur) - _t->_prevPaletteBlends;
|
uint16_t noOfBlends = (255U * timeMS / _t->_dur) - _t->_prevPaletteBlends;
|
||||||
for (int i=0; i<noOfBlends; i++, _t->_prevPaletteBlends++) nblendPaletteTowardPalette(_t->_palT, targetPalette, 48);
|
for (int i=0; i<noOfBlends; i++, _t->_prevPaletteBlends++) nblendPaletteTowardPalette(_t->_palT, targetPalette, 48);
|
||||||
targetPalette = _t->_palT; // copy transitioning/temporary palette
|
targetPalette = _t->_palT; // copy transitioning/temporary palette
|
||||||
@ -381,7 +353,8 @@ void Segment::handleTransition() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Segment::setUp(uint16_t i1, uint16_t i2, uint8_t grp, uint8_t spc, uint16_t ofs, uint16_t i1Y, uint16_t i2Y) {
|
// segId is given when called from network callback, changes are queued if that segment is currently in its effect function
|
||||||
|
void Segment::setUp(uint16_t i1, uint16_t i2, uint8_t grp, uint8_t spc, uint16_t ofs, uint16_t i1Y, uint16_t i2Y, uint8_t segId) {
|
||||||
// return if neither bounds nor grouping have changed
|
// return if neither bounds nor grouping have changed
|
||||||
bool boundsUnchanged = (start == i1 && stop == i2);
|
bool boundsUnchanged = (start == i1 && stop == i2);
|
||||||
#ifndef WLED_DISABLE_2D
|
#ifndef WLED_DISABLE_2D
|
||||||
@ -391,10 +364,22 @@ void Segment::setUp(uint16_t i1, uint16_t i2, uint8_t grp, uint8_t spc, uint16_t
|
|||||||
&& (!grp || (grouping == grp && spacing == spc))
|
&& (!grp || (grouping == grp && spacing == spc))
|
||||||
&& (ofs == UINT16_MAX || ofs == offset)) return;
|
&& (ofs == UINT16_MAX || ofs == offset)) return;
|
||||||
|
|
||||||
if (stop) fill(BLACK); //turn old segment range off
|
if (stop) fill(BLACK); // turn old segment range off (clears pixels if changing spacing)
|
||||||
|
if (grp) { // prevent assignment of 0
|
||||||
|
grouping = grp;
|
||||||
|
spacing = spc;
|
||||||
|
} else {
|
||||||
|
grouping = 1;
|
||||||
|
spacing = 0;
|
||||||
|
}
|
||||||
|
if (ofs < UINT16_MAX) offset = ofs;
|
||||||
|
|
||||||
|
markForReset();
|
||||||
|
if (boundsUnchanged) return;
|
||||||
|
|
||||||
|
// apply change immediately
|
||||||
if (i2 <= i1) { //disable segment
|
if (i2 <= i1) { //disable segment
|
||||||
stop = 0;
|
stop = 0;
|
||||||
markForReset();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (i1 < Segment::maxWidth || (i1 >= Segment::maxWidth*Segment::maxHeight && i1 < strip.getLengthTotal())) start = i1; // Segment::maxWidth equals strip.getLengthTotal() for 1D
|
if (i1 < Segment::maxWidth || (i1 >= Segment::maxWidth*Segment::maxHeight && i1 < strip.getLengthTotal())) start = i1; // Segment::maxWidth equals strip.getLengthTotal() for 1D
|
||||||
@ -407,13 +392,12 @@ void Segment::setUp(uint16_t i1, uint16_t i2, uint8_t grp, uint8_t spc, uint16_t
|
|||||||
stopY = i2Y > Segment::maxHeight ? Segment::maxHeight : MAX(1,i2Y);
|
stopY = i2Y > Segment::maxHeight ? Segment::maxHeight : MAX(1,i2Y);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (grp) {
|
// safety check
|
||||||
grouping = grp;
|
if (start >= stop || startY >= stopY) {
|
||||||
spacing = spc;
|
stop = 0;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
if (ofs < UINT16_MAX) offset = ofs;
|
refreshLightCapabilities();
|
||||||
markForReset();
|
|
||||||
if (!boundsUnchanged) refreshLightCapabilities();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -460,8 +444,7 @@ void Segment::setMode(uint8_t fx, bool loadDefaults) {
|
|||||||
// if we have a valid mode & is not reserved
|
// if we have a valid mode & is not reserved
|
||||||
if (fx < strip.getModeCount() && strncmp_P("RSVD", strip.getModeData(fx), 4)) {
|
if (fx < strip.getModeCount() && strncmp_P("RSVD", strip.getModeData(fx), 4)) {
|
||||||
if (fx != mode) {
|
if (fx != mode) {
|
||||||
startTransition(strip.getTransition()); // set effect transitions
|
if (fadeTransition) startTransition(strip.getTransition()); // set effect transitions
|
||||||
//markForReset(); // transition will handle this
|
|
||||||
mode = fx;
|
mode = fx;
|
||||||
|
|
||||||
// load default values from effect string
|
// load default values from effect string
|
||||||
@ -546,8 +529,7 @@ uint16_t Segment::virtualLength() const {
|
|||||||
return vLen;
|
return vLen;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
uint16_t groupLen = groupLength();
|
uint16_t groupLen = groupLength(); // is always >= 1
|
||||||
if (groupLen < 1) groupLen = 1; // prevent division by zero - better safe than sorry ...
|
|
||||||
uint16_t vLength = (length() + groupLen - 1) / groupLen;
|
uint16_t vLength = (length() + groupLen - 1) / groupLen;
|
||||||
if (mirror) vLength = (vLength + 1) /2; // divide by 2 if mirror, leave at least a single LED
|
if (mirror) vLength = (vLength + 1) /2; // divide by 2 if mirror, leave at least a single LED
|
||||||
return vLength;
|
return vLength;
|
||||||
@ -555,6 +537,7 @@ uint16_t Segment::virtualLength() const {
|
|||||||
|
|
||||||
void IRAM_ATTR Segment::setPixelColor(int i, uint32_t col)
|
void IRAM_ATTR Segment::setPixelColor(int i, uint32_t col)
|
||||||
{
|
{
|
||||||
|
if (!isActive()) return; // not active
|
||||||
#ifndef WLED_DISABLE_2D
|
#ifndef WLED_DISABLE_2D
|
||||||
int vStrip = i>>16; // hack to allow running on virtual strips (2D segment columns/rows)
|
int vStrip = i>>16; // hack to allow running on virtual strips (2D segment columns/rows)
|
||||||
#endif
|
#endif
|
||||||
@ -622,8 +605,6 @@ void IRAM_ATTR Segment::setPixelColor(int i, uint32_t col)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (leds) leds[i] = col;
|
|
||||||
|
|
||||||
uint16_t len = length();
|
uint16_t len = length();
|
||||||
uint8_t _bri_t = currentBri(on ? opacity : 0);
|
uint8_t _bri_t = currentBri(on ? opacity : 0);
|
||||||
if (_bri_t < 255) {
|
if (_bri_t < 255) {
|
||||||
@ -665,6 +646,7 @@ void IRAM_ATTR Segment::setPixelColor(int i, uint32_t col)
|
|||||||
// anti-aliased normalized version of setPixelColor()
|
// anti-aliased normalized version of setPixelColor()
|
||||||
void Segment::setPixelColor(float i, uint32_t col, bool aa)
|
void Segment::setPixelColor(float i, uint32_t col, bool aa)
|
||||||
{
|
{
|
||||||
|
if (!isActive()) return; // not active
|
||||||
int vStrip = int(i/10.0f); // hack to allow running on virtual strips (2D segment columns/rows)
|
int vStrip = int(i/10.0f); // hack to allow running on virtual strips (2D segment columns/rows)
|
||||||
i -= int(i);
|
i -= int(i);
|
||||||
|
|
||||||
@ -696,6 +678,7 @@ void Segment::setPixelColor(float i, uint32_t col, bool aa)
|
|||||||
|
|
||||||
uint32_t Segment::getPixelColor(int i)
|
uint32_t Segment::getPixelColor(int i)
|
||||||
{
|
{
|
||||||
|
if (!isActive()) return 0; // not active
|
||||||
#ifndef WLED_DISABLE_2D
|
#ifndef WLED_DISABLE_2D
|
||||||
int vStrip = i>>16;
|
int vStrip = i>>16;
|
||||||
#endif
|
#endif
|
||||||
@ -723,8 +706,6 @@ uint32_t Segment::getPixelColor(int i)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (leds) return RGBW32(leds[i].r, leds[i].g, leds[i].b, 0);
|
|
||||||
|
|
||||||
if (reverse) i = virtualLength() - i - 1;
|
if (reverse) i = virtualLength() - i - 1;
|
||||||
i *= groupLength();
|
i *= groupLength();
|
||||||
i += start;
|
i += start;
|
||||||
@ -765,6 +746,11 @@ void Segment::refreshLightCapabilities() {
|
|||||||
uint16_t segStartIdx = 0xFFFFU;
|
uint16_t segStartIdx = 0xFFFFU;
|
||||||
uint16_t segStopIdx = 0;
|
uint16_t segStopIdx = 0;
|
||||||
|
|
||||||
|
if (!isActive()) {
|
||||||
|
_capabilities = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (start < Segment::maxWidth * Segment::maxHeight) {
|
if (start < Segment::maxWidth * Segment::maxHeight) {
|
||||||
// we are withing 2D matrix (includes 1D segments)
|
// we are withing 2D matrix (includes 1D segments)
|
||||||
for (int y = startY; y < stopY; y++) for (int x = start; x < stop; x++) {
|
for (int y = startY; y < stopY; y++) for (int x = start; x < stop; x++) {
|
||||||
@ -809,6 +795,7 @@ void Segment::refreshLightCapabilities() {
|
|||||||
* Fills segment with color
|
* Fills segment with color
|
||||||
*/
|
*/
|
||||||
void Segment::fill(uint32_t c) {
|
void Segment::fill(uint32_t c) {
|
||||||
|
if (!isActive()) return; // not active
|
||||||
const uint16_t cols = is2D() ? virtualWidth() : virtualLength();
|
const uint16_t cols = is2D() ? virtualWidth() : virtualLength();
|
||||||
const uint16_t rows = virtualHeight(); // will be 1 for 1D
|
const uint16_t rows = virtualHeight(); // will be 1 for 1D
|
||||||
for(uint16_t y = 0; y < rows; y++) for (uint16_t x = 0; x < cols; x++) {
|
for(uint16_t y = 0; y < rows; y++) for (uint16_t x = 0; x < cols; x++) {
|
||||||
@ -824,6 +811,7 @@ void Segment::blendPixelColor(int n, uint32_t color, uint8_t blend) {
|
|||||||
|
|
||||||
// Adds the specified color with the existing pixel color perserving color balance.
|
// Adds the specified color with the existing pixel color perserving color balance.
|
||||||
void Segment::addPixelColor(int n, uint32_t color, bool fast) {
|
void Segment::addPixelColor(int n, uint32_t color, bool fast) {
|
||||||
|
if (!isActive()) return; // not active
|
||||||
uint32_t col = getPixelColor(n);
|
uint32_t col = getPixelColor(n);
|
||||||
uint8_t r = R(col);
|
uint8_t r = R(col);
|
||||||
uint8_t g = G(col);
|
uint8_t g = G(col);
|
||||||
@ -842,6 +830,7 @@ void Segment::addPixelColor(int n, uint32_t color, bool fast) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Segment::fadePixelColor(uint16_t n, uint8_t fade) {
|
void Segment::fadePixelColor(uint16_t n, uint8_t fade) {
|
||||||
|
if (!isActive()) return; // not active
|
||||||
CRGB pix = CRGB(getPixelColor(n)).nscale8_video(fade);
|
CRGB pix = CRGB(getPixelColor(n)).nscale8_video(fade);
|
||||||
setPixelColor(n, pix);
|
setPixelColor(n, pix);
|
||||||
}
|
}
|
||||||
@ -850,6 +839,7 @@ void Segment::fadePixelColor(uint16_t n, uint8_t fade) {
|
|||||||
* fade out function, higher rate = quicker fade
|
* fade out function, higher rate = quicker fade
|
||||||
*/
|
*/
|
||||||
void Segment::fade_out(uint8_t rate) {
|
void Segment::fade_out(uint8_t rate) {
|
||||||
|
if (!isActive()) return; // not active
|
||||||
const uint16_t cols = is2D() ? virtualWidth() : virtualLength();
|
const uint16_t cols = is2D() ? virtualWidth() : virtualLength();
|
||||||
const uint16_t rows = virtualHeight(); // will be 1 for 1D
|
const uint16_t rows = virtualHeight(); // will be 1 for 1D
|
||||||
|
|
||||||
@ -887,7 +877,7 @@ void Segment::fade_out(uint8_t rate) {
|
|||||||
|
|
||||||
// fades all pixels to black using nscale8()
|
// fades all pixels to black using nscale8()
|
||||||
void Segment::fadeToBlackBy(uint8_t fadeBy) {
|
void Segment::fadeToBlackBy(uint8_t fadeBy) {
|
||||||
if (fadeBy == 0) return; // optimization - no scaling to apply
|
if (!isActive() || fadeBy == 0) return; // optimization - no scaling to apply
|
||||||
const uint16_t cols = is2D() ? virtualWidth() : virtualLength();
|
const uint16_t cols = is2D() ? virtualWidth() : virtualLength();
|
||||||
const uint16_t rows = virtualHeight(); // will be 1 for 1D
|
const uint16_t rows = virtualHeight(); // will be 1 for 1D
|
||||||
|
|
||||||
@ -902,7 +892,7 @@ void Segment::fadeToBlackBy(uint8_t fadeBy) {
|
|||||||
*/
|
*/
|
||||||
void Segment::blur(uint8_t blur_amount)
|
void Segment::blur(uint8_t blur_amount)
|
||||||
{
|
{
|
||||||
if (blur_amount == 0) return; // optimization: 0 means "don't blur"
|
if (!isActive() || blur_amount == 0) return; // optimization: 0 means "don't blur"
|
||||||
#ifndef WLED_DISABLE_2D
|
#ifndef WLED_DISABLE_2D
|
||||||
if (is2D()) {
|
if (is2D()) {
|
||||||
// compatibility with 2D
|
// compatibility with 2D
|
||||||
@ -1068,24 +1058,6 @@ void WS2812FX::finalizeInit(void)
|
|||||||
Segment::maxHeight = 1;
|
Segment::maxHeight = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//initialize leds array. TBD: realloc if nr of leds change
|
|
||||||
if (Segment::_globalLeds) {
|
|
||||||
purgeSegments(true);
|
|
||||||
free(Segment::_globalLeds);
|
|
||||||
Segment::_globalLeds = nullptr;
|
|
||||||
}
|
|
||||||
if (useLedsArray) {
|
|
||||||
size_t arrSize = sizeof(CRGB) * getLengthTotal();
|
|
||||||
// softhack007 disabled; putting leds into psram leads to horrible slowdown on WROVER boards (see setUpLeds())
|
|
||||||
//#if defined(ARDUINO_ARCH_ESP32) && defined(WLED_USE_PSRAM)
|
|
||||||
//if (psramFound())
|
|
||||||
// Segment::_globalLeds = (CRGB*) ps_malloc(arrSize);
|
|
||||||
//else
|
|
||||||
//#endif
|
|
||||||
Segment::_globalLeds = (CRGB*) malloc(arrSize);
|
|
||||||
if (Segment::_globalLeds && (arrSize > 0)) memset(Segment::_globalLeds, 0, arrSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
//segments are created in makeAutoSegments();
|
//segments are created in makeAutoSegments();
|
||||||
DEBUG_PRINTLN(F("Loading custom palettes"));
|
DEBUG_PRINTLN(F("Loading custom palettes"));
|
||||||
loadCustomPalettes(); // (re)load all custom palettes
|
loadCustomPalettes(); // (re)load all custom palettes
|
||||||
@ -1094,7 +1066,7 @@ void WS2812FX::finalizeInit(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void WS2812FX::service() {
|
void WS2812FX::service() {
|
||||||
uint32_t nowUp = millis(); // Be aware, millis() rolls over every 49 days
|
unsigned long nowUp = millis(); // Be aware, millis() rolls over every 49 days
|
||||||
now = nowUp + timebase;
|
now = nowUp + timebase;
|
||||||
if (nowUp - _lastShow < MIN_SHOW_DELAY) return;
|
if (nowUp - _lastShow < MIN_SHOW_DELAY) return;
|
||||||
bool doShow = false;
|
bool doShow = false;
|
||||||
@ -1107,12 +1079,9 @@ void WS2812FX::service() {
|
|||||||
// reset the segment runtime data if needed
|
// reset the segment runtime data if needed
|
||||||
seg.resetIfRequired();
|
seg.resetIfRequired();
|
||||||
|
|
||||||
if (!seg.isActive()) continue;
|
|
||||||
|
|
||||||
// last condition ensures all solid segments are updated at the same time
|
// last condition ensures all solid segments are updated at the same time
|
||||||
if(nowUp > seg.next_time || _triggered || (doShow && seg.mode == FX_MODE_STATIC))
|
if (seg.isActive() && (nowUp > seg.next_time || _triggered || (doShow && seg.mode == FX_MODE_STATIC)))
|
||||||
{
|
{
|
||||||
if (seg.grouping == 0) seg.grouping = 1; //sanity check
|
|
||||||
doShow = true;
|
doShow = true;
|
||||||
uint16_t delay = FRAMETIME;
|
uint16_t delay = FRAMETIME;
|
||||||
|
|
||||||
@ -1136,16 +1105,24 @@ void WS2812FX::service() {
|
|||||||
|
|
||||||
seg.next_time = nowUp + delay;
|
seg.next_time = nowUp + delay;
|
||||||
}
|
}
|
||||||
|
if (_segment_index == _queuedChangesSegId) setUpSegmentFromQueuedChanges();
|
||||||
_segment_index++;
|
_segment_index++;
|
||||||
}
|
}
|
||||||
_virtualSegmentLength = 0;
|
_virtualSegmentLength = 0;
|
||||||
busses.setSegmentCCT(-1);
|
busses.setSegmentCCT(-1);
|
||||||
|
_isServicing = false;
|
||||||
|
_triggered = false;
|
||||||
|
|
||||||
|
#ifdef WLED_DEBUG
|
||||||
|
if (millis() - nowUp > _frametime) DEBUG_PRINTLN(F("Slow effects."));
|
||||||
|
#endif
|
||||||
if (doShow) {
|
if (doShow) {
|
||||||
yield();
|
yield();
|
||||||
show();
|
show();
|
||||||
}
|
}
|
||||||
_triggered = false;
|
#ifdef WLED_DEBUG
|
||||||
_isServicing = false;
|
if (millis() - nowUp > _frametime) DEBUG_PRINTLN(F("Slow strip."));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void IRAM_ATTR WS2812FX::setPixelColor(int i, uint32_t col)
|
void IRAM_ATTR WS2812FX::setPixelColor(int i, uint32_t col)
|
||||||
@ -1174,7 +1151,7 @@ uint32_t WS2812FX::getPixelColor(uint16_t i)
|
|||||||
#define MA_FOR_ESP 100 //how much mA does the ESP use (Wemos D1 about 80mA, ESP32 about 120mA)
|
#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
|
//you can set it to 0 if the ESP is powered by USB and the LEDs by external
|
||||||
|
|
||||||
void WS2812FX::estimateCurrentAndLimitBri() {
|
uint8_t WS2812FX::estimateCurrentAndLimitBri() {
|
||||||
//power limit calculation
|
//power limit calculation
|
||||||
//each LED can draw up 195075 "power units" (approx. 53mA)
|
//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
|
//one PU is the power it takes to have 1 channel 1 step brighter per brightness step
|
||||||
@ -1182,35 +1159,28 @@ void WS2812FX::estimateCurrentAndLimitBri() {
|
|||||||
bool useWackyWS2815PowerModel = false;
|
bool useWackyWS2815PowerModel = false;
|
||||||
byte actualMilliampsPerLed = milliampsPerLed;
|
byte actualMilliampsPerLed = milliampsPerLed;
|
||||||
|
|
||||||
|
if (ablMilliampsMax < 150 || actualMilliampsPerLed == 0) { //0 mA per LED and too low numbers turn off calculation
|
||||||
|
currentMilliamps = 0;
|
||||||
|
return _brightness;
|
||||||
|
}
|
||||||
|
|
||||||
if (milliampsPerLed == 255) {
|
if (milliampsPerLed == 255) {
|
||||||
useWackyWS2815PowerModel = true;
|
useWackyWS2815PowerModel = true;
|
||||||
actualMilliampsPerLed = 12; // from testing an actual strip
|
actualMilliampsPerLed = 12; // from testing an actual strip
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ablMilliampsMax < 150 || actualMilliampsPerLed == 0) { //0 mA per LED and too low numbers turn off calculation
|
size_t powerBudget = (ablMilliampsMax - MA_FOR_ESP); //100mA for ESP power
|
||||||
currentMilliamps = 0;
|
|
||||||
busses.setBrightness(_brightness);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t pLen = getLengthPhysical();
|
|
||||||
uint32_t puPerMilliamp = 195075 / actualMilliampsPerLed;
|
|
||||||
uint32_t powerBudget = (ablMilliampsMax - MA_FOR_ESP) * puPerMilliamp; //100mA for ESP power
|
|
||||||
if (powerBudget > puPerMilliamp * pLen) { //each LED uses about 1mA in standby, exclude that from power budget
|
|
||||||
powerBudget -= puPerMilliamp * pLen;
|
|
||||||
} else {
|
|
||||||
powerBudget = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t powerSum = 0;
|
|
||||||
|
|
||||||
|
size_t pLen = 0; //getLengthPhysical();
|
||||||
|
size_t powerSum = 0;
|
||||||
for (uint_fast8_t bNum = 0; bNum < busses.getNumBusses(); bNum++) {
|
for (uint_fast8_t bNum = 0; bNum < busses.getNumBusses(); bNum++) {
|
||||||
Bus *bus = busses.getBus(bNum);
|
Bus *bus = busses.getBus(bNum);
|
||||||
if (bus->getType() >= TYPE_NET_DDP_RGB) continue; //exclude non-physical network busses
|
if (!IS_DIGITAL(bus->getType())) continue; //exclude non-digital network busses
|
||||||
uint16_t len = bus->getLength();
|
uint16_t len = bus->getLength();
|
||||||
|
pLen += len;
|
||||||
uint32_t busPowerSum = 0;
|
uint32_t busPowerSum = 0;
|
||||||
for (uint_fast16_t i = 0; i < len; i++) { //sum up the usage of each LED
|
for (uint_fast16_t i = 0; i < len; i++) { //sum up the usage of each LED
|
||||||
uint32_t c = bus->getPixelColor(i);
|
uint32_t c = bus->getPixelColor(i); // always returns original or restored color without brightness scaling
|
||||||
byte r = R(c), g = G(c), b = B(c), w = W(c);
|
byte r = R(c), g = G(c), b = B(c), w = W(c);
|
||||||
|
|
||||||
if(useWackyWS2815PowerModel) { //ignore white component on WS2815 power calculation
|
if(useWackyWS2815PowerModel) { //ignore white component on WS2815 power calculation
|
||||||
@ -1222,51 +1192,75 @@ void WS2812FX::estimateCurrentAndLimitBri() {
|
|||||||
|
|
||||||
if (bus->hasWhite()) { //RGBW led total output with white LEDs enabled is still 50mA, so each channel uses less
|
if (bus->hasWhite()) { //RGBW led total output with white LEDs enabled is still 50mA, so each channel uses less
|
||||||
busPowerSum *= 3;
|
busPowerSum *= 3;
|
||||||
busPowerSum = busPowerSum >> 2; //same as /= 4
|
busPowerSum >>= 2; //same as /= 4
|
||||||
}
|
}
|
||||||
powerSum += busPowerSum;
|
powerSum += busPowerSum;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t powerSum0 = powerSum;
|
if (powerBudget > pLen) { //each LED uses about 1mA in standby, exclude that from power budget
|
||||||
//powerSum *= _brightness; // for NPBrightnessBus
|
powerBudget -= pLen;
|
||||||
powerSum *= 255; // no need to scale down powerSum - NPB-LG getPixelColor returns colors scaled down by brightness
|
} else {
|
||||||
|
powerBudget = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (powerSum > powerBudget) //scale brightness down to stay in current limit
|
// powerSum has all the values of channels summed (max would be pLen*765 as white is excluded) so convert to milliAmps
|
||||||
{
|
powerSum = (powerSum * actualMilliampsPerLed) / 765;
|
||||||
float scale = (float)powerBudget / (float)powerSum;
|
|
||||||
|
uint8_t newBri = _brightness;
|
||||||
|
if (powerSum * _brightness / 255 > powerBudget) { //scale brightness down to stay in current limit
|
||||||
|
float scale = (float)(powerBudget * 255) / (float)(powerSum * _brightness);
|
||||||
uint16_t scaleI = scale * 255;
|
uint16_t scaleI = scale * 255;
|
||||||
uint8_t scaleB = (scaleI > 255) ? 255 : scaleI;
|
uint8_t scaleB = (scaleI > 255) ? 255 : scaleI;
|
||||||
uint8_t newBri = scale8(_brightness, scaleB);
|
newBri = scale8(_brightness, scaleB) + 1;
|
||||||
// to keep brightness uniform, sets virtual busses too - softhack007: apply reductions immediately
|
|
||||||
if (scaleB < 255) busses.setBrightness(scaleB, true); // NPB-LG has already applied brightness, so its suffifient to post-apply scaling ==> use scaleB instead of newBri
|
|
||||||
busses.setBrightness(newBri, false); // set new brightness for next frame
|
|
||||||
//currentMilliamps = (powerSum0 * newBri) / puPerMilliamp; // for NPBrightnessBus
|
|
||||||
currentMilliamps = (powerSum0 * scaleB) / puPerMilliamp; // for NPBus-LG
|
|
||||||
} else {
|
|
||||||
currentMilliamps = powerSum / puPerMilliamp;
|
|
||||||
busses.setBrightness(_brightness, false); // set new brightness for next frame
|
|
||||||
}
|
}
|
||||||
|
currentMilliamps = (powerSum * newBri) / 255;
|
||||||
currentMilliamps += MA_FOR_ESP; //add power of ESP back to estimate
|
currentMilliamps += MA_FOR_ESP; //add power of ESP back to estimate
|
||||||
currentMilliamps += pLen; //add standby power back to estimate
|
currentMilliamps += pLen; //add standby power (1mA/LED) back to estimate
|
||||||
|
return newBri;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WS2812FX::show(void) {
|
void WS2812FX::show(void) {
|
||||||
|
|
||||||
// avoid race condition, caputre _callback value
|
// avoid race condition, caputre _callback value
|
||||||
show_callback callback = _callback;
|
show_callback callback = _callback;
|
||||||
if (callback) callback();
|
if (callback) callback();
|
||||||
|
|
||||||
estimateCurrentAndLimitBri();
|
#ifdef WLED_DEBUG
|
||||||
|
static unsigned long sumMicros = 0, sumCurrent = 0;
|
||||||
|
static size_t calls = 0;
|
||||||
|
unsigned long microsStart = micros();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uint8_t newBri = estimateCurrentAndLimitBri();
|
||||||
|
busses.setBrightness(newBri); // "repaints" all pixels if brightness changed
|
||||||
|
|
||||||
|
#ifdef WLED_DEBUG
|
||||||
|
sumCurrent += micros() - microsStart;
|
||||||
|
#endif
|
||||||
|
|
||||||
// some buses send asynchronously and this method will return before
|
// some buses send asynchronously and this method will return before
|
||||||
// all of the data has been sent.
|
// all of the data has been sent.
|
||||||
// See https://github.com/Makuna/NeoPixelBus/wiki/ESP32-NeoMethods#neoesp32rmt-methods
|
// See https://github.com/Makuna/NeoPixelBus/wiki/ESP32-NeoMethods#neoesp32rmt-methods
|
||||||
busses.show();
|
busses.show();
|
||||||
|
|
||||||
|
// restore bus brightness to its original value
|
||||||
|
// this is done right after show, so this is only OK if LED updates are completed before show() returns
|
||||||
|
// or async show has a separate buffer (ESP32 RMT and I2S are ok)
|
||||||
|
if (newBri < _brightness) busses.setBrightness(_brightness);
|
||||||
|
|
||||||
|
#ifdef WLED_DEBUG
|
||||||
|
sumMicros += micros() - microsStart;
|
||||||
|
if (++calls == 100) {
|
||||||
|
DEBUG_PRINTF("%d show calls: %lu[us] avg: %lu[us] (current: %lu[us] avg: %lu[us])\n", calls, sumMicros, sumMicros/calls, sumCurrent, sumCurrent/calls);
|
||||||
|
sumMicros = sumCurrent = 0;
|
||||||
|
calls = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
unsigned long now = millis();
|
unsigned long now = millis();
|
||||||
unsigned long diff = now - _lastShow;
|
size_t diff = now - _lastShow;
|
||||||
uint16_t fpsCurr = 200;
|
size_t fpsCurr = 200;
|
||||||
if (diff > 0) fpsCurr = 1000 / diff;
|
if (diff > 0) fpsCurr = 1000 / diff;
|
||||||
_cumulativeFps = (3 * _cumulativeFps + fpsCurr) >> 2;
|
_cumulativeFps = (3 * _cumulativeFps + fpsCurr +2) >> 2; // "+2" for proper rounding (2/4 = 0.5)
|
||||||
_lastShow = now;
|
_lastShow = now;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1323,6 +1317,8 @@ void WS2812FX::setCCT(uint16_t k) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// direct=true either expects the caller to call show() themselves (realtime modes) or be ok waiting for the next frame for the change to apply
|
||||||
|
// direct=false immediately triggers an effect redraw
|
||||||
void WS2812FX::setBrightness(uint8_t b, bool direct) {
|
void WS2812FX::setBrightness(uint8_t b, bool direct) {
|
||||||
if (gammaCorrectBri) b = gamma8(b);
|
if (gammaCorrectBri) b = gamma8(b);
|
||||||
if (_brightness == b) return;
|
if (_brightness == b) return;
|
||||||
@ -1332,12 +1328,12 @@ void WS2812FX::setBrightness(uint8_t b, bool direct) {
|
|||||||
seg.freeze = false;
|
seg.freeze = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (direct) {
|
// setting brightness with NeoPixelBusLg has no effect on already painted pixels,
|
||||||
// would be dangerous if applied immediately (could exceed ABL), but will not output until the next show()
|
// so we need to force an update to existing buffer
|
||||||
busses.setBrightness(b);
|
busses.setBrightness(b);
|
||||||
} else {
|
if (!direct) {
|
||||||
unsigned long t = millis();
|
unsigned long t = millis();
|
||||||
if (_segments[0].next_time > t + 22 && t - _lastShow > MIN_SHOW_DELAY) show(); //apply brightness change immediately if no refresh soon
|
if (_segments[0].next_time > t + 22 && t - _lastShow > MIN_SHOW_DELAY) trigger(); //apply brightness change immediately if no refresh soon
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1444,9 +1440,32 @@ Segment& WS2812FX::getSegment(uint8_t id) {
|
|||||||
return _segments[id >= _segments.size() ? getMainSegmentId() : id]; // vectors
|
return _segments[id >= _segments.size() ? getMainSegmentId() : id]; // vectors
|
||||||
}
|
}
|
||||||
|
|
||||||
void WS2812FX::setSegment(uint8_t n, uint16_t i1, uint16_t i2, uint8_t grouping, uint8_t spacing, uint16_t offset, uint16_t startY, uint16_t stopY) {
|
// sets new segment bounds, queues if that segment is currently running
|
||||||
if (n >= _segments.size()) return;
|
void WS2812FX::setSegment(uint8_t segId, uint16_t i1, uint16_t i2, uint8_t grouping, uint8_t spacing, uint16_t offset, uint16_t startY, uint16_t stopY) {
|
||||||
_segments[n].setUp(i1, i2, grouping, spacing, offset, startY, stopY);
|
if (segId >= getSegmentsNum()) {
|
||||||
|
if (i2 <= i1) return; // do not append empty/inactive segments
|
||||||
|
appendSegment(Segment(0, strip.getLengthTotal()));
|
||||||
|
segId = getSegmentsNum()-1; // segments are added at the end of list
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_queuedChangesSegId == segId) _queuedChangesSegId = 255; // cancel queued change if already queued for this segment
|
||||||
|
|
||||||
|
if (segId < getMaxSegments() && segId == getCurrSegmentId() && isServicing()) { // queue change to prevent concurrent access
|
||||||
|
// queuing a change for a second segment will lead to the loss of the first change if not yet applied
|
||||||
|
// however this is not a problem as the queued change is applied immediately after the effect function in that segment returns
|
||||||
|
_qStart = i1; _qStop = i2; _qStartY = startY; _qStopY = stopY;
|
||||||
|
_qGrouping = grouping; _qSpacing = spacing; _qOffset = offset;
|
||||||
|
_queuedChangesSegId = segId;
|
||||||
|
return; // queued changes are applied immediately after effect function returns
|
||||||
|
}
|
||||||
|
|
||||||
|
_segments[segId].setUp(i1, i2, grouping, spacing, offset, startY, stopY);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WS2812FX::setUpSegmentFromQueuedChanges() {
|
||||||
|
if (_queuedChangesSegId >= getSegmentsNum()) return;
|
||||||
|
getSegment(_queuedChangesSegId).setUp(_qStart, _qStop, _qGrouping, _qSpacing, _qOffset, _qStartY, _qStopY);
|
||||||
|
_queuedChangesSegId = 255;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WS2812FX::restartRuntime() {
|
void WS2812FX::restartRuntime() {
|
||||||
@ -1614,7 +1633,7 @@ void WS2812FX::printSize() {
|
|||||||
DEBUG_PRINTF("Data: %d*%d=%uB\n", sizeof(const char *), _modeData.size(), (_modeData.capacity()*sizeof(const char *)));
|
DEBUG_PRINTF("Data: %d*%d=%uB\n", sizeof(const char *), _modeData.size(), (_modeData.capacity()*sizeof(const char *)));
|
||||||
DEBUG_PRINTF("Map: %d*%d=%uB\n", sizeof(uint16_t), (int)customMappingSize, customMappingSize*sizeof(uint16_t));
|
DEBUG_PRINTF("Map: %d*%d=%uB\n", sizeof(uint16_t), (int)customMappingSize, customMappingSize*sizeof(uint16_t));
|
||||||
size = getLengthTotal();
|
size = getLengthTotal();
|
||||||
if (useLedsArray) DEBUG_PRINTF("Buffer: %d*%u=%uB\n", sizeof(CRGB), size, size*sizeof(CRGB));
|
if (useGlobalLedBuffer) DEBUG_PRINTF("Buffer: %d*%u=%uB\n", sizeof(CRGB), size, size*sizeof(CRGB));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -91,71 +91,128 @@ uint32_t Bus::autoWhiteCalc(uint32_t c) {
|
|||||||
return RGBW32(r, g, b, w);
|
return RGBW32(r, g, b, w);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t *Bus::allocData(size_t size) {
|
||||||
|
if (_data) free(_data); // should not happen, but for safety
|
||||||
|
return _data = (uint8_t *)(size>0 ? calloc(size, sizeof(uint8_t)) : nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
BusDigital::BusDigital(BusConfig &bc, uint8_t nr, const ColorOrderMap &com) : Bus(bc.type, bc.start, bc.autoWhite), _colorOrderMap(com) {
|
|
||||||
|
BusDigital::BusDigital(BusConfig &bc, uint8_t nr, const ColorOrderMap &com)
|
||||||
|
: Bus(bc.type, bc.start, bc.autoWhite, bc.count, bc.reversed, (bc.refreshReq || bc.type == TYPE_TM1814))
|
||||||
|
, _skip(bc.skipAmount) //sacrificial pixels
|
||||||
|
, _colorOrder(bc.colorOrder)
|
||||||
|
, _colorOrderMap(com)
|
||||||
|
{
|
||||||
if (!IS_DIGITAL(bc.type) || !bc.count) return;
|
if (!IS_DIGITAL(bc.type) || !bc.count) return;
|
||||||
if (!pinManager.allocatePin(bc.pins[0], true, PinOwner::BusDigital)) return;
|
if (!pinManager.allocatePin(bc.pins[0], true, PinOwner::BusDigital)) return;
|
||||||
_frequencykHz = 0U;
|
_frequencykHz = 0U;
|
||||||
_pins[0] = bc.pins[0];
|
_pins[0] = bc.pins[0];
|
||||||
if (IS_2PIN(bc.type)) {
|
if (IS_2PIN(bc.type)) {
|
||||||
if (!pinManager.allocatePin(bc.pins[1], true, PinOwner::BusDigital)) {
|
if (!pinManager.allocatePin(bc.pins[1], true, PinOwner::BusDigital)) {
|
||||||
cleanup(); return;
|
cleanup();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
_pins[1] = bc.pins[1];
|
_pins[1] = bc.pins[1];
|
||||||
_frequencykHz = bc.frequency ? bc.frequency : 2000U; // 2MHz clock if undefined
|
_frequencykHz = bc.frequency ? bc.frequency : 2000U; // 2MHz clock if undefined
|
||||||
}
|
}
|
||||||
reversed = bc.reversed;
|
|
||||||
_needsRefresh = bc.refreshReq || bc.type == TYPE_TM1814;
|
|
||||||
_skip = bc.skipAmount; //sacrificial pixels
|
|
||||||
_len = bc.count + _skip;
|
|
||||||
_iType = PolyBus::getI(bc.type, _pins, nr);
|
_iType = PolyBus::getI(bc.type, _pins, nr);
|
||||||
if (_iType == I_NONE) return;
|
if (_iType == I_NONE) return;
|
||||||
uint16_t lenToCreate = _len;
|
if (bc.doubleBuffer && !allocData(bc.count * (Bus::hasWhite(_type) + 3*Bus::hasRGB(_type)))) return; //warning: hardcoded channel count
|
||||||
if (bc.type == TYPE_WS2812_1CH_X3) lenToCreate = NUM_ICS_WS2812_1CH_3X(_len); // only needs a third of "RGB" LEDs for NeoPixelBus
|
_buffering = bc.doubleBuffer;
|
||||||
_busPtr = PolyBus::create(_iType, _pins, lenToCreate, nr, _frequencykHz);
|
uint16_t lenToCreate = bc.count;
|
||||||
|
if (bc.type == TYPE_WS2812_1CH_X3) lenToCreate = NUM_ICS_WS2812_1CH_3X(bc.count); // only needs a third of "RGB" LEDs for NeoPixelBus
|
||||||
|
_busPtr = PolyBus::create(_iType, _pins, lenToCreate + _skip, nr, _frequencykHz);
|
||||||
_valid = (_busPtr != nullptr);
|
_valid = (_busPtr != nullptr);
|
||||||
_colorOrder = bc.colorOrder;
|
DEBUG_PRINTF("%successfully inited strip %u (len %u) with type %u and pins %u,%u (itype %u)\n", _valid?"S":"Uns", nr, bc.count, bc.type, _pins[0], _pins[1], _iType);
|
||||||
DEBUG_PRINTF("%successfully inited strip %u (len %u) with type %u and pins %u,%u (itype %u)\n", _valid?"S":"Uns", nr, _len, bc.type, _pins[0],_pins[1],_iType);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BusDigital::show() {
|
void BusDigital::show() {
|
||||||
PolyBus::show(_busPtr, _iType);
|
if (!_valid) return;
|
||||||
|
if (_buffering) { // should be _data != nullptr, but that causes ~20% FPS drop
|
||||||
|
size_t channels = Bus::hasWhite(_type) + 3*Bus::hasRGB(_type);
|
||||||
|
for (size_t i=0; i<_len; i++) {
|
||||||
|
size_t offset = i*channels;
|
||||||
|
uint8_t co = _colorOrderMap.getPixelColorOrder(i+_start, _colorOrder);
|
||||||
|
uint32_t c;
|
||||||
|
if (_type == TYPE_WS2812_1CH_X3) { // map to correct IC, each controls 3 LEDs (_len is always a multiple of 3)
|
||||||
|
switch (i%3) {
|
||||||
|
case 0: c = RGBW32(_data[offset] , _data[offset+1], _data[offset+2], 0); break;
|
||||||
|
case 1: c = RGBW32(_data[offset-1], _data[offset] , _data[offset+1], 0); break;
|
||||||
|
case 2: c = RGBW32(_data[offset-2], _data[offset-1], _data[offset] , 0); break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
c = RGBW32(_data[offset],_data[offset+1],_data[offset+2],(Bus::hasWhite(_type)?_data[offset+3]:0));
|
||||||
|
}
|
||||||
|
uint16_t pix = i;
|
||||||
|
if (_reversed) pix = _len - pix -1;
|
||||||
|
else pix += _skip;
|
||||||
|
PolyBus::setPixelColor(_busPtr, _iType, pix, c, co);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PolyBus::show(_busPtr, _iType, !_buffering); // faster if buffer consistency is not important
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BusDigital::canShow() {
|
bool BusDigital::canShow() {
|
||||||
|
if (!_valid) return true;
|
||||||
return PolyBus::canShow(_busPtr, _iType);
|
return PolyBus::canShow(_busPtr, _iType);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BusDigital::setBrightness(uint8_t b, bool immediate) {
|
void BusDigital::setBrightness(uint8_t b) {
|
||||||
|
if (_bri == b) return;
|
||||||
//Fix for turning off onboard LED breaking bus
|
//Fix for turning off onboard LED breaking bus
|
||||||
#ifdef LED_BUILTIN
|
#ifdef LED_BUILTIN
|
||||||
if (_bri == 0 && b > 0) {
|
if (_bri == 0) { // && b > 0, covered by guard if above
|
||||||
if (_pins[0] == LED_BUILTIN || _pins[1] == LED_BUILTIN) PolyBus::begin(_busPtr, _iType, _pins);
|
if (_pins[0] == LED_BUILTIN || _pins[1] == LED_BUILTIN) reinit();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
Bus::setBrightness(b, immediate);
|
uint8_t prevBri = _bri;
|
||||||
PolyBus::setBrightness(_busPtr, _iType, b, immediate);
|
Bus::setBrightness(b);
|
||||||
|
PolyBus::setBrightness(_busPtr, _iType, b);
|
||||||
|
|
||||||
|
if (_buffering) return;
|
||||||
|
|
||||||
|
// must update/repaint every LED in the NeoPixelBus buffer to the new brightness
|
||||||
|
// the only case where repainting is unnecessary is when all pixels are set after the brightness change but before the next show
|
||||||
|
// (which we can't rely on)
|
||||||
|
uint16_t hwLen = _len;
|
||||||
|
if (_type == TYPE_WS2812_1CH_X3) hwLen = NUM_ICS_WS2812_1CH_3X(_len); // only needs a third of "RGB" LEDs for NeoPixelBus
|
||||||
|
for (uint_fast16_t i = 0; i < hwLen; i++) {
|
||||||
|
// use 0 as color order, actual order does not matter here as we just update the channel values as-is
|
||||||
|
uint32_t c = restoreColorLossy(PolyBus::getPixelColor(_busPtr, _iType, i, 0),prevBri);
|
||||||
|
PolyBus::setPixelColor(_busPtr, _iType, i, c, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//If LEDs are skipped, it is possible to use the first as a status LED.
|
//If LEDs are skipped, it is possible to use the first as a status LED.
|
||||||
//TODO only show if no new show due in the next 50ms
|
//TODO only show if no new show due in the next 50ms
|
||||||
void BusDigital::setStatusPixel(uint32_t c) {
|
void BusDigital::setStatusPixel(uint32_t c) {
|
||||||
if (_skip && canShow()) {
|
if (_valid && _skip) {
|
||||||
PolyBus::setPixelColor(_busPtr, _iType, 0, c, _colorOrderMap.getPixelColorOrder(_start, _colorOrder));
|
PolyBus::setPixelColor(_busPtr, _iType, 0, c, _colorOrderMap.getPixelColorOrder(_start, _colorOrder));
|
||||||
PolyBus::show(_busPtr, _iType);
|
if (canShow()) PolyBus::show(_busPtr, _iType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void IRAM_ATTR BusDigital::setPixelColor(uint16_t pix, uint32_t c) {
|
void IRAM_ATTR BusDigital::setPixelColor(uint16_t pix, uint32_t c) {
|
||||||
if (_type == TYPE_SK6812_RGBW || _type == TYPE_TM1814 || _type == TYPE_WS2812_1CH_X3) c = autoWhiteCalc(c);
|
if (!_valid) return;
|
||||||
|
if (Bus::hasWhite(_type)) c = autoWhiteCalc(c);
|
||||||
if (_cct >= 1900) c = colorBalanceFromKelvin(_cct, c); //color correction from CCT
|
if (_cct >= 1900) c = colorBalanceFromKelvin(_cct, c); //color correction from CCT
|
||||||
if (reversed) pix = _len - pix -1;
|
if (_buffering) { // should be _data != nullptr, but that causes ~20% FPS drop
|
||||||
|
size_t channels = Bus::hasWhite(_type) + 3*Bus::hasRGB(_type);
|
||||||
|
size_t offset = pix*channels;
|
||||||
|
if (Bus::hasRGB(_type)) {
|
||||||
|
_data[offset++] = R(c);
|
||||||
|
_data[offset++] = G(c);
|
||||||
|
_data[offset++] = B(c);
|
||||||
|
}
|
||||||
|
if (Bus::hasWhite(_type)) _data[offset] = W(c);
|
||||||
|
} else {
|
||||||
|
if (_reversed) pix = _len - pix -1;
|
||||||
else pix += _skip;
|
else pix += _skip;
|
||||||
uint8_t co = _colorOrderMap.getPixelColorOrder(pix+_start, _colorOrder);
|
uint8_t co = _colorOrderMap.getPixelColorOrder(pix+_start, _colorOrder);
|
||||||
if (_type == TYPE_WS2812_1CH_X3) { // map to correct IC, each controls 3 LEDs
|
if (_type == TYPE_WS2812_1CH_X3) { // map to correct IC, each controls 3 LEDs
|
||||||
uint16_t pOld = pix;
|
uint16_t pOld = pix;
|
||||||
pix = IC_INDEX_WS2812_1CH_3X(pix);
|
pix = IC_INDEX_WS2812_1CH_3X(pix);
|
||||||
uint32_t cOld = PolyBus::getPixelColor(_busPtr, _iType, pix, co);
|
uint32_t cOld = restoreColorLossy(PolyBus::getPixelColor(_busPtr, _iType, pix, co),_bri);
|
||||||
switch (pOld % 3) { // change only the single channel (TODO: this can cause loss because of get/set)
|
switch (pOld % 3) { // change only the single channel (TODO: this can cause loss because of get/set)
|
||||||
case 0: c = RGBW32(R(cOld), W(c) , B(cOld), 0); break;
|
case 0: c = RGBW32(R(cOld), W(c) , B(cOld), 0); break;
|
||||||
case 1: c = RGBW32(W(c) , G(cOld), B(cOld), 0); break;
|
case 1: c = RGBW32(W(c) , G(cOld), B(cOld), 0); break;
|
||||||
@ -164,23 +221,38 @@ void IRAM_ATTR BusDigital::setPixelColor(uint16_t pix, uint32_t c) {
|
|||||||
}
|
}
|
||||||
PolyBus::setPixelColor(_busPtr, _iType, pix, c, co);
|
PolyBus::setPixelColor(_busPtr, _iType, pix, c, co);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns original color if global buffering is enabled, else returns lossly restored color from bus
|
||||||
uint32_t BusDigital::getPixelColor(uint16_t pix) {
|
uint32_t BusDigital::getPixelColor(uint16_t pix) {
|
||||||
if (reversed) pix = _len - pix -1;
|
if (!_valid) return 0;
|
||||||
|
if (_buffering) { // should be _data != nullptr, but that causes ~20% FPS drop
|
||||||
|
size_t channels = Bus::hasWhite(_type) + 3*Bus::hasRGB(_type);
|
||||||
|
size_t offset = pix*channels;
|
||||||
|
uint32_t c;
|
||||||
|
if (!Bus::hasRGB(_type)) {
|
||||||
|
c = RGBW32(_data[offset], _data[offset], _data[offset], _data[offset]);
|
||||||
|
} else {
|
||||||
|
c = RGBW32(_data[offset], _data[offset+1], _data[offset+2], Bus::hasWhite(_type) ? _data[offset+3] : 0);
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
} else {
|
||||||
|
if (_reversed) pix = _len - pix -1;
|
||||||
else pix += _skip;
|
else pix += _skip;
|
||||||
uint8_t co = _colorOrderMap.getPixelColorOrder(pix+_start, _colorOrder);
|
uint8_t co = _colorOrderMap.getPixelColorOrder(pix+_start, _colorOrder);
|
||||||
|
uint32_t c = restoreColorLossy(PolyBus::getPixelColor(_busPtr, _iType, (_type==TYPE_WS2812_1CH_X3) ? IC_INDEX_WS2812_1CH_3X(pix) : pix, co),_bri);
|
||||||
if (_type == TYPE_WS2812_1CH_X3) { // map to correct IC, each controls 3 LEDs
|
if (_type == TYPE_WS2812_1CH_X3) { // map to correct IC, each controls 3 LEDs
|
||||||
uint16_t pOld = pix;
|
uint8_t r = R(c);
|
||||||
pix = IC_INDEX_WS2812_1CH_3X(pix);
|
uint8_t g = _reversed ? B(c) : G(c); // should G and B be switched if _reversed?
|
||||||
uint32_t c = PolyBus::getPixelColor(_busPtr, _iType, pix, co);
|
uint8_t b = _reversed ? G(c) : B(c);
|
||||||
switch (pOld % 3) { // get only the single channel
|
switch (pix % 3) { // get only the single channel
|
||||||
case 0: c = RGBW32(G(c), G(c), G(c), G(c)); break;
|
case 0: c = RGBW32(g, g, g, g); break;
|
||||||
case 1: c = RGBW32(R(c), R(c), R(c), R(c)); break;
|
case 1: c = RGBW32(r, r, r, r); break;
|
||||||
case 2: c = RGBW32(B(c), B(c), B(c), B(c)); break;
|
case 2: c = RGBW32(b, b, b, b); break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
return PolyBus::getPixelColor(_busPtr, _iType, pix, co);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t BusDigital::getPins(uint8_t* pinArray) {
|
uint8_t BusDigital::getPins(uint8_t* pinArray) {
|
||||||
@ -196,6 +268,7 @@ void BusDigital::setColorOrder(uint8_t colorOrder) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void BusDigital::reinit() {
|
void BusDigital::reinit() {
|
||||||
|
if (!_valid) return;
|
||||||
PolyBus::begin(_busPtr, _iType, _pins);
|
PolyBus::begin(_busPtr, _iType, _pins);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,13 +278,15 @@ void BusDigital::cleanup() {
|
|||||||
_iType = I_NONE;
|
_iType = I_NONE;
|
||||||
_valid = false;
|
_valid = false;
|
||||||
_busPtr = nullptr;
|
_busPtr = nullptr;
|
||||||
|
if (_data != nullptr) freeData();
|
||||||
pinManager.deallocatePin(_pins[1], PinOwner::BusDigital);
|
pinManager.deallocatePin(_pins[1], PinOwner::BusDigital);
|
||||||
pinManager.deallocatePin(_pins[0], PinOwner::BusDigital);
|
pinManager.deallocatePin(_pins[0], PinOwner::BusDigital);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BusPwm::BusPwm(BusConfig &bc) : Bus(bc.type, bc.start, bc.autoWhite) {
|
BusPwm::BusPwm(BusConfig &bc)
|
||||||
_valid = false;
|
: Bus(bc.type, bc.start, bc.autoWhite, 1, bc.reversed)
|
||||||
|
{
|
||||||
if (!IS_PWM(bc.type)) return;
|
if (!IS_PWM(bc.type)) return;
|
||||||
uint8_t numPins = NUM_PWM_PINS(bc.type);
|
uint8_t numPins = NUM_PWM_PINS(bc.type);
|
||||||
_frequency = bc.frequency ? bc.frequency : WLED_PWM_FREQ;
|
_frequency = bc.frequency ? bc.frequency : WLED_PWM_FREQ;
|
||||||
@ -239,7 +314,7 @@ BusPwm::BusPwm(BusConfig &bc) : Bus(bc.type, bc.start, bc.autoWhite) {
|
|||||||
ledcAttachPin(_pins[i], _ledcStart + i);
|
ledcAttachPin(_pins[i], _ledcStart + i);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
reversed = bc.reversed;
|
_data = _pwmdata; // avoid malloc() and use stack
|
||||||
_valid = true;
|
_valid = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -307,7 +382,7 @@ void BusPwm::show() {
|
|||||||
uint8_t numPins = NUM_PWM_PINS(_type);
|
uint8_t numPins = NUM_PWM_PINS(_type);
|
||||||
for (uint8_t i = 0; i < numPins; i++) {
|
for (uint8_t i = 0; i < numPins; i++) {
|
||||||
uint8_t scaled = (_data[i] * _bri) / 255;
|
uint8_t scaled = (_data[i] * _bri) / 255;
|
||||||
if (reversed) scaled = 255 - scaled;
|
if (_reversed) scaled = 255 - scaled;
|
||||||
#ifdef ESP8266
|
#ifdef ESP8266
|
||||||
analogWrite(_pins[i], scaled);
|
analogWrite(_pins[i], scaled);
|
||||||
#else
|
#else
|
||||||
@ -342,8 +417,10 @@ void BusPwm::deallocatePins() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BusOnOff::BusOnOff(BusConfig &bc) : Bus(bc.type, bc.start, bc.autoWhite) {
|
BusOnOff::BusOnOff(BusConfig &bc)
|
||||||
_valid = false;
|
: Bus(bc.type, bc.start, bc.autoWhite, 1, bc.reversed)
|
||||||
|
, _onoffdata(0)
|
||||||
|
{
|
||||||
if (bc.type != TYPE_ONOFF) return;
|
if (bc.type != TYPE_ONOFF) return;
|
||||||
|
|
||||||
uint8_t currentPin = bc.pins[0];
|
uint8_t currentPin = bc.pins[0];
|
||||||
@ -352,7 +429,7 @@ BusOnOff::BusOnOff(BusConfig &bc) : Bus(bc.type, bc.start, bc.autoWhite) {
|
|||||||
}
|
}
|
||||||
_pin = currentPin; //store only after allocatePin() succeeds
|
_pin = currentPin; //store only after allocatePin() succeeds
|
||||||
pinMode(_pin, OUTPUT);
|
pinMode(_pin, OUTPUT);
|
||||||
reversed = bc.reversed;
|
_data = &_onoffdata; // avoid malloc() and use stack
|
||||||
_valid = true;
|
_valid = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -363,18 +440,17 @@ void BusOnOff::setPixelColor(uint16_t pix, uint32_t c) {
|
|||||||
uint8_t g = G(c);
|
uint8_t g = G(c);
|
||||||
uint8_t b = B(c);
|
uint8_t b = B(c);
|
||||||
uint8_t w = W(c);
|
uint8_t w = W(c);
|
||||||
|
_data[0] = bool(r|g|b|w) && bool(_bri) ? 0xFF : 0;
|
||||||
_data = bool(r|g|b|w) && bool(_bri) ? 0xFF : 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t BusOnOff::getPixelColor(uint16_t pix) {
|
uint32_t BusOnOff::getPixelColor(uint16_t pix) {
|
||||||
if (!_valid) return 0;
|
if (!_valid) return 0;
|
||||||
return RGBW32(_data, _data, _data, _data);
|
return RGBW32(_data[0], _data[0], _data[0], _data[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BusOnOff::show() {
|
void BusOnOff::show() {
|
||||||
if (!_valid) return;
|
if (!_valid) return;
|
||||||
digitalWrite(_pin, reversed ? !(bool)_data : (bool)_data);
|
digitalWrite(_pin, _reversed ? !(bool)_data[0] : (bool)_data[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t BusOnOff::getPins(uint8_t* pinArray) {
|
uint8_t BusOnOff::getPins(uint8_t* pinArray) {
|
||||||
@ -384,8 +460,10 @@ uint8_t BusOnOff::getPins(uint8_t* pinArray) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BusNetwork::BusNetwork(BusConfig &bc) : Bus(bc.type, bc.start, bc.autoWhite) {
|
BusNetwork::BusNetwork(BusConfig &bc)
|
||||||
_valid = false;
|
: Bus(bc.type, bc.start, bc.autoWhite, bc.count)
|
||||||
|
, _broadcastLock(false)
|
||||||
|
{
|
||||||
switch (bc.type) {
|
switch (bc.type) {
|
||||||
case TYPE_NET_ARTNET_RGB:
|
case TYPE_NET_ARTNET_RGB:
|
||||||
_rgbw = false;
|
_rgbw = false;
|
||||||
@ -401,18 +479,13 @@ BusNetwork::BusNetwork(BusConfig &bc) : Bus(bc.type, bc.start, bc.autoWhite) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
_UDPchannels = _rgbw ? 4 : 3;
|
_UDPchannels = _rgbw ? 4 : 3;
|
||||||
_data = (byte *)malloc(bc.count * _UDPchannels);
|
|
||||||
if (_data == nullptr) return;
|
|
||||||
memset(_data, 0, bc.count * _UDPchannels);
|
|
||||||
_len = bc.count;
|
|
||||||
_client = IPAddress(bc.pins[0],bc.pins[1],bc.pins[2],bc.pins[3]);
|
_client = IPAddress(bc.pins[0],bc.pins[1],bc.pins[2],bc.pins[3]);
|
||||||
_broadcastLock = false;
|
_valid = (allocData(_len * _UDPchannels) != nullptr);
|
||||||
_valid = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BusNetwork::setPixelColor(uint16_t pix, uint32_t c) {
|
void BusNetwork::setPixelColor(uint16_t pix, uint32_t c) {
|
||||||
if (!_valid || pix >= _len) return;
|
if (!_valid || pix >= _len) return;
|
||||||
if (hasWhite()) c = autoWhiteCalc(c);
|
if (_rgbw) c = autoWhiteCalc(c);
|
||||||
if (_cct >= 1900) c = colorBalanceFromKelvin(_cct, c); //color correction from CCT
|
if (_cct >= 1900) c = colorBalanceFromKelvin(_cct, c); //color correction from CCT
|
||||||
uint16_t offset = pix * _UDPchannels;
|
uint16_t offset = pix * _UDPchannels;
|
||||||
_data[offset] = R(c);
|
_data[offset] = R(c);
|
||||||
@ -424,7 +497,7 @@ void BusNetwork::setPixelColor(uint16_t pix, uint32_t c) {
|
|||||||
uint32_t BusNetwork::getPixelColor(uint16_t pix) {
|
uint32_t BusNetwork::getPixelColor(uint16_t pix) {
|
||||||
if (!_valid || pix >= _len) return 0;
|
if (!_valid || pix >= _len) return 0;
|
||||||
uint16_t offset = pix * _UDPchannels;
|
uint16_t offset = pix * _UDPchannels;
|
||||||
return RGBW32(_data[offset], _data[offset+1], _data[offset+2], _rgbw ? (_data[offset+3] << 24) : 0);
|
return RGBW32(_data[offset], _data[offset+1], _data[offset+2], (_rgbw ? _data[offset+3] : 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void BusNetwork::show() {
|
void BusNetwork::show() {
|
||||||
@ -444,8 +517,7 @@ uint8_t BusNetwork::getPins(uint8_t* pinArray) {
|
|||||||
void BusNetwork::cleanup() {
|
void BusNetwork::cleanup() {
|
||||||
_type = I_NONE;
|
_type = I_NONE;
|
||||||
_valid = false;
|
_valid = false;
|
||||||
if (_data != nullptr) free(_data);
|
freeData();
|
||||||
_data = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -506,7 +578,7 @@ void BusManager::setStatusPixel(uint32_t c) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void IRAM_ATTR BusManager::setPixelColor(uint16_t pix, uint32_t c, int16_t cct) {
|
void IRAM_ATTR BusManager::setPixelColor(uint16_t pix, uint32_t c) {
|
||||||
for (uint8_t i = 0; i < numBusses; i++) {
|
for (uint8_t i = 0; i < numBusses; i++) {
|
||||||
Bus* b = busses[i];
|
Bus* b = busses[i];
|
||||||
uint16_t bstart = b->getStart();
|
uint16_t bstart = b->getStart();
|
||||||
@ -515,9 +587,9 @@ void IRAM_ATTR BusManager::setPixelColor(uint16_t pix, uint32_t c, int16_t cct)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BusManager::setBrightness(uint8_t b, bool immediate) {
|
void BusManager::setBrightness(uint8_t b) {
|
||||||
for (uint8_t i = 0; i < numBusses; i++) {
|
for (uint8_t i = 0; i < numBusses; i++) {
|
||||||
busses[i]->setBrightness(b, immediate);
|
busses[i]->setBrightness(b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,10 @@
|
|||||||
#define IC_INDEX_WS2812_2CH_3X(i) ((i)*2/3)
|
#define IC_INDEX_WS2812_2CH_3X(i) ((i)*2/3)
|
||||||
#define WS2812_2CH_3X_SPANS_2_ICS(i) ((i)&0x01) // every other LED zone is on two different ICs
|
#define WS2812_2CH_3X_SPANS_2_ICS(i) ((i)&0x01) // every other LED zone is on two different ICs
|
||||||
|
|
||||||
|
// flag for using double buffering in BusDigital
|
||||||
|
extern bool useGlobalLedBuffer;
|
||||||
|
|
||||||
|
|
||||||
//temporary struct for passing bus configuration to bus
|
//temporary struct for passing bus configuration to bus
|
||||||
struct BusConfig {
|
struct BusConfig {
|
||||||
uint8_t type;
|
uint8_t type;
|
||||||
@ -30,15 +34,25 @@ struct BusConfig {
|
|||||||
uint8_t autoWhite;
|
uint8_t autoWhite;
|
||||||
uint8_t pins[5] = {LEDPIN, 255, 255, 255, 255};
|
uint8_t pins[5] = {LEDPIN, 255, 255, 255, 255};
|
||||||
uint16_t frequency;
|
uint16_t frequency;
|
||||||
BusConfig(uint8_t busType, uint8_t* ppins, uint16_t pstart, uint16_t len = 1, uint8_t pcolorOrder = COL_ORDER_GRB, bool rev = false, uint8_t skip = 0, byte aw=RGBW_MODE_MANUAL_ONLY, uint16_t clock_kHz=0U) {
|
bool doubleBuffer;
|
||||||
|
|
||||||
|
BusConfig(uint8_t busType, uint8_t* ppins, uint16_t pstart, uint16_t len = 1, uint8_t pcolorOrder = COL_ORDER_GRB, bool rev = false, uint8_t skip = 0, byte aw=RGBW_MODE_MANUAL_ONLY, uint16_t clock_kHz=0U, bool dblBfr=false)
|
||||||
|
: count(len)
|
||||||
|
, start(pstart)
|
||||||
|
, colorOrder(pcolorOrder)
|
||||||
|
, reversed(rev)
|
||||||
|
, skipAmount(skip)
|
||||||
|
, autoWhite(aw)
|
||||||
|
, frequency(clock_kHz)
|
||||||
|
, doubleBuffer(dblBfr)
|
||||||
|
{
|
||||||
refreshReq = (bool) GET_BIT(busType,7);
|
refreshReq = (bool) GET_BIT(busType,7);
|
||||||
type = busType & 0x7F; // bit 7 may be/is hacked to include refresh info (1=refresh in off state, 0=no refresh)
|
type = busType & 0x7F; // bit 7 may be/is hacked to include refresh info (1=refresh in off state, 0=no refresh)
|
||||||
count = len; start = pstart; colorOrder = pcolorOrder; reversed = rev; skipAmount = skip; autoWhite = aw; frequency = clock_kHz;
|
size_t nPins = 1;
|
||||||
uint8_t nPins = 1;
|
|
||||||
if (type >= TYPE_NET_DDP_RGB && type < 96) nPins = 4; //virtual network bus. 4 "pins" store IP address
|
if (type >= TYPE_NET_DDP_RGB && type < 96) nPins = 4; //virtual network bus. 4 "pins" store IP address
|
||||||
else if (type > 47) nPins = 2;
|
else if (type > 47) nPins = 2;
|
||||||
else if (type > 40 && type < 46) nPins = NUM_PWM_PINS(type);
|
else if (type > 40 && type < 46) nPins = NUM_PWM_PINS(type);
|
||||||
for (uint8_t i = 0; i < nPins; i++) pins[i] = ppins[i];
|
for (size_t i = 0; i < nPins; i++) pins[i] = ppins[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
//validates start and length and extends total if needed
|
//validates start and length and extends total if needed
|
||||||
@ -54,6 +68,7 @@ struct BusConfig {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Defines an LED Strip and its color ordering.
|
// Defines an LED Strip and its color ordering.
|
||||||
struct ColorOrderMapEntry {
|
struct ColorOrderMapEntry {
|
||||||
uint16_t start;
|
uint16_t start;
|
||||||
@ -64,9 +79,7 @@ struct ColorOrderMapEntry {
|
|||||||
struct ColorOrderMap {
|
struct ColorOrderMap {
|
||||||
void add(uint16_t start, uint16_t len, uint8_t colorOrder);
|
void add(uint16_t start, uint16_t len, uint8_t colorOrder);
|
||||||
|
|
||||||
uint8_t count() const {
|
uint8_t count() const { return _count; }
|
||||||
return _count;
|
|
||||||
}
|
|
||||||
|
|
||||||
void reset() {
|
void reset() {
|
||||||
_count = 0;
|
_count = 0;
|
||||||
@ -87,17 +100,20 @@ struct ColorOrderMap {
|
|||||||
ColorOrderMapEntry _mappings[WLED_MAX_COLOR_ORDER_MAPPINGS];
|
ColorOrderMapEntry _mappings[WLED_MAX_COLOR_ORDER_MAPPINGS];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//parent class of BusDigital, BusPwm, and BusNetwork
|
//parent class of BusDigital, BusPwm, and BusNetwork
|
||||||
class Bus {
|
class Bus {
|
||||||
public:
|
public:
|
||||||
Bus(uint8_t type, uint16_t start, uint8_t aw)
|
Bus(uint8_t type, uint16_t start, uint8_t aw, uint16_t len = 1, bool reversed = false, bool refresh = false)
|
||||||
: _bri(255)
|
: _type(type)
|
||||||
, _len(1)
|
, _bri(255)
|
||||||
|
, _start(start)
|
||||||
|
, _len(len)
|
||||||
|
, _reversed(reversed)
|
||||||
, _valid(false)
|
, _valid(false)
|
||||||
, _needsRefresh(false)
|
, _needsRefresh(refresh)
|
||||||
|
, _data(nullptr) // keep data access consistent across all types of buses
|
||||||
{
|
{
|
||||||
_type = type;
|
|
||||||
_start = start;
|
|
||||||
_autoWhiteMode = Bus::hasWhite(_type) ? aw : RGBW_MODE_MANUAL_ONLY;
|
_autoWhiteMode = Bus::hasWhite(_type) ? aw : RGBW_MODE_MANUAL_ONLY;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -108,7 +124,7 @@ class Bus {
|
|||||||
virtual void setStatusPixel(uint32_t c) {}
|
virtual void setStatusPixel(uint32_t c) {}
|
||||||
virtual void setPixelColor(uint16_t pix, uint32_t c) = 0;
|
virtual void setPixelColor(uint16_t pix, uint32_t c) = 0;
|
||||||
virtual uint32_t getPixelColor(uint16_t pix) { return 0; }
|
virtual uint32_t getPixelColor(uint16_t pix) { return 0; }
|
||||||
virtual void setBrightness(uint8_t b, bool immediate=false) { _bri = b; };
|
virtual void setBrightness(uint8_t b) { _bri = b; };
|
||||||
virtual void cleanup() = 0;
|
virtual void cleanup() = 0;
|
||||||
virtual uint8_t getPins(uint8_t* pinArray) { return 0; }
|
virtual uint8_t getPins(uint8_t* pinArray) { return 0; }
|
||||||
virtual uint16_t getLength() { return _len; }
|
virtual uint16_t getLength() { return _len; }
|
||||||
@ -116,27 +132,31 @@ class Bus {
|
|||||||
virtual uint8_t getColorOrder() { return COL_ORDER_RGB; }
|
virtual uint8_t getColorOrder() { return COL_ORDER_RGB; }
|
||||||
virtual uint8_t skippedLeds() { return 0; }
|
virtual uint8_t skippedLeds() { return 0; }
|
||||||
virtual uint16_t getFrequency() { return 0U; }
|
virtual uint16_t getFrequency() { return 0U; }
|
||||||
|
inline void setReversed(bool reversed) { _reversed = reversed; }
|
||||||
inline uint16_t getStart() { return _start; }
|
inline uint16_t getStart() { return _start; }
|
||||||
inline void setStart(uint16_t start) { _start = start; }
|
inline void setStart(uint16_t start) { _start = start; }
|
||||||
inline uint8_t getType() { return _type; }
|
inline uint8_t getType() { return _type; }
|
||||||
inline bool isOk() { return _valid; }
|
inline bool isOk() { return _valid; }
|
||||||
|
inline bool isReversed() { return _reversed; }
|
||||||
inline bool isOffRefreshRequired() { return _needsRefresh; }
|
inline bool isOffRefreshRequired() { return _needsRefresh; }
|
||||||
bool containsPixel(uint16_t pix) { return pix >= _start && pix < _start+_len; }
|
bool containsPixel(uint16_t pix) { return pix >= _start && pix < _start+_len; }
|
||||||
|
|
||||||
virtual bool hasRGB() {
|
virtual bool hasRGB(void) { return Bus::hasRGB(_type); }
|
||||||
if ((_type >= TYPE_WS2812_1CH && _type <= TYPE_WS2812_WWA) || _type == TYPE_ANALOG_1CH || _type == TYPE_ANALOG_2CH || _type == TYPE_ONOFF) return false;
|
static bool hasRGB(uint8_t type) {
|
||||||
|
if ((type >= TYPE_WS2812_1CH && type <= TYPE_WS2812_WWA) || type == TYPE_ANALOG_1CH || type == TYPE_ANALOG_2CH || type == TYPE_ONOFF) return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
virtual bool hasWhite() { return Bus::hasWhite(_type); }
|
virtual bool hasWhite(void) { return Bus::hasWhite(_type); }
|
||||||
static bool hasWhite(uint8_t type) {
|
static bool hasWhite(uint8_t type) {
|
||||||
if ((type >= TYPE_WS2812_1CH && type <= TYPE_WS2812_WWA) || type == TYPE_SK6812_RGBW || type == TYPE_TM1814) return true; // digital types with white channel
|
if ((type >= TYPE_WS2812_1CH && type <= TYPE_WS2812_WWA) || type == TYPE_SK6812_RGBW || type == TYPE_TM1814) return true; // digital types with white channel
|
||||||
if (type > TYPE_ONOFF && type <= TYPE_ANALOG_5CH && type != TYPE_ANALOG_3CH) return true; // analog types with white channel
|
if (type > TYPE_ONOFF && type <= TYPE_ANALOG_5CH && type != TYPE_ANALOG_3CH) return true; // analog types with white channel
|
||||||
if (type == TYPE_NET_DDP_RGBW) return true; // network types with white channel
|
if (type == TYPE_NET_DDP_RGBW) return true; // network types with white channel
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
virtual bool hasCCT() {
|
virtual bool hasCCT(void) { return Bus::hasCCT(_type); }
|
||||||
if (_type == TYPE_WS2812_2CH_X3 || _type == TYPE_WS2812_WWA ||
|
static bool hasCCT(uint8_t type) {
|
||||||
_type == TYPE_ANALOG_2CH || _type == TYPE_ANALOG_5CH) return true;
|
if (type == TYPE_WS2812_2CH_X3 || type == TYPE_WS2812_WWA ||
|
||||||
|
type == TYPE_ANALOG_2CH || type == TYPE_ANALOG_5CH) return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
static void setCCT(uint16_t cct) {
|
static void setCCT(uint16_t cct) {
|
||||||
@ -155,107 +175,87 @@ class Bus {
|
|||||||
inline static void setGlobalAWMode(uint8_t m) { if (m < 5) _gAWM = m; else _gAWM = AW_GLOBAL_DISABLED; }
|
inline static void setGlobalAWMode(uint8_t m) { if (m < 5) _gAWM = m; else _gAWM = AW_GLOBAL_DISABLED; }
|
||||||
inline static uint8_t getGlobalAWMode() { return _gAWM; }
|
inline static uint8_t getGlobalAWMode() { return _gAWM; }
|
||||||
|
|
||||||
bool reversed = false;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
uint8_t _type;
|
uint8_t _type;
|
||||||
uint8_t _bri;
|
uint8_t _bri;
|
||||||
uint16_t _start;
|
uint16_t _start;
|
||||||
uint16_t _len;
|
uint16_t _len;
|
||||||
|
bool _reversed;
|
||||||
bool _valid;
|
bool _valid;
|
||||||
bool _needsRefresh;
|
bool _needsRefresh;
|
||||||
uint8_t _autoWhiteMode;
|
uint8_t _autoWhiteMode;
|
||||||
|
uint8_t *_data;
|
||||||
static uint8_t _gAWM;
|
static uint8_t _gAWM;
|
||||||
static int16_t _cct;
|
static int16_t _cct;
|
||||||
static uint8_t _cctBlend;
|
static uint8_t _cctBlend;
|
||||||
|
|
||||||
uint32_t autoWhiteCalc(uint32_t c);
|
uint32_t autoWhiteCalc(uint32_t c);
|
||||||
|
uint8_t *allocData(size_t size = 1);
|
||||||
|
void freeData() { if (_data != nullptr) free(_data); _data = nullptr; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class BusDigital : public Bus {
|
class BusDigital : public Bus {
|
||||||
public:
|
public:
|
||||||
BusDigital(BusConfig &bc, uint8_t nr, const ColorOrderMap &com);
|
BusDigital(BusConfig &bc, uint8_t nr, const ColorOrderMap &com);
|
||||||
|
~BusDigital() { cleanup(); }
|
||||||
|
|
||||||
inline void show();
|
void show();
|
||||||
|
|
||||||
bool canShow();
|
bool canShow();
|
||||||
|
void setBrightness(uint8_t b);
|
||||||
void setBrightness(uint8_t b, bool immediate);
|
|
||||||
|
|
||||||
void setStatusPixel(uint32_t c);
|
void setStatusPixel(uint32_t c);
|
||||||
|
|
||||||
void setPixelColor(uint16_t pix, uint32_t c);
|
void setPixelColor(uint16_t pix, uint32_t c);
|
||||||
|
|
||||||
uint32_t getPixelColor(uint16_t pix);
|
|
||||||
|
|
||||||
uint8_t getColorOrder() {
|
|
||||||
return _colorOrder;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t getLength() {
|
|
||||||
return _len - _skip;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t getPins(uint8_t* pinArray);
|
|
||||||
|
|
||||||
void setColorOrder(uint8_t colorOrder);
|
void setColorOrder(uint8_t colorOrder);
|
||||||
|
uint32_t getPixelColor(uint16_t pix);
|
||||||
uint8_t skippedLeds() {
|
uint8_t getColorOrder() { return _colorOrder; }
|
||||||
return _skip;
|
uint8_t getPins(uint8_t* pinArray);
|
||||||
}
|
uint8_t skippedLeds() { return _skip; }
|
||||||
|
|
||||||
uint16_t getFrequency() { return _frequencykHz; }
|
uint16_t getFrequency() { return _frequencykHz; }
|
||||||
|
|
||||||
void reinit();
|
void reinit();
|
||||||
|
|
||||||
void cleanup();
|
void cleanup();
|
||||||
|
|
||||||
~BusDigital() {
|
|
||||||
cleanup();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint8_t _colorOrder = COL_ORDER_GRB;
|
uint8_t _skip;
|
||||||
uint8_t _pins[2] = {255, 255};
|
uint8_t _colorOrder;
|
||||||
uint8_t _iType = 0; //I_NONE;
|
uint8_t _pins[2];
|
||||||
uint8_t _skip = 0;
|
uint8_t _iType;
|
||||||
uint16_t _frequencykHz = 0U;
|
uint16_t _frequencykHz;
|
||||||
void * _busPtr = nullptr;
|
void * _busPtr;
|
||||||
const ColorOrderMap &_colorOrderMap;
|
const ColorOrderMap &_colorOrderMap;
|
||||||
|
bool _buffering; // temporary until we figure out why comparison "_data != nullptr" causes severe FPS drop
|
||||||
|
|
||||||
|
inline uint32_t restoreColorLossy(uint32_t c, uint8_t restoreBri) {
|
||||||
|
if (restoreBri < 255) {
|
||||||
|
uint8_t* chan = (uint8_t*) &c;
|
||||||
|
for (uint_fast8_t i=0; i<4; i++) {
|
||||||
|
uint_fast16_t val = chan[i];
|
||||||
|
chan[i] = ((val << 8) + restoreBri) / (restoreBri + 1); //adding _bri slighly improves recovery / stops degradation on re-scale
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class BusPwm : public Bus {
|
class BusPwm : public Bus {
|
||||||
public:
|
public:
|
||||||
BusPwm(BusConfig &bc);
|
BusPwm(BusConfig &bc);
|
||||||
|
~BusPwm() { cleanup(); }
|
||||||
|
|
||||||
void setPixelColor(uint16_t pix, uint32_t c);
|
void setPixelColor(uint16_t pix, uint32_t c);
|
||||||
|
uint32_t getPixelColor(uint16_t pix); //does no index check
|
||||||
//does no index check
|
|
||||||
uint32_t getPixelColor(uint16_t pix);
|
|
||||||
|
|
||||||
void show();
|
|
||||||
|
|
||||||
uint8_t getPins(uint8_t* pinArray);
|
uint8_t getPins(uint8_t* pinArray);
|
||||||
|
|
||||||
uint16_t getFrequency() { return _frequency; }
|
uint16_t getFrequency() { return _frequency; }
|
||||||
|
void show();
|
||||||
void cleanup() {
|
void cleanup() { deallocatePins(); }
|
||||||
deallocatePins();
|
|
||||||
}
|
|
||||||
|
|
||||||
~BusPwm() {
|
|
||||||
cleanup();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint8_t _pins[5] = {255, 255, 255, 255, 255};
|
uint8_t _pins[5];
|
||||||
uint8_t _data[5] = {0};
|
uint8_t _pwmdata[5];
|
||||||
#ifdef ARDUINO_ARCH_ESP32
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
uint8_t _ledcStart = 255;
|
uint8_t _ledcStart;
|
||||||
#endif
|
#endif
|
||||||
uint16_t _frequency = 0U;
|
uint16_t _frequency;
|
||||||
|
|
||||||
void deallocatePins();
|
void deallocatePins();
|
||||||
};
|
};
|
||||||
@ -264,72 +264,46 @@ class BusPwm : public Bus {
|
|||||||
class BusOnOff : public Bus {
|
class BusOnOff : public Bus {
|
||||||
public:
|
public:
|
||||||
BusOnOff(BusConfig &bc);
|
BusOnOff(BusConfig &bc);
|
||||||
|
~BusOnOff() { cleanup(); }
|
||||||
|
|
||||||
void setPixelColor(uint16_t pix, uint32_t c);
|
void setPixelColor(uint16_t pix, uint32_t c);
|
||||||
|
|
||||||
uint32_t getPixelColor(uint16_t pix);
|
uint32_t getPixelColor(uint16_t pix);
|
||||||
|
|
||||||
void show();
|
|
||||||
|
|
||||||
uint8_t getPins(uint8_t* pinArray);
|
uint8_t getPins(uint8_t* pinArray);
|
||||||
|
void show();
|
||||||
void cleanup() {
|
void cleanup() { pinManager.deallocatePin(_pin, PinOwner::BusOnOff); }
|
||||||
pinManager.deallocatePin(_pin, PinOwner::BusOnOff);
|
|
||||||
}
|
|
||||||
|
|
||||||
~BusOnOff() {
|
|
||||||
cleanup();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint8_t _pin = 255;
|
uint8_t _pin;
|
||||||
uint8_t _data = 0;
|
uint8_t _onoffdata;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class BusNetwork : public Bus {
|
class BusNetwork : public Bus {
|
||||||
public:
|
public:
|
||||||
BusNetwork(BusConfig &bc);
|
BusNetwork(BusConfig &bc);
|
||||||
|
~BusNetwork() { cleanup(); }
|
||||||
|
|
||||||
bool hasRGB() { return true; }
|
bool hasRGB() { return true; }
|
||||||
bool hasWhite() { return _rgbw; }
|
bool hasWhite() { return _rgbw; }
|
||||||
|
bool canShow() { return !_broadcastLock; } // this should be a return value from UDP routine if it is still sending data out
|
||||||
void setPixelColor(uint16_t pix, uint32_t c);
|
void setPixelColor(uint16_t pix, uint32_t c);
|
||||||
|
|
||||||
uint32_t getPixelColor(uint16_t pix);
|
uint32_t getPixelColor(uint16_t pix);
|
||||||
|
|
||||||
void show();
|
|
||||||
|
|
||||||
bool canShow() {
|
|
||||||
// this should be a return value from UDP routine if it is still sending data out
|
|
||||||
return !_broadcastLock;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t getPins(uint8_t* pinArray);
|
uint8_t getPins(uint8_t* pinArray);
|
||||||
|
void show();
|
||||||
uint16_t getLength() {
|
|
||||||
return _len;
|
|
||||||
}
|
|
||||||
|
|
||||||
void cleanup();
|
void cleanup();
|
||||||
|
|
||||||
~BusNetwork() {
|
|
||||||
cleanup();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
IPAddress _client;
|
IPAddress _client;
|
||||||
uint8_t _UDPtype;
|
uint8_t _UDPtype;
|
||||||
uint8_t _UDPchannels;
|
uint8_t _UDPchannels;
|
||||||
bool _rgbw;
|
bool _rgbw;
|
||||||
bool _broadcastLock;
|
bool _broadcastLock;
|
||||||
byte *_data;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class BusManager {
|
class BusManager {
|
||||||
public:
|
public:
|
||||||
BusManager() {};
|
BusManager() : numBusses(0) {};
|
||||||
|
|
||||||
//utility to get the approx. memory usage of a given BusConfig
|
//utility to get the approx. memory usage of a given BusConfig
|
||||||
static uint32_t memUsage(BusConfig &bc);
|
static uint32_t memUsage(BusConfig &bc);
|
||||||
@ -340,38 +314,24 @@ class BusManager {
|
|||||||
void removeAll();
|
void removeAll();
|
||||||
|
|
||||||
void show();
|
void show();
|
||||||
|
|
||||||
void setStatusPixel(uint32_t c);
|
|
||||||
|
|
||||||
void setPixelColor(uint16_t pix, uint32_t c, int16_t cct=-1);
|
|
||||||
|
|
||||||
void setBrightness(uint8_t b, bool immediate=false); // immediate=true is for use in ABL, it applies brightness immediately (warning: inefficient)
|
|
||||||
|
|
||||||
void setSegmentCCT(int16_t cct, bool allowWBCorrection = false);
|
|
||||||
|
|
||||||
uint32_t getPixelColor(uint16_t pix);
|
|
||||||
|
|
||||||
bool canAllShow();
|
bool canAllShow();
|
||||||
|
void setStatusPixel(uint32_t c);
|
||||||
|
void setPixelColor(uint16_t pix, uint32_t c);
|
||||||
|
void setBrightness(uint8_t b);
|
||||||
|
void setSegmentCCT(int16_t cct, bool allowWBCorrection = false);
|
||||||
|
uint32_t getPixelColor(uint16_t pix);
|
||||||
|
|
||||||
Bus* getBus(uint8_t busNr);
|
Bus* getBus(uint8_t busNr);
|
||||||
|
|
||||||
//semi-duplicate of strip.getLengthTotal() (though that just returns strip._length, calculated in finalizeInit())
|
//semi-duplicate of strip.getLengthTotal() (though that just returns strip._length, calculated in finalizeInit())
|
||||||
uint16_t getTotalLength();
|
uint16_t getTotalLength();
|
||||||
|
inline uint8_t getNumBusses() const { return numBusses; }
|
||||||
|
|
||||||
inline void updateColorOrderMap(const ColorOrderMap &com) {
|
inline void updateColorOrderMap(const ColorOrderMap &com) { memcpy(&colorOrderMap, &com, sizeof(ColorOrderMap)); }
|
||||||
memcpy(&colorOrderMap, &com, sizeof(ColorOrderMap));
|
inline const ColorOrderMap& getColorOrderMap() const { return colorOrderMap; }
|
||||||
}
|
|
||||||
|
|
||||||
inline const ColorOrderMap& getColorOrderMap() const {
|
|
||||||
return colorOrderMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline uint8_t getNumBusses() {
|
|
||||||
return numBusses;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint8_t numBusses = 0;
|
uint8_t numBusses;
|
||||||
Bus* busses[WLED_MAX_BUSSES+WLED_MIN_VIRTUAL_BUSSES];
|
Bus* busses[WLED_MAX_BUSSES+WLED_MIN_VIRTUAL_BUSSES];
|
||||||
ColorOrderMap colorOrderMap;
|
ColorOrderMap colorOrderMap;
|
||||||
|
|
||||||
|
@ -280,6 +280,7 @@ class PolyBus {
|
|||||||
#endif
|
#endif
|
||||||
if (clock_kHz) dotStar_strip->SetMethodSettings(NeoSpiSettings((uint32_t)clock_kHz*1000));
|
if (clock_kHz) dotStar_strip->SetMethodSettings(NeoSpiSettings((uint32_t)clock_kHz*1000));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Begin & initialize the PixelSettings for TM1814 strips.
|
// Begin & initialize the PixelSettings for TM1814 strips.
|
||||||
template <class T>
|
template <class T>
|
||||||
static void beginTM1814(void* busPtr) {
|
static void beginTM1814(void* busPtr) {
|
||||||
@ -288,6 +289,7 @@ class PolyBus {
|
|||||||
// Max current for each LED (22.5 mA).
|
// Max current for each LED (22.5 mA).
|
||||||
tm1814_strip->SetPixelSettings(NeoTm1814Settings(/*R*/225, /*G*/225, /*B*/225, /*W*/225));
|
tm1814_strip->SetPixelSettings(NeoTm1814Settings(/*R*/225, /*G*/225, /*B*/225, /*W*/225));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void begin(void* busPtr, uint8_t busType, uint8_t* pins, uint16_t clock_kHz = 0U) {
|
static void begin(void* busPtr, uint8_t busType, uint8_t* pins, uint16_t clock_kHz = 0U) {
|
||||||
switch (busType) {
|
switch (busType) {
|
||||||
case I_NONE: break;
|
case I_NONE: break;
|
||||||
@ -390,7 +392,8 @@ class PolyBus {
|
|||||||
case I_SS_WS1_3: (static_cast<B_SS_WS1_3*>(busPtr))->Begin(); break;
|
case I_SS_WS1_3: (static_cast<B_SS_WS1_3*>(busPtr))->Begin(); break;
|
||||||
case I_SS_P98_3: (static_cast<B_SS_P98_3*>(busPtr))->Begin(); break;
|
case I_SS_P98_3: (static_cast<B_SS_P98_3*>(busPtr))->Begin(); break;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
static void* create(uint8_t busType, uint8_t* pins, uint16_t len, uint8_t channel, uint16_t clock_kHz = 0U) {
|
static void* create(uint8_t busType, uint8_t* pins, uint16_t len, uint8_t channel, uint16_t clock_kHz = 0U) {
|
||||||
void* busPtr = nullptr;
|
void* busPtr = nullptr;
|
||||||
switch (busType) {
|
switch (busType) {
|
||||||
@ -491,104 +494,106 @@ class PolyBus {
|
|||||||
}
|
}
|
||||||
begin(busPtr, busType, pins, clock_kHz);
|
begin(busPtr, busType, pins, clock_kHz);
|
||||||
return busPtr;
|
return busPtr;
|
||||||
};
|
}
|
||||||
static void show(void* busPtr, uint8_t busType) {
|
|
||||||
|
static void show(void* busPtr, uint8_t busType, bool consistent = true) {
|
||||||
switch (busType) {
|
switch (busType) {
|
||||||
case I_NONE: break;
|
case I_NONE: break;
|
||||||
#ifdef ESP8266
|
#ifdef ESP8266
|
||||||
case I_8266_U0_NEO_3: (static_cast<B_8266_U0_NEO_3*>(busPtr))->Show(); break;
|
case I_8266_U0_NEO_3: (static_cast<B_8266_U0_NEO_3*>(busPtr))->Show(consistent); break;
|
||||||
case I_8266_U1_NEO_3: (static_cast<B_8266_U1_NEO_3*>(busPtr))->Show(); break;
|
case I_8266_U1_NEO_3: (static_cast<B_8266_U1_NEO_3*>(busPtr))->Show(consistent); break;
|
||||||
case I_8266_DM_NEO_3: (static_cast<B_8266_DM_NEO_3*>(busPtr))->Show(); break;
|
case I_8266_DM_NEO_3: (static_cast<B_8266_DM_NEO_3*>(busPtr))->Show(consistent); break;
|
||||||
case I_8266_BB_NEO_3: (static_cast<B_8266_BB_NEO_3*>(busPtr))->Show(); break;
|
case I_8266_BB_NEO_3: (static_cast<B_8266_BB_NEO_3*>(busPtr))->Show(consistent); break;
|
||||||
case I_8266_U0_NEO_4: (static_cast<B_8266_U0_NEO_4*>(busPtr))->Show(); break;
|
case I_8266_U0_NEO_4: (static_cast<B_8266_U0_NEO_4*>(busPtr))->Show(consistent); break;
|
||||||
case I_8266_U1_NEO_4: (static_cast<B_8266_U1_NEO_4*>(busPtr))->Show(); break;
|
case I_8266_U1_NEO_4: (static_cast<B_8266_U1_NEO_4*>(busPtr))->Show(consistent); break;
|
||||||
case I_8266_DM_NEO_4: (static_cast<B_8266_DM_NEO_4*>(busPtr))->Show(); break;
|
case I_8266_DM_NEO_4: (static_cast<B_8266_DM_NEO_4*>(busPtr))->Show(consistent); break;
|
||||||
case I_8266_BB_NEO_4: (static_cast<B_8266_BB_NEO_4*>(busPtr))->Show(); break;
|
case I_8266_BB_NEO_4: (static_cast<B_8266_BB_NEO_4*>(busPtr))->Show(consistent); break;
|
||||||
case I_8266_U0_400_3: (static_cast<B_8266_U0_400_3*>(busPtr))->Show(); break;
|
case I_8266_U0_400_3: (static_cast<B_8266_U0_400_3*>(busPtr))->Show(consistent); break;
|
||||||
case I_8266_U1_400_3: (static_cast<B_8266_U1_400_3*>(busPtr))->Show(); break;
|
case I_8266_U1_400_3: (static_cast<B_8266_U1_400_3*>(busPtr))->Show(consistent); break;
|
||||||
case I_8266_DM_400_3: (static_cast<B_8266_DM_400_3*>(busPtr))->Show(); break;
|
case I_8266_DM_400_3: (static_cast<B_8266_DM_400_3*>(busPtr))->Show(consistent); break;
|
||||||
case I_8266_BB_400_3: (static_cast<B_8266_BB_400_3*>(busPtr))->Show(); break;
|
case I_8266_BB_400_3: (static_cast<B_8266_BB_400_3*>(busPtr))->Show(consistent); break;
|
||||||
case I_8266_U0_TM1_4: (static_cast<B_8266_U0_TM1_4*>(busPtr))->Show(); break;
|
case I_8266_U0_TM1_4: (static_cast<B_8266_U0_TM1_4*>(busPtr))->Show(consistent); break;
|
||||||
case I_8266_U1_TM1_4: (static_cast<B_8266_U1_TM1_4*>(busPtr))->Show(); break;
|
case I_8266_U1_TM1_4: (static_cast<B_8266_U1_TM1_4*>(busPtr))->Show(consistent); break;
|
||||||
case I_8266_DM_TM1_4: (static_cast<B_8266_DM_TM1_4*>(busPtr))->Show(); break;
|
case I_8266_DM_TM1_4: (static_cast<B_8266_DM_TM1_4*>(busPtr))->Show(consistent); break;
|
||||||
case I_8266_BB_TM1_4: (static_cast<B_8266_BB_TM1_4*>(busPtr))->Show(); break;
|
case I_8266_BB_TM1_4: (static_cast<B_8266_BB_TM1_4*>(busPtr))->Show(consistent); break;
|
||||||
case I_8266_U0_TM2_3: (static_cast<B_8266_U0_TM2_4*>(busPtr))->Show(); break;
|
case I_8266_U0_TM2_3: (static_cast<B_8266_U0_TM2_4*>(busPtr))->Show(consistent); break;
|
||||||
case I_8266_U1_TM2_3: (static_cast<B_8266_U1_TM2_4*>(busPtr))->Show(); break;
|
case I_8266_U1_TM2_3: (static_cast<B_8266_U1_TM2_4*>(busPtr))->Show(consistent); break;
|
||||||
case I_8266_DM_TM2_3: (static_cast<B_8266_DM_TM2_4*>(busPtr))->Show(); break;
|
case I_8266_DM_TM2_3: (static_cast<B_8266_DM_TM2_4*>(busPtr))->Show(consistent); break;
|
||||||
case I_8266_BB_TM2_3: (static_cast<B_8266_BB_TM2_4*>(busPtr))->Show(); break;
|
case I_8266_BB_TM2_3: (static_cast<B_8266_BB_TM2_4*>(busPtr))->Show(consistent); break;
|
||||||
case I_8266_U0_UCS_3: (static_cast<B_8266_U0_UCS_3*>(busPtr))->Show(); break;
|
case I_8266_U0_UCS_3: (static_cast<B_8266_U0_UCS_3*>(busPtr))->Show(consistent); break;
|
||||||
case I_8266_U1_UCS_3: (static_cast<B_8266_U1_UCS_3*>(busPtr))->Show(); break;
|
case I_8266_U1_UCS_3: (static_cast<B_8266_U1_UCS_3*>(busPtr))->Show(consistent); break;
|
||||||
case I_8266_DM_UCS_3: (static_cast<B_8266_DM_UCS_3*>(busPtr))->Show(); break;
|
case I_8266_DM_UCS_3: (static_cast<B_8266_DM_UCS_3*>(busPtr))->Show(consistent); break;
|
||||||
case I_8266_BB_UCS_3: (static_cast<B_8266_BB_UCS_3*>(busPtr))->Show(); break;
|
case I_8266_BB_UCS_3: (static_cast<B_8266_BB_UCS_3*>(busPtr))->Show(consistent); break;
|
||||||
case I_8266_U0_UCS_4: (static_cast<B_8266_U0_UCS_4*>(busPtr))->Show(); break;
|
case I_8266_U0_UCS_4: (static_cast<B_8266_U0_UCS_4*>(busPtr))->Show(consistent); break;
|
||||||
case I_8266_U1_UCS_4: (static_cast<B_8266_U1_UCS_4*>(busPtr))->Show(); break;
|
case I_8266_U1_UCS_4: (static_cast<B_8266_U1_UCS_4*>(busPtr))->Show(consistent); break;
|
||||||
case I_8266_DM_UCS_4: (static_cast<B_8266_DM_UCS_4*>(busPtr))->Show(); break;
|
case I_8266_DM_UCS_4: (static_cast<B_8266_DM_UCS_4*>(busPtr))->Show(consistent); break;
|
||||||
case I_8266_BB_UCS_4: (static_cast<B_8266_BB_UCS_4*>(busPtr))->Show(); break;
|
case I_8266_BB_UCS_4: (static_cast<B_8266_BB_UCS_4*>(busPtr))->Show(consistent); break;
|
||||||
#endif
|
#endif
|
||||||
#ifdef ARDUINO_ARCH_ESP32
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
case I_32_RN_NEO_3: (static_cast<B_32_RN_NEO_3*>(busPtr))->Show(); break;
|
case I_32_RN_NEO_3: (static_cast<B_32_RN_NEO_3*>(busPtr))->Show(consistent); break;
|
||||||
#ifndef WLED_NO_I2S0_PIXELBUS
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
case I_32_I0_NEO_3: (static_cast<B_32_I0_NEO_3*>(busPtr))->Show(); break;
|
case I_32_I0_NEO_3: (static_cast<B_32_I0_NEO_3*>(busPtr))->Show(consistent); break;
|
||||||
#endif
|
#endif
|
||||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
case I_32_I1_NEO_3: (static_cast<B_32_I1_NEO_3*>(busPtr))->Show(); break;
|
case I_32_I1_NEO_3: (static_cast<B_32_I1_NEO_3*>(busPtr))->Show(consistent); break;
|
||||||
#endif
|
#endif
|
||||||
// case I_32_BB_NEO_3: (static_cast<B_32_BB_NEO_3*>(busPtr))->Show(); break;
|
// case I_32_BB_NEO_3: (static_cast<B_32_BB_NEO_3*>(busPtr))->Show(consistent); break;
|
||||||
case I_32_RN_NEO_4: (static_cast<B_32_RN_NEO_4*>(busPtr))->Show(); break;
|
case I_32_RN_NEO_4: (static_cast<B_32_RN_NEO_4*>(busPtr))->Show(consistent); break;
|
||||||
#ifndef WLED_NO_I2S0_PIXELBUS
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
case I_32_I0_NEO_4: (static_cast<B_32_I0_NEO_4*>(busPtr))->Show(); break;
|
case I_32_I0_NEO_4: (static_cast<B_32_I0_NEO_4*>(busPtr))->Show(consistent); break;
|
||||||
#endif
|
#endif
|
||||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
case I_32_I1_NEO_4: (static_cast<B_32_I1_NEO_4*>(busPtr))->Show(); break;
|
case I_32_I1_NEO_4: (static_cast<B_32_I1_NEO_4*>(busPtr))->Show(consistent); break;
|
||||||
#endif
|
#endif
|
||||||
// case I_32_BB_NEO_4: (static_cast<B_32_BB_NEO_4*>(busPtr))->Show(); break;
|
// case I_32_BB_NEO_4: (static_cast<B_32_BB_NEO_4*>(busPtr))->Show(consistent); break;
|
||||||
case I_32_RN_400_3: (static_cast<B_32_RN_400_3*>(busPtr))->Show(); break;
|
case I_32_RN_400_3: (static_cast<B_32_RN_400_3*>(busPtr))->Show(consistent); break;
|
||||||
#ifndef WLED_NO_I2S0_PIXELBUS
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
case I_32_I0_400_3: (static_cast<B_32_I0_400_3*>(busPtr))->Show(); break;
|
case I_32_I0_400_3: (static_cast<B_32_I0_400_3*>(busPtr))->Show(consistent); break;
|
||||||
#endif
|
#endif
|
||||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
case I_32_I1_400_3: (static_cast<B_32_I1_400_3*>(busPtr))->Show(); break;
|
case I_32_I1_400_3: (static_cast<B_32_I1_400_3*>(busPtr))->Show(consistent); break;
|
||||||
#endif
|
#endif
|
||||||
// case I_32_BB_400_3: (static_cast<B_32_BB_400_3*>(busPtr))->Show(); break;
|
// case I_32_BB_400_3: (static_cast<B_32_BB_400_3*>(busPtr))->Show(consistent); break;
|
||||||
case I_32_RN_TM1_4: (static_cast<B_32_RN_TM1_4*>(busPtr))->Show(); break;
|
case I_32_RN_TM1_4: (static_cast<B_32_RN_TM1_4*>(busPtr))->Show(consistent); break;
|
||||||
case I_32_RN_TM2_3: (static_cast<B_32_RN_TM2_3*>(busPtr))->Show(); break;
|
case I_32_RN_TM2_3: (static_cast<B_32_RN_TM2_3*>(busPtr))->Show(consistent); break;
|
||||||
#ifndef WLED_NO_I2S0_PIXELBUS
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
case I_32_I0_TM1_4: (static_cast<B_32_I0_TM1_4*>(busPtr))->Show(); break;
|
case I_32_I0_TM1_4: (static_cast<B_32_I0_TM1_4*>(busPtr))->Show(consistent); break;
|
||||||
case I_32_I0_TM2_3: (static_cast<B_32_I0_TM2_3*>(busPtr))->Show(); break;
|
case I_32_I0_TM2_3: (static_cast<B_32_I0_TM2_3*>(busPtr))->Show(consistent); break;
|
||||||
#endif
|
#endif
|
||||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
case I_32_I1_TM1_4: (static_cast<B_32_I1_TM1_4*>(busPtr))->Show(); break;
|
case I_32_I1_TM1_4: (static_cast<B_32_I1_TM1_4*>(busPtr))->Show(consistent); break;
|
||||||
case I_32_I1_TM2_3: (static_cast<B_32_I1_TM2_3*>(busPtr))->Show(); break;
|
case I_32_I1_TM2_3: (static_cast<B_32_I1_TM2_3*>(busPtr))->Show(consistent); break;
|
||||||
#endif
|
#endif
|
||||||
case I_32_RN_UCS_3: (static_cast<B_32_RN_UCS_3*>(busPtr))->Show(); break;
|
case I_32_RN_UCS_3: (static_cast<B_32_RN_UCS_3*>(busPtr))->Show(consistent); break;
|
||||||
#ifndef WLED_NO_I2S0_PIXELBUS
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
case I_32_I0_UCS_3: (static_cast<B_32_I0_UCS_3*>(busPtr))->Show(); break;
|
case I_32_I0_UCS_3: (static_cast<B_32_I0_UCS_3*>(busPtr))->Show(consistent); break;
|
||||||
#endif
|
#endif
|
||||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
case I_32_I1_UCS_3: (static_cast<B_32_I1_UCS_3*>(busPtr))->Show(); break;
|
case I_32_I1_UCS_3: (static_cast<B_32_I1_UCS_3*>(busPtr))->Show(consistent); break;
|
||||||
#endif
|
#endif
|
||||||
// case I_32_BB_UCS_3: (static_cast<B_32_BB_NEO_3*>(busPtr))->Show(); break;
|
// case I_32_BB_UCS_3: (static_cast<B_32_BB_NEO_3*>(busPtr))->Show(consistent); break;
|
||||||
case I_32_RN_UCS_4: (static_cast<B_32_RN_UCS_4*>(busPtr))->Show(); break;
|
case I_32_RN_UCS_4: (static_cast<B_32_RN_UCS_4*>(busPtr))->Show(consistent); break;
|
||||||
#ifndef WLED_NO_I2S0_PIXELBUS
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
case I_32_I0_UCS_4: (static_cast<B_32_I0_UCS_4*>(busPtr))->Show(); break;
|
case I_32_I0_UCS_4: (static_cast<B_32_I0_UCS_4*>(busPtr))->Show(consistent); break;
|
||||||
#endif
|
#endif
|
||||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
case I_32_I1_UCS_4: (static_cast<B_32_I1_UCS_4*>(busPtr))->Show(); break;
|
case I_32_I1_UCS_4: (static_cast<B_32_I1_UCS_4*>(busPtr))->Show(consistent); break;
|
||||||
#endif
|
#endif
|
||||||
// case I_32_BB_UCS_4: (static_cast<B_32_BB_UCS_4*>(busPtr))->Show(); break;
|
// case I_32_BB_UCS_4: (static_cast<B_32_BB_UCS_4*>(busPtr))->Show(consistent); break;
|
||||||
#endif
|
#endif
|
||||||
case I_HS_DOT_3: (static_cast<B_HS_DOT_3*>(busPtr))->Show(); break;
|
case I_HS_DOT_3: (static_cast<B_HS_DOT_3*>(busPtr))->Show(consistent); break;
|
||||||
case I_SS_DOT_3: (static_cast<B_SS_DOT_3*>(busPtr))->Show(); break;
|
case I_SS_DOT_3: (static_cast<B_SS_DOT_3*>(busPtr))->Show(consistent); break;
|
||||||
case I_HS_LPD_3: (static_cast<B_HS_LPD_3*>(busPtr))->Show(); break;
|
case I_HS_LPD_3: (static_cast<B_HS_LPD_3*>(busPtr))->Show(consistent); break;
|
||||||
case I_SS_LPD_3: (static_cast<B_SS_LPD_3*>(busPtr))->Show(); break;
|
case I_SS_LPD_3: (static_cast<B_SS_LPD_3*>(busPtr))->Show(consistent); break;
|
||||||
case I_HS_LPO_3: (static_cast<B_HS_LPO_3*>(busPtr))->Show(); break;
|
case I_HS_LPO_3: (static_cast<B_HS_LPO_3*>(busPtr))->Show(consistent); break;
|
||||||
case I_SS_LPO_3: (static_cast<B_SS_LPO_3*>(busPtr))->Show(); break;
|
case I_SS_LPO_3: (static_cast<B_SS_LPO_3*>(busPtr))->Show(consistent); break;
|
||||||
case I_HS_WS1_3: (static_cast<B_HS_WS1_3*>(busPtr))->Show(); break;
|
case I_HS_WS1_3: (static_cast<B_HS_WS1_3*>(busPtr))->Show(consistent); break;
|
||||||
case I_SS_WS1_3: (static_cast<B_SS_WS1_3*>(busPtr))->Show(); break;
|
case I_SS_WS1_3: (static_cast<B_SS_WS1_3*>(busPtr))->Show(consistent); break;
|
||||||
case I_HS_P98_3: (static_cast<B_HS_P98_3*>(busPtr))->Show(); break;
|
case I_HS_P98_3: (static_cast<B_HS_P98_3*>(busPtr))->Show(consistent); break;
|
||||||
case I_SS_P98_3: (static_cast<B_SS_P98_3*>(busPtr))->Show(); break;
|
case I_SS_P98_3: (static_cast<B_SS_P98_3*>(busPtr))->Show(consistent); break;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
static bool canShow(void* busPtr, uint8_t busType) {
|
static bool canShow(void* busPtr, uint8_t busType) {
|
||||||
switch (busType) {
|
switch (busType) {
|
||||||
case I_NONE: return true;
|
case I_NONE: return true;
|
||||||
@ -685,7 +690,8 @@ class PolyBus {
|
|||||||
case I_SS_P98_3: return (static_cast<B_SS_P98_3*>(busPtr))->CanShow(); break;
|
case I_SS_P98_3: return (static_cast<B_SS_P98_3*>(busPtr))->CanShow(); break;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
};
|
}
|
||||||
|
|
||||||
static void setPixelColor(void* busPtr, uint8_t busType, uint16_t pix, uint32_t c, uint8_t co) {
|
static void setPixelColor(void* busPtr, uint8_t busType, uint16_t pix, uint32_t c, uint8_t co) {
|
||||||
uint8_t r = c >> 16;
|
uint8_t r = c >> 16;
|
||||||
uint8_t g = c >> 8;
|
uint8_t g = c >> 8;
|
||||||
@ -805,104 +811,106 @@ class PolyBus {
|
|||||||
case I_HS_P98_3: (static_cast<B_HS_P98_3*>(busPtr))->SetPixelColor(pix, RgbColor(col)); break;
|
case I_HS_P98_3: (static_cast<B_HS_P98_3*>(busPtr))->SetPixelColor(pix, RgbColor(col)); break;
|
||||||
case I_SS_P98_3: (static_cast<B_SS_P98_3*>(busPtr))->SetPixelColor(pix, RgbColor(col)); break;
|
case I_SS_P98_3: (static_cast<B_SS_P98_3*>(busPtr))->SetPixelColor(pix, RgbColor(col)); break;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
static void setBrightness(void* busPtr, uint8_t busType, uint8_t b, bool immediate) { // immediate=true is for use in ABL, it applies brightness immediately (warning: inefficient)
|
|
||||||
|
static void setBrightness(void* busPtr, uint8_t busType, uint8_t b) {
|
||||||
switch (busType) {
|
switch (busType) {
|
||||||
case I_NONE: break;
|
case I_NONE: break;
|
||||||
#ifdef ESP8266
|
#ifdef ESP8266
|
||||||
case I_8266_U0_NEO_3: (static_cast<B_8266_U0_NEO_3*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_8266_U0_NEO_3*>(busPtr))->ApplyPostAdjustments(); break;
|
case I_8266_U0_NEO_3: (static_cast<B_8266_U0_NEO_3*>(busPtr))->SetLuminance(b); break;
|
||||||
case I_8266_U1_NEO_3: (static_cast<B_8266_U1_NEO_3*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_8266_U1_NEO_3*>(busPtr))->ApplyPostAdjustments(); break;
|
case I_8266_U1_NEO_3: (static_cast<B_8266_U1_NEO_3*>(busPtr))->SetLuminance(b); break;
|
||||||
case I_8266_DM_NEO_3: (static_cast<B_8266_DM_NEO_3*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_8266_DM_NEO_3*>(busPtr))->ApplyPostAdjustments(); break;
|
case I_8266_DM_NEO_3: (static_cast<B_8266_DM_NEO_3*>(busPtr))->SetLuminance(b); break;
|
||||||
case I_8266_BB_NEO_3: (static_cast<B_8266_BB_NEO_3*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_8266_BB_NEO_3*>(busPtr))->ApplyPostAdjustments(); break;
|
case I_8266_BB_NEO_3: (static_cast<B_8266_BB_NEO_3*>(busPtr))->SetLuminance(b); break;
|
||||||
case I_8266_U0_NEO_4: (static_cast<B_8266_U0_NEO_4*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_8266_U0_NEO_4*>(busPtr))->ApplyPostAdjustments(); break;
|
case I_8266_U0_NEO_4: (static_cast<B_8266_U0_NEO_4*>(busPtr))->SetLuminance(b); break;
|
||||||
case I_8266_U1_NEO_4: (static_cast<B_8266_U1_NEO_4*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_8266_U1_NEO_4*>(busPtr))->ApplyPostAdjustments(); break;
|
case I_8266_U1_NEO_4: (static_cast<B_8266_U1_NEO_4*>(busPtr))->SetLuminance(b); break;
|
||||||
case I_8266_DM_NEO_4: (static_cast<B_8266_DM_NEO_4*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_8266_DM_NEO_4*>(busPtr))->ApplyPostAdjustments(); break;
|
case I_8266_DM_NEO_4: (static_cast<B_8266_DM_NEO_4*>(busPtr))->SetLuminance(b); break;
|
||||||
case I_8266_BB_NEO_4: (static_cast<B_8266_BB_NEO_4*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_8266_BB_NEO_4*>(busPtr))->ApplyPostAdjustments(); break;
|
case I_8266_BB_NEO_4: (static_cast<B_8266_BB_NEO_4*>(busPtr))->SetLuminance(b); break;
|
||||||
case I_8266_U0_400_3: (static_cast<B_8266_U0_400_3*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_8266_U0_400_3*>(busPtr))->ApplyPostAdjustments(); break;
|
case I_8266_U0_400_3: (static_cast<B_8266_U0_400_3*>(busPtr))->SetLuminance(b); break;
|
||||||
case I_8266_U1_400_3: (static_cast<B_8266_U1_400_3*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_8266_U1_400_3*>(busPtr))->ApplyPostAdjustments(); break;
|
case I_8266_U1_400_3: (static_cast<B_8266_U1_400_3*>(busPtr))->SetLuminance(b); break;
|
||||||
case I_8266_DM_400_3: (static_cast<B_8266_DM_400_3*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_8266_DM_400_3*>(busPtr))->ApplyPostAdjustments(); break;
|
case I_8266_DM_400_3: (static_cast<B_8266_DM_400_3*>(busPtr))->SetLuminance(b); break;
|
||||||
case I_8266_BB_400_3: (static_cast<B_8266_BB_400_3*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_8266_BB_400_3*>(busPtr))->ApplyPostAdjustments(); break;
|
case I_8266_BB_400_3: (static_cast<B_8266_BB_400_3*>(busPtr))->SetLuminance(b); break;
|
||||||
case I_8266_U0_TM1_4: (static_cast<B_8266_U0_TM1_4*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_8266_U0_TM1_4*>(busPtr))->ApplyPostAdjustments(); break;
|
case I_8266_U0_TM1_4: (static_cast<B_8266_U0_TM1_4*>(busPtr))->SetLuminance(b); break;
|
||||||
case I_8266_U1_TM1_4: (static_cast<B_8266_U1_TM1_4*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_8266_U1_TM1_4*>(busPtr))->ApplyPostAdjustments(); break;
|
case I_8266_U1_TM1_4: (static_cast<B_8266_U1_TM1_4*>(busPtr))->SetLuminance(b); break;
|
||||||
case I_8266_DM_TM1_4: (static_cast<B_8266_DM_TM1_4*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_8266_DM_TM1_4*>(busPtr))->ApplyPostAdjustments(); break;
|
case I_8266_DM_TM1_4: (static_cast<B_8266_DM_TM1_4*>(busPtr))->SetLuminance(b); break;
|
||||||
case I_8266_BB_TM1_4: (static_cast<B_8266_BB_TM1_4*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_8266_BB_TM1_4*>(busPtr))->ApplyPostAdjustments(); break;
|
case I_8266_BB_TM1_4: (static_cast<B_8266_BB_TM1_4*>(busPtr))->SetLuminance(b); break;
|
||||||
case I_8266_U0_TM2_3: (static_cast<B_8266_U0_TM2_4*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_8266_U0_TM2_4*>(busPtr))->ApplyPostAdjustments(); break;
|
case I_8266_U0_TM2_3: (static_cast<B_8266_U0_TM2_4*>(busPtr))->SetLuminance(b); break;
|
||||||
case I_8266_U1_TM2_3: (static_cast<B_8266_U1_TM2_4*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_8266_U1_TM2_4*>(busPtr))->ApplyPostAdjustments(); break;
|
case I_8266_U1_TM2_3: (static_cast<B_8266_U1_TM2_4*>(busPtr))->SetLuminance(b); break;
|
||||||
case I_8266_DM_TM2_3: (static_cast<B_8266_DM_TM2_4*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_8266_DM_TM2_4*>(busPtr))->ApplyPostAdjustments(); break;
|
case I_8266_DM_TM2_3: (static_cast<B_8266_DM_TM2_4*>(busPtr))->SetLuminance(b); break;
|
||||||
case I_8266_BB_TM2_3: (static_cast<B_8266_BB_TM2_4*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_8266_BB_TM2_4*>(busPtr))->ApplyPostAdjustments(); break;
|
case I_8266_BB_TM2_3: (static_cast<B_8266_BB_TM2_4*>(busPtr))->SetLuminance(b); break;
|
||||||
case I_8266_U0_UCS_3: (static_cast<B_8266_U0_UCS_3*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_8266_U0_UCS_3*>(busPtr))->ApplyPostAdjustments(); break;
|
case I_8266_U0_UCS_3: (static_cast<B_8266_U0_UCS_3*>(busPtr))->SetLuminance(b); break;
|
||||||
case I_8266_U1_UCS_3: (static_cast<B_8266_U1_UCS_3*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_8266_U1_UCS_3*>(busPtr))->ApplyPostAdjustments(); break;
|
case I_8266_U1_UCS_3: (static_cast<B_8266_U1_UCS_3*>(busPtr))->SetLuminance(b); break;
|
||||||
case I_8266_DM_UCS_3: (static_cast<B_8266_DM_UCS_3*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_8266_DM_UCS_3*>(busPtr))->ApplyPostAdjustments(); break;
|
case I_8266_DM_UCS_3: (static_cast<B_8266_DM_UCS_3*>(busPtr))->SetLuminance(b); break;
|
||||||
case I_8266_BB_UCS_3: (static_cast<B_8266_BB_UCS_3*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_8266_BB_UCS_3*>(busPtr))->ApplyPostAdjustments(); break;
|
case I_8266_BB_UCS_3: (static_cast<B_8266_BB_UCS_3*>(busPtr))->SetLuminance(b); break;
|
||||||
case I_8266_U0_UCS_4: (static_cast<B_8266_U0_UCS_4*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_8266_U0_UCS_4*>(busPtr))->ApplyPostAdjustments(); break;
|
case I_8266_U0_UCS_4: (static_cast<B_8266_U0_UCS_4*>(busPtr))->SetLuminance(b); break;
|
||||||
case I_8266_U1_UCS_4: (static_cast<B_8266_U1_UCS_4*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_8266_U1_UCS_4*>(busPtr))->ApplyPostAdjustments(); break;
|
case I_8266_U1_UCS_4: (static_cast<B_8266_U1_UCS_4*>(busPtr))->SetLuminance(b); break;
|
||||||
case I_8266_DM_UCS_4: (static_cast<B_8266_DM_UCS_4*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_8266_DM_UCS_4*>(busPtr))->ApplyPostAdjustments(); break;
|
case I_8266_DM_UCS_4: (static_cast<B_8266_DM_UCS_4*>(busPtr))->SetLuminance(b); break;
|
||||||
case I_8266_BB_UCS_4: (static_cast<B_8266_BB_UCS_4*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_8266_BB_UCS_4*>(busPtr))->ApplyPostAdjustments(); break;
|
case I_8266_BB_UCS_4: (static_cast<B_8266_BB_UCS_4*>(busPtr))->SetLuminance(b); break;
|
||||||
#endif
|
#endif
|
||||||
#ifdef ARDUINO_ARCH_ESP32
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
case I_32_RN_NEO_3: (static_cast<B_32_RN_NEO_3*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_32_RN_NEO_3*>(busPtr))->ApplyPostAdjustments(); break;
|
case I_32_RN_NEO_3: (static_cast<B_32_RN_NEO_3*>(busPtr))->SetLuminance(b); break;
|
||||||
#ifndef WLED_NO_I2S0_PIXELBUS
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
case I_32_I0_NEO_3: (static_cast<B_32_I0_NEO_3*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_32_I0_NEO_3*>(busPtr))->ApplyPostAdjustments(); break;
|
case I_32_I0_NEO_3: (static_cast<B_32_I0_NEO_3*>(busPtr))->SetLuminance(b); break;
|
||||||
#endif
|
#endif
|
||||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
case I_32_I1_NEO_3: (static_cast<B_32_I1_NEO_3*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_32_I1_NEO_3*>(busPtr))->ApplyPostAdjustments(); break;
|
case I_32_I1_NEO_3: (static_cast<B_32_I1_NEO_3*>(busPtr))->SetLuminance(b); break;
|
||||||
#endif
|
#endif
|
||||||
// case I_32_BB_NEO_3: (static_cast<B_32_BB_NEO_3*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_32_BB_NEO_3*>(busPtr))->ApplyPostAdjustments(); break;
|
// case I_32_BB_NEO_3: (static_cast<B_32_BB_NEO_3*>(busPtr))->SetLuminance(b); break;
|
||||||
case I_32_RN_NEO_4: (static_cast<B_32_RN_NEO_4*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_32_RN_NEO_4*>(busPtr))->ApplyPostAdjustments(); break;
|
case I_32_RN_NEO_4: (static_cast<B_32_RN_NEO_4*>(busPtr))->SetLuminance(b); break;
|
||||||
#ifndef WLED_NO_I2S0_PIXELBUS
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
case I_32_I0_NEO_4: (static_cast<B_32_I0_NEO_4*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_32_I0_NEO_4*>(busPtr))->ApplyPostAdjustments(); break;
|
case I_32_I0_NEO_4: (static_cast<B_32_I0_NEO_4*>(busPtr))->SetLuminance(b); break;
|
||||||
#endif
|
#endif
|
||||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
case I_32_I1_NEO_4: (static_cast<B_32_I1_NEO_4*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_32_I1_NEO_4*>(busPtr))->ApplyPostAdjustments(); break;
|
case I_32_I1_NEO_4: (static_cast<B_32_I1_NEO_4*>(busPtr))->SetLuminance(b); break;
|
||||||
#endif
|
#endif
|
||||||
// case I_32_BB_NEO_4: (static_cast<B_32_BB_NEO_4*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_32_BB_NEO_4*>(busPtr))->ApplyPostAdjustments(); break;
|
// case I_32_BB_NEO_4: (static_cast<B_32_BB_NEO_4*>(busPtr))->SetLuminance(b); break;
|
||||||
case I_32_RN_400_3: (static_cast<B_32_RN_400_3*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_32_RN_400_3*>(busPtr))->ApplyPostAdjustments(); break;
|
case I_32_RN_400_3: (static_cast<B_32_RN_400_3*>(busPtr))->SetLuminance(b); break;
|
||||||
#ifndef WLED_NO_I2S0_PIXELBUS
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
case I_32_I0_400_3: (static_cast<B_32_I0_400_3*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_32_I0_400_3*>(busPtr))->ApplyPostAdjustments(); break;
|
case I_32_I0_400_3: (static_cast<B_32_I0_400_3*>(busPtr))->SetLuminance(b); break;
|
||||||
#endif
|
#endif
|
||||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
case I_32_I1_400_3: (static_cast<B_32_I1_400_3*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_32_I1_400_3*>(busPtr))->ApplyPostAdjustments(); break;
|
case I_32_I1_400_3: (static_cast<B_32_I1_400_3*>(busPtr))->SetLuminance(b); break;
|
||||||
#endif
|
#endif
|
||||||
// case I_32_BB_400_3: (static_cast<B_32_BB_400_3*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_32_BB_400_3*>(busPtr))->ApplyPostAdjustments(); break;
|
// case I_32_BB_400_3: (static_cast<B_32_BB_400_3*>(busPtr))->SetLuminance(b); break;
|
||||||
case I_32_RN_TM1_4: (static_cast<B_32_RN_TM1_4*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_32_RN_TM1_4*>(busPtr))->ApplyPostAdjustments(); break;
|
case I_32_RN_TM1_4: (static_cast<B_32_RN_TM1_4*>(busPtr))->SetLuminance(b); break;
|
||||||
case I_32_RN_TM2_3: (static_cast<B_32_RN_TM2_3*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_32_RN_TM2_3*>(busPtr))->ApplyPostAdjustments(); break;
|
case I_32_RN_TM2_3: (static_cast<B_32_RN_TM2_3*>(busPtr))->SetLuminance(b); break;
|
||||||
#ifndef WLED_NO_I2S0_PIXELBUS
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
case I_32_I0_TM1_4: (static_cast<B_32_I0_TM1_4*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_32_I0_TM1_4*>(busPtr))->ApplyPostAdjustments(); break;
|
case I_32_I0_TM1_4: (static_cast<B_32_I0_TM1_4*>(busPtr))->SetLuminance(b); break;
|
||||||
case I_32_I0_TM2_3: (static_cast<B_32_I0_TM2_3*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_32_I0_TM2_3*>(busPtr))->ApplyPostAdjustments(); break;
|
case I_32_I0_TM2_3: (static_cast<B_32_I0_TM2_3*>(busPtr))->SetLuminance(b); break;
|
||||||
#endif
|
#endif
|
||||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
case I_32_I1_TM1_4: (static_cast<B_32_I1_TM1_4*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_32_I1_TM1_4*>(busPtr))->ApplyPostAdjustments(); break;
|
case I_32_I1_TM1_4: (static_cast<B_32_I1_TM1_4*>(busPtr))->SetLuminance(b); break;
|
||||||
case I_32_I1_TM2_3: (static_cast<B_32_I1_TM2_3*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_32_I1_TM2_3*>(busPtr))->ApplyPostAdjustments(); break;
|
case I_32_I1_TM2_3: (static_cast<B_32_I1_TM2_3*>(busPtr))->SetLuminance(b); break;
|
||||||
#endif
|
#endif
|
||||||
case I_32_RN_UCS_3: (static_cast<B_32_RN_UCS_3*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_32_RN_UCS_3*>(busPtr))->ApplyPostAdjustments(); break;
|
case I_32_RN_UCS_3: (static_cast<B_32_RN_UCS_3*>(busPtr))->SetLuminance(b); break;
|
||||||
#ifndef WLED_NO_I2S0_PIXELBUS
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
case I_32_I0_UCS_3: (static_cast<B_32_I0_UCS_3*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_32_I0_UCS_3*>(busPtr))->ApplyPostAdjustments(); break;
|
case I_32_I0_UCS_3: (static_cast<B_32_I0_UCS_3*>(busPtr))->SetLuminance(b); break;
|
||||||
#endif
|
#endif
|
||||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
case I_32_I1_UCS_3: (static_cast<B_32_I1_UCS_3*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_32_I1_UCS_3*>(busPtr))->ApplyPostAdjustments(); break;
|
case I_32_I1_UCS_3: (static_cast<B_32_I1_UCS_3*>(busPtr))->SetLuminance(b); break;
|
||||||
#endif
|
#endif
|
||||||
// case I_32_BB_UCS_3: (static_cast<B_32_BB_UCS_3*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_32_BB_UCS_3*>(busPtr))->ApplyPostAdjustments(); break;
|
// case I_32_BB_UCS_3: (static_cast<B_32_BB_UCS_3*>(busPtr))->SetLuminance(b); break;
|
||||||
case I_32_RN_UCS_4: (static_cast<B_32_RN_UCS_4*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_32_RN_UCS_4*>(busPtr))->ApplyPostAdjustments(); break;
|
case I_32_RN_UCS_4: (static_cast<B_32_RN_UCS_4*>(busPtr))->SetLuminance(b); break;
|
||||||
#ifndef WLED_NO_I2S0_PIXELBUS
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
case I_32_I0_UCS_4: (static_cast<B_32_I0_UCS_4*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_32_I0_UCS_4*>(busPtr))->ApplyPostAdjustments(); break;
|
case I_32_I0_UCS_4: (static_cast<B_32_I0_UCS_4*>(busPtr))->SetLuminance(b); break;
|
||||||
#endif
|
#endif
|
||||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
case I_32_I1_UCS_4: (static_cast<B_32_I1_UCS_4*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_32_I1_UCS_4*>(busPtr))->ApplyPostAdjustments(); break;
|
case I_32_I1_UCS_4: (static_cast<B_32_I1_UCS_4*>(busPtr))->SetLuminance(b); break;
|
||||||
#endif
|
#endif
|
||||||
// case I_32_BB_UCS_4: (static_cast<B_32_BB_UCS_4*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_32_BB_UCS_4*>(busPtr))->ApplyPostAdjustments(); break;
|
// case I_32_BB_UCS_4: (static_cast<B_32_BB_UCS_4*>(busPtr))->SetLuminance(b); break;
|
||||||
#endif
|
#endif
|
||||||
case I_HS_DOT_3: (static_cast<B_HS_DOT_3*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_HS_DOT_3*>(busPtr))->ApplyPostAdjustments(); break;
|
case I_HS_DOT_3: (static_cast<B_HS_DOT_3*>(busPtr))->SetLuminance(b); break;
|
||||||
case I_SS_DOT_3: (static_cast<B_SS_DOT_3*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_SS_DOT_3*>(busPtr))->ApplyPostAdjustments(); break;
|
case I_SS_DOT_3: (static_cast<B_SS_DOT_3*>(busPtr))->SetLuminance(b); break;
|
||||||
case I_HS_LPD_3: (static_cast<B_HS_LPD_3*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_HS_LPD_3*>(busPtr))->ApplyPostAdjustments(); break;
|
case I_HS_LPD_3: (static_cast<B_HS_LPD_3*>(busPtr))->SetLuminance(b); break;
|
||||||
case I_SS_LPD_3: (static_cast<B_SS_LPD_3*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_SS_LPD_3*>(busPtr))->ApplyPostAdjustments(); break;
|
case I_SS_LPD_3: (static_cast<B_SS_LPD_3*>(busPtr))->SetLuminance(b); break;
|
||||||
case I_HS_LPO_3: (static_cast<B_HS_LPO_3*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_HS_LPO_3*>(busPtr))->ApplyPostAdjustments(); break;
|
case I_HS_LPO_3: (static_cast<B_HS_LPO_3*>(busPtr))->SetLuminance(b); break;
|
||||||
case I_SS_LPO_3: (static_cast<B_SS_LPO_3*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_SS_LPO_3*>(busPtr))->ApplyPostAdjustments(); break;
|
case I_SS_LPO_3: (static_cast<B_SS_LPO_3*>(busPtr))->SetLuminance(b); break;
|
||||||
case I_HS_WS1_3: (static_cast<B_HS_WS1_3*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_HS_WS1_3*>(busPtr))->ApplyPostAdjustments(); break;
|
case I_HS_WS1_3: (static_cast<B_HS_WS1_3*>(busPtr))->SetLuminance(b); break;
|
||||||
case I_SS_WS1_3: (static_cast<B_SS_WS1_3*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_SS_WS1_3*>(busPtr))->ApplyPostAdjustments(); break;
|
case I_SS_WS1_3: (static_cast<B_SS_WS1_3*>(busPtr))->SetLuminance(b); break;
|
||||||
case I_HS_P98_3: (static_cast<B_HS_P98_3*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_HS_P98_3*>(busPtr))->ApplyPostAdjustments(); break;
|
case I_HS_P98_3: (static_cast<B_HS_P98_3*>(busPtr))->SetLuminance(b); break;
|
||||||
case I_SS_P98_3: (static_cast<B_SS_P98_3*>(busPtr))->SetLuminance(b); if (immediate) (static_cast<B_SS_P98_3*>(busPtr))->ApplyPostAdjustments(); break;
|
case I_SS_P98_3: (static_cast<B_SS_P98_3*>(busPtr))->SetLuminance(b); break;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
static uint32_t getPixelColor(void* busPtr, uint8_t busType, uint16_t pix, uint8_t co) {
|
static uint32_t getPixelColor(void* busPtr, uint8_t busType, uint16_t pix, uint8_t co) {
|
||||||
RgbwColor col(0,0,0,0);
|
RgbwColor col(0,0,0,0);
|
||||||
switch (busType) {
|
switch (busType) {
|
||||||
|
@ -90,7 +90,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
|||||||
CJSON(strip.cctBlending, hw_led[F("cb")]);
|
CJSON(strip.cctBlending, hw_led[F("cb")]);
|
||||||
Bus::setCCTBlend(strip.cctBlending);
|
Bus::setCCTBlend(strip.cctBlending);
|
||||||
strip.setTargetFps(hw_led["fps"]); //NOP if 0, default 42 FPS
|
strip.setTargetFps(hw_led["fps"]); //NOP if 0, default 42 FPS
|
||||||
CJSON(strip.useLedsArray, hw_led[F("ld")]);
|
CJSON(useGlobalLedBuffer, hw_led[F("ld")]);
|
||||||
|
|
||||||
#ifndef WLED_DISABLE_2D
|
#ifndef WLED_DISABLE_2D
|
||||||
// 2D Matrix Settings
|
// 2D Matrix Settings
|
||||||
@ -134,7 +134,8 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
|||||||
if (fromFS || !ins.isNull()) {
|
if (fromFS || !ins.isNull()) {
|
||||||
uint8_t s = 0; // bus iterator
|
uint8_t s = 0; // bus iterator
|
||||||
if (fromFS) busses.removeAll(); // can't safely manipulate busses directly in network callback
|
if (fromFS) busses.removeAll(); // can't safely manipulate busses directly in network callback
|
||||||
uint32_t mem = 0;
|
uint32_t mem = 0, globalBufMem = 0;
|
||||||
|
uint16_t maxlen = 0;
|
||||||
bool busesChanged = false;
|
bool busesChanged = false;
|
||||||
for (JsonObject elm : ins) {
|
for (JsonObject elm : ins) {
|
||||||
if (s >= WLED_MAX_BUSSES+WLED_MIN_VIRTUAL_BUSSES) break;
|
if (s >= WLED_MAX_BUSSES+WLED_MIN_VIRTUAL_BUSSES) break;
|
||||||
@ -160,12 +161,16 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
|||||||
ledType |= refresh << 7; // hack bit 7 to indicate strip requires off refresh
|
ledType |= refresh << 7; // hack bit 7 to indicate strip requires off refresh
|
||||||
uint8_t AWmode = elm[F("rgbwm")] | autoWhiteMode;
|
uint8_t AWmode = elm[F("rgbwm")] | autoWhiteMode;
|
||||||
if (fromFS) {
|
if (fromFS) {
|
||||||
BusConfig bc = BusConfig(ledType, pins, start, length, colorOrder, reversed, skipFirst, AWmode, freqkHz);
|
BusConfig bc = BusConfig(ledType, pins, start, length, colorOrder, reversed, skipFirst, AWmode, freqkHz, useGlobalLedBuffer);
|
||||||
mem += BusManager::memUsage(bc);
|
mem += BusManager::memUsage(bc);
|
||||||
if (mem <= MAX_LED_MEMORY) if (busses.add(bc) == -1) break; // finalization will be done in WLED::beginStrip()
|
if (useGlobalLedBuffer && start + length > maxlen) {
|
||||||
|
maxlen = start + length;
|
||||||
|
globalBufMem = maxlen * 4;
|
||||||
|
}
|
||||||
|
if (mem + globalBufMem <= MAX_LED_MEMORY) if (busses.add(bc) == -1) break; // finalization will be done in WLED::beginStrip()
|
||||||
} else {
|
} else {
|
||||||
if (busConfigs[s] != nullptr) delete busConfigs[s];
|
if (busConfigs[s] != nullptr) delete busConfigs[s];
|
||||||
busConfigs[s] = new BusConfig(ledType, pins, start, length, colorOrder, reversed, skipFirst, AWmode);
|
busConfigs[s] = new BusConfig(ledType, pins, start, length, colorOrder, reversed, skipFirst, AWmode, freqkHz, useGlobalLedBuffer);
|
||||||
busesChanged = true;
|
busesChanged = true;
|
||||||
}
|
}
|
||||||
s++;
|
s++;
|
||||||
@ -173,7 +178,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
|||||||
doInitBusses = busesChanged;
|
doInitBusses = busesChanged;
|
||||||
// finalization done in beginStrip()
|
// finalization done in beginStrip()
|
||||||
}
|
}
|
||||||
if (hw_led["rev"]) busses.getBus(0)->reversed = true; //set 0.11 global reversed setting for first bus
|
if (hw_led["rev"]) busses.getBus(0)->setReversed(true); //set 0.11 global reversed setting for first bus
|
||||||
|
|
||||||
// read color order map configuration
|
// read color order map configuration
|
||||||
JsonArray hw_com = hw[F("com")];
|
JsonArray hw_com = hw[F("com")];
|
||||||
@ -711,7 +716,7 @@ void serializeConfig() {
|
|||||||
hw_led[F("cb")] = strip.cctBlending;
|
hw_led[F("cb")] = strip.cctBlending;
|
||||||
hw_led["fps"] = strip.getTargetFps();
|
hw_led["fps"] = strip.getTargetFps();
|
||||||
hw_led[F("rgbwm")] = Bus::getGlobalAWMode(); // global auto white mode override
|
hw_led[F("rgbwm")] = Bus::getGlobalAWMode(); // global auto white mode override
|
||||||
hw_led[F("ld")] = strip.useLedsArray;
|
hw_led[F("ld")] = useGlobalLedBuffer;
|
||||||
|
|
||||||
#ifndef WLED_DISABLE_2D
|
#ifndef WLED_DISABLE_2D
|
||||||
// 2D Matrix Settings
|
// 2D Matrix Settings
|
||||||
@ -746,7 +751,7 @@ void serializeConfig() {
|
|||||||
uint8_t nPins = bus->getPins(pins);
|
uint8_t nPins = bus->getPins(pins);
|
||||||
for (uint8_t i = 0; i < nPins; i++) ins_pin.add(pins[i]);
|
for (uint8_t i = 0; i < nPins; i++) ins_pin.add(pins[i]);
|
||||||
ins[F("order")] = bus->getColorOrder();
|
ins[F("order")] = bus->getColorOrder();
|
||||||
ins["rev"] = bus->reversed;
|
ins["rev"] = bus->isReversed();
|
||||||
ins[F("skip")] = bus->skippedLeds();
|
ins[F("skip")] = bus->skippedLeds();
|
||||||
ins["type"] = bus->getType() & 0x7F;
|
ins["type"] = bus->getType() & 0x7F;
|
||||||
ins["ref"] = bus->isOffRefreshRequired();
|
ins["ref"] = bus->isOffRefreshRequired();
|
||||||
|
@ -141,7 +141,7 @@
|
|||||||
let len = parseInt(d.getElementsByName("LC"+n)[0].value);
|
let len = parseInt(d.getElementsByName("LC"+n)[0].value);
|
||||||
len += parseInt(d.getElementsByName("SL"+n)[0].value); // skipped LEDs are allocated too
|
len += parseInt(d.getElementsByName("SL"+n)[0].value); // skipped LEDs are allocated too
|
||||||
let dbl = 0;
|
let dbl = 0;
|
||||||
if (d.Sf.LD.checked) dbl = len * 3; // double buffering
|
if (d.Sf.LD.checked) dbl = len * 4; // double buffering
|
||||||
if (t < 32) {
|
if (t < 32) {
|
||||||
if (t==26 || t==29) len *= 2; // 16 bit LEDs
|
if (t==26 || t==29) len *= 2; // 16 bit LEDs
|
||||||
if (maxM < 10000 && d.getElementsByName("L0"+n)[0].value == 3) { //8266 DMA uses 5x the mem
|
if (maxM < 10000 && d.getElementsByName("L0"+n)[0].value == 3) { //8266 DMA uses 5x the mem
|
||||||
|
@ -22,7 +22,7 @@ bool deserializeSegment(JsonObject elem, byte it, byte presetId)
|
|||||||
|
|
||||||
int stop = elem["stop"] | -1;
|
int stop = elem["stop"] | -1;
|
||||||
|
|
||||||
// if using vectors use this code to append segment
|
// append segment
|
||||||
if (id >= strip.getSegmentsNum()) {
|
if (id >= strip.getSegmentsNum()) {
|
||||||
if (stop <= 0) return false; // ignore empty/inactive segments
|
if (stop <= 0) return false; // ignore empty/inactive segments
|
||||||
strip.appendSegment(Segment(0, strip.getLengthTotal()));
|
strip.appendSegment(Segment(0, strip.getLengthTotal()));
|
||||||
@ -110,7 +110,11 @@ bool deserializeSegment(JsonObject elem, byte it, byte presetId)
|
|||||||
of = offsetAbs;
|
of = offsetAbs;
|
||||||
}
|
}
|
||||||
if (stop > start && of > len -1) of = len -1;
|
if (stop > start && of > len -1) of = len -1;
|
||||||
seg.setUp(start, stop, grp, spc, of, startY, stopY);
|
|
||||||
|
// update segment (delete if necessary)
|
||||||
|
// do not call seg.setUp() here, as it may cause a crash due to concurrent access if the segment is currently drawing effects
|
||||||
|
// WS2812FX handles queueing of the change
|
||||||
|
strip.setSegment(id, start, stop, grp, spc, of, startY, stopY);
|
||||||
|
|
||||||
if (seg.reset && seg.stop == 0) return true; // segment was deleted & is marked for reset, no need to change anything else
|
if (seg.reset && seg.stop == 0) return true; // segment was deleted & is marked for reset, no need to change anything else
|
||||||
|
|
||||||
@ -468,12 +472,14 @@ void serializeSegment(JsonObject& root, Segment& seg, byte id, bool forPreset, b
|
|||||||
if (segmentBounds) {
|
if (segmentBounds) {
|
||||||
root["start"] = seg.start;
|
root["start"] = seg.start;
|
||||||
root["stop"] = seg.stop;
|
root["stop"] = seg.stop;
|
||||||
|
#ifndef WLED_DISABLE_2D
|
||||||
if (strip.isMatrix) {
|
if (strip.isMatrix) {
|
||||||
root[F("startY")] = seg.startY;
|
root[F("startY")] = seg.startY;
|
||||||
root[F("stopY")] = seg.stopY;
|
root[F("stopY")] = seg.stopY;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
if (!forPreset) root["len"] = (seg.stop >= seg.start) ? (seg.stop - seg.start) : 0;
|
if (!forPreset) root["len"] = seg.stop - seg.start;
|
||||||
root["grp"] = seg.grouping;
|
root["grp"] = seg.grouping;
|
||||||
root[F("spc")] = seg.spacing;
|
root[F("spc")] = seg.spacing;
|
||||||
root[F("of")] = seg.offset;
|
root[F("of")] = seg.offset;
|
||||||
@ -1060,7 +1066,10 @@ void serveJson(AsyncWebServerRequest* request)
|
|||||||
|
|
||||||
DEBUG_PRINTF("JSON buffer size: %u for request: %d\n", lDoc.memoryUsage(), subJson);
|
DEBUG_PRINTF("JSON buffer size: %u for request: %d\n", lDoc.memoryUsage(), subJson);
|
||||||
|
|
||||||
size_t len = response->setLength();
|
#ifdef WLED_DEBUG
|
||||||
|
size_t len =
|
||||||
|
#endif
|
||||||
|
response->setLength();
|
||||||
DEBUG_PRINT(F("JSON content length: ")); DEBUG_PRINTLN(len);
|
DEBUG_PRINT(F("JSON content length: ")); DEBUG_PRINTLN(len);
|
||||||
|
|
||||||
request->send(response);
|
request->send(response);
|
||||||
@ -1090,9 +1099,13 @@ bool serveLiveLeds(AsyncWebServerRequest* request, uint32_t wsClient)
|
|||||||
for (size_t i= 0; i < used; i += n)
|
for (size_t i= 0; i < used; i += n)
|
||||||
{
|
{
|
||||||
uint32_t c = strip.getPixelColor(i);
|
uint32_t c = strip.getPixelColor(i);
|
||||||
uint8_t r = qadd8(W(c), R(c)); //add white channel to RGB channels as a simple RGBW -> RGB map
|
uint8_t r = R(c);
|
||||||
uint8_t g = qadd8(W(c), G(c));
|
uint8_t g = G(c);
|
||||||
uint8_t b = qadd8(W(c), B(c));
|
uint8_t b = B(c);
|
||||||
|
uint8_t w = W(c);
|
||||||
|
r = scale8(qadd8(w, r), strip.getBrightness()); //R, add white channel to RGB channels as a simple RGBW -> RGB map
|
||||||
|
g = scale8(qadd8(w, g), strip.getBrightness()); //G
|
||||||
|
b = scale8(qadd8(w, b), strip.getBrightness()); //B
|
||||||
olen += sprintf(obuf + olen, "\"%06X\",", RGBW32(r,g,b,0));
|
olen += sprintf(obuf + olen, "\"%06X\",", RGBW32(r,g,b,0));
|
||||||
}
|
}
|
||||||
olen -= 1;
|
olen -= 1;
|
||||||
|
@ -195,7 +195,7 @@ void handleTransitions()
|
|||||||
applyFinalBri();
|
applyFinalBri();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (tper - tperLast < 0.004) return;
|
if (tper - tperLast < 0.004f) return;
|
||||||
tperLast = tper;
|
tperLast = tper;
|
||||||
briT = briOld + ((bri - briOld) * tper);
|
briT = briOld + ((bri - briOld) * tper);
|
||||||
|
|
||||||
|
@ -91,7 +91,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
|||||||
Bus::setCCTBlend(strip.cctBlending);
|
Bus::setCCTBlend(strip.cctBlending);
|
||||||
Bus::setGlobalAWMode(request->arg(F("AW")).toInt());
|
Bus::setGlobalAWMode(request->arg(F("AW")).toInt());
|
||||||
strip.setTargetFps(request->arg(F("FR")).toInt());
|
strip.setTargetFps(request->arg(F("FR")).toInt());
|
||||||
strip.useLedsArray = request->hasArg(F("LD"));
|
useGlobalLedBuffer = request->hasArg(F("LD"));
|
||||||
|
|
||||||
bool busesChanged = false;
|
bool busesChanged = false;
|
||||||
for (uint8_t s = 0; s < WLED_MAX_BUSSES+WLED_MIN_VIRTUAL_BUSSES; s++) {
|
for (uint8_t s = 0; s < WLED_MAX_BUSSES+WLED_MIN_VIRTUAL_BUSSES; s++) {
|
||||||
@ -153,7 +153,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
|||||||
// actual finalization is done in WLED::loop() (removing old busses and adding new)
|
// actual finalization is done in WLED::loop() (removing old busses and adding new)
|
||||||
// this may happen even before this loop is finished so we do "doInitBusses" after the loop
|
// this may happen even before this loop is finished so we do "doInitBusses" after the loop
|
||||||
if (busConfigs[s] != nullptr) delete busConfigs[s];
|
if (busConfigs[s] != nullptr) delete busConfigs[s];
|
||||||
busConfigs[s] = new BusConfig(type, pins, start, length, colorOrder | (channelSwap<<4), request->hasArg(cv), skip, awmode, freqHz);
|
busConfigs[s] = new BusConfig(type, pins, start, length, colorOrder | (channelSwap<<4), request->hasArg(cv), skip, awmode, freqHz, useGlobalLedBuffer);
|
||||||
busesChanged = true;
|
busesChanged = true;
|
||||||
}
|
}
|
||||||
//doInitBusses = busesChanged; // we will do that below to ensure all input data is processed
|
//doInitBusses = busesChanged; // we will do that below to ensure all input data is processed
|
||||||
@ -797,7 +797,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
|
|||||||
if (pos > 0) {
|
if (pos > 0) {
|
||||||
spcI = getNumVal(&req, pos);
|
spcI = getNumVal(&req, pos);
|
||||||
}
|
}
|
||||||
selseg.setUp(startI, stopI, grpI, spcI, UINT16_MAX, startY, stopY);
|
strip.setSegment(selectedSeg, startI, stopI, grpI, spcI, UINT16_MAX, startY, stopY);
|
||||||
|
|
||||||
pos = req.indexOf(F("RV=")); //Segment reverse
|
pos = req.indexOf(F("RV=")); //Segment reverse
|
||||||
if (pos > 0) selseg.reverse = req.charAt(pos+3) != '0';
|
if (pos > 0) selseg.reverse = req.charAt(pos+3) != '0';
|
||||||
|
@ -23,7 +23,7 @@ void WLED::reset()
|
|||||||
#ifdef WLED_ENABLE_WEBSOCKETS
|
#ifdef WLED_ENABLE_WEBSOCKETS
|
||||||
ws.closeAll(1012);
|
ws.closeAll(1012);
|
||||||
#endif
|
#endif
|
||||||
long dly = millis();
|
unsigned long dly = millis();
|
||||||
while (millis() - dly < 450) {
|
while (millis() - dly < 450) {
|
||||||
yield(); // enough time to send response to client
|
yield(); // enough time to send response to client
|
||||||
}
|
}
|
||||||
@ -35,10 +35,18 @@ void WLED::reset()
|
|||||||
void WLED::loop()
|
void WLED::loop()
|
||||||
{
|
{
|
||||||
#ifdef WLED_DEBUG
|
#ifdef WLED_DEBUG
|
||||||
|
static unsigned long lastRun = 0;
|
||||||
|
unsigned long loopMillis = millis();
|
||||||
|
size_t loopDelay = loopMillis - lastRun;
|
||||||
|
if (lastRun == 0) loopDelay=0; // startup - don't have valid data from last run.
|
||||||
|
if (loopDelay > 2) DEBUG_PRINTF("Loop delayed more than %ums.\n", loopDelay);
|
||||||
|
static unsigned long maxLoopMillis = 0;
|
||||||
|
static size_t avgLoopMillis = 0;
|
||||||
static unsigned long maxUsermodMillis = 0;
|
static unsigned long maxUsermodMillis = 0;
|
||||||
static uint16_t avgUsermodMillis = 0;
|
static size_t avgUsermodMillis = 0;
|
||||||
static unsigned long maxStripMillis = 0;
|
static unsigned long maxStripMillis = 0;
|
||||||
static uint16_t avgStripMillis = 0;
|
static size_t avgStripMillis = 0;
|
||||||
|
unsigned long stripMillis;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
handleTime();
|
handleTime();
|
||||||
@ -80,6 +88,9 @@ void WLED::loop()
|
|||||||
yield();
|
yield();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WLED_DEBUG
|
||||||
|
stripMillis = millis();
|
||||||
|
#endif
|
||||||
if (!realtimeMode || realtimeOverride || (realtimeMode && useMainSegmentOnly)) // block stuff if WARLS/Adalight is enabled
|
if (!realtimeMode || realtimeOverride || (realtimeMode && useMainSegmentOnly)) // block stuff if WARLS/Adalight is enabled
|
||||||
{
|
{
|
||||||
if (apActive) dnsServer.processNextRequest();
|
if (apActive) dnsServer.processNextRequest();
|
||||||
@ -98,22 +109,18 @@ void WLED::loop()
|
|||||||
handlePresets();
|
handlePresets();
|
||||||
yield();
|
yield();
|
||||||
|
|
||||||
#ifdef WLED_DEBUG
|
|
||||||
unsigned long stripMillis = millis();
|
|
||||||
#endif
|
|
||||||
if (!offMode || strip.isOffRefreshRequired())
|
if (!offMode || strip.isOffRefreshRequired())
|
||||||
strip.service();
|
strip.service();
|
||||||
#ifdef ESP8266
|
#ifdef ESP8266
|
||||||
else if (!noWifiSleep)
|
else if (!noWifiSleep)
|
||||||
delay(1); //required to make sure ESP enters modem sleep (see #1184)
|
delay(1); //required to make sure ESP enters modem sleep (see #1184)
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
#ifdef WLED_DEBUG
|
#ifdef WLED_DEBUG
|
||||||
stripMillis = millis() - stripMillis;
|
stripMillis = millis() - stripMillis;
|
||||||
if (stripMillis > 50) DEBUG_PRINTLN("Slow strip.");
|
|
||||||
avgStripMillis += stripMillis;
|
avgStripMillis += stripMillis;
|
||||||
if (stripMillis > maxStripMillis) maxStripMillis = stripMillis;
|
if (stripMillis > maxStripMillis) maxStripMillis = stripMillis;
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
|
|
||||||
yield();
|
yield();
|
||||||
#ifdef ESP8266
|
#ifdef ESP8266
|
||||||
@ -152,11 +159,16 @@ void WLED::loop()
|
|||||||
DEBUG_PRINTLN(F("Re-init busses."));
|
DEBUG_PRINTLN(F("Re-init busses."));
|
||||||
bool aligned = strip.checkSegmentAlignment(); //see if old segments match old bus(ses)
|
bool aligned = strip.checkSegmentAlignment(); //see if old segments match old bus(ses)
|
||||||
busses.removeAll();
|
busses.removeAll();
|
||||||
uint32_t mem = 0;
|
uint32_t mem = 0, globalBufMem = 0;
|
||||||
|
uint16_t maxlen = 0;
|
||||||
for (uint8_t i = 0; i < WLED_MAX_BUSSES+WLED_MIN_VIRTUAL_BUSSES; i++) {
|
for (uint8_t i = 0; i < WLED_MAX_BUSSES+WLED_MIN_VIRTUAL_BUSSES; i++) {
|
||||||
if (busConfigs[i] == nullptr) break;
|
if (busConfigs[i] == nullptr) break;
|
||||||
mem += BusManager::memUsage(*busConfigs[i]);
|
mem += BusManager::memUsage(*busConfigs[i]);
|
||||||
if (mem <= MAX_LED_MEMORY) {
|
if (useGlobalLedBuffer && busConfigs[i]->start + busConfigs[i]->count > maxlen) {
|
||||||
|
maxlen = busConfigs[i]->start + busConfigs[i]->count;
|
||||||
|
globalBufMem = maxlen * 4;
|
||||||
|
}
|
||||||
|
if (mem + globalBufMem <= MAX_LED_MEMORY) {
|
||||||
busses.add(*busConfigs[i]);
|
busses.add(*busConfigs[i]);
|
||||||
}
|
}
|
||||||
delete busConfigs[i]; busConfigs[i] = nullptr;
|
delete busConfigs[i]; busConfigs[i] = nullptr;
|
||||||
@ -177,8 +189,31 @@ void WLED::loop()
|
|||||||
handleWs();
|
handleWs();
|
||||||
handleStatusLED();
|
handleStatusLED();
|
||||||
|
|
||||||
|
toki.resetTick();
|
||||||
|
|
||||||
|
#if WLED_WATCHDOG_TIMEOUT > 0
|
||||||
|
// we finished our mainloop, reset the watchdog timer
|
||||||
|
if (!strip.isUpdating())
|
||||||
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
|
esp_task_wdt_reset();
|
||||||
|
#else
|
||||||
|
ESP.wdtFeed();
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (doReboot && (!doInitBusses || !doSerializeConfig)) // if busses have to be inited & saved, wait until next iteration
|
||||||
|
reset();
|
||||||
|
|
||||||
// DEBUG serial logging (every 30s)
|
// DEBUG serial logging (every 30s)
|
||||||
#ifdef WLED_DEBUG
|
#ifdef WLED_DEBUG
|
||||||
|
loopMillis = millis() - loopMillis;
|
||||||
|
if (loopMillis > 30) {
|
||||||
|
DEBUG_PRINTF("Loop took %lums.\n", loopMillis);
|
||||||
|
DEBUG_PRINTF("Usermods took %lums.\n", usermodMillis);
|
||||||
|
DEBUG_PRINTF("Strip took %lums.\n", stripMillis);
|
||||||
|
}
|
||||||
|
avgLoopMillis += loopMillis;
|
||||||
|
if (loopMillis > maxLoopMillis) maxLoopMillis = loopMillis;
|
||||||
if (millis() - debugTime > 29999) {
|
if (millis() - debugTime > 29999) {
|
||||||
DEBUG_PRINTLN(F("---DEBUG INFO---"));
|
DEBUG_PRINTLN(F("---DEBUG INFO---"));
|
||||||
DEBUG_PRINT(F("Runtime: ")); DEBUG_PRINTLN(millis());
|
DEBUG_PRINT(F("Runtime: ")); DEBUG_PRINTLN(millis());
|
||||||
@ -201,11 +236,13 @@ void WLED::loop()
|
|||||||
DEBUG_PRINT(F("Client IP: ")); DEBUG_PRINTLN(Network.localIP());
|
DEBUG_PRINT(F("Client IP: ")); DEBUG_PRINTLN(Network.localIP());
|
||||||
if (loops > 0) { // avoid division by zero
|
if (loops > 0) { // avoid division by zero
|
||||||
DEBUG_PRINT(F("Loops/sec: ")); DEBUG_PRINTLN(loops / 30);
|
DEBUG_PRINT(F("Loops/sec: ")); DEBUG_PRINTLN(loops / 30);
|
||||||
|
DEBUG_PRINT(F("Loop time[ms]: ")); DEBUG_PRINT(avgLoopMillis/loops); DEBUG_PRINT("/");DEBUG_PRINTLN(maxLoopMillis);
|
||||||
DEBUG_PRINT(F("UM time[ms]: ")); DEBUG_PRINT(avgUsermodMillis/loops); DEBUG_PRINT("/");DEBUG_PRINTLN(maxUsermodMillis);
|
DEBUG_PRINT(F("UM time[ms]: ")); DEBUG_PRINT(avgUsermodMillis/loops); DEBUG_PRINT("/");DEBUG_PRINTLN(maxUsermodMillis);
|
||||||
DEBUG_PRINT(F("Strip time[ms]: ")); DEBUG_PRINT(avgStripMillis/loops); DEBUG_PRINT("/"); DEBUG_PRINTLN(maxStripMillis);
|
DEBUG_PRINT(F("Strip time[ms]: ")); DEBUG_PRINT(avgStripMillis/loops); DEBUG_PRINT("/"); DEBUG_PRINTLN(maxStripMillis);
|
||||||
}
|
}
|
||||||
strip.printSize();
|
strip.printSize();
|
||||||
loops = 0;
|
loops = 0;
|
||||||
|
maxLoopMillis = 0;
|
||||||
maxUsermodMillis = 0;
|
maxUsermodMillis = 0;
|
||||||
maxStripMillis = 0;
|
maxStripMillis = 0;
|
||||||
avgUsermodMillis = 0;
|
avgUsermodMillis = 0;
|
||||||
@ -213,21 +250,8 @@ void WLED::loop()
|
|||||||
debugTime = millis();
|
debugTime = millis();
|
||||||
}
|
}
|
||||||
loops++;
|
loops++;
|
||||||
|
lastRun = millis();
|
||||||
#endif // WLED_DEBUG
|
#endif // WLED_DEBUG
|
||||||
toki.resetTick();
|
|
||||||
|
|
||||||
#if WLED_WATCHDOG_TIMEOUT > 0
|
|
||||||
// we finished our mainloop, reset the watchdog timer
|
|
||||||
if (!strip.isUpdating())
|
|
||||||
#ifdef ARDUINO_ARCH_ESP32
|
|
||||||
esp_task_wdt_reset();
|
|
||||||
#else
|
|
||||||
ESP.wdtFeed();
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (doReboot && (!doInitBusses || !doSerializeConfig)) // if busses have to be inited & saved, wait until next iteration
|
|
||||||
reset();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WLED::enableWatchdog() {
|
void WLED::enableWatchdog() {
|
||||||
@ -512,7 +536,7 @@ void WLED::initAP(bool resetAP)
|
|||||||
DEBUG_PRINTLN(apSSID);
|
DEBUG_PRINTLN(apSSID);
|
||||||
WiFi.softAPConfig(IPAddress(4, 3, 2, 1), IPAddress(4, 3, 2, 1), IPAddress(255, 255, 255, 0));
|
WiFi.softAPConfig(IPAddress(4, 3, 2, 1), IPAddress(4, 3, 2, 1), IPAddress(255, 255, 255, 0));
|
||||||
WiFi.softAP(apSSID, apPass, apChannel, apHide);
|
WiFi.softAP(apSSID, apPass, apChannel, apHide);
|
||||||
#if defined(LOLIN_WIFI_FIX) && (defined(ARDUINO_ARCH_ESP32C3) || defined(ARDUINO_ARCH_ESP32S2))
|
#if defined(LOLIN_WIFI_FIX) && (defined(ARDUINO_ARCH_ESP32C3) || defined(ARDUINO_ARCH_ESP32S2) || defined(ARDUINO_ARCH_ESP32S3))
|
||||||
WiFi.setTxPower(WIFI_POWER_8_5dBm);
|
WiFi.setTxPower(WIFI_POWER_8_5dBm);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -690,7 +714,7 @@ void WLED::initConnection()
|
|||||||
|
|
||||||
WiFi.begin(clientSSID, clientPass);
|
WiFi.begin(clientSSID, clientPass);
|
||||||
#ifdef ARDUINO_ARCH_ESP32
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
#if defined(LOLIN_WIFI_FIX) && (defined(ARDUINO_ARCH_ESP32C3) || defined(ARDUINO_ARCH_ESP32S2))
|
#if defined(LOLIN_WIFI_FIX) && (defined(ARDUINO_ARCH_ESP32C3) || defined(ARDUINO_ARCH_ESP32S2) || defined(ARDUINO_ARCH_ESP32S3))
|
||||||
WiFi.setTxPower(WIFI_POWER_8_5dBm);
|
WiFi.setTxPower(WIFI_POWER_8_5dBm);
|
||||||
#endif
|
#endif
|
||||||
WiFi.setSleep(!noWifiSleep);
|
WiFi.setSleep(!noWifiSleep);
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// version code in format yymmddb (b = daily build)
|
// version code in format yymmddb (b = daily build)
|
||||||
#define VERSION 2307130
|
#define VERSION 2307180
|
||||||
|
|
||||||
//uncomment this if you have a "my_config.h" file you'd like to use
|
//uncomment this if you have a "my_config.h" file you'd like to use
|
||||||
//#define WLED_USE_MY_CONFIG
|
//#define WLED_USE_MY_CONFIG
|
||||||
@ -332,6 +332,11 @@ WLED_GLOBAL byte bootPreset _INIT(0); // save preset to load
|
|||||||
//if false, only one segment spanning the total LEDs is created,
|
//if false, only one segment spanning the total LEDs is created,
|
||||||
//but not on LED settings save if there is more than one segment currently
|
//but not on LED settings save if there is more than one segment currently
|
||||||
WLED_GLOBAL bool autoSegments _INIT(false);
|
WLED_GLOBAL bool autoSegments _INIT(false);
|
||||||
|
#ifdef ESP8266
|
||||||
|
WLED_GLOBAL bool useGlobalLedBuffer _INIT(false); // double buffering disabled on ESP8266
|
||||||
|
#else
|
||||||
|
WLED_GLOBAL bool useGlobalLedBuffer _INIT(true); // double buffering enabled on ESP32
|
||||||
|
#endif
|
||||||
WLED_GLOBAL bool correctWB _INIT(false); // CCT color correction of RGB color
|
WLED_GLOBAL bool correctWB _INIT(false); // CCT color correction of RGB color
|
||||||
WLED_GLOBAL bool cctFromRgb _INIT(false); // CCT is calculated from RGB instead of using seg.cct
|
WLED_GLOBAL bool cctFromRgb _INIT(false); // CCT is calculated from RGB instead of using seg.cct
|
||||||
WLED_GLOBAL bool gammaCorrectCol _INIT(true); // use gamma correction on colors
|
WLED_GLOBAL bool gammaCorrectCol _INIT(true); // use gamma correction on colors
|
||||||
@ -508,7 +513,7 @@ WLED_GLOBAL uint16_t userVar0 _INIT(0), userVar1 _INIT(0); //available for use i
|
|||||||
// wifi
|
// wifi
|
||||||
WLED_GLOBAL bool apActive _INIT(false);
|
WLED_GLOBAL bool apActive _INIT(false);
|
||||||
WLED_GLOBAL bool forceReconnect _INIT(false);
|
WLED_GLOBAL bool forceReconnect _INIT(false);
|
||||||
WLED_GLOBAL uint32_t lastReconnectAttempt _INIT(0);
|
WLED_GLOBAL unsigned long lastReconnectAttempt _INIT(0);
|
||||||
WLED_GLOBAL bool interfacesInited _INIT(false);
|
WLED_GLOBAL bool interfacesInited _INIT(false);
|
||||||
WLED_GLOBAL bool wasConnected _INIT(false);
|
WLED_GLOBAL bool wasConnected _INIT(false);
|
||||||
|
|
||||||
|
@ -166,23 +166,24 @@ bool sendLiveLedsWs(uint32_t wsClient)
|
|||||||
size_t n = ((used -1)/MAX_LIVE_LEDS_WS) +1; //only serve every n'th LED if count over MAX_LIVE_LEDS_WS
|
size_t n = ((used -1)/MAX_LIVE_LEDS_WS) +1; //only serve every n'th LED if count over MAX_LIVE_LEDS_WS
|
||||||
size_t pos = (strip.isMatrix ? 4 : 2); // start of data
|
size_t pos = (strip.isMatrix ? 4 : 2); // start of data
|
||||||
size_t bufSize = pos + (used/n)*3;
|
size_t bufSize = pos + (used/n)*3;
|
||||||
size_t skipLines = 0;
|
|
||||||
|
|
||||||
AsyncWebSocketMessageBuffer * wsBuf = ws.makeBuffer(bufSize);
|
AsyncWebSocketMessageBuffer * wsBuf = ws.makeBuffer(bufSize);
|
||||||
if (!wsBuf) return false; //out of memory
|
if (!wsBuf) return false; //out of memory
|
||||||
uint8_t* buffer = wsBuf->get();
|
uint8_t* buffer = wsBuf->get();
|
||||||
buffer[0] = 'L';
|
buffer[0] = 'L';
|
||||||
buffer[1] = 1; //version
|
buffer[1] = 1; //version
|
||||||
|
|
||||||
#ifndef WLED_DISABLE_2D
|
#ifndef WLED_DISABLE_2D
|
||||||
|
size_t skipLines = 0;
|
||||||
if (strip.isMatrix) {
|
if (strip.isMatrix) {
|
||||||
buffer[1] = 2; //version
|
buffer[1] = 2; //version
|
||||||
buffer[2] = Segment::maxWidth;
|
buffer[2] = Segment::maxWidth;
|
||||||
buffer[3] = Segment::maxHeight;
|
buffer[3] = Segment::maxHeight;
|
||||||
if (Segment::maxWidth * Segment::maxHeight > MAX_LIVE_LEDS_WS*4) {
|
if (used > MAX_LIVE_LEDS_WS*4) {
|
||||||
buffer[2] = Segment::maxWidth/4;
|
buffer[2] = Segment::maxWidth/4;
|
||||||
buffer[3] = Segment::maxHeight/4;
|
buffer[3] = Segment::maxHeight/4;
|
||||||
skipLines = 3;
|
skipLines = 3;
|
||||||
} else if (Segment::maxWidth * Segment::maxHeight > MAX_LIVE_LEDS_WS) {
|
} else if (used > MAX_LIVE_LEDS_WS) {
|
||||||
buffer[2] = Segment::maxWidth/2;
|
buffer[2] = Segment::maxWidth/2;
|
||||||
buffer[3] = Segment::maxHeight/2;
|
buffer[3] = Segment::maxHeight/2;
|
||||||
skipLines = 1;
|
skipLines = 1;
|
||||||
@ -198,9 +199,13 @@ bool sendLiveLedsWs(uint32_t wsClient)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
uint32_t c = strip.getPixelColor(i);
|
uint32_t c = strip.getPixelColor(i);
|
||||||
buffer[pos++] = qadd8(W(c), R(c)); //R, add white channel to RGB channels as a simple RGBW -> RGB map
|
uint8_t r = R(c);
|
||||||
buffer[pos++] = qadd8(W(c), G(c)); //G
|
uint8_t g = G(c);
|
||||||
buffer[pos++] = qadd8(W(c), B(c)); //B
|
uint8_t b = B(c);
|
||||||
|
uint8_t w = W(c);
|
||||||
|
buffer[pos++] = scale8(qadd8(w, r), strip.getBrightness()); //R, add white channel to RGB channels as a simple RGBW -> RGB map
|
||||||
|
buffer[pos++] = scale8(qadd8(w, g), strip.getBrightness()); //G
|
||||||
|
buffer[pos++] = scale8(qadd8(w, b), strip.getBrightness()); //B
|
||||||
}
|
}
|
||||||
|
|
||||||
wsc->binary(wsBuf);
|
wsc->binary(wsBuf);
|
||||||
|
@ -355,7 +355,7 @@ void getSettingsJS(byte subPage, char* dest)
|
|||||||
sappend('v',SET_F("CB"),strip.cctBlending);
|
sappend('v',SET_F("CB"),strip.cctBlending);
|
||||||
sappend('v',SET_F("FR"),strip.getTargetFps());
|
sappend('v',SET_F("FR"),strip.getTargetFps());
|
||||||
sappend('v',SET_F("AW"),Bus::getGlobalAWMode());
|
sappend('v',SET_F("AW"),Bus::getGlobalAWMode());
|
||||||
sappend('c',SET_F("LD"),strip.useLedsArray);
|
sappend('c',SET_F("LD"),useGlobalLedBuffer);
|
||||||
|
|
||||||
for (uint8_t s=0; s < busses.getNumBusses(); s++) {
|
for (uint8_t s=0; s < busses.getNumBusses(); s++) {
|
||||||
Bus* bus = busses.getBus(s);
|
Bus* bus = busses.getBus(s);
|
||||||
@ -382,7 +382,7 @@ void getSettingsJS(byte subPage, char* dest)
|
|||||||
sappend('v',lt,bus->getType());
|
sappend('v',lt,bus->getType());
|
||||||
sappend('v',co,bus->getColorOrder() & 0x0F);
|
sappend('v',co,bus->getColorOrder() & 0x0F);
|
||||||
sappend('v',ls,bus->getStart());
|
sappend('v',ls,bus->getStart());
|
||||||
sappend('c',cv,bus->reversed);
|
sappend('c',cv,bus->isReversed());
|
||||||
sappend('v',sl,bus->skippedLeds());
|
sappend('v',sl,bus->skippedLeds());
|
||||||
sappend('c',rf,bus->isOffRefreshRequired());
|
sappend('c',rf,bus->isOffRefreshRequired());
|
||||||
sappend('v',aw,bus->getAutoWhiteMode());
|
sappend('v',aw,bus->getAutoWhiteMode());
|
||||||
|
Loading…
Reference in New Issue
Block a user