diff --git a/platformio.ini b/platformio.ini index e334b7e35..8d9109c02 100644 --- a/platformio.ini +++ b/platformio.ini @@ -10,7 +10,7 @@ # ------------------------------------------------------------------------------ # CI/release binaries -default_envs = nodemcuv2, esp8266_2m, esp01_1m_full, nodemcuv2_160, esp8266_2m_160, esp01_1m_full_160, esp32dev, esp32_eth, esp32dev_audioreactive, lolin_s2_mini, esp32c3dev, esp32s3dev_8MB, esp32s3dev_8MB_PSRAM_opi, esp32s3_4M_PSRAM_qspi, esp32_wrover +default_envs = nodemcuv2, esp8266_2m, esp01_1m_full, nodemcuv2_160, esp8266_2m_160, esp01_1m_full_160, esp32dev, esp32_eth, esp32dev_audioreactive, lolin_s2_mini, esp32c3dev, esp32s3dev_16MB_opi, esp32s3dev_8MB_opi, esp32s3_4M_qspi, esp32_wrover src_dir = ./wled00 data_dir = ./wled00/data @@ -86,7 +86,6 @@ debug_flags = -D DEBUG=1 -D WLED_DEBUG # This reduces the OTA size with ~45KB, so it's especially useful on low memory boards (512k/1m). # ------------------------------------------------------------------------------ build_flags = - -Wno-attributes -DMQTT_MAX_PACKET_SIZE=1024 -DSECURE_CLIENT=SECURE_CLIENT_BEARSSL -DBEARSSL_SSL_BASIC @@ -104,10 +103,6 @@ build_flags = build_unflags = -build_flags_esp8266 = ${common.build_flags} ${esp8266.build_flags} -build_flags_esp32 = ${common.build_flags} ${esp32.build_flags} -build_flags_esp32_V4= ${common.build_flags} ${esp32_idf_V4.build_flags} - ldscript_1m128k = eagle.flash.1m128.ld ldscript_2m512k = eagle.flash.2m512.ld ldscript_2m1m = eagle.flash.2m1m.ld @@ -174,7 +169,7 @@ lib_deps = # SHT85 ;robtillaart/SHT85@~0.3.3 # Audioreactive usermod - ;kosme/arduinoFFT @ 2.0.0 + ;kosme/arduinoFFT @ 2.0.1 extra_scripts = ${scripts_defaults.extra_scripts} @@ -218,14 +213,19 @@ build_flags = -g #use LITTLEFS library by lorol in ESP32 core 1.x.x instead of built-in in 2.x.x -D LOROL_LITTLEFS ; -DARDUINO_USB_CDC_ON_BOOT=0 ;; this flag is mandatory for "classic ESP32" when building with arduino-esp32 >=2.0.3 +tiny_partitions = tools/WLED_ESP32_2MB_noOTA.csv default_partitions = tools/WLED_ESP32_4MB_1MB_FS.csv +extended_partitions = tools/WLED_ESP32_4MB_700k_FS.csv +big_partitions = tools/WLED_ESP32_4MB_256KB_FS.csv ;; 1.8MB firmware, 256KB filesystem, coredump support +large_partitions = tools/WLED_ESP32_8MB.csv +extreme_partitions = tools/WLED_ESP32_16MB_9MB_FS.csv lib_deps = https://github.com/lorol/LITTLEFS.git https://github.com/pbolduc/AsyncTCP.git @ 1.2.0 ${env.lib_deps} # additional build flags for audioreactive AR_build_flags = -D USERMOD_AUDIOREACTIVE -AR_lib_deps = kosme/arduinoFFT @ 2.0.0 +AR_lib_deps = kosme/arduinoFFT @ 2.0.1 [esp32_idf_V4] ;; experimental build environment for ESP32 using ESP-IDF 4.4.x / arduino-esp32 v2.0.5 @@ -233,24 +233,21 @@ AR_lib_deps = kosme/arduinoFFT @ 2.0.0 ;; ;; 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. -platform = espressif32@5.3.0 -platform_packages = +platform = espressif32@ ~6.3.2 +platform_packages = platformio/framework-arduinoespressif32 @ 3.20009.0 ;; select arduino-esp32 v2.0.9 (arduino-esp32 2.0.10 thru 2.0.14 are buggy so avoid them) build_flags = -g -Wshadow=compatible-local ;; emit warning in case a local variable "shadows" another local one -DARDUINO_ARCH_ESP32 -DESP32 - #-DCONFIG_LITTLEFS_FOR_IDF_3_2 -D CONFIG_ASYNC_TCP_USE_WDT=0 -DARDUINO_USB_CDC_ON_BOOT=0 ;; this flag is mandatory for "classic ESP32" when building with arduino-esp32 >=2.0.3 -default_partitions = tools/WLED_ESP32_4MB_1MB_FS.csv lib_deps = https://github.com/pbolduc/AsyncTCP.git @ 1.2.0 ${env.lib_deps} [esp32s2] ;; generic definitions for all ESP32-S2 boards -platform = espressif32@5.3.0 -platform_packages = -default_partitions = tools/WLED_ESP32_4MB_1MB_FS.csv +platform = espressif32@ ~6.3.2 +platform_packages = platformio/framework-arduinoespressif32 @ 3.20009.0 ;; select arduino-esp32 v2.0.9 (arduino-esp32 2.0.10 thru 2.0.14 are buggy so avoid them) build_flags = -g -DARDUINO_ARCH_ESP32 -DARDUINO_ARCH_ESP32S2 @@ -267,8 +264,8 @@ lib_deps = [esp32c3] ;; generic definitions for all ESP32-C3 boards -platform = espressif32@5.3.0 -platform_packages = +platform = espressif32@ ~6.3.2 +platform_packages = platformio/framework-arduinoespressif32 @ 3.20009.0 ;; select arduino-esp32 v2.0.9 (arduino-esp32 2.0.10 thru 2.0.14 are buggy so avoid them) build_flags = -g -DARDUINO_ARCH_ESP32 -DARDUINO_ARCH_ESP32C3 @@ -284,8 +281,8 @@ lib_deps = [esp32s3] ;; generic definitions for all ESP32-S3 boards -platform = espressif32@5.3.0 -platform_packages = +platform = espressif32@ ~6.3.2 +platform_packages = platformio/framework-arduinoespressif32 @ 3.20009.0 ;; select arduino-esp32 v2.0.9 (arduino-esp32 2.0.10 thru 2.0.14 are buggy so avoid them) build_flags = -g -DESP32 -DARDUINO_ARCH_ESP32 @@ -296,7 +293,6 @@ build_flags = -g -DCO ;; please make sure that the following flags are properly set (to 0 or 1) by your board.json, or included in your custom platformio_override.ini entry: ;; ARDUINO_USB_MODE, ARDUINO_USB_CDC_ON_BOOT - lib_deps = https://github.com/pbolduc/AsyncTCP.git @ 1.2.0 ${env.lib_deps} @@ -312,14 +308,14 @@ platform = ${common.platform_wled_default} platform_packages = ${common.platform_packages} board_build.ldscript = ${common.ldscript_4m1m} build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp8266} -D WLED_RELEASE_NAME=ESP8266 #-DWLED_DISABLE_2D +build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_RELEASE_NAME=ESP8266 #-DWLED_DISABLE_2D lib_deps = ${esp8266.lib_deps} monitor_filters = esp8266_exception_decoder [env:nodemcuv2_160] extends = env:nodemcuv2 board_build.f_cpu = 160000000L -build_flags = ${common.build_flags_esp8266} -D WLED_RELEASE_NAME=ESP8266_160 #-DWLED_DISABLE_2D +build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_RELEASE_NAME=ESP8266_160 #-DWLED_DISABLE_2D [env:esp8266_2m] board = esp_wroom_02 @@ -327,13 +323,13 @@ platform = ${common.platform_wled_default} platform_packages = ${common.platform_packages} board_build.ldscript = ${common.ldscript_2m512k} build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp8266} -D WLED_RELEASE_NAME=ESP02 +build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_RELEASE_NAME=ESP02 lib_deps = ${esp8266.lib_deps} [env:esp8266_2m_160] extends = env:esp8266_2m board_build.f_cpu = 160000000L -build_flags = ${common.build_flags_esp8266} -D WLED_RELEASE_NAME=ESP02_160 +build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_RELEASE_NAME=ESP02_160 [env:esp01_1m_full] board = esp01_1m @@ -341,14 +337,14 @@ platform = ${common.platform_wled_default} platform_packages = ${common.platform_packages} board_build.ldscript = ${common.ldscript_1m128k} build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp8266} -D WLED_RELEASE_NAME=ESP01 -D WLED_DISABLE_OTA +build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_RELEASE_NAME=ESP01 -D WLED_DISABLE_OTA ; -D WLED_USE_UNREAL_MATH ;; may cause wrong sunset/sunrise times, but saves 7064 bytes FLASH and 975 bytes RAM lib_deps = ${esp8266.lib_deps} [env:esp01_1m_full_160] extends = env:esp01_1m_full board_build.f_cpu = 160000000L -build_flags = ${common.build_flags_esp8266} -D WLED_RELEASE_NAME=ESP01_160 -D WLED_DISABLE_OTA +build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_RELEASE_NAME=ESP01_160 -D WLED_DISABLE_OTA ; -D WLED_USE_UNREAL_MATH ;; may cause wrong sunset/sunrise times, but saves 7064 bytes FLASH and 975 bytes RAM [env:esp32dev] @@ -356,17 +352,30 @@ board = esp32dev platform = ${esp32.platform} platform_packages = ${esp32.platform_packages} build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp32} -D WLED_RELEASE_NAME=ESP32 #-D WLED_DISABLE_BROWNOUT_DET +build_flags = ${common.build_flags} ${esp32.build_flags} -D WLED_RELEASE_NAME=ESP32 #-D WLED_DISABLE_BROWNOUT_DET lib_deps = ${esp32.lib_deps} monitor_filters = esp32_exception_decoder board_build.partitions = ${esp32.default_partitions} +[env:esp32dev_8M] +board = esp32dev +platform = ${esp32_idf_V4.platform} +platform_packages = ${esp32_idf_V4.platform_packages} +build_unflags = ${common.build_unflags} +build_flags = ${common.build_flags} ${esp32_idf_V4.build_flags} -D WLED_RELEASE_NAME=ESP32_8M #-D WLED_DISABLE_BROWNOUT_DET + ${esp32.AR_build_flags} +lib_deps = ${esp32_idf_V4.lib_deps} + ${esp32.AR_lib_deps} +monitor_filters = esp32_exception_decoder +board_build.partitions = ${esp32.large_partitions} +; board_build.f_flash = 80000000L + [env:esp32dev_audioreactive] board = esp32dev platform = ${esp32.platform} platform_packages = ${esp32.platform_packages} build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp32} -D WLED_RELEASE_NAME=ESP32_audioreactive #-D WLED_DISABLE_BROWNOUT_DET +build_flags = ${common.build_flags} ${esp32.build_flags} -D WLED_RELEASE_NAME=ESP32_audioreactive #-D WLED_DISABLE_BROWNOUT_DET ${esp32.AR_build_flags} lib_deps = ${esp32.lib_deps} ${esp32.AR_lib_deps} @@ -381,22 +390,26 @@ platform = ${esp32.platform} platform_packages = ${esp32.platform_packages} upload_speed = 921600 build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp32} -D WLED_RELEASE_NAME=ESP32_Ethernet -D RLYPIN=-1 -D WLED_USE_ETHERNET -D BTNPIN=-1 +build_flags = ${common.build_flags} ${esp32.build_flags} -D WLED_RELEASE_NAME=ESP32_Ethernet -D RLYPIN=-1 -D WLED_USE_ETHERNET -D BTNPIN=-1 -D WLED_DISABLE_ESPNOW ;; ESP-NOW requires wifi, may crash with ethernet only lib_deps = ${esp32.lib_deps} board_build.partitions = ${esp32.default_partitions} [env:esp32_wrover] -platform = ${esp32.platform} +extends = esp32_idf_V4 +platform = ${esp32_idf_V4.platform} +platform_packages = ${esp32_idf_V4.platform_packages} board = ttgo-t7-v14-mini32 board_build.f_flash = 80000000L board_build.flash_mode = qio -board_build.partitions = tools/WLED_ESP32-wrover_4MB.csv +board_build.partitions = ${esp32.default_partitions} build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp32} -D WLED_RELEASE_NAME=ESP32_WROVER +build_flags = ${common.build_flags} ${esp32_idf_V4.build_flags} -D WLED_RELEASE_NAME=ESP32_WROVER -DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue ;; Older ESP32 (rev.<3) need a PSRAM fix (increases static RAM used) https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-guides/external-ram.html -D LEDPIN=25 -lib_deps = ${esp32.lib_deps} + ; ${esp32.AR_build_flags} +lib_deps = ${esp32_idf_V4.lib_deps} + ; ${esp32.AR_lib_deps} [env:esp32c3dev] extends = esp32c3 @@ -404,7 +417,7 @@ platform = ${esp32c3.platform} platform_packages = ${esp32c3.platform_packages} framework = arduino board = esp32-c3-devkitm-1 -board_build.partitions = tools/WLED_ESP32_4MB_1MB_FS.csv +board_build.partitions = ${esp32.default_partitions} build_flags = ${common.build_flags} ${esp32c3.build_flags} -D WLED_RELEASE_NAME=ESP32-C3 -D WLED_WATCHDOG_TIMEOUT=0 -DLOLIN_WIFI_FIX ; seems to work much better with this @@ -414,35 +427,15 @@ upload_speed = 460800 build_unflags = ${common.build_unflags} lib_deps = ${esp32c3.lib_deps} -[env:esp32s3dev_8MB] -;; ESP32-S3-DevKitC-1 development board, with 8MB FLASH, no PSRAM (flash_mode: qio) -board = esp32-s3-devkitc-1 -platform = ${esp32s3.platform} -platform_packages = ${esp32s3.platform_packages} -upload_speed = 921600 ; or 460800 -build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags} ${esp32s3.build_flags} -D WLED_RELEASE_NAME=ESP32-S3_8MB - -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=1 ;; -D ARDUINO_USB_MODE=1 ;; for boards with USB-OTG connector only (USBCDC or "TinyUSB") - ${esp32.AR_build_flags} -lib_deps = ${esp32s3.lib_deps} - ${esp32.AR_lib_deps} -board_build.partitions = tools/WLED_ESP32_8MB.csv -board_build.f_flash = 80000000L -board_build.flash_mode = qio -; board_build.flash_mode = dio ;; try this if you have problems at startup -monitor_filters = esp32_exception_decoder - -[env:esp32s3dev_8MB_PSRAM_opi] -;; ESP32-S3 development board, with 8MB FLASH and >= 8MB PSRAM (memory_type: qio_opi) +[env:esp32s3dev_16MB_opi] +;; ESP32-S3 development board, with 16MB FLASH and >= 8MB PSRAM (memory_type: qio_opi) board = esp32-s3-devkitc-1 ;; generic dev board; the next line adds PSRAM support board_build.arduino.memory_type = qio_opi ;; use with PSRAM: 8MB or 16MB platform = ${esp32s3.platform} platform_packages = ${esp32s3.platform_packages} upload_speed = 921600 build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags} ${esp32s3.build_flags} -D WLED_RELEASE_NAME=ESP32-S3_8MB_PSRAM_opi +build_flags = ${common.build_flags} ${esp32s3.build_flags} -D WLED_RELEASE_NAME=ESP32-S3_16MB_opi -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=1 -D ARDUINO_USB_MODE=1 ;; for boards with USB-OTG connector only (USBCDC or "TinyUSB") @@ -450,12 +443,33 @@ build_flags = ${common.build_flags} ${esp32s3.build_flags} -D WLED_RELEASE_NAME= ${esp32.AR_build_flags} lib_deps = ${esp32s3.lib_deps} ${esp32.AR_lib_deps} -board_build.partitions = tools/WLED_ESP32_8MB.csv +board_build.partitions = ${esp32.extreme_partitions} board_build.f_flash = 80000000L board_build.flash_mode = qio monitor_filters = esp32_exception_decoder -[env:esp32s3_4M_PSRAM_qspi] +[env:esp32s3dev_8MB_opi] +;; ESP32-S3 development board, with 8MB FLASH and >= 8MB PSRAM (memory_type: qio_opi) +board = esp32-s3-devkitc-1 ;; generic dev board; the next line adds PSRAM support +board_build.arduino.memory_type = qio_opi ;; use with PSRAM: 8MB or 16MB +platform = ${esp32s3.platform} +platform_packages = ${esp32s3.platform_packages} +upload_speed = 921600 +build_unflags = ${common.build_unflags} +build_flags = ${common.build_flags} ${esp32s3.build_flags} -D WLED_RELEASE_NAME=ESP32-S3_8MB_opi + -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=1 -D ARDUINO_USB_MODE=1 ;; for boards with USB-OTG connector only (USBCDC or "TinyUSB") + -DBOARD_HAS_PSRAM + ${esp32.AR_build_flags} +lib_deps = ${esp32s3.lib_deps} + ${esp32.AR_lib_deps} +board_build.partitions = ${esp32.large_partitions} +board_build.f_flash = 80000000L +board_build.flash_mode = qio +monitor_filters = esp32_exception_decoder + +[env:esp32s3_4M_qspi] ;; ESP32-S3, with 4MB FLASH and <= 4MB PSRAM (memory_type: qio_qspi) 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 @@ -463,14 +477,14 @@ platform = ${esp32s3.platform} platform_packages = ${esp32s3.platform_packages} upload_speed = 921600 build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags} ${esp32s3.build_flags} -D WLED_RELEASE_NAME=ESP32-S3_4M_PSRAM_qspi +build_flags = ${common.build_flags} ${esp32s3.build_flags} -D WLED_RELEASE_NAME=ESP32-S3_4M_qspi -DARDUINO_USB_CDC_ON_BOOT=1 -DARDUINO_USB_MODE=1 ;; for boards with USB-OTG connector only (USBCDC or "TinyUSB") -DBOARD_HAS_PSRAM -D WLED_WATCHDOG_TIMEOUT=0 ${esp32.AR_build_flags} lib_deps = ${esp32s3.lib_deps} ${esp32.AR_lib_deps} -board_build.partitions = tools/WLED_ESP32_4MB_1MB_FS.csv +board_build.partitions = ${esp32.default_partitions} board_build.f_flash = 80000000L board_build.flash_mode = qio monitor_filters = esp32_exception_decoder @@ -479,9 +493,9 @@ monitor_filters = esp32_exception_decoder platform = ${esp32s2.platform} platform_packages = ${esp32s2.platform_packages} board = lolin_s2_mini -board_build.partitions = tools/WLED_ESP32_4MB_1MB_FS.csv -;board_build.flash_mode = qio -;board_build.f_flash = 80000000L +board_build.partitions = ${esp32.default_partitions} +board_build.flash_mode = qio +board_build.f_flash = 80000000L build_unflags = ${common.build_unflags} build_flags = ${common.build_flags} ${esp32s2.build_flags} -D WLED_RELEASE_NAME=ESP32-S2 -DARDUINO_USB_CDC_ON_BOOT=1 diff --git a/platformio_override.sample.ini b/platformio_override.sample.ini index d7d41f3a6..05bd1983e 100644 --- a/platformio_override.sample.ini +++ b/platformio_override.sample.ini @@ -28,12 +28,15 @@ lib_deps = ${esp8266.lib_deps} ; robtillaart/SHT85@~0.3.3 ; gmag11/QuickESPNow ;@ 0.6.2 ; https://github.com/blazoncek/QuickESPNow.git#optional-debug ;; exludes debug library -; https://github.com/kosme/arduinoFFT#develop @ 1.9.2+sha.419d7b0 ;; used for USERMOD_AUDIOREACTIVE - using "known working" hash -; build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp8266} +; https://github.com/kosme/arduinoFFT#develop @ 2.0.1 ;; used for USERMOD_AUDIOREACTIVE +build_unflags = ${common.build_unflags} +build_flags = ${common.build_flags} ${esp8266.build_flags} ; ; *** To use the below defines/overrides, copy and paste each onto it's own line just below build_flags in the section above. ; +; Set a release name that may be used to distinguish required binary for flashing +; -D WLED_RELEASE_NAME=ESP32_MULTI_USREMODS +; ; disable specific features ; -D WLED_DISABLE_OTA ; -D WLED_DISABLE_ALEXA @@ -56,6 +59,7 @@ build_flags = ${common.build_flags_esp8266} ; -D IRPIN=4 ; -D RLYPIN=12 ; -D RLYMDE=1 +; -D RLYODRAIN=0 ; -D LED_BUILTIN=2 # GPIO of built-in LED ; ; Limit max buses @@ -179,7 +183,7 @@ platform = ${common.platform_wled_default} platform_packages = ${common.platform_packages} board_build.ldscript = ${common.ldscript_4m1m} build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp8266} +build_flags = ${common.build_flags} ${esp8266.build_flags} lib_deps = ${esp8266.lib_deps} [env:d1_mini] @@ -189,7 +193,7 @@ platform_packages = ${common.platform_packages} upload_speed = 921600 board_build.ldscript = ${common.ldscript_4m1m} build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp8266} +build_flags = ${common.build_flags} ${esp8266.build_flags} lib_deps = ${esp8266.lib_deps} monitor_filters = esp8266_exception_decoder @@ -199,7 +203,7 @@ platform = ${common.platform_wled_default} platform_packages = ${common.platform_packages} board_build.ldscript = ${common.ldscript_4m1m} build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp8266} +build_flags = ${common.build_flags} ${esp8266.build_flags} lib_deps = ${esp8266.lib_deps} [env:h803wf] @@ -208,7 +212,7 @@ platform = ${common.platform_wled_default} platform_packages = ${common.platform_packages} board_build.ldscript = ${common.ldscript_4m1m} build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp8266} -D LEDPIN=1 -D WLED_DISABLE_INFRARED +build_flags = ${common.build_flags} ${esp8266.build_flags} -D LEDPIN=1 -D WLED_DISABLE_INFRARED lib_deps = ${esp8266.lib_deps} [env:esp32dev_qio80] @@ -216,7 +220,7 @@ board = esp32dev platform = ${esp32.platform} platform_packages = ${esp32.platform_packages} build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp32} -D WLED_RELEASE_NAME=ESP32_qio80 #-D WLED_DISABLE_BROWNOUT_DET +build_flags = ${common.build_flags} ${esp32.build_flags} #-D WLED_DISABLE_BROWNOUT_DET lib_deps = ${esp32.lib_deps} monitor_filters = esp32_exception_decoder board_build.partitions = ${esp32.default_partitions} @@ -231,7 +235,7 @@ board = esp32dev platform = ${esp32_idf_V4.platform} platform_packages = ${esp32_idf_V4.platform_packages} build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags} ${esp32_idf_V4.build_flags} -D WLED_RELEASE_NAME=ESP32_V4_qio80 #-D WLED_DISABLE_BROWNOUT_DET +build_flags = ${common.build_flags} ${esp32_idf_V4.build_flags} #-D WLED_DISABLE_BROWNOUT_DET lib_deps = ${esp32_idf_V4.lib_deps} monitor_filters = esp32_exception_decoder board_build.partitions = ${esp32_idf_V4.default_partitions} @@ -240,14 +244,14 @@ board_build.flash_mode = dio [env:esp32s2_saola] board = esp32-s2-saola-1 -platform = https://github.com/tasmota/platform-espressif32/releases/download/v2.0.2.2/platform-tasmota-espressif32-2.0.2.zip -platform_packages = +platform = ${esp32s2.platform} +platform_packages = ${esp32s2.platform_packages} framework = arduino board_build.partitions = tools/WLED_ESP32_4MB_1MB_FS.csv board_build.flash_mode = qio upload_speed = 460800 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} ;-DLOLIN_WIFI_FIX ;; try this in case Wifi does not work -DARDUINO_USB_CDC_ON_BOOT=1 lib_deps = ${esp32s2.lib_deps} @@ -265,7 +269,7 @@ platform = ${common.platform_wled_default} platform_packages = ${common.platform_packages} board_build.ldscript = ${common.ldscript_1m128k} build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp8266} -D WLED_DISABLE_OTA +build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_DISABLE_OTA lib_deps = ${esp8266.lib_deps} [env:esp8285_H801] @@ -274,7 +278,7 @@ platform = ${common.platform_wled_default} platform_packages = ${common.platform_packages} board_build.ldscript = ${common.ldscript_1m128k} build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp8266} -D WLED_DISABLE_OTA +build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_DISABLE_OTA lib_deps = ${esp8266.lib_deps} [env:d1_mini_5CH_Shojo_PCB] @@ -283,7 +287,7 @@ platform = ${common.platform_wled_default} platform_packages = ${common.platform_packages} board_build.ldscript = ${common.ldscript_4m1m} build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp8266} -D WLED_USE_SHOJO_PCB +build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_USE_SHOJO_PCB lib_deps = ${esp8266.lib_deps} [env:d1_mini_debug] @@ -293,7 +297,7 @@ platform = ${common.platform_wled_default} platform_packages = ${common.platform_packages} board_build.ldscript = ${common.ldscript_4m1m} build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp8266} ${common.debug_flags} +build_flags = ${common.build_flags} ${esp8266.build_flags} ${common.debug_flags} lib_deps = ${esp8266.lib_deps} [env:d1_mini_ota] @@ -305,7 +309,7 @@ platform = ${common.platform_wled_default} platform_packages = ${common.platform_packages} board_build.ldscript = ${common.ldscript_4m1m} build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp8266} +build_flags = ${common.build_flags} ${esp8266.build_flags} lib_deps = ${esp8266.lib_deps} [env:anavi_miracle_controller] @@ -314,7 +318,7 @@ platform = ${common.platform_wled_default} platform_packages = ${common.platform_packages} board_build.ldscript = ${common.ldscript_4m1m} build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp8266} -D LEDPIN=12 -D IRPIN=-1 -D RLYPIN=2 +build_flags = ${common.build_flags} ${esp8266.build_flags} -D LEDPIN=12 -D IRPIN=-1 -D RLYPIN=2 lib_deps = ${esp8266.lib_deps} [env:esp32c3dev_2MB] @@ -324,7 +328,7 @@ extends = esp32c3 platform = ${esp32c3.platform} platform_packages = ${esp32c3.platform_packages} board = esp32-c3-devkitm-1 -build_flags = ${common.build_flags} ${esp32c3.build_flags} #-D WLED_RELEASE_NAME=ESP32-C3 +build_flags = ${common.build_flags} ${esp32c3.build_flags} -D WLED_WATCHDOG_TIMEOUT=0 -D WLED_DISABLE_OTA ; -DARDUINO_USB_CDC_ON_BOOT=1 ;; for virtual CDC USB @@ -341,7 +345,7 @@ platform = ${esp32.platform} platform_packages = ${esp32.platform_packages} upload_speed = 460800 build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp32} +build_flags = ${common.build_flags} ${esp32.build_flags} -D LEDPIN=16 -D RLYPIN=19 -D BTNPIN=17 @@ -361,7 +365,7 @@ board_build.partitions = ${esp32.default_partitions} [env:m5atom] board = esp32dev build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp32} -D LEDPIN=27 -D BTNPIN=39 +build_flags = ${common.build_flags} ${esp32.build_flags} -D LEDPIN=27 -D BTNPIN=39 lib_deps = ${esp32.lib_deps} platform = ${esp32.platform} platform_packages = ${esp32.platform_packages} @@ -371,14 +375,14 @@ board_build.partitions = ${esp32.default_partitions} board = esp_wroom_02 platform = ${common.platform_wled_default} board_build.ldscript = ${common.ldscript_2m512k} -build_flags = ${common.build_flags_esp8266} -D LEDPIN=3 -D BTNPIN=1 +build_flags = ${common.build_flags} ${esp8266.build_flags} -D LEDPIN=3 -D BTNPIN=1 lib_deps = ${esp8266.lib_deps} [env:sp511e] board = esp_wroom_02 platform = ${common.platform_wled_default} board_build.ldscript = ${common.ldscript_2m512k} -build_flags = ${common.build_flags_esp8266} -D LEDPIN=3 -D BTNPIN=2 -D IRPIN=5 -D WLED_MAX_BUTTONS=3 +build_flags = ${common.build_flags} ${esp8266.build_flags} -D LEDPIN=3 -D BTNPIN=2 -D IRPIN=5 -D WLED_MAX_BUTTONS=3 lib_deps = ${esp8266.lib_deps} [env:Athom_RGBCW] ;7w and 5w(GU10) bulbs @@ -387,7 +391,7 @@ platform = ${common.platform_wled_default} platform_packages = ${common.platform_packages} board_build.ldscript = ${common.ldscript_2m512k} build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp8266} -D WLED_RELEASE_NAME=ESP8266 -D BTNPIN=-1 -D RLYPIN=-1 -D DATA_PINS=4,12,14,13,5 +build_flags = ${common.build_flags} ${esp8266.build_flags} -D BTNPIN=-1 -D RLYPIN=-1 -D DATA_PINS=4,12,14,13,5 -D DEFAULT_LED_TYPE=TYPE_ANALOG_5CH -D WLED_DISABLE_INFRARED -D WLED_MAX_CCT_BLEND=0 lib_deps = ${esp8266.lib_deps} @@ -397,7 +401,7 @@ platform = ${common.platform_wled_default} platform_packages = ${common.platform_packages} board_build.ldscript = ${common.ldscript_2m512k} build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp8266} -D WLED_RELEASE_NAME=ESP8266 -D BTNPIN=-1 -D RLYPIN=-1 -D DATA_PINS=4,12,14,5,13 +build_flags = ${common.build_flags} ${esp8266.build_flags} -D BTNPIN=-1 -D RLYPIN=-1 -D DATA_PINS=4,12,14,5,13 -D DEFAULT_LED_TYPE=TYPE_ANALOG_5CH -D WLED_DISABLE_INFRARED -D WLED_MAX_CCT_BLEND=0 -D WLED_USE_IC_CCT lib_deps = ${esp8266.lib_deps} @@ -407,7 +411,7 @@ platform = ${common.platform_wled_default} platform_packages = ${common.platform_packages} board_build.ldscript = ${common.ldscript_2m512k} build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp8266} -D WLED_RELEASE_NAME=ESP8266 -D BTNPIN=0 -D RLYPIN=-1 -D LEDPIN=1 -D WLED_DISABLE_INFRARED +build_flags = ${common.build_flags} ${esp8266.build_flags} -D BTNPIN=0 -D RLYPIN=-1 -D LEDPIN=1 -D WLED_DISABLE_INFRARED lib_deps = ${esp8266.lib_deps} [env:Athom_4Pin_Controller] ; With clock and data interface @@ -416,7 +420,7 @@ platform = ${common.platform_wled_default} platform_packages = ${common.platform_packages} board_build.ldscript = ${common.ldscript_2m512k} build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp8266} -D WLED_RELEASE_NAME=ESP8266 -D BTNPIN=0 -D RLYPIN=12 -D LEDPIN=1 -D WLED_DISABLE_INFRARED +build_flags = ${common.build_flags} ${esp8266.build_flags} -D BTNPIN=0 -D RLYPIN=12 -D LEDPIN=1 -D WLED_DISABLE_INFRARED lib_deps = ${esp8266.lib_deps} [env:Athom_5Pin_Controller] ;Analog light strip controller @@ -425,7 +429,7 @@ platform = ${common.platform_wled_default} platform_packages = ${common.platform_packages} board_build.ldscript = ${common.ldscript_2m512k} build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp8266} -D WLED_RELEASE_NAME=ESP8266 -D BTNPIN=0 -D RLYPIN=-1 DATA_PINS=4,12,14,13 -D WLED_DISABLE_INFRARED +build_flags = ${common.build_flags} ${esp8266.build_flags} -D BTNPIN=0 -D RLYPIN=-1 DATA_PINS=4,12,14,13 -D WLED_DISABLE_INFRARED lib_deps = ${esp8266.lib_deps} [env:MY9291] @@ -434,7 +438,7 @@ platform = ${common.platform_wled_default} platform_packages = ${common.platform_packages} board_build.ldscript = ${common.ldscript_1m128k} build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp8266} -D WLED_RELEASE_NAME=ESP01 -D WLED_DISABLE_OTA -D USERMOD_MY9291 +build_flags = ${common.build_flags} ${esp8266.build_flags} -D WLED_DISABLE_OTA -D USERMOD_MY9291 lib_deps = ${esp8266.lib_deps} # ------------------------------------------------------------------------------ @@ -448,7 +452,7 @@ platform = ${common.platform_wled_default} platform_packages = ${common.platform_packages} board_build.ldscript = ${common.ldscript_2m512k} build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp8266} +build_flags = ${common.build_flags} ${esp8266.build_flags} lib_deps = ${esp8266.lib_deps} [env:codm-controller-0_6-rev2] @@ -457,7 +461,7 @@ platform = ${common.platform_wled_default} platform_packages = ${common.platform_packages} board_build.ldscript = ${common.ldscript_4m1m} build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags_esp8266} +build_flags = ${common.build_flags} ${esp8266.build_flags} lib_deps = ${esp8266.lib_deps} # ------------------------------------------------------------------------------ @@ -468,7 +472,7 @@ board = esp32dev platform = ${esp32.platform} platform_packages = ${esp32.platform_packages} upload_speed = 921600 -build_flags = ${common.build_flags_esp32} -D WLED_DISABLE_BROWNOUT_DET -D WLED_DISABLE_INFRARED +build_flags = ${common.build_flags} ${esp32.build_flags} -D WLED_DISABLE_BROWNOUT_DET -D WLED_DISABLE_INFRARED -D USERMOD_RTC -D USERMOD_ELEKSTUBE_IPS -D LEDPIN=12 diff --git a/tools/WLED_ESP32_4MB_256KB_FS.csv b/tools/WLED_ESP32_4MB_256KB_FS.csv new file mode 100644 index 000000000..e54c22bbd --- /dev/null +++ b/tools/WLED_ESP32_4MB_256KB_FS.csv @@ -0,0 +1,7 @@ +# Name, Type, SubType, Offset, Size, Flags +nvs, data, nvs, 0x9000, 0x5000, +otadata, data, ota, 0xe000, 0x2000, +app0, app, ota_0, 0x10000, 0x1D0000, +app1, app, ota_1, 0x1E0000,0x1D0000, +spiffs, data, spiffs, 0x3B0000,0x40000, +coredump, data, coredump,,64K \ No newline at end of file diff --git a/tools/WLED_ESP32_4MB_700k_FS.csv b/tools/WLED_ESP32_4MB_700k_FS.csv new file mode 100644 index 000000000..39c88e543 --- /dev/null +++ b/tools/WLED_ESP32_4MB_700k_FS.csv @@ -0,0 +1,6 @@ +# Name, Type, SubType, Offset, Size, Flags +nvs, data, nvs, 0x9000, 0x5000, +otadata, data, ota, 0xe000, 0x2000, +app0, app, ota_0, 0x10000, 0x1A0000, +app1, app, ota_1, 0x1B0000,0x1A0000, +spiffs, data, spiffs, 0x350000,0xB0000, diff --git a/usermods/BH1750_v2/usermod_bh1750.h b/usermods/BH1750_v2/usermod_bh1750.h index ede4aabc4..2a2bd4637 100644 --- a/usermods/BH1750_v2/usermod_bh1750.h +++ b/usermods/BH1750_v2/usermod_bh1750.h @@ -59,7 +59,7 @@ private: bool sensorFound = false; // Home Assistant and MQTT - String mqttLuminanceTopic = F(""); + String mqttLuminanceTopic; bool mqttInitialized = false; bool HomeAssistantDiscovery = true; // Publish Home Assistant Discovery messages diff --git a/usermods/audioreactive/audio_source.h b/usermods/audioreactive/audio_source.h index 18d00da3c..a7337eaf9 100644 --- a/usermods/audioreactive/audio_source.h +++ b/usermods/audioreactive/audio_source.h @@ -71,7 +71,7 @@ * if you want to receive two channels, one is the actual data from microphone and another channel is suppose to receive 0, it's different data in two channels, you need to choose I2S_CHANNEL_FMT_RIGHT_LEFT in this case. */ -#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 4, 0)) && (ESP_IDF_VERSION <= ESP_IDF_VERSION_VAL(4, 4, 4)) +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 4, 0)) && (ESP_IDF_VERSION <= ESP_IDF_VERSION_VAL(4, 4, 6)) // espressif bug: only_left has no sound, left and right are swapped // https://github.com/espressif/esp-idf/issues/9635 I2S mic not working since 4.4 (IDFGH-8138) // https://github.com/espressif/esp-idf/issues/8538 I2S channel selection issue? (IDFGH-6918) @@ -770,4 +770,4 @@ class SPH0654 : public I2SSource { #endif } }; -#endif \ No newline at end of file +#endif diff --git a/usermods/audioreactive/readme.md b/usermods/audioreactive/readme.md index 47804b611..4668ca881 100644 --- a/usermods/audioreactive/readme.md +++ b/usermods/audioreactive/readme.md @@ -27,18 +27,11 @@ Currently ESP8266 is not supported, due to low speed and small RAM of this chip. There are however plans to create a lightweight audioreactive for the 8266, with reduced features. ## Installation -### using customised _arduinoFFT_ library for use with this usermod -Add `-D USERMOD_AUDIOREACTIVE` to your PlatformIO environment `build_flags`, as well as `https://github.com/blazoncek/arduinoFFT.git` to your `lib_deps`. -If you are not using PlatformIO (which you should) try adding `#define USERMOD_AUDIOREACTIVE` to *my_config.h* and make sure you have _arduinoFFT_ library downloaded and installed. +### using latest _arduinoFFT_ library version 2.x +The latest arduinoFFT release version should be used for audioreactive. -Customised _arduinoFFT_ library for use with this usermod can be found at https://github.com/blazoncek/arduinoFFT.git - -### using latest (develop) _arduinoFFT_ library -Alternatively, you can use the latest arduinoFFT development version. -ArduinoFFT `develop` library is slightly more accurate, and slightly faster than our customised library, however also needs additional 2kB RAM. - -* `build_flags` = `-D USERMOD_AUDIOREACTIVE` `-D UM_AUDIOREACTIVE_USE_NEW_FFT` -* `lib_deps`= `https://github.com/kosme/arduinoFFT#develop @ 1.9.2` +* `build_flags` = `-D USERMOD_AUDIOREACTIVE` +* `lib_deps`= `kosme/arduinoFFT @ 2.0.1` ## Configuration diff --git a/usermods/multi_relay/usermod_multi_relay.h b/usermods/multi_relay/usermod_multi_relay.h index cb1eec8e1..efb3c8ae1 100644 --- a/usermods/multi_relay/usermod_multi_relay.h +++ b/usermods/multi_relay/usermod_multi_relay.h @@ -667,7 +667,7 @@ void MultiRelay::addToJsonInfo(JsonObject &root) { for (int i=0; i= 1) + unsigned width = virtualWidth(); // segment width in logical pixels (can be 0 if segment is inactive) + unsigned height = virtualHeight(); // segment height in logical pixels (is always >= 1) return isActive() ? (x%width) + (y%height) * width : 0; } @@ -175,16 +175,12 @@ void IRAM_ATTR Segment::setPixelColorXY(int x, int y, uint32_t col) uint8_t _bri_t = currentBri(); if (_bri_t < 255) { - byte r = scale8(R(col), _bri_t); - byte g = scale8(G(col), _bri_t); - byte b = scale8(B(col), _bri_t); - byte w = scale8(W(col), _bri_t); - col = RGBW32(r, g, b, w); + col = color_fade(col, _bri_t); } if (reverse ) x = virtualWidth() - x - 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) { unsigned t = x; x = y; y = t; } // swap X & Y if segment transposed x *= groupLength(); // expand to physical pixels y *= groupLength(); // expand to physical pixels @@ -193,7 +189,7 @@ void IRAM_ATTR Segment::setPixelColorXY(int x, int y, uint32_t col) uint32_t tmpCol = col; for (int j = 0; j < grouping; j++) { // groupping vertically for (int g = 0; g < grouping; g++) { // groupping horizontally - uint16_t xX = (x+g), yY = (y+j); + unsigned xX = (x+g), yY = (y+j); if (xX >= width() || yY >= height()) continue; // we have reached one dimension's end #ifndef WLED_DISABLE_MODE_BLEND @@ -225,16 +221,16 @@ void Segment::setPixelColorXY(float x, float y, uint32_t col, bool aa) if (!isActive()) return; // not active if (x<0.0f || x>1.0f || y<0.0f || y>1.0f) return; // not normalized - const uint16_t cols = virtualWidth(); - const uint16_t rows = virtualHeight(); + const unsigned cols = virtualWidth(); + const unsigned rows = virtualHeight(); float fX = x * (cols-1); float fY = y * (rows-1); if (aa) { - uint16_t xL = roundf(fX-0.49f); - uint16_t xR = roundf(fX+0.49f); - uint16_t yT = roundf(fY-0.49f); - uint16_t yB = roundf(fY+0.49f); + unsigned xL = roundf(fX-0.49f); + unsigned xR = roundf(fX+0.49f); + unsigned yT = roundf(fY-0.49f); + unsigned yB = roundf(fY+0.49f); float dL = (fX - xL)*(fX - xL); float dR = (xR - fX)*(xR - fX); float dT = (fY - yT)*(fY - yT); @@ -265,12 +261,12 @@ void Segment::setPixelColorXY(float x, float y, uint32_t col, bool aa) #endif // returns RGBW values of pixel -uint32_t IRAM_ATTR Segment::getPixelColorXY(uint16_t x, uint16_t y) { +uint32_t IRAM_ATTR Segment::getPixelColorXY(int x, int y) { if (!isActive()) return 0; // not active 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_y) y = virtualHeight() - y - 1; - if (transpose) { uint16_t t = x; x = y; y = t; } // swap X & Y if segment transposed + if (transpose) { unsigned t = x; x = y; y = t; } // swap X & Y if segment transposed x *= groupLength(); // expand to physical pixels y *= groupLength(); // expand to physical pixels if (x >= width() || y >= height()) return 0; @@ -278,92 +274,102 @@ uint32_t IRAM_ATTR Segment::getPixelColorXY(uint16_t x, uint16_t y) { } // blurRow: perform a blur on a row of a rectangular matrix -void Segment::blurRow(uint16_t row, fract8 blur_amount) { +void Segment::blurRow(uint32_t row, fract8 blur_amount, bool smear){ if (!isActive() || blur_amount == 0) return; // not active - const uint_fast16_t cols = virtualWidth(); - const uint_fast16_t rows = virtualHeight(); + const unsigned cols = virtualWidth(); + const unsigned rows = virtualHeight(); if (row >= rows) return; // blur one row - uint8_t keep = 255 - blur_amount; + uint8_t keep = smear ? 255 : 255 - blur_amount; uint8_t seep = blur_amount >> 1; - CRGB carryover = CRGB::Black; + uint32_t carryover = BLACK; + uint32_t lastnew; + uint32_t last; + uint32_t curnew = BLACK; for (unsigned x = 0; x < cols; x++) { - CRGB cur = getPixelColorXY(x, row); - CRGB before = cur; // remember color before blur - CRGB part = cur; - part.nscale8(seep); - cur.nscale8(keep); - cur += carryover; - if (x>0) { - CRGB prev = CRGB(getPixelColorXY(x-1, row)) + part; - setPixelColorXY(x-1, row, prev); - } - if (before != cur) // optimization: only set pixel if color has changed - setPixelColorXY(x, row, cur); + uint32_t cur = getPixelColorXY(x, row); + uint32_t part = color_fade(cur, seep); + curnew = color_fade(cur, keep); + if (x > 0) { + if (carryover) + curnew = color_add(curnew, carryover, true); + uint32_t prev = color_add(lastnew, part, true); + if (last != prev) // optimization: only set pixel if color has changed + setPixelColorXY(x - 1, row, prev); + } else // first pixel + setPixelColorXY(x, row, curnew); + lastnew = curnew; + last = cur; // save original value for comparison on next iteration carryover = part; } + setPixelColorXY(cols-1, row, curnew); // set last pixel } // blurCol: perform a blur on a column of a rectangular matrix -void Segment::blurCol(uint16_t col, fract8 blur_amount) { +void Segment::blurCol(uint32_t col, fract8 blur_amount, bool smear) { if (!isActive() || blur_amount == 0) return; // not active - const uint_fast16_t cols = virtualWidth(); - const uint_fast16_t rows = virtualHeight(); + const unsigned cols = virtualWidth(); + const unsigned rows = virtualHeight(); if (col >= cols) return; // blur one column - uint8_t keep = 255 - blur_amount; + uint8_t keep = smear ? 255 : 255 - blur_amount; uint8_t seep = blur_amount >> 1; - CRGB carryover = CRGB::Black; + uint32_t carryover = BLACK; + uint32_t lastnew; + uint32_t last; + uint32_t curnew = BLACK; for (unsigned y = 0; y < rows; y++) { - CRGB cur = getPixelColorXY(col, y); - CRGB part = cur; - CRGB before = cur; // remember color before blur - part.nscale8(seep); - cur.nscale8(keep); - cur += carryover; - if (y>0) { - CRGB prev = CRGB(getPixelColorXY(col, y-1)) + part; - setPixelColorXY(col, y-1, prev); - } - if (before != cur) // optimization: only set pixel if color has changed - setPixelColorXY(col, y, cur); - carryover = part; + uint32_t cur = getPixelColorXY(col, y); + uint32_t part = color_fade(cur, seep); + curnew = color_fade(cur, keep); + if (y > 0) { + if (carryover) + curnew = color_add(curnew, carryover, true); + uint32_t prev = color_add(lastnew, part, true); + if (last != prev) // optimization: only set pixel if color has changed + setPixelColorXY(col, y - 1, prev); + } else // first pixel + setPixelColorXY(col, y, curnew); + lastnew = curnew; + last = cur; //save original value for comparison on next iteration + carryover = part; } + setPixelColorXY(col, rows - 1, curnew); } // 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) { if (!isActive() || blur_amount == 0) return; // not active - const uint16_t cols = virtualWidth(); - const uint16_t rows = virtualHeight(); - const uint16_t dim1 = vertical ? rows : cols; - const uint16_t dim2 = vertical ? cols : rows; + const unsigned cols = virtualWidth(); + const unsigned rows = virtualHeight(); + const unsigned dim1 = vertical ? rows : cols; + const unsigned dim2 = vertical ? cols : rows; if (i >= dim2) return; const float seep = blur_amount/255.f; const float keep = 3.f - 2.f*seep; // 1D box blur CRGB tmp[dim1]; - for (int j = 0; j < dim1; j++) { - uint16_t x = vertical ? i : j; - uint16_t y = vertical ? j : i; - int16_t xp = vertical ? x : x-1; // "signed" to prevent underflow - int16_t yp = vertical ? y-1 : y; // "signed" to prevent underflow - uint16_t xn = vertical ? x : x+1; - uint16_t yn = vertical ? y+1 : y; + for (unsigned j = 0; j < dim1; j++) { + unsigned x = vertical ? i : j; + unsigned y = vertical ? j : i; + int xp = vertical ? x : x-1; // "signed" to prevent underflow + int yp = vertical ? y-1 : y; // "signed" to prevent underflow + unsigned xn = vertical ? x : x+1; + unsigned yn = vertical ? y+1 : y; CRGB curr = getPixelColorXY(x,y); CRGB prev = (xp<0 || yp<0) ? CRGB::Black : getPixelColorXY(xp,yp); CRGB next = ((vertical && yn>=dim1) || (!vertical && xn>=dim1)) ? CRGB::Black : getPixelColorXY(xn,yn); - uint16_t r, g, b; + unsigned r, g, b; r = (curr.r*keep + (prev.r + next.r)*seep) / 3; g = (curr.g*keep + (prev.g + next.g)*seep) / 3; b = (curr.b*keep + (prev.b + next.b)*seep) / 3; tmp[j] = CRGB(r,g,b); } - for (int j = 0; j < dim1; j++) { - uint16_t x = vertical ? i : j; - uint16_t y = vertical ? j : i; + for (unsigned j = 0; j < dim1; j++) { + unsigned x = vertical ? i : j; + unsigned y = vertical ? j : i; setPixelColorXY(x, y, tmp[j]); } } @@ -383,14 +389,14 @@ void Segment::box_blur(uint16_t i, bool vertical, fract8 blur_amount) { // it can be used to (slowly) clear the LEDs to black. void Segment::blur1d(fract8 blur_amount) { - const uint16_t rows = virtualHeight(); + const unsigned rows = virtualHeight(); for (unsigned y = 0; y < rows; y++) blurRow(y, blur_amount); } void Segment::moveX(int8_t delta, bool wrap) { if (!isActive()) return; // not active - const uint16_t cols = virtualWidth(); - const uint16_t rows = virtualHeight(); + const int cols = virtualWidth(); + const int rows = virtualHeight(); if (!delta || abs(delta) >= cols) return; uint32_t newPxCol[cols]; for (int y = 0; y < rows; y++) { @@ -407,8 +413,8 @@ void Segment::moveX(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 rows = virtualHeight(); + const int cols = virtualWidth(); + const int rows = virtualHeight(); if (!delta || abs(delta) >= rows) return; uint32_t newPxCol[rows]; for (int x = 0; x < cols; x++) { @@ -468,13 +474,13 @@ 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 void Segment::fill_circle(uint16_t cx, uint16_t cy, uint8_t radius, CRGB col) { if (!isActive() || radius == 0) return; // not active - const uint16_t cols = virtualWidth(); - const uint16_t rows = virtualHeight(); - for (int16_t y = -radius; y <= radius; y++) { - for (int16_t x = -radius; x <= radius; x++) { + const int cols = virtualWidth(); + const int rows = virtualHeight(); + for (int y = -radius; y <= radius; y++) { + for (int x = -radius; x <= radius; x++) { if (x * x + y * y <= radius * radius && - int16_t(cx)+x>=0 && int16_t(cy)+y>=0 && - int16_t(cx)+x=0 && int(cy)+y>=0 && + int(cx)+x= cols || x1 >= cols || y0 >= rows || y1 >= rows) return; - const int16_t dx = abs(x1-x0), sx = x0dy ? dx : -dy)/2, e2; + const int dx = abs(x1-x0), sx = x0dy ? dx : -dy)/2, e2; for (;;) { setPixelColorXY(x0,y0,c); if (x0==x1 && y0==y1) break; @@ -519,8 +525,8 @@ void Segment::drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, if (!isActive()) return; // not active if (chr < 32 || chr > 126) return; // only ASCII 32-126 supported chr -= 32; // align with font table entries - const uint16_t cols = virtualWidth(); - const uint16_t rows = virtualHeight(); + const int cols = virtualWidth(); + const int rows = virtualHeight(); const int font = w*h; CRGB col = CRGB(color); @@ -559,7 +565,7 @@ void Segment::drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, 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 - uint8_t xx = x & 0xff, yy = y & 0xff, ix = 255 - xx, iy = 255 - yy; + unsigned xx = x & 0xff, yy = y & 0xff, ix = 255 - xx, iy = 255 - yy; // calculate the intensities for each affected pixel uint8_t wu[4] = {WU_WEIGHT(ix, iy), WU_WEIGHT(xx, iy), WU_WEIGHT(ix, yy), WU_WEIGHT(xx, yy)}; diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index 9ab1f578b..ce510f16e 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -327,7 +327,7 @@ void Segment::stopTransition() { } void Segment::handleTransition() { - uint16_t _progress = progress(); + unsigned _progress = progress(); if (_progress == 0xFFFFU) stopTransition(); } @@ -412,9 +412,9 @@ void Segment::restoreSegenv(tmpsegd_t &tmpSeg) { #endif uint8_t IRAM_ATTR Segment::currentBri(bool useCct) { - uint32_t prog = progress(); + unsigned prog = progress(); if (prog < 0xFFFFU) { - uint32_t curBri = (useCct ? cct : (on ? opacity : 0)) * prog; + unsigned curBri = (useCct ? cct : (on ? opacity : 0)) * prog; curBri += (useCct ? _t->_cctT : _t->_briT) * (0xFFFFU - prog); return curBri / 0xFFFFU; } @@ -423,7 +423,7 @@ uint8_t IRAM_ATTR Segment::currentBri(bool useCct) { uint8_t IRAM_ATTR Segment::currentMode() { #ifndef WLED_DISABLE_MODE_BLEND - uint16_t prog = progress(); + unsigned prog = progress(); if (modeBlending && prog < 0xFFFFU) return _t->_modeT; #endif return mode; @@ -440,13 +440,13 @@ uint32_t IRAM_ATTR Segment::currentColor(uint8_t slot) { CRGBPalette16 IRAM_ATTR &Segment::currentPalette(CRGBPalette16 &targetPalette, uint8_t pal) { loadPalette(targetPalette, pal); - uint16_t prog = progress(); + unsigned prog = progress(); if (strip.paletteFade && prog < 0xFFFFU) { // blend palettes // 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 - uint16_t noOfBlends = ((255U * prog) / 0xFFFFU) - _t->_prevPaletteBlends; - for (int i=0; i_prevPaletteBlends++) nblendPaletteTowardPalette(_t->_palT, targetPalette, 48); + unsigned noOfBlends = ((255U * prog) / 0xFFFFU) - _t->_prevPaletteBlends; + for (unsigned i=0; i_prevPaletteBlends++) nblendPaletteTowardPalette(_t->_palT, targetPalette, 48); targetPalette = _t->_palT; // copy transitioning/temporary palette } return targetPalette; @@ -576,7 +576,7 @@ void Segment::setMode(uint8_t fx, bool loadDefaults) { mode = fx; // load default values from effect string if (loadDefaults) { - int16_t sOpt; + int sOpt; sOpt = extractModeDefaults(fx, "sx"); speed = (sOpt >= 0) ? sOpt : DEFAULT_SPEED; sOpt = extractModeDefaults(fx, "ix"); intensity = (sOpt >= 0) ? sOpt : DEFAULT_INTENSITY; sOpt = extractModeDefaults(fx, "c1"); custom1 = (sOpt >= 0) ? sOpt : DEFAULT_C1; @@ -610,21 +610,21 @@ void Segment::setPalette(uint8_t pal) { // 2D matrix uint16_t IRAM_ATTR Segment::virtualWidth() const { - uint16_t groupLen = groupLength(); - uint16_t vWidth = ((transpose ? height() : width()) + groupLen - 1) / groupLen; + unsigned groupLen = groupLength(); + unsigned vWidth = ((transpose ? height() : width()) + groupLen - 1) / groupLen; if (mirror) vWidth = (vWidth + 1) /2; // divide by 2 if mirror, leave at least a single LED return vWidth; } uint16_t IRAM_ATTR Segment::virtualHeight() const { - uint16_t groupLen = groupLength(); - uint16_t vHeight = ((transpose ? width() : height()) + groupLen - 1) / groupLen; + unsigned groupLen = groupLength(); + unsigned vHeight = ((transpose ? width() : height()) + groupLen - 1) / groupLen; if (mirror_y) vHeight = (vHeight + 1) /2; // divide by 2 if mirror, leave at least a single LED return vHeight; } uint16_t IRAM_ATTR Segment::nrOfVStrips() const { - uint16_t vLen = 1; + unsigned vLen = 1; #ifndef WLED_DISABLE_2D if (is2D()) { switch (map1D2D) { @@ -641,9 +641,9 @@ uint16_t IRAM_ATTR Segment::nrOfVStrips() const { uint16_t IRAM_ATTR Segment::virtualLength() const { #ifndef WLED_DISABLE_2D if (is2D()) { - uint16_t vW = virtualWidth(); - uint16_t vH = virtualHeight(); - uint16_t vLen = vW * vH; // use all pixels from segment + unsigned vW = virtualWidth(); + unsigned vH = virtualHeight(); + unsigned vLen = vW * vH; // use all pixels from segment switch (map1D2D) { case M12_pBar: vLen = vH; @@ -656,8 +656,8 @@ uint16_t IRAM_ATTR Segment::virtualLength() const { return vLen; } #endif - uint16_t groupLen = groupLength(); // is always >= 1 - uint16_t vLength = (length() + groupLen - 1) / groupLen; + unsigned groupLen = groupLength(); // is always >= 1 + unsigned vLength = (length() + groupLen - 1) / groupLen; if (mirror) vLength = (vLength + 1) /2; // divide by 2 if mirror, leave at least a single LED return vLength; } @@ -674,8 +674,8 @@ void IRAM_ATTR Segment::setPixelColor(int i, uint32_t col) #ifndef WLED_DISABLE_2D if (is2D()) { - uint16_t vH = virtualHeight(); // segment height in logical pixels - uint16_t vW = virtualWidth(); + int vH = virtualHeight(); // segment height in logical pixels + int vW = virtualWidth(); switch (map1D2D) { case M12_Pixels: // use all available pixels as a long strip @@ -732,14 +732,10 @@ void IRAM_ATTR Segment::setPixelColor(int i, uint32_t col) } #endif - uint16_t len = length(); + unsigned len = length(); uint8_t _bri_t = currentBri(); if (_bri_t < 255) { - byte r = scale8(R(col), _bri_t); - byte g = scale8(G(col), _bri_t); - byte b = scale8(B(col), _bri_t); - byte w = scale8(W(col), _bri_t); - col = RGBW32(r, g, b, w); + col = color_fade(col, _bri_t); } // expand pixel (taking into account start, grouping, spacing [and offset]) @@ -789,8 +785,8 @@ void Segment::setPixelColor(float i, uint32_t col, bool aa) float fC = i * (virtualLength()-1); if (aa) { - uint16_t iL = roundf(fC-0.49f); - uint16_t iR = roundf(fC+0.49f); + unsigned iL = roundf(fC-0.49f); + unsigned iR = roundf(fC+0.49f); float dL = (fC - iL)*(fC - iL); float dR = (iR - fC)*(iR - fC); uint32_t cIL = getPixelColor(iL | (vStrip<<16)); @@ -807,7 +803,7 @@ void Segment::setPixelColor(float i, uint32_t col, bool aa) setPixelColor(iL | (vStrip<<16), col); } } else { - setPixelColor(uint16_t(roundf(fC)) | (vStrip<<16), col); + setPixelColor(int(roundf(fC)) | (vStrip<<16), col); } } #endif @@ -822,8 +818,8 @@ uint32_t IRAM_ATTR Segment::getPixelColor(int i) #ifndef WLED_DISABLE_2D if (is2D()) { - uint16_t vH = virtualHeight(); // segment height in logical pixels - uint16_t vW = virtualWidth(); + unsigned vH = virtualHeight(); // segment height in logical pixels + unsigned vW = virtualWidth(); switch (map1D2D) { case M12_Pixels: return getPixelColorXY(i % vW, i / vW); @@ -879,9 +875,9 @@ uint8_t Segment::differs(Segment& b) const { } void Segment::refreshLightCapabilities() { - uint8_t capabilities = 0; - uint16_t segStartIdx = 0xFFFFU; - uint16_t segStopIdx = 0; + unsigned capabilities = 0; + unsigned segStartIdx = 0xFFFFU; + unsigned segStopIdx = 0; if (!isActive()) { _capabilities = 0; @@ -891,7 +887,7 @@ void Segment::refreshLightCapabilities() { if (start < Segment::maxWidth * Segment::maxHeight) { // we are withing 2D matrix (includes 1D segments) for (int y = startY; y < stopY; y++) for (int x = start; x < stop; x++) { - uint16_t index = strip.getMappedPixelIndex(x + Segment::maxWidth * y); // convert logical address to physical + unsigned index = strip.getMappedPixelIndex(x + Segment::maxWidth * y); // convert logical address to physical if (index < 0xFFFFU) { if (segStartIdx > index) segStartIdx = index; if (segStopIdx < index) segStopIdx = index; @@ -916,7 +912,7 @@ void Segment::refreshLightCapabilities() { if (!cctFromRgb && bus->hasCCT()) capabilities |= SEG_CAPABILITY_CCT; if (correctWB && (bus->hasRGB() || bus->hasCCT())) capabilities |= SEG_CAPABILITY_CCT; //white balance correction (CCT slider) if (bus->hasWhite()) { - uint8_t aWM = Bus::getGlobalAWMode() == AW_GLOBAL_DISABLED ? bus->getAutoWhiteMode() : Bus::getGlobalAWMode(); + unsigned aWM = Bus::getGlobalAWMode() == AW_GLOBAL_DISABLED ? bus->getAutoWhiteMode() : Bus::getGlobalAWMode(); bool whiteSlider = (aWM == RGBW_MODE_DUAL || aWM == RGBW_MODE_MANUAL_ONLY); // white slider allowed // if auto white calculation from RGB is active (Accurate/Brighter), force RGB controls even if there are no RGB busses if (!whiteSlider) capabilities |= SEG_CAPABILITY_RGB; @@ -932,8 +928,8 @@ void Segment::refreshLightCapabilities() { */ void Segment::fill(uint32_t c) { if (!isActive()) return; // not active - const uint16_t cols = is2D() ? virtualWidth() : virtualLength(); - const uint16_t rows = virtualHeight(); // will be 1 for 1D + const int cols = is2D() ? virtualWidth() : virtualLength(); + const int rows = virtualHeight(); // will be 1 for 1D for (int y = 0; y < rows; y++) for (int x = 0; x < cols; x++) { if (is2D()) setPixelColorXY(x, y, c); else setPixelColor(x, c); @@ -945,8 +941,8 @@ void Segment::fill(uint32_t c) { */ void Segment::fade_out(uint8_t rate) { if (!isActive()) return; // not active - const uint16_t cols = is2D() ? virtualWidth() : virtualLength(); - const uint16_t rows = virtualHeight(); // will be 1 for 1D + const int cols = is2D() ? virtualWidth() : virtualLength(); + const int rows = virtualHeight(); // will be 1 for 1D rate = (255-rate) >> 1; float mappedRate = float(rate) +1.1f; @@ -983,8 +979,8 @@ void Segment::fade_out(uint8_t rate) { // fades all pixels to black using nscale8() void Segment::fadeToBlackBy(uint8_t fadeBy) { if (!isActive() || fadeBy == 0) return; // optimization - no scaling to apply - const uint16_t cols = is2D() ? virtualWidth() : virtualLength(); - const uint16_t rows = virtualHeight(); // will be 1 for 1D + const int cols = is2D() ? virtualWidth() : virtualLength(); + const int rows = virtualHeight(); // will be 1 for 1D for (int y = 0; y < rows; y++) for (int x = 0; x < cols; x++) { if (is2D()) setPixelColorXY(x, y, color_fade(getPixelColorXY(x,y), 255-fadeBy)); @@ -995,33 +991,43 @@ void Segment::fadeToBlackBy(uint8_t fadeBy) { /* * blurs segment content, source: FastLED colorutils.cpp */ -void Segment::blur(uint8_t blur_amount) { +void Segment::blur(uint8_t blur_amount, bool smear) { if (!isActive() || blur_amount == 0) return; // optimization: 0 means "don't blur" #ifndef WLED_DISABLE_2D if (is2D()) { // compatibility with 2D const unsigned cols = virtualWidth(); const unsigned rows = virtualHeight(); - for (unsigned i = 0; i < rows; i++) blurRow(i, blur_amount); // blur all rows - for (unsigned k = 0; k < cols; k++) blurCol(k, blur_amount); // blur all columns + for (unsigned i = 0; i < rows; i++) blurRow(i, blur_amount, smear); // blur all rows + for (unsigned k = 0; k < cols; k++) blurCol(k, blur_amount, smear); // blur all columns return; } #endif - uint8_t keep = 255 - blur_amount; + uint8_t keep = smear ? 255 : 255 - blur_amount; uint8_t seep = blur_amount >> 1; - uint32_t carryover = BLACK; unsigned vlength = virtualLength(); + uint32_t carryover = BLACK; + uint32_t lastnew; + uint32_t last; + uint32_t curnew = BLACK; for (unsigned i = 0; i < vlength; i++) { uint32_t cur = getPixelColor(i); uint32_t part = color_fade(cur, seep); - cur = color_add(color_fade(cur, keep), carryover, true); + curnew = color_fade(cur, keep); if (i > 0) { - uint32_t c = getPixelColor(i-1); - setPixelColor(i-1, color_add(c, part, true)); + if (carryover) + curnew = color_add(curnew, carryover, true); + uint32_t prev = color_add(lastnew, part, true); + if (last != prev) // optimization: only set pixel if color has changed + setPixelColor(i - 1, prev); } - setPixelColor(i, cur); + else // first pixel + setPixelColor(i, curnew); + lastnew = curnew; + last = cur; // save original value for comparison on next iteration carryover = part; } + setPixelColor(vlength - 1, curnew); } /* @@ -1059,7 +1065,7 @@ uint32_t Segment::color_from_palette(uint16_t i, bool mapping, bool wrap, uint8_ // default palette or no RGB support on segment if ((palette == 0 && mcol < NUM_COLORS) || !_isRGB) return (pbri == 255) ? color : color_fade(color, pbri, true); - uint8_t paletteIndex = i; + unsigned paletteIndex = i; if (mapping && virtualLength() > 1) paletteIndex = (i*255)/(virtualLength() -1); // paletteBlend: 0 - wrap when moving, 1 - always wrap, 2 - never wrap, 3 - none (undefined) if (!wrap && strip.paletteBlend != 3) paletteIndex = scale8(paletteIndex, 240); //cut off blend at palette "end" @@ -1093,21 +1099,24 @@ void WS2812FX::finalizeInit(void) { //if busses failed to load, add default (fresh install, FS issue, ...) if (BusManager::getNumBusses() == 0) { DEBUG_PRINTLN(F("No busses, init default")); - const uint8_t defDataPins[] = {DATA_PINS}; - const uint16_t defCounts[] = {PIXEL_COUNTS}; - const uint8_t defNumBusses = ((sizeof defDataPins) / (sizeof defDataPins[0])); - const uint8_t defNumCounts = ((sizeof defCounts) / (sizeof defCounts[0])); - uint16_t prevLen = 0; - for (int i = 0; i < defNumBusses && i < WLED_MAX_BUSSES+WLED_MIN_VIRTUAL_BUSSES; i++) { - uint8_t defPin[] = {defDataPins[i]}; + const unsigned defDataPins[] = {DATA_PINS}; + const unsigned defCounts[] = {PIXEL_COUNTS}; + const unsigned defNumPins = ((sizeof defDataPins) / (sizeof defDataPins[0])); + const unsigned defNumCounts = ((sizeof defCounts) / (sizeof defCounts[0])); + const unsigned defNumBusses = defNumPins > defNumCounts && defNumCounts > 1 && defNumPins%defNumCounts == 0 ? defNumCounts : defNumPins; + const unsigned pinsPerBus = defNumPins / defNumBusses; + unsigned prevLen = 0; + for (unsigned i = 0; i < defNumBusses && i < WLED_MAX_BUSSES+WLED_MIN_VIRTUAL_BUSSES; i++) { + uint8_t defPin[5]; // max 5 pins + for (unsigned j = 0; j < pinsPerBus; j++) defPin[j] = defDataPins[i*pinsPerBus + j]; // when booting without config (1st boot) we need to make sure GPIOs defined for LED output don't clash with hardware // i.e. DEBUG (GPIO1), DMX (2), SPI RAM/FLASH (16&17 on ESP32-WROVER/PICO), etc if (pinManager.isPinAllocated(defPin[0])) { defPin[0] = 1; // start with GPIO1 and work upwards while (pinManager.isPinAllocated(defPin[0]) && defPin[0] < WLED_NUM_PINS) defPin[0]++; } - uint16_t start = prevLen; - uint16_t count = defCounts[(i < defNumCounts) ? i : defNumCounts -1]; + unsigned start = prevLen; + unsigned count = defCounts[(i < defNumCounts) ? i : defNumCounts -1]; prevLen += count; BusConfig defCfg = BusConfig(DEFAULT_LED_TYPE, defPin, start, count, DEFAULT_LED_COLOR_ORDER, false, 0, RGBW_MODE_MANUAL_ONLY); if (BusManager::add(defCfg) == -1) break; @@ -1123,7 +1132,7 @@ void WS2812FX::finalizeInit(void) { _hasWhiteChannel |= bus->hasWhite(); //refresh is required to remain off if at least one of the strips requires the refresh. _isOffRefreshRequired |= bus->isOffRefreshRequired(); - uint16_t busEnd = bus->getStart() + bus->getLength(); + unsigned busEnd = bus->getStart() + bus->getLength(); if (busEnd > _length) _length = busEnd; #ifdef ESP8266 if ((!IS_DIGITAL(bus->getType()) || IS_2PIN(bus->getType()))) continue; @@ -1167,10 +1176,10 @@ void WS2812FX::service() { if (nowUp > seg.next_time || _triggered || (doShow && seg.mode == FX_MODE_STATIC)) { doShow = true; - uint16_t delay = FRAMETIME; + unsigned delay = FRAMETIME; if (!seg.freeze) { //only run effect function if not frozen - int16_t oldCCT = BusManager::getSegmentCCT(); // store original CCT value (actually it is not Segment based) + int oldCCT = BusManager::getSegmentCCT(); // store original CCT value (actually it is not Segment based) _virtualSegmentLength = seg.virtualLength(); //SEGLEN _colors_t[0] = gamma32(seg.currentColor(0)); _colors_t[1] = gamma32(seg.currentColor(1)); @@ -1194,7 +1203,7 @@ void WS2812FX::service() { Segment::modeBlend(true); // set semaphore seg.swapSegenv(_tmpSegData); // temporarily store new mode state (and swap it with transitional state) _virtualSegmentLength = seg.virtualLength(); // update SEGLEN (mapping may have changed) - uint16_t d2 = (*_mode[tmpMode])(); // run old mode + unsigned d2 = (*_mode[tmpMode])(); // run old mode seg.restoreSegenv(_tmpSegData); // restore mode state (will also update transitional state) delay = MIN(delay,d2); // use shortest delay Segment::modeBlend(false); // unset semaphore @@ -1369,13 +1378,13 @@ uint8_t WS2812FX::getActiveSegmentsNum(void) { } uint16_t WS2812FX::getLengthTotal(void) { - uint16_t len = Segment::maxWidth * Segment::maxHeight; // will be _length for 1D (see finalizeInit()) but should cover whole matrix for 2D + unsigned len = Segment::maxWidth * Segment::maxHeight; // will be _length for 1D (see finalizeInit()) but should cover whole matrix for 2D if (isMatrix && _length > len) len = _length; // for 2D with trailing strip return len; } uint16_t WS2812FX::getLengthPhysical(void) { - uint16_t len = 0; + unsigned len = 0; for (size_t b = 0; b < BusManager::getNumBusses(); b++) { Bus *bus = BusManager::getBus(b); if (bus->getType() >= TYPE_NET_DDP_RGB) continue; //exclude non-physical network busses @@ -1452,8 +1461,8 @@ void WS2812FX::resetSegments() { void WS2812FX::makeAutoSegments(bool forceReset) { if (autoSegments) { //make one segment per bus - uint16_t segStarts[MAX_NUM_SEGMENTS] = {0}; - uint16_t segStops [MAX_NUM_SEGMENTS] = {0}; + unsigned segStarts[MAX_NUM_SEGMENTS] = {0}; + unsigned segStops [MAX_NUM_SEGMENTS] = {0}; size_t s = 0; #ifndef WLED_DISABLE_2D @@ -1658,12 +1667,18 @@ bool WS2812FX::deserializeMap(uint8_t n) { return false; // if file does not load properly then exit } + JsonObject root = pDoc->as(); + // if we are loading default ledmap (at boot) set matrix width and height from the ledmap (compatible with WLED MM ledmaps) + if (isMatrix && n == 0 && (!root[F("width")].isNull() || !root[F("height")].isNull())) { + Segment::maxWidth = min(max(root[F("width")].as(), 1), 128); + Segment::maxHeight = min(max(root[F("height")].as(), 1), 128); + } + if (customMappingTable) delete[] customMappingTable; customMappingTable = new uint16_t[getLengthTotal()]; if (customMappingTable) { DEBUG_PRINT(F("Reading LED map from ")); DEBUG_PRINTLN(fileName); - JsonObject root = pDoc->as(); JsonArray map = root[F("map")]; if (!map.isNull() && map.size()) { // not an empty map customMappingSize = min((unsigned)map.size(), (unsigned)getLengthTotal()); diff --git a/wled00/bus_manager.cpp b/wled00/bus_manager.cpp index 82e81a387..ac6923f40 100644 --- a/wled00/bus_manager.cpp +++ b/wled00/bus_manager.cpp @@ -466,7 +466,22 @@ void BusPwm::setPixelColor(uint16_t pix, uint32_t c) { //does no index check uint32_t BusPwm::getPixelColor(uint16_t pix) { if (!_valid) return 0; - return RGBW32(_data[0], _data[1], _data[2], _data[3]); + // TODO getting the reverse from CCT is involved (a quick approximation when CCT blending is ste to 0 implemented) + switch (_type) { + case TYPE_ANALOG_1CH: //one channel (white), relies on auto white calculation + return RGBW32(0, 0, 0, _data[0]); + case TYPE_ANALOG_2CH: //warm white + cold white + if (cctICused) return RGBW32(0, 0, 0, _data[0]); + else return RGBW32(0, 0, 0, _data[0] + _data[1]); + case TYPE_ANALOG_5CH: //RGB + warm white + cold white + if (cctICused) return RGBW32(_data[0], _data[1], _data[2], _data[3]); + else return RGBW32(_data[0], _data[1], _data[2], _data[3] + _data[4]); + case TYPE_ANALOG_4CH: //RGBW + return RGBW32(_data[0], _data[1], _data[2], _data[3]); + case TYPE_ANALOG_3CH: //standard dumb RGB + return RGBW32(_data[0], _data[1], _data[2], 0); + } + return RGBW32(_data[0], _data[0], _data[0], _data[0]); } #ifndef ESP8266 diff --git a/wled00/bus_wrapper.h b/wled00/bus_wrapper.h index 966a391c3..e383b17ed 100644 --- a/wled00/bus_wrapper.h +++ b/wled00/bus_wrapper.h @@ -538,6 +538,11 @@ class PolyBus { } static void* create(uint8_t busType, uint8_t* pins, uint16_t len, uint8_t channel, uint16_t clock_kHz = 0U) { + #if defined(ARDUINO_ARCH_ESP32) && !(defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32C3)) + // NOTE: "channel" is only used on ESP32 (and its variants) for RMT channel allocation + // since 0.15.0-b3 I2S1 is favoured for classic ESP32 and moved to position 0 (channel 0) so we need to subtract 1 for correct RMT allocation + if (channel > 1) channel--; // accommodate I2S1 which is used as 1st bus on classic ESP32 + #endif void* busPtr = nullptr; switch (busType) { case I_NONE: break; diff --git a/wled00/button.cpp b/wled00/button.cpp index ce47a17ac..3b73df81d 100644 --- a/wled00/button.cpp +++ b/wled00/button.cpp @@ -379,7 +379,7 @@ void handleIO() esp32RMTInvertIdle(); #endif if (rlyPin>=0) { - pinMode(rlyPin, OUTPUT); + pinMode(rlyPin, rlyOpenDrain ? OUTPUT_OPEN_DRAIN : OUTPUT); digitalWrite(rlyPin, rlyMde); } offMode = false; @@ -400,7 +400,7 @@ void handleIO() esp32RMTInvertIdle(); #endif if (rlyPin>=0) { - pinMode(rlyPin, OUTPUT); + pinMode(rlyPin, rlyOpenDrain ? OUTPUT_OPEN_DRAIN : OUTPUT); digitalWrite(rlyPin, !rlyMde); } } diff --git a/wled00/cfg.cpp b/wled00/cfg.cpp index 530777ab5..22bfe577a 100644 --- a/wled00/cfg.cpp +++ b/wled00/cfg.cpp @@ -335,12 +335,14 @@ bool deserializeConfig(JsonObject doc, bool fromFS) { CJSON(irApplyToAllSelected, hw["ir"]["sel"]); JsonObject relay = hw[F("relay")]; + + rlyOpenDrain = relay[F("odrain")] | rlyOpenDrain; int hw_relay_pin = relay["pin"] | -2; if (hw_relay_pin > -2) { pinManager.deallocatePin(rlyPin, PinOwner::Relay); if (pinManager.allocatePin(hw_relay_pin,true, PinOwner::Relay)) { rlyPin = hw_relay_pin; - pinMode(rlyPin, OUTPUT); + pinMode(rlyPin, rlyOpenDrain ? OUTPUT_OPEN_DRAIN : OUTPUT); } else { rlyPin = -1; } @@ -868,6 +870,7 @@ void serializeConfig() { JsonObject hw_relay = hw.createNestedObject(F("relay")); hw_relay["pin"] = rlyPin; hw_relay["rev"] = !rlyMde; + hw_relay[F("odrain")] = rlyOpenDrain; hw[F("baud")] = serialBaud; diff --git a/wled00/colors.cpp b/wled00/colors.cpp index 3ed54d959..30d2c069e 100644 --- a/wled00/colors.cpp +++ b/wled00/colors.cpp @@ -65,24 +65,30 @@ uint32_t color_add(uint32_t c1, uint32_t c2, bool fast) * fades color toward black * if using "video" method the resulting color will never become black unless it is already black */ + uint32_t color_fade(uint32_t c1, uint8_t amount, bool video) { - uint8_t r = R(c1); - uint8_t g = G(c1); - uint8_t b = B(c1); - uint8_t w = W(c1); - if (video) { - r = scale8_video(r, amount); - g = scale8_video(g, amount); - b = scale8_video(b, amount); - w = scale8_video(w, amount); - } else { - r = scale8(r, amount); - g = scale8(g, amount); - b = scale8(b, amount); - w = scale8(w, amount); + uint32_t scaledcolor; // color order is: W R G B from MSB to LSB + uint32_t r = R(c1); + uint32_t g = G(c1); + uint32_t b = B(c1); + uint32_t w = W(c1); + if (video) { + uint32_t scale = amount; // 32bit for faster calculation + scaledcolor = (((r * scale) >> 8) << 16) + ((r && scale) ? 1 : 0); + scaledcolor |= (((g * scale) >> 8) << 8) + ((g && scale) ? 1 : 0); + scaledcolor |= ((b * scale) >> 8) + ((b && scale) ? 1 : 0); + scaledcolor |= (((w * scale) >> 8) << 24) + ((w && scale) ? 1 : 0); + return scaledcolor; + } + else { + uint32_t scale = 1 + amount; + scaledcolor = ((r * scale) >> 8) << 16; + scaledcolor |= ((g * scale) >> 8) << 8; + scaledcolor |= (b * scale) >> 8; + scaledcolor |= ((w * scale) >> 8) << 24; + return scaledcolor; } - return RGBW32(r, g, b, w); } void setRandomColor(byte* rgb) diff --git a/wled00/data/index.css b/wled00/data/index.css index fa6e20077..6ac3f3a1f 100644 --- a/wled00/data/index.css +++ b/wled00/data/index.css @@ -358,7 +358,7 @@ button { #putil, #segutil, #segutil2 { min-height: 42px; - margin: 13px auto 0; + margin: 0 auto; } #segutil .segin { diff --git a/wled00/data/index.js b/wled00/data/index.js index 03ee276a8..bbf6bd109 100644 --- a/wled00/data/index.js +++ b/wled00/data/index.js @@ -430,7 +430,7 @@ function presetError(empty) if (bckstr.length > 10) hasBackup = true; } catch (e) {} - var cn = `
`; + var cn = `
`; if (empty) cn += `You have no presets yet!`; else @@ -442,8 +442,8 @@ function presetError(empty) cn += `However, there is backup preset data of a previous installation available.
(Saving a preset will hide this and overwrite the backup)`; else cn += `Here is a backup of the last known good state:`; - cn += `
`; - cn += `
`; + cn += `
`; + cn += `
`; } cn += `
`; gId('pcont').innerHTML = cn; @@ -863,14 +863,11 @@ function populateSegments(s) gId("segcont").classList.remove("hide"); let noNewSegs = (lowestUnused >= maxSeg); resetUtil(noNewSegs); - if (gId('selall')) gId('selall').checked = true; for (var i = 0; i <= lSeg; i++) { if (!gId(`seg${i}`)) continue; updateLen(i); updateTrail(gId(`seg${i}bri`)); gId(`segr${i}`).classList.add("hide"); - //if (i2) d.querySelectorAll(".pop").forEach((e)=>{e.classList.remove("hide");}); - var cd = gId('csl').querySelectorAll("button"); for (let e = cd.length-1; e >= 0; e--) { cd[e].dataset.r = i.col[e][0]; @@ -1838,7 +1833,7 @@ function makeSeg() }); var cn = `
`+ `
`+ - ``+ + ``+ ``+ ``+ ``+ @@ -1864,13 +1859,19 @@ function makeSeg() function resetUtil(off=false) { - gId('segutil').innerHTML = `
` + gId('segutil').innerHTML = `
` + '' + `
Add segment
` + '
' + `` + '
' + '
'; + gId('selall').checked = true; + for (var i = 0; i <= lSeg; i++) { + if (!gId(`seg${i}`)) continue; + if (!gId(`seg${i}sel`).checked) gId('selall').checked = false; // uncheck if at least one is unselected. + } + if (lSeg>2) d.querySelectorAll("#Segments .pop").forEach((e)=>{e.classList.remove("hide");}); } function makePlSel(el, incPl=false) diff --git a/wled00/data/settings_leds.htm b/wled00/data/settings_leds.htm index 1ab3374a0..e95e36a34 100644 --- a/wled00/data/settings_leds.htm +++ b/wled00/data/settings_leds.htm @@ -620,7 +620,8 @@ Swap: Apply IR change to main segment only:
IR info
- Relay GPIO: Invert  ✕
+ Relay GPIO:  ✕ Invert Open drain

Defaults

Turn LEDs on after power up/reset:
diff --git a/wled00/data/settings_wifi.htm b/wled00/data/settings_wifi.htm index 3577e80d2..3c15d5a86 100644 --- a/wled00/data/settings_wifi.htm +++ b/wled00/data/settings_wifi.htm @@ -52,40 +52,42 @@ } scanLoops = 0; - let cs = d.querySelectorAll("#wifi_entries input[type=text]"); - for (let input of (cs||[])) { - let found = false; - let select = cE("select"); - select.id = input.id; - select.name = input.name; - select.setAttribute("onchange", "T(this)"); - preScanSSID = input.value; + if (networks.length > 0) { + let cs = d.querySelectorAll("#wifi_entries input[type=text]"); + for (let input of (cs||[])) { + let found = false; + let select = cE("select"); + select.id = input.id; + select.name = input.name; + select.setAttribute("onchange", "T(this)"); + preScanSSID = input.value; - for (let i = 0; i < select.children.length; i++) { - select.removeChild(select.children[i]); - } - - for (let i = 0; i < networks.length; i++) { - const option = cE("option"); - - option.setAttribute("value", networks[i].ssid); - option.textContent = `${networks[i].ssid} (${networks[i].rssi} dBm)`; - - if (networks[i].ssid === input.value) { - option.setAttribute("selected", "selected"); - found = true; + for (let i = 0; i < select.children.length; i++) { + select.removeChild(select.children[i]); } + for (let i = 0; i < networks.length; i++) { + const option = cE("option"); + + option.setAttribute("value", networks[i].ssid); + option.textContent = `${networks[i].ssid} (${networks[i].rssi} dBm)`; + + if (networks[i].ssid === input.value) { + option.setAttribute("selected", "selected"); + found = true; + } + + select.appendChild(option); + } + const option = cE("option"); + + option.setAttribute("value", "!Cs"); + option.textContent = "Other network..."; select.appendChild(option); + + if (input.value === "" || input.value === "Your_Network" || found) input.replaceWith(select); + else select.remove(); } - const option = cE("option"); - - option.setAttribute("value", "!Cs"); - option.textContent = "Other network..."; - select.appendChild(option); - - if (input.value === "" || input.value === "Your_Network" || found) input.replaceWith(select); - else select.remove(); } button.disabled = false; diff --git a/wled00/json.cpp b/wled00/json.cpp index bc4d1808a..ae8224ad3 100644 --- a/wled00/json.cpp +++ b/wled00/json.cpp @@ -276,8 +276,8 @@ bool deserializeSegment(JsonObject elem, byte it, byte presetId) seg.fill(BLACK); } - uint16_t start = 0, stop = 0; - byte set = 0; //0 nothing set, 1 start set, 2 range set + start = 0, stop = 0; + set = 0; //0 nothing set, 1 start set, 2 range set for (size_t i = 0; i < iarr.size(); i++) { if(iarr[i].is()) { @@ -636,6 +636,7 @@ void serializeInfo(JsonObject root) root[F("ver")] = versionString; root[F("vid")] = VERSION; root[F("cn")] = F(WLED_CODENAME); + root[F("release")] = FPSTR(releaseString); JsonObject leds = root.createNestedObject(F("leds")); leds[F("count")] = strip.getLengthTotal(); diff --git a/wled00/set.cpp b/wled00/set.cpp index a2e884c81..d3382be18 100644 --- a/wled00/set.cpp +++ b/wled00/set.cpp @@ -243,6 +243,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage) rlyPin = -1; } rlyMde = (bool)request->hasArg(F("RM")); + rlyOpenDrain = (bool)request->hasArg(F("RO")); disablePullUp = (bool)request->hasArg(F("IP")); touchThreshold = request->arg(F("TT")).toInt(); diff --git a/wled00/wled.h b/wled00/wled.h index b94f7790b..139c451f8 100644 --- a/wled00/wled.h +++ b/wled00/wled.h @@ -243,27 +243,32 @@ using PSRAMDynamicJsonDocument = BasicJsonDocument; // int arr[]{0,1,2} becomes WLED_GLOBAL int arr[] _INIT_N(({0,1,2})); #ifndef WLED_DEFINE_GLOBAL_VARS -# define WLED_GLOBAL extern -# define _INIT(x) -# define _INIT_N(x) + #define WLED_GLOBAL extern + #define _INIT(x) + #define _INIT_N(x) + #define _INIT_PROGMEM(x) #else -# define WLED_GLOBAL -# define _INIT(x) = x - -//needed to ignore commas in array definitions -#define UNPACK( ... ) __VA_ARGS__ -# define _INIT_N(x) UNPACK x + #define WLED_GLOBAL + #define _INIT(x) = x + //needed to ignore commas in array definitions + #define UNPACK( ... ) __VA_ARGS__ + #define _INIT_N(x) UNPACK x + #define _INIT_PROGMEM(x) PROGMEM = x #endif #define STRINGIFY(X) #X #define TOSTRING(X) STRINGIFY(X) #ifndef WLED_VERSION - #define WLED_VERSION "dev" + #define WLED_VERSION dev +#endif +#ifndef WLED_RELEASE_NAME + #define WLED_RELEASE_NAME dev_release #endif // Global Variable definitions WLED_GLOBAL char versionString[] _INIT(TOSTRING(WLED_VERSION)); +WLED_GLOBAL char releaseString[] _INIT_PROGMEM(TOSTRING(WLED_RELEASE_NAME)); // somehow this will not work if using "const char releaseString[] #define WLED_CODENAME "Kōsen" // AP and OTA default passwords (for maximum security change them!) @@ -288,6 +293,12 @@ WLED_GLOBAL bool rlyMde _INIT(true); #else WLED_GLOBAL bool rlyMde _INIT(RLYMDE); #endif +//Use open drain (floating pin) when relay should be off +#ifndef RLYODRAIN +WLED_GLOBAL bool rlyOpenDrain _INIT(false); +#else +WLED_GLOBAL bool rlyOpenDrain _INIT(RLYODRAIN); +#endif #ifndef IRPIN #define IRPIN -1 #endif diff --git a/wled00/xml.cpp b/wled00/xml.cpp index 3915d9b0e..f44b6b894 100644 --- a/wled00/xml.cpp +++ b/wled00/xml.cpp @@ -458,6 +458,7 @@ void getSettingsJS(byte subPage, char* dest) sappend('i',SET_F("PB"),strip.paletteBlend); sappend('v',SET_F("RL"),rlyPin); sappend('c',SET_F("RM"),rlyMde); + sappend('c',SET_F("RO"),rlyOpenDrain); for (uint8_t i=0; i")); + oappend((char*)FPSTR(releaseString)); oappend(SET_F("
(")); #if defined(ARDUINO_ARCH_ESP32) oappend(ESP.getChipModel());
${isM?'Start X':'Start LED'}