kopia lustrzana https://github.com/Aircoookie/WLED
Porównaj commity
95 Commity
5ead284568
...
78f539ba22
Autor | SHA1 | Data |
---|---|---|
James Myatt | 78f539ba22 | |
Blaz Kristan | 6f3d7e76c9 | |
Frank | 57665e8964 | |
Blaz Kristan | 3e20724058 | |
Blaž Kristan | d126611e87 | |
Blaž Kristan | 1b75be5710 | |
Damian Schneider | 084fc2fcd1 | |
Damian Schneider | 459156fe57 | |
Blaz Kristan | 94cdd88474 | |
Blaz Kristan | 30435e6406 | |
Blaz Kristan | bd1c06a7a7 | |
Blaž Kristan | ff3cce0ed2 | |
Blaz Kristan | 38539aac74 | |
Blaz Kristan | 58e8346209 | |
Blaz Kristan | ba9ce4adf2 | |
Blaž Kristan | bd60fe5a13 | |
Blaž Kristan | b72f3baab7 | |
Blaž Kristan | d1d54ce9c8 | |
Blaž Kristan | 954f26308b | |
Blaž Kristan | 1cafa0b33f | |
Damian Schneider | 18c17168e1 | |
Damian Schneider | d3a97f1062 | |
Blaž Kristan | d18f078b1e | |
gaaat98 | 9ffcde878a | |
Blaz Kristan | aa970d6ca5 | |
Damian Schneider | 503c68320a | |
Blaz Kristan | a106342439 | |
Blaž Kristan | 3b0e6ec65c | |
Blaž Kristan | 8691ddc081 | |
Blaz Kristan | 24c5935661 | |
Woody | 78b37b592e | |
Woody | 4db88cf86b | |
Woody | a7e17eabff | |
Blaž Kristan | 93d9ce18b2 | |
Will Miles | 6f7ac93d84 | |
Carlos Cruz | fa5d60ca26 | |
Blaz Kristan | 20ed81cd86 | |
Blaž Kristan | 6f38874096 | |
Blaž Kristan | b7db5be4df | |
Blaz Kristan | 157dbffc59 | |
Blaz Kristan | f21ab3588d | |
Will Miles | 2900bda8f9 | |
Blaz Kristan | 5f37c19d42 | |
Woody | 6f6356e617 | |
Woody | 5d152baac0 | |
Woody | d7739f9764 | |
Woody | d6e73fde50 | |
Blaz Kristan | fd149b3f46 | |
Blaž Kristan | d1d45e7166 | |
Blaz Kristan | 4b19759dd6 | |
Blaz Kristan | 47f44680a3 | |
Woody | 0a344ada97 | |
Woody | 3b98d01f71 | |
Woody | 23d8000239 | |
Woody | c32ee40ca0 | |
Woody | 213f45494f | |
Frank | 85a51e6c42 | |
Blaz Kristan | ecfdc6f0a8 | |
Woody | 1c1c3fd832 | |
Woody | 7bafe995e5 | |
Blaž Kristan | 3c23672347 | |
thatdonfc | 33fe68d7eb | |
Blaz Kristan | b031fa1531 | |
Blaž Kristan | dab4dc3f41 | |
Blaž Kristan | 78096803ea | |
Blaž Kristan | f1987b9544 | |
Will Miles | 8b6bf08a23 | |
Will Miles | 2640203c88 | |
thatdonfc | 2dafa9644f | |
thatdonfc | 92ebeddcb0 | |
thatdonfc | ecee073e08 | |
thatdonfc | 6d1b9ffad2 | |
Woody | 7ee4b54154 | |
Woody | e3271b8082 | |
Woody | c6ff45f959 | |
Blaz Kristan | 7a9eff7f35 | |
Will Miles | 5f2480c3d9 | |
Will Miles | 0593a078c6 | |
Will Miles | 323c70dcdf | |
Will Miles | a1b0f84444 | |
Will Miles | df6c271830 | |
Will Miles | 12bf04826a | |
Blaz Kristan | 0dcb56eab5 | |
Blaž Kristan | 505768db04 | |
Robert | c74db95c14 | |
Robert | af3f27feae | |
Damian Schneider | 0637c1c9d4 | |
Damian Schneider | 0453a5fb3d | |
Carlos Cruz | ab13db73e7 | |
Damian Schneider | 509675fe66 | |
Damian Schneider | 5c09ee29db | |
Damian Schneider | 15526bd6e8 | |
Damian Schneider | c8f48168b4 | |
Blaz Kristan | f2c30ba3f7 | |
Woody | 1eaac0072d |
|
@ -37,7 +37,7 @@ jobs:
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
cache: 'npm'
|
cache: 'npm'
|
||||||
- run: npm install
|
- run: npm ci
|
||||||
- name: Cache PlatformIO
|
- name: Cache PlatformIO
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
|
@ -61,7 +61,7 @@ jobs:
|
||||||
name: firmware-${{ matrix.environment }}
|
name: firmware-${{ matrix.environment }}
|
||||||
path: |
|
path: |
|
||||||
build_output/release/*.bin
|
build_output/release/*.bin
|
||||||
build_output/release/*_ESP02.bin.gz
|
build_output/release/*_ESP02*.bin.gz
|
||||||
release:
|
release:
|
||||||
name: Create Release
|
name: Create Release
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
48
CHANGELOG.md
48
CHANGELOG.md
|
@ -1,5 +1,51 @@
|
||||||
## WLED changelog
|
## WLED changelog
|
||||||
|
|
||||||
|
#### Build 2404120
|
||||||
|
- v0.15.0-b3
|
||||||
|
- fix for #3896 & WS2815 current saving
|
||||||
|
- conditional compile for AA setPixelColor()
|
||||||
|
|
||||||
|
#### Build 2404100
|
||||||
|
- Internals: #3859, #3862, #3873, #3875
|
||||||
|
- Prefer I2S1 over RMT on ESP32
|
||||||
|
- usermod for Adafruit MAX17048 (#3667 by @ccruz09)
|
||||||
|
- Runtime detection of ESP32 PICO, general PSRAM support
|
||||||
|
- Extend JSON API "info" object
|
||||||
|
- add "clock" - CPU clock in MHz
|
||||||
|
- add "flash" - flash size in MB
|
||||||
|
- Fix for #3879
|
||||||
|
- Analog PWM fix for ESP8266 (#3887 by @gaaat98)
|
||||||
|
- Fix for #3870 (#3880 by @DedeHai)
|
||||||
|
- ESP32 S3/S2 touch fix (#3798 by @DedeHai)
|
||||||
|
- PIO env. PSRAM fix for S3 & S3 with 4M flash
|
||||||
|
- audioreactive always included for S3 & S2
|
||||||
|
- Fix for #3889
|
||||||
|
- BREAKING: Effect: modified KITT (Scanner) (#3763)
|
||||||
|
|
||||||
|
#### Build 2403280
|
||||||
|
- Individual color channel control for JSON API (fixes #3860)
|
||||||
|
- "col":[int|string|object|array, int|string|object|array, int|string|object|array]
|
||||||
|
int = Kelvin temperature or 0 for black
|
||||||
|
string = hex representation of [WW]RRGGBB
|
||||||
|
object = individual channel control {"r":0,"g":127,"b":255,"w":255}, each being optional (valid to send {})
|
||||||
|
array = direct channel values [r,g,b,w] (w element being optional)
|
||||||
|
- runtime selection for CCT IC (Athom 15W bulb)
|
||||||
|
- #3850 (by @w00000dy)
|
||||||
|
- Rotary encoder palette count bugfix
|
||||||
|
- bugfixes and optimisations
|
||||||
|
|
||||||
|
#### Build 2403240
|
||||||
|
- v0.15.0-b2
|
||||||
|
- WS2805 support (RGB + WW + CW, 600kbps)
|
||||||
|
- Unified PSRAM use
|
||||||
|
- NeoPixelBus v2.7.9
|
||||||
|
- Ubiquitous PSRAM mode for all variants of ESP32
|
||||||
|
- SSD1309_64 I2C Support for FLD Usermod (#3836 by @THATDONFC)
|
||||||
|
- Palette cycling fix (add support for `{"seg":[{"pal":"X~Y~"}]}` or `{"seg":[{"pal":"X~Yr"}]}`)
|
||||||
|
- FW1906 Support (#3810 by @deece and @Robert-github-com)
|
||||||
|
- ESPAsyncWebServer 2.2.0 (#3828 by @willmmiles)
|
||||||
|
- Bugfixes: #3843, #3844
|
||||||
|
|
||||||
#### Build 2403190
|
#### Build 2403190
|
||||||
- limit max PWM frequency (fix incorrect PWM resolution)
|
- limit max PWM frequency (fix incorrect PWM resolution)
|
||||||
- Segment UI bugfix
|
- Segment UI bugfix
|
||||||
|
@ -52,7 +98,7 @@
|
||||||
|
|
||||||
#### Build 2309120 till build 2402010
|
#### Build 2309120 till build 2402010
|
||||||
- WLED version 0.15.0-a0
|
- WLED version 0.15.0-a0
|
||||||
- Multi-WiFi support. Add up to 3 (or more via cusom compile) WiFis to connect to
|
- Multi-WiFi support. Add up to 3 (or more via cusom compile) WiFis to connect to (with help from @JPZV)
|
||||||
- Temporary AP. Use your WLED in public with temporary AP.
|
- Temporary AP. Use your WLED in public with temporary AP.
|
||||||
- Github CI build system enhancements (#3718 by @WoodyLetsCode)
|
- Github CI build system enhancements (#3718 by @WoodyLetsCode)
|
||||||
- Accessibility: Node list ( #3715 by @WoodyLetsCode)
|
- Accessibility: Node list ( #3715 by @WoodyLetsCode)
|
||||||
|
|
Plik diff jest za duży
Load Diff
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "wled",
|
"name": "wled",
|
||||||
"version": "0.15.0-b1",
|
"version": "0.15.0-b3",
|
||||||
"description": "Tools for WLED project",
|
"description": "Tools for WLED project",
|
||||||
"main": "tools/cdata.js",
|
"main": "tools/cdata.js",
|
||||||
"directories": {
|
"directories": {
|
||||||
|
@ -26,7 +26,6 @@
|
||||||
"clean-css": "^5.3.3",
|
"clean-css": "^5.3.3",
|
||||||
"html-minifier-terser": "^7.2.0",
|
"html-minifier-terser": "^7.2.0",
|
||||||
"inliner": "^1.13.1",
|
"inliner": "^1.13.1",
|
||||||
"nodemon": "^3.0.2",
|
"nodemon": "^3.0.2"
|
||||||
"zlib": "^1.0.5"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import shutil
|
||||||
import gzip
|
import gzip
|
||||||
|
|
||||||
OUTPUT_DIR = "build_output{}".format(os.path.sep)
|
OUTPUT_DIR = "build_output{}".format(os.path.sep)
|
||||||
|
#OUTPUT_DIR = os.path.join("build_output")
|
||||||
|
|
||||||
def _get_cpp_define_value(env, define):
|
def _get_cpp_define_value(env, define):
|
||||||
define_list = [item[-1] for item in env["CPPDEFINES"] if item[0] == define]
|
define_list = [item[-1] for item in env["CPPDEFINES"] if item[0] == define]
|
||||||
|
@ -13,24 +14,24 @@ def _get_cpp_define_value(env, define):
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def _create_dirs(dirs=["firmware", "map"]):
|
def _create_dirs(dirs=["map", "release", "firmware"]):
|
||||||
# check if output directories exist and create if necessary
|
|
||||||
if not os.path.isdir(OUTPUT_DIR):
|
|
||||||
os.mkdir(OUTPUT_DIR)
|
|
||||||
|
|
||||||
for d in dirs:
|
for d in dirs:
|
||||||
if not os.path.isdir("{}{}".format(OUTPUT_DIR, d)):
|
os.makedirs(os.path.join(OUTPUT_DIR, d), exist_ok=True)
|
||||||
os.mkdir("{}{}".format(OUTPUT_DIR, d))
|
|
||||||
|
|
||||||
def create_release(source):
|
def create_release(source):
|
||||||
release_name = _get_cpp_define_value(env, "WLED_RELEASE_NAME")
|
release_name = _get_cpp_define_value(env, "WLED_RELEASE_NAME")
|
||||||
if release_name:
|
if release_name:
|
||||||
_create_dirs(["release"])
|
|
||||||
version = _get_cpp_define_value(env, "WLED_VERSION")
|
version = _get_cpp_define_value(env, "WLED_VERSION")
|
||||||
# get file extension of source file (.bin or .bin.gz)
|
release_file = os.path.join(OUTPUT_DIR, "release", f"WLED_{version}_{release_name}.bin")
|
||||||
ext = source.split(".", 1)[1]
|
release_gz_file = release_file + ".gz"
|
||||||
release_file = "{}release{}WLED_{}_{}.{}".format(OUTPUT_DIR, os.path.sep, version, release_name, ext)
|
print(f"Copying {source} to {release_file}")
|
||||||
shutil.copy(source, release_file)
|
shutil.copy(source, release_file)
|
||||||
|
bin_gzip(release_file, release_gz_file)
|
||||||
|
else:
|
||||||
|
variant = env["PIOENV"]
|
||||||
|
bin_file = "{}firmware{}{}.bin".format(OUTPUT_DIR, os.path.sep, variant)
|
||||||
|
print(f"Copying {source} to {bin_file}")
|
||||||
|
shutil.copy(source, bin_file)
|
||||||
|
|
||||||
def bin_rename_copy(source, target, env):
|
def bin_rename_copy(source, target, env):
|
||||||
_create_dirs()
|
_create_dirs()
|
||||||
|
@ -38,38 +39,21 @@ def bin_rename_copy(source, target, env):
|
||||||
|
|
||||||
# create string with location and file names based on variant
|
# create string with location and file names based on variant
|
||||||
map_file = "{}map{}{}.map".format(OUTPUT_DIR, os.path.sep, variant)
|
map_file = "{}map{}{}.map".format(OUTPUT_DIR, os.path.sep, variant)
|
||||||
bin_file = "{}firmware{}{}.bin".format(OUTPUT_DIR, os.path.sep, variant)
|
|
||||||
|
|
||||||
# check if new target files exist and remove if necessary
|
create_release(str(target[0]))
|
||||||
for f in [map_file, bin_file]:
|
|
||||||
if os.path.isfile(f):
|
|
||||||
os.remove(f)
|
|
||||||
|
|
||||||
# copy firmware.bin to firmware/<variant>.bin
|
|
||||||
shutil.copy(str(target[0]), bin_file)
|
|
||||||
|
|
||||||
create_release(bin_file)
|
|
||||||
|
|
||||||
# copy firmware.map to map/<variant>.map
|
# copy firmware.map to map/<variant>.map
|
||||||
if os.path.isfile("firmware.map"):
|
if os.path.isfile("firmware.map"):
|
||||||
shutil.move("firmware.map", map_file)
|
shutil.move("firmware.map", map_file)
|
||||||
|
|
||||||
def bin_gzip(source, target, env):
|
def bin_gzip(source, target):
|
||||||
_create_dirs()
|
# only create gzip for esp8266
|
||||||
variant = env["PIOENV"]
|
if not env["PIOPLATFORM"] == "espressif8266":
|
||||||
|
return
|
||||||
# create string with location and file names based on variant
|
|
||||||
bin_file = "{}firmware{}{}.bin".format(OUTPUT_DIR, os.path.sep, variant)
|
print(f"Creating gzip file {target} from {source}")
|
||||||
gzip_file = "{}firmware{}{}.bin.gz".format(OUTPUT_DIR, os.path.sep, variant)
|
with open(source,"rb") as fp:
|
||||||
|
with gzip.open(target, "wb", compresslevel = 9) as f:
|
||||||
# check if new target files exist and remove if necessary
|
|
||||||
if os.path.isfile(gzip_file): os.remove(gzip_file)
|
|
||||||
|
|
||||||
# write gzip firmware file
|
|
||||||
with open(bin_file,"rb") as fp:
|
|
||||||
with gzip.open(gzip_file, "wb", compresslevel = 9) as f:
|
|
||||||
shutil.copyfileobj(fp, f)
|
shutil.copyfileobj(fp, f)
|
||||||
|
|
||||||
create_release(gzip_file)
|
env.AddPostAction("$BUILD_DIR/${PROGNAME}.bin", bin_rename_copy)
|
||||||
|
|
||||||
env.AddPostAction("$BUILD_DIR/${PROGNAME}.bin", [bin_rename_copy, bin_gzip])
|
|
||||||
|
|
|
@ -10,7 +10,11 @@
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
# CI/release binaries
|
# 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, 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_8MB, esp32s3dev_8MB_PSRAM_opi, esp32s3_4M_PSRAM_qspi, esp32_wrover
|
||||||
|
|
||||||
|
# Note that the combination of WLED_BRAND_NAME, WLED_PRODUCT_NAME and ESP architecture
|
||||||
|
# (JSON API info fields: "brand", "product", "arch") must identify OTA-compatible official releases.
|
||||||
|
# This may be used by third-party tools to automate identifying and applying OTA updates.
|
||||||
|
|
||||||
src_dir = ./wled00
|
src_dir = ./wled00
|
||||||
data_dir = ./wled00/data
|
data_dir = ./wled00/data
|
||||||
|
@ -41,14 +45,13 @@ arduino_core_git = https://github.com/platformio/platform-espressif8266#feature/
|
||||||
platform_wled_default = ${common.arduino_core_3_1_2}
|
platform_wled_default = ${common.arduino_core_3_1_2}
|
||||||
# We use 2.7.4.7 for all, includes PWM flicker fix and Wstring optimization
|
# We use 2.7.4.7 for all, includes PWM flicker fix and Wstring optimization
|
||||||
#platform_packages = tasmota/framework-arduinoespressif8266 @ 3.20704.7
|
#platform_packages = tasmota/framework-arduinoespressif8266 @ 3.20704.7
|
||||||
platform_packages = platformio/framework-arduinoespressif8266
|
platform_packages = platformio/toolchain-xtensa @ ~2.100300.220621 #2.40802.200502
|
||||||
platformio/toolchain-xtensa @ ~2.100300.220621 #2.40802.200502
|
|
||||||
platformio/tool-esptool #@ ~1.413.0
|
platformio/tool-esptool #@ ~1.413.0
|
||||||
platformio/tool-esptoolpy #@ ~1.30000.0
|
platformio/tool-esptoolpy #@ ~1.30000.0
|
||||||
|
|
||||||
## previous platform for 8266, in case of problems with the new one
|
## previous platform for 8266, in case of problems with the new one
|
||||||
## you'll need makuna/NeoPixelBus@ 2.6.9 for arduino_core_3_2_0, which does not support Ucs890x
|
## you'll need makuna/NeoPixelBus@ 2.6.9 for arduino_core_3_0_2, which does not support Ucs890x
|
||||||
;; platform_wled_default = ${common.arduino_core_3_2_0}
|
;; platform_wled_default = ${common.arduino_core_3_0_2}
|
||||||
;; platform_packages = tasmota/framework-arduinoespressif8266 @ 3.20704.7
|
;; platform_packages = tasmota/framework-arduinoespressif8266 @ 3.20704.7
|
||||||
;; platformio/toolchain-xtensa @ ~2.40802.200502
|
;; platformio/toolchain-xtensa @ ~2.40802.200502
|
||||||
;; platformio/tool-esptool @ ~1.413.0
|
;; platformio/tool-esptool @ ~1.413.0
|
||||||
|
@ -143,8 +146,8 @@ lib_compat_mode = strict
|
||||||
lib_deps =
|
lib_deps =
|
||||||
fastled/FastLED @ 3.6.0
|
fastled/FastLED @ 3.6.0
|
||||||
IRremoteESP8266 @ 2.8.2
|
IRremoteESP8266 @ 2.8.2
|
||||||
makuna/NeoPixelBus @ 2.7.5
|
makuna/NeoPixelBus @ 2.7.9
|
||||||
https://github.com/Aircoookie/ESPAsyncWebServer.git @ ^2.1.0
|
https://github.com/Aircoookie/ESPAsyncWebServer.git @ 2.2.1
|
||||||
# for I2C interface
|
# for I2C interface
|
||||||
;Wire
|
;Wire
|
||||||
# ESP-NOW library
|
# ESP-NOW library
|
||||||
|
@ -164,6 +167,9 @@ lib_deps =
|
||||||
#For ADS1115 sensor uncomment following
|
#For ADS1115 sensor uncomment following
|
||||||
;adafruit/Adafruit BusIO @ 1.13.2
|
;adafruit/Adafruit BusIO @ 1.13.2
|
||||||
;adafruit/Adafruit ADS1X15 @ 2.4.0
|
;adafruit/Adafruit ADS1X15 @ 2.4.0
|
||||||
|
#For MAX1704x Lipo Monitor / Fuel Gauge uncomment following
|
||||||
|
; https://github.com/adafruit/Adafruit_BusIO @ 1.14.5
|
||||||
|
; https://github.com/adafruit/Adafruit_MAX1704X @ 1.0.2
|
||||||
#For MPU6050 IMU uncomment follwoing
|
#For MPU6050 IMU uncomment follwoing
|
||||||
;electroniccats/MPU6050 @1.0.1
|
;electroniccats/MPU6050 @1.0.1
|
||||||
# For -D USERMOD_ANIMARTRIX
|
# For -D USERMOD_ANIMARTRIX
|
||||||
|
@ -172,7 +178,7 @@ lib_deps =
|
||||||
# SHT85
|
# SHT85
|
||||||
;robtillaart/SHT85@~0.3.3
|
;robtillaart/SHT85@~0.3.3
|
||||||
# Audioreactive usermod
|
# Audioreactive usermod
|
||||||
;kosme/arduinoFFT @ 2.0.0
|
;kosme/arduinoFFT @ 2.0.1
|
||||||
|
|
||||||
extra_scripts = ${scripts_defaults.extra_scripts}
|
extra_scripts = ${scripts_defaults.extra_scripts}
|
||||||
|
|
||||||
|
@ -223,7 +229,7 @@ lib_deps =
|
||||||
${env.lib_deps}
|
${env.lib_deps}
|
||||||
# additional build flags for audioreactive
|
# additional build flags for audioreactive
|
||||||
AR_build_flags = -D USERMOD_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]
|
[esp32_idf_V4]
|
||||||
;; experimental build environment for ESP32 using ESP-IDF 4.4.x / arduino-esp32 v2.0.5
|
;; experimental build environment for ESP32 using ESP-IDF 4.4.x / arduino-esp32 v2.0.5
|
||||||
|
@ -236,7 +242,6 @@ platform_packages =
|
||||||
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
|
||||||
#-DCONFIG_LITTLEFS_FOR_IDF_3_2
|
|
||||||
-D CONFIG_ASYNC_TCP_USE_WDT=0
|
-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
|
-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
|
default_partitions = tools/WLED_ESP32_4MB_1MB_FS.csv
|
||||||
|
@ -310,14 +315,14 @@ platform = ${common.platform_wled_default}
|
||||||
platform_packages = ${common.platform_packages}
|
platform_packages = ${common.platform_packages}
|
||||||
board_build.ldscript = ${common.ldscript_4m1m}
|
board_build.ldscript = ${common.ldscript_4m1m}
|
||||||
build_unflags = ${common.build_unflags}
|
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} -D WLED_RELEASE_NAME=ESP8266 -D WLED_PRODUCT_NAME=FOSS #-DWLED_DISABLE_2D
|
||||||
lib_deps = ${esp8266.lib_deps}
|
lib_deps = ${esp8266.lib_deps}
|
||||||
monitor_filters = esp8266_exception_decoder
|
monitor_filters = esp8266_exception_decoder
|
||||||
|
|
||||||
[env:nodemcuv2_160]
|
[env:nodemcuv2_160]
|
||||||
extends = env:nodemcuv2
|
extends = env:nodemcuv2
|
||||||
board_build.f_cpu = 160000000L
|
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} -D WLED_RELEASE_NAME=ESP8266_160 -D WLED_PRODUCT_NAME=FOSS_OC #-DWLED_DISABLE_2D
|
||||||
|
|
||||||
[env:esp8266_2m]
|
[env:esp8266_2m]
|
||||||
board = esp_wroom_02
|
board = esp_wroom_02
|
||||||
|
@ -325,13 +330,13 @@ platform = ${common.platform_wled_default}
|
||||||
platform_packages = ${common.platform_packages}
|
platform_packages = ${common.platform_packages}
|
||||||
board_build.ldscript = ${common.ldscript_2m512k}
|
board_build.ldscript = ${common.ldscript_2m512k}
|
||||||
build_unflags = ${common.build_unflags}
|
build_unflags = ${common.build_unflags}
|
||||||
build_flags = ${common.build_flags_esp8266} -D WLED_RELEASE_NAME=ESP02
|
build_flags = ${common.build_flags_esp8266} -D WLED_RELEASE_NAME=ESP02 -D WLED_PRODUCT_NAME=FOSS
|
||||||
lib_deps = ${esp8266.lib_deps}
|
lib_deps = ${esp8266.lib_deps}
|
||||||
|
|
||||||
[env:esp8266_2m_160]
|
[env:esp8266_2m_160]
|
||||||
extends = env:esp8266_2m
|
extends = env:esp8266_2m
|
||||||
board_build.f_cpu = 160000000L
|
board_build.f_cpu = 160000000L
|
||||||
build_flags = ${common.build_flags_esp8266} -D WLED_RELEASE_NAME=ESP02_160
|
build_flags = ${common.build_flags_esp8266} -D WLED_RELEASE_NAME=ESP02_160 -D WLED_PRODUCT_NAME=FOSS_OC
|
||||||
|
|
||||||
[env:esp01_1m_full]
|
[env:esp01_1m_full]
|
||||||
board = esp01_1m
|
board = esp01_1m
|
||||||
|
@ -339,14 +344,14 @@ platform = ${common.platform_wled_default}
|
||||||
platform_packages = ${common.platform_packages}
|
platform_packages = ${common.platform_packages}
|
||||||
board_build.ldscript = ${common.ldscript_1m128k}
|
board_build.ldscript = ${common.ldscript_1m128k}
|
||||||
build_unflags = ${common.build_unflags}
|
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} -D WLED_RELEASE_NAME=ESP01 -D WLED_PRODUCT_NAME=FOSS -D WLED_DISABLE_OTA
|
||||||
; -D WLED_USE_UNREAL_MATH ;; may cause wrong sunset/sunrise times, but saves 7064 bytes FLASH and 975 bytes RAM
|
; -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}
|
lib_deps = ${esp8266.lib_deps}
|
||||||
|
|
||||||
[env:esp01_1m_full_160]
|
[env:esp01_1m_full_160]
|
||||||
extends = env:esp01_1m_full
|
extends = env:esp01_1m_full
|
||||||
board_build.f_cpu = 160000000L
|
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} -D WLED_RELEASE_NAME=ESP01_160 -D WLED_PRODUCT_NAME=FOSS_OC -D WLED_DISABLE_OTA
|
||||||
; -D WLED_USE_UNREAL_MATH ;; may cause wrong sunset/sunrise times, but saves 7064 bytes FLASH and 975 bytes RAM
|
; -D WLED_USE_UNREAL_MATH ;; may cause wrong sunset/sunrise times, but saves 7064 bytes FLASH and 975 bytes RAM
|
||||||
|
|
||||||
[env:esp32dev]
|
[env:esp32dev]
|
||||||
|
@ -354,7 +359,7 @@ board = esp32dev
|
||||||
platform = ${esp32.platform}
|
platform = ${esp32.platform}
|
||||||
platform_packages = ${esp32.platform_packages}
|
platform_packages = ${esp32.platform_packages}
|
||||||
build_unflags = ${common.build_unflags}
|
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} -D WLED_RELEASE_NAME=ESP32 -D WLED_PRODUCT_NAME=FOSS #-D WLED_DISABLE_BROWNOUT_DET
|
||||||
lib_deps = ${esp32.lib_deps}
|
lib_deps = ${esp32.lib_deps}
|
||||||
monitor_filters = esp32_exception_decoder
|
monitor_filters = esp32_exception_decoder
|
||||||
board_build.partitions = ${esp32.default_partitions}
|
board_build.partitions = ${esp32.default_partitions}
|
||||||
|
@ -364,7 +369,7 @@ board = esp32dev
|
||||||
platform = ${esp32.platform}
|
platform = ${esp32.platform}
|
||||||
platform_packages = ${esp32.platform_packages}
|
platform_packages = ${esp32.platform_packages}
|
||||||
build_unflags = ${common.build_unflags}
|
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} -D WLED_RELEASE_NAME=ESP32_audioreactive -D WLED_PRODUCT_NAME=FOSS_AR #-D WLED_DISABLE_BROWNOUT_DET
|
||||||
${esp32.AR_build_flags}
|
${esp32.AR_build_flags}
|
||||||
lib_deps = ${esp32.lib_deps}
|
lib_deps = ${esp32.lib_deps}
|
||||||
${esp32.AR_lib_deps}
|
${esp32.AR_lib_deps}
|
||||||
|
@ -379,7 +384,7 @@ platform = ${esp32.platform}
|
||||||
platform_packages = ${esp32.platform_packages}
|
platform_packages = ${esp32.platform_packages}
|
||||||
upload_speed = 921600
|
upload_speed = 921600
|
||||||
build_unflags = ${common.build_unflags}
|
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} -D WLED_RELEASE_NAME=ESP32_Ethernet -D WLED_PRODUCT_NAME=FOSS_Eth -D RLYPIN=-1 -D WLED_USE_ETHERNET -D BTNPIN=-1
|
||||||
-D WLED_DISABLE_ESPNOW ;; ESP-NOW requires wifi, may crash with ethernet only
|
-D WLED_DISABLE_ESPNOW ;; ESP-NOW requires wifi, may crash with ethernet only
|
||||||
lib_deps = ${esp32.lib_deps}
|
lib_deps = ${esp32.lib_deps}
|
||||||
board_build.partitions = ${esp32.default_partitions}
|
board_build.partitions = ${esp32.default_partitions}
|
||||||
|
@ -389,11 +394,10 @@ platform = ${esp32.platform}
|
||||||
board = ttgo-t7-v14-mini32
|
board = ttgo-t7-v14-mini32
|
||||||
board_build.f_flash = 80000000L
|
board_build.f_flash = 80000000L
|
||||||
board_build.flash_mode = qio
|
board_build.flash_mode = qio
|
||||||
board_build.partitions = ${esp32.default_partitions}
|
board_build.partitions = tools/WLED_ESP32-wrover_4MB.csv
|
||||||
build_unflags = ${common.build_unflags}
|
build_unflags = ${common.build_unflags}
|
||||||
build_flags = ${common.build_flags_esp32} -D WLED_RELEASE_NAME=ESP32_WROVER
|
build_flags = ${common.build_flags_esp32} -D WLED_RELEASE_NAME=ESP32_WROVER -D WLED_PRODUCT_NAME=FOSS_PSRAM
|
||||||
-DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue
|
-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 WLED_USE_PSRAM
|
|
||||||
-D LEDPIN=25
|
-D LEDPIN=25
|
||||||
lib_deps = ${esp32.lib_deps}
|
lib_deps = ${esp32.lib_deps}
|
||||||
|
|
||||||
|
@ -404,7 +408,7 @@ platform_packages = ${esp32c3.platform_packages}
|
||||||
framework = arduino
|
framework = arduino
|
||||||
board = esp32-c3-devkitm-1
|
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_PRODUCT_NAME=FOSS
|
||||||
-D WLED_WATCHDOG_TIMEOUT=0
|
-D WLED_WATCHDOG_TIMEOUT=0
|
||||||
-DLOLIN_WIFI_FIX ; seems to work much better with this
|
-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
|
||||||
|
@ -420,12 +424,13 @@ platform = ${esp32s3.platform}
|
||||||
platform_packages = ${esp32s3.platform_packages}
|
platform_packages = ${esp32s3.platform_packages}
|
||||||
upload_speed = 921600 ; or 460800
|
upload_speed = 921600 ; or 460800
|
||||||
build_unflags = ${common.build_unflags}
|
build_unflags = ${common.build_unflags}
|
||||||
build_flags = ${common.build_flags} ${esp32s3.build_flags} -D WLED_RELEASE_NAME=ESP32-S3_8MB
|
build_flags = ${common.build_flags} ${esp32s3.build_flags} -D WLED_RELEASE_NAME=ESP32-S3_8MB -D WLED_PRODUCT_NAME=FOSS
|
||||||
-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=1 ;; 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
|
${esp32.AR_build_flags}
|
||||||
lib_deps = ${esp32s3.lib_deps}
|
lib_deps = ${esp32s3.lib_deps}
|
||||||
|
${esp32.AR_lib_deps}
|
||||||
board_build.partitions = tools/WLED_ESP32_8MB.csv
|
board_build.partitions = tools/WLED_ESP32_8MB.csv
|
||||||
board_build.f_flash = 80000000L
|
board_build.f_flash = 80000000L
|
||||||
board_build.flash_mode = qio
|
board_build.flash_mode = qio
|
||||||
|
@ -440,18 +445,39 @@ platform = ${esp32s3.platform}
|
||||||
platform_packages = ${esp32s3.platform_packages}
|
platform_packages = ${esp32s3.platform_packages}
|
||||||
upload_speed = 921600
|
upload_speed = 921600
|
||||||
build_unflags = ${common.build_unflags}
|
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_8MB_PSRAM_opi -D WLED_PRODUCT_NAME=FOSS_PSRAM
|
||||||
-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=1 ;; 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
|
-DBOARD_HAS_PSRAM
|
||||||
-D WLED_USE_PSRAM -DBOARD_HAS_PSRAM ; tells WLED that PSRAM shall be used
|
${esp32.AR_build_flags}
|
||||||
lib_deps = ${esp32s3.lib_deps}
|
lib_deps = ${esp32s3.lib_deps}
|
||||||
|
${esp32.AR_lib_deps}
|
||||||
board_build.partitions = tools/WLED_ESP32_8MB.csv
|
board_build.partitions = tools/WLED_ESP32_8MB.csv
|
||||||
board_build.f_flash = 80000000L
|
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:esp32s3_4M_PSRAM_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
|
||||||
|
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 -D WLED_PRODUCT_NAME=FOSS_PSRAM
|
||||||
|
-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.f_flash = 80000000L
|
||||||
|
board_build.flash_mode = qio
|
||||||
|
monitor_filters = esp32_exception_decoder
|
||||||
|
|
||||||
[env:lolin_s2_mini]
|
[env:lolin_s2_mini]
|
||||||
platform = ${esp32s2.platform}
|
platform = ${esp32s2.platform}
|
||||||
platform_packages = ${esp32s2.platform_packages}
|
platform_packages = ${esp32s2.platform_packages}
|
||||||
|
@ -460,13 +486,12 @@ board_build.partitions = tools/WLED_ESP32_4MB_1MB_FS.csv
|
||||||
;board_build.flash_mode = qio
|
;board_build.flash_mode = qio
|
||||||
;board_build.f_flash = 80000000L
|
;board_build.f_flash = 80000000L
|
||||||
build_unflags = ${common.build_unflags}
|
build_unflags = ${common.build_unflags}
|
||||||
build_flags = ${common.build_flags} ${esp32s2.build_flags} -D WLED_RELEASE_NAME=ESP32-S2
|
build_flags = ${common.build_flags} ${esp32s2.build_flags} -D WLED_RELEASE_NAME=ESP32-S2 -D WLED_PRODUCT_NAME=FOSS_PSRAM
|
||||||
-DBOARD_HAS_PSRAM
|
|
||||||
-DARDUINO_USB_CDC_ON_BOOT=1
|
-DARDUINO_USB_CDC_ON_BOOT=1
|
||||||
-DARDUINO_USB_MSC_ON_BOOT=0
|
-DARDUINO_USB_MSC_ON_BOOT=0
|
||||||
-DARDUINO_USB_DFU_ON_BOOT=0
|
-DARDUINO_USB_DFU_ON_BOOT=0
|
||||||
|
-DBOARD_HAS_PSRAM
|
||||||
-DLOLIN_WIFI_FIX ; seems to work much better with this
|
-DLOLIN_WIFI_FIX ; seems to work much better with this
|
||||||
-D WLED_USE_PSRAM
|
|
||||||
-D WLED_WATCHDOG_TIMEOUT=0
|
-D WLED_WATCHDOG_TIMEOUT=0
|
||||||
-D CONFIG_ASYNC_TCP_USE_WDT=0
|
-D CONFIG_ASYNC_TCP_USE_WDT=0
|
||||||
-D LEDPIN=16
|
-D LEDPIN=16
|
||||||
|
@ -476,4 +501,6 @@ build_flags = ${common.build_flags} ${esp32s2.build_flags} -D WLED_RELEASE_NAME=
|
||||||
-D HW_PIN_DATASPI=11
|
-D HW_PIN_DATASPI=11
|
||||||
-D HW_PIN_MISOSPI=9
|
-D HW_PIN_MISOSPI=9
|
||||||
; -D STATUSLED=15
|
; -D STATUSLED=15
|
||||||
|
${esp32.AR_build_flags}
|
||||||
lib_deps = ${esp32s2.lib_deps}
|
lib_deps = ${esp32s2.lib_deps}
|
||||||
|
${esp32.AR_lib_deps}
|
||||||
|
|
|
@ -155,9 +155,8 @@ build_flags = ${common.build_flags_esp8266}
|
||||||
; set default color order of your led strip
|
; set default color order of your led strip
|
||||||
; -D DEFAULT_LED_COLOR_ORDER=COL_ORDER_GRB
|
; -D DEFAULT_LED_COLOR_ORDER=COL_ORDER_GRB
|
||||||
;
|
;
|
||||||
; use PSRAM if a device (ESP) has one
|
; use PSRAM on classic ESP32 rev.1 (rev.3 or above has no issues)
|
||||||
; -DBOARD_HAS_PSRAM
|
; -DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue
|
||||||
; -D WLED_USE_PSRAM
|
|
||||||
;
|
;
|
||||||
; configure I2C and SPI interface (for various hardware)
|
; configure I2C and SPI interface (for various hardware)
|
||||||
; -D I2CSDAPIN=33 # initialise interface
|
; -D I2CSDAPIN=33 # initialise interface
|
||||||
|
|
|
@ -36,7 +36,7 @@ marshmallow==3.19.0
|
||||||
# via platformio
|
# via platformio
|
||||||
packaging==23.1
|
packaging==23.1
|
||||||
# via marshmallow
|
# via marshmallow
|
||||||
platformio==6.1.6
|
platformio==6.1.14
|
||||||
# via -r requirements.in
|
# via -r requirements.in
|
||||||
pyelftools==0.29
|
pyelftools==0.29
|
||||||
# via platformio
|
# via platformio
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# Name, Type, SubType, Offset, Size, Flags
|
# Name, Type, SubType, Offset, Size, Flags
|
||||||
nvs, data, nvs, 0x9000, 0x5000,
|
nvs, data, nvs, 0x9000, 0x5000,
|
||||||
otadata, data, ota, 0xe000, 0x2000,
|
otadata, data, ota, 0xe000, 0x2000,
|
||||||
app0, app, ota_0, 0x10000, 0x180000,
|
app0, app, ota_0, 0x10000, 0x1A0000,
|
||||||
app1, app, ota_1, 0x190000,0x180000,
|
app1, app, ota_1, 0x1B0000,0x1A0000,
|
||||||
spiffs, data, spiffs, 0x310000,0xF0000,
|
spiffs, data, spiffs, 0x350000,0xB0000,
|
||||||
|
|
|
|
@ -83,6 +83,7 @@ describe('Script', () => {
|
||||||
// Backup files
|
// Backup files
|
||||||
fs.cpSync("wled00/data", "wled00Backup", { recursive: true });
|
fs.cpSync("wled00/data", "wled00Backup", { recursive: true });
|
||||||
fs.cpSync("tools/cdata.js", "cdata.bak.js");
|
fs.cpSync("tools/cdata.js", "cdata.bak.js");
|
||||||
|
fs.cpSync("package.json", "package.bak.json");
|
||||||
});
|
});
|
||||||
after(() => {
|
after(() => {
|
||||||
// Restore backup
|
// Restore backup
|
||||||
|
@ -90,6 +91,8 @@ describe('Script', () => {
|
||||||
fs.renameSync("wled00Backup", "wled00/data");
|
fs.renameSync("wled00Backup", "wled00/data");
|
||||||
fs.rmSync("tools/cdata.js");
|
fs.rmSync("tools/cdata.js");
|
||||||
fs.renameSync("cdata.bak.js", "tools/cdata.js");
|
fs.renameSync("cdata.bak.js", "tools/cdata.js");
|
||||||
|
fs.rmSync("package.json");
|
||||||
|
fs.renameSync("package.bak.json", "package.json");
|
||||||
});
|
});
|
||||||
|
|
||||||
// delete all html_*.h files
|
// delete all html_*.h files
|
||||||
|
@ -131,7 +134,7 @@ describe('Script', () => {
|
||||||
// run script cdata.js again and wait for it to finish
|
// run script cdata.js again and wait for it to finish
|
||||||
await execPromise('node tools/cdata.js');
|
await execPromise('node tools/cdata.js');
|
||||||
|
|
||||||
checkIfFileWasNewlyCreated(path.join(folderPath, resultFile));
|
await checkIfFileWasNewlyCreated(path.join(folderPath, resultFile));
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('should build if', () => {
|
describe('should build if', () => {
|
||||||
|
@ -182,6 +185,10 @@ describe('Script', () => {
|
||||||
it('cdata.js changes', async () => {
|
it('cdata.js changes', async () => {
|
||||||
await testFileModification('tools/cdata.js', 'html_ui.h');
|
await testFileModification('tools/cdata.js', 'html_ui.h');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('package.json changes', async () => {
|
||||||
|
await testFileModification('package.json', 'html_ui.h');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('should not build if', () => {
|
describe('should not build if', () => {
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* Writes compressed C arrays of data files (web interface)
|
* Writes compressed C arrays of data files (web interface)
|
||||||
* How to use it?
|
* How to use it?
|
||||||
*
|
*
|
||||||
* 1) Install Node 11+ and npm
|
* 1) Install Node 20+ and npm
|
||||||
* 2) npm install
|
* 2) npm install
|
||||||
* 3) npm run build
|
* 3) npm run build
|
||||||
*
|
*
|
||||||
|
@ -15,10 +15,10 @@
|
||||||
* It uses NodeJS packages to inline, minify and GZIP files. See writeHtmlGzipped and writeChunks invocations at the bottom of the page.
|
* It uses NodeJS packages to inline, minify and GZIP files. See writeHtmlGzipped and writeChunks invocations at the bottom of the page.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const fs = require("fs");
|
const fs = require("node:fs");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const inliner = require("inliner");
|
const inliner = require("inliner");
|
||||||
const zlib = require("zlib");
|
const zlib = require("node:zlib");
|
||||||
const CleanCSS = require("clean-css");
|
const CleanCSS = require("clean-css");
|
||||||
const minifyHtml = require("html-minifier-terser").minify;
|
const minifyHtml = require("html-minifier-terser").minify;
|
||||||
const packageJson = require("../package.json");
|
const packageJson = require("../package.json");
|
||||||
|
@ -207,7 +207,7 @@ function isAnyFileInFolderNewerThan(folderPath, time) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the web UI is already built
|
// Check if the web UI is already built
|
||||||
function isAlreadyBuilt(folderPath) {
|
function isAlreadyBuilt(webUIPath, packageJsonPath = "package.json") {
|
||||||
let lastBuildTime = Infinity;
|
let lastBuildTime = Infinity;
|
||||||
|
|
||||||
for (const file of output) {
|
for (const file of output) {
|
||||||
|
@ -220,7 +220,7 @@ function isAlreadyBuilt(folderPath) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return !isAnyFileInFolderNewerThan(folderPath, lastBuildTime) && !isFileNewerThan("tools/cdata.js", lastBuildTime);
|
return !isAnyFileInFolderNewerThan(webUIPath, lastBuildTime) && !isFileNewerThan(packageJsonPath, lastBuildTime) && !isFileNewerThan(__filename, lastBuildTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't run this script if we're in a test environment
|
// Don't run this script if we're in a test environment
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
# Adafruit MAX17048 Usermod (LiPo & LiIon Battery Monitor & Fuel Gauge)
|
||||||
|
This usermod reads information from an Adafruit MAX17048 and outputs the following:
|
||||||
|
- Battery Voltage
|
||||||
|
- Battery Level Percentage
|
||||||
|
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
Libraries:
|
||||||
|
- `Adafruit_BusIO@~1.14.5` (by [adafruit](https://github.com/adafruit/Adafruit_BusIO))
|
||||||
|
- `Adafruit_MAX1704X@~1.0.2` (by [adafruit](https://github.com/adafruit/Adafruit_MAX1704X))
|
||||||
|
|
||||||
|
These must be added under `lib_deps` in your `platform.ini` (or `platform_override.ini`).
|
||||||
|
Data is published over MQTT - make sure you've enabled the MQTT sync interface.
|
||||||
|
|
||||||
|
## Compilation
|
||||||
|
|
||||||
|
To enable, compile with `USERMOD_MAX17048` define in the build_flags (e.g. in `platformio.ini` or `platformio_override.ini`) such as in the example below:
|
||||||
|
```ini
|
||||||
|
[env:usermod_max17048_d1_mini]
|
||||||
|
extends = env:d1_mini
|
||||||
|
build_flags =
|
||||||
|
${common.build_flags_esp8266}
|
||||||
|
-D USERMOD_MAX17048
|
||||||
|
lib_deps =
|
||||||
|
${esp8266.lib_deps}
|
||||||
|
https://github.com/adafruit/Adafruit_BusIO @ 1.14.5
|
||||||
|
https://github.com/adafruit/Adafruit_MAX1704X @ 1.0.2
|
||||||
|
```
|
||||||
|
|
||||||
|
### Configuration Options
|
||||||
|
The following settings can be set at compile-time but are configurable on the usermod menu (except First Monitor time):
|
||||||
|
- USERMOD_MAX17048_MIN_MONITOR_INTERVAL (the min number of milliseconds between checks, defaults to 10,000 ms)
|
||||||
|
- USERMOD_MAX17048_MAX_MONITOR_INTERVAL (the max number of milliseconds between checks, defaults to 10,000 ms)
|
||||||
|
- USERMOD_MAX17048_FIRST_MONITOR_AT
|
||||||
|
|
||||||
|
|
||||||
|
Additionally, the Usermod Menu allows you to:
|
||||||
|
- Enable or Disable the usermod
|
||||||
|
- Enable or Disable Home Assistant Discovery (turn on/off to sent MQTT Discovery entries for Home Assistant)
|
||||||
|
- Configure SCL/SDA GPIO Pins
|
||||||
|
|
||||||
|
## API
|
||||||
|
The following method is available to interact with the usermod from other code modules:
|
||||||
|
- `getBatteryVoltageV` read the last battery voltage (in Volt) obtained from the sensor
|
||||||
|
- `getBatteryPercent` reads the last battery percentage obtained from the sensor
|
||||||
|
|
||||||
|
## MQTT
|
||||||
|
MQTT topics are as follows (`<deviceTopic>` is set in MQTT section of Sync Setup menu):
|
||||||
|
Measurement type | MQTT topic
|
||||||
|
--- | ---
|
||||||
|
Battery Voltage | `<deviceTopic>/batteryVoltage`
|
||||||
|
Battery Percent | `<deviceTopic>/batteryPercent`
|
||||||
|
|
||||||
|
## Authors
|
||||||
|
Carlos Cruz [@ccruz09](https://github.com/ccruz09)
|
||||||
|
|
||||||
|
|
||||||
|
## Revision History
|
||||||
|
Jan 2024
|
||||||
|
- Added Home Assistant Discovery
|
||||||
|
- Implemented PinManager to register pins
|
||||||
|
- Added API call for other modules to read battery voltage and percentage
|
||||||
|
- Added info-screen outputs
|
||||||
|
- Updated `readme.md`
|
|
@ -0,0 +1,281 @@
|
||||||
|
// force the compiler to show a warning to confirm that this file is included
|
||||||
|
#warning **** Included USERMOD_MAX17048 V2.0 ****
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "wled.h"
|
||||||
|
#include "Adafruit_MAX1704X.h"
|
||||||
|
|
||||||
|
|
||||||
|
// the max interval to check battery level, 10 seconds
|
||||||
|
#ifndef USERMOD_MAX17048_MAX_MONITOR_INTERVAL
|
||||||
|
#define USERMOD_MAX17048_MAX_MONITOR_INTERVAL 10000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// the min interval to check battery level, 500 ms
|
||||||
|
#ifndef USERMOD_MAX17048_MIN_MONITOR_INTERVAL
|
||||||
|
#define USERMOD_MAX17048_MIN_MONITOR_INTERVAL 500
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// how many seconds after boot to perform the first check, 10 seconds
|
||||||
|
#ifndef USERMOD_MAX17048_FIRST_MONITOR_AT
|
||||||
|
#define USERMOD_MAX17048_FIRST_MONITOR_AT 10000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Usermod to display Battery Life using Adafruit's MAX17048 LiPoly/ LiIon Fuel Gauge and Battery Monitor.
|
||||||
|
*/
|
||||||
|
class Usermod_MAX17048 : public Usermod {
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
bool enabled = true;
|
||||||
|
|
||||||
|
unsigned long maxReadingInterval = USERMOD_MAX17048_MAX_MONITOR_INTERVAL;
|
||||||
|
unsigned long minReadingInterval = USERMOD_MAX17048_MIN_MONITOR_INTERVAL;
|
||||||
|
unsigned long lastCheck = UINT32_MAX - (USERMOD_MAX17048_MAX_MONITOR_INTERVAL - USERMOD_MAX17048_FIRST_MONITOR_AT);
|
||||||
|
unsigned long lastSend = UINT32_MAX - (USERMOD_MAX17048_MAX_MONITOR_INTERVAL - USERMOD_MAX17048_FIRST_MONITOR_AT);
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t VoltageDecimals = 3; // Number of decimal places in published voltage values
|
||||||
|
uint8_t PercentDecimals = 1; // Number of decimal places in published percent values
|
||||||
|
|
||||||
|
// string that are used multiple time (this will save some flash memory)
|
||||||
|
static const char _name[];
|
||||||
|
static const char _enabled[];
|
||||||
|
static const char _maxReadInterval[];
|
||||||
|
static const char _minReadInterval[];
|
||||||
|
static const char _HomeAssistantDiscovery[];
|
||||||
|
|
||||||
|
bool monitorFound = false;
|
||||||
|
bool firstReadComplete = false;
|
||||||
|
bool initDone = false;
|
||||||
|
|
||||||
|
Adafruit_MAX17048 maxLipo;
|
||||||
|
float lastBattVoltage = -10;
|
||||||
|
float lastBattPercent = -1;
|
||||||
|
|
||||||
|
// MQTT and Home Assistant Variables
|
||||||
|
bool HomeAssistantDiscovery = false; // Publish Home Assistant Device Information
|
||||||
|
bool mqttInitialized = false;
|
||||||
|
|
||||||
|
void _mqttInitialize()
|
||||||
|
{
|
||||||
|
char mqttBatteryVoltageTopic[128];
|
||||||
|
char mqttBatteryPercentTopic[128];
|
||||||
|
|
||||||
|
snprintf_P(mqttBatteryVoltageTopic, 127, PSTR("%s/batteryVoltage"), mqttDeviceTopic);
|
||||||
|
snprintf_P(mqttBatteryPercentTopic, 127, PSTR("%s/batteryPercent"), mqttDeviceTopic);
|
||||||
|
|
||||||
|
if (HomeAssistantDiscovery) {
|
||||||
|
_createMqttSensor(F("BatteryVoltage"), mqttBatteryVoltageTopic, "voltage", F("V"));
|
||||||
|
_createMqttSensor(F("BatteryPercent"), mqttBatteryPercentTopic, "battery", F("%"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _createMqttSensor(const String &name, const String &topic, const String &deviceClass, const String &unitOfMeasurement)
|
||||||
|
{
|
||||||
|
String t = String(F("homeassistant/sensor/")) + mqttClientID + F("/") + name + F("/config");
|
||||||
|
|
||||||
|
StaticJsonDocument<600> doc;
|
||||||
|
|
||||||
|
doc[F("name")] = String(serverDescription) + " " + name;
|
||||||
|
doc[F("state_topic")] = topic;
|
||||||
|
doc[F("unique_id")] = String(mqttClientID) + name;
|
||||||
|
if (unitOfMeasurement != "")
|
||||||
|
doc[F("unit_of_measurement")] = unitOfMeasurement;
|
||||||
|
if (deviceClass != "")
|
||||||
|
doc[F("device_class")] = deviceClass;
|
||||||
|
doc[F("expire_after")] = 1800;
|
||||||
|
|
||||||
|
JsonObject device = doc.createNestedObject(F("device")); // attach the sensor to the same device
|
||||||
|
device[F("name")] = serverDescription;
|
||||||
|
device[F("identifiers")] = "wled-sensor-" + String(mqttClientID);
|
||||||
|
device[F("manufacturer")] = F("WLED");
|
||||||
|
device[F("model")] = F("FOSS");
|
||||||
|
device[F("sw_version")] = versionString;
|
||||||
|
|
||||||
|
String temp;
|
||||||
|
serializeJson(doc, temp);
|
||||||
|
DEBUG_PRINTLN(t);
|
||||||
|
DEBUG_PRINTLN(temp);
|
||||||
|
|
||||||
|
mqtt->publish(t.c_str(), 0, true, temp.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void publishMqtt(const char *topic, const char* state) {
|
||||||
|
#ifndef WLED_DISABLE_MQTT
|
||||||
|
//Check if MQTT Connected, otherwise it will crash the 8266
|
||||||
|
if (WLED_MQTT_CONNECTED){
|
||||||
|
char subuf[128];
|
||||||
|
snprintf_P(subuf, 127, PSTR("%s/%s"), mqttDeviceTopic, topic);
|
||||||
|
mqtt->publish(subuf, 0, false, state);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
inline void enable(bool enable) { enabled = enable; }
|
||||||
|
|
||||||
|
inline bool isEnabled() { return enabled; }
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
// do your set-up here
|
||||||
|
if (i2c_scl<0 || i2c_sda<0) { enabled = false; return; }
|
||||||
|
monitorFound = maxLipo.begin();
|
||||||
|
initDone = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
// if usermod is disabled or called during strip updating just exit
|
||||||
|
// NOTE: on very long strips strip.isUpdating() may always return true so update accordingly
|
||||||
|
if (!enabled || strip.isUpdating()) return;
|
||||||
|
|
||||||
|
unsigned long now = millis();
|
||||||
|
|
||||||
|
if (now - lastCheck < minReadingInterval) { return; }
|
||||||
|
|
||||||
|
bool shouldUpdate = now - lastSend > maxReadingInterval;
|
||||||
|
|
||||||
|
float battVoltage = maxLipo.cellVoltage();
|
||||||
|
float battPercent = maxLipo.cellPercent();
|
||||||
|
lastCheck = millis();
|
||||||
|
firstReadComplete = true;
|
||||||
|
|
||||||
|
if (shouldUpdate)
|
||||||
|
{
|
||||||
|
lastBattVoltage = roundf(battVoltage * powf(10, VoltageDecimals)) / powf(10, VoltageDecimals);
|
||||||
|
lastBattPercent = roundf(battPercent * powf(10, PercentDecimals)) / powf(10, PercentDecimals);
|
||||||
|
lastSend = millis();
|
||||||
|
|
||||||
|
publishMqtt("batteryVoltage", String(lastBattVoltage, VoltageDecimals).c_str());
|
||||||
|
publishMqtt("batteryPercent", String(lastBattPercent, PercentDecimals).c_str());
|
||||||
|
DEBUG_PRINTLN(F("Battery Voltage: ") + String(lastBattVoltage, VoltageDecimals) + F("V"));
|
||||||
|
DEBUG_PRINTLN(F("Battery Percent: ") + String(lastBattPercent, PercentDecimals) + F("%"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void onMqttConnect(bool sessionPresent)
|
||||||
|
{
|
||||||
|
if (WLED_MQTT_CONNECTED && !mqttInitialized)
|
||||||
|
{
|
||||||
|
_mqttInitialize();
|
||||||
|
mqttInitialized = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline float getBatteryVoltageV() {
|
||||||
|
return (float) lastBattVoltage;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline float getBatteryPercent() {
|
||||||
|
return (float) lastBattPercent;
|
||||||
|
}
|
||||||
|
|
||||||
|
void addToJsonInfo(JsonObject& root)
|
||||||
|
{
|
||||||
|
// if "u" object does not exist yet wee need to create it
|
||||||
|
JsonObject user = root["u"];
|
||||||
|
if (user.isNull()) user = root.createNestedObject("u");
|
||||||
|
|
||||||
|
|
||||||
|
JsonArray battery_json = user.createNestedArray(F("Battery Monitor"));
|
||||||
|
if (!enabled) {
|
||||||
|
battery_json.add(F("Disabled"));
|
||||||
|
}
|
||||||
|
else if(!monitorFound) {
|
||||||
|
battery_json.add(F("MAX17048 Not Found"));
|
||||||
|
}
|
||||||
|
else if (!firstReadComplete) {
|
||||||
|
// if we haven't read the sensor yet, let the user know
|
||||||
|
// that we are still waiting for the first measurement
|
||||||
|
battery_json.add((USERMOD_MAX17048_FIRST_MONITOR_AT - millis()) / 1000);
|
||||||
|
battery_json.add(F(" sec until read"));
|
||||||
|
} else {
|
||||||
|
battery_json.add(F("Enabled"));
|
||||||
|
JsonArray voltage_json = user.createNestedArray(F("Battery Voltage"));
|
||||||
|
voltage_json.add(lastBattVoltage);
|
||||||
|
voltage_json.add(F("V"));
|
||||||
|
JsonArray percent_json = user.createNestedArray(F("Battery Percent"));
|
||||||
|
percent_json.add(lastBattPercent);
|
||||||
|
percent_json.add(F("%"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void addToJsonState(JsonObject& root)
|
||||||
|
{
|
||||||
|
JsonObject usermod = root[FPSTR(_name)];
|
||||||
|
if (usermod.isNull())
|
||||||
|
{
|
||||||
|
usermod = root.createNestedObject(FPSTR(_name));
|
||||||
|
}
|
||||||
|
usermod[FPSTR(_enabled)] = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
void readFromJsonState(JsonObject& root)
|
||||||
|
{
|
||||||
|
JsonObject usermod = root[FPSTR(_name)];
|
||||||
|
if (!usermod.isNull())
|
||||||
|
{
|
||||||
|
if (usermod[FPSTR(_enabled)].is<bool>())
|
||||||
|
{
|
||||||
|
enabled = usermod[FPSTR(_enabled)].as<bool>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void addToConfig(JsonObject& root)
|
||||||
|
{
|
||||||
|
JsonObject top = root.createNestedObject(FPSTR(_name));
|
||||||
|
top[FPSTR(_enabled)] = enabled;
|
||||||
|
top[FPSTR(_maxReadInterval)] = maxReadingInterval;
|
||||||
|
top[FPSTR(_minReadInterval)] = minReadingInterval;
|
||||||
|
top[FPSTR(_HomeAssistantDiscovery)] = HomeAssistantDiscovery;
|
||||||
|
DEBUG_PRINT(F(_name));
|
||||||
|
DEBUG_PRINTLN(F(" config saved."));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool readFromConfig(JsonObject& root)
|
||||||
|
{
|
||||||
|
JsonObject top = root[FPSTR(_name)];
|
||||||
|
|
||||||
|
if (top.isNull()) {
|
||||||
|
DEBUG_PRINT(F(_name));
|
||||||
|
DEBUG_PRINTLN(F(": No config found. (Using defaults.)"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool configComplete = !top.isNull();
|
||||||
|
|
||||||
|
configComplete &= getJsonValue(top[FPSTR(_enabled)], enabled);
|
||||||
|
configComplete &= getJsonValue(top[FPSTR(_maxReadInterval)], maxReadingInterval, USERMOD_MAX17048_MAX_MONITOR_INTERVAL);
|
||||||
|
configComplete &= getJsonValue(top[FPSTR(_minReadInterval)], minReadingInterval, USERMOD_MAX17048_MIN_MONITOR_INTERVAL);
|
||||||
|
configComplete &= getJsonValue(top[FPSTR(_HomeAssistantDiscovery)], HomeAssistantDiscovery, false);
|
||||||
|
|
||||||
|
DEBUG_PRINT(FPSTR(_name));
|
||||||
|
if (!initDone) {
|
||||||
|
// first run: reading from cfg.json
|
||||||
|
DEBUG_PRINTLN(F(" config loaded."));
|
||||||
|
} else {
|
||||||
|
DEBUG_PRINTLN(F(" config (re)loaded."));
|
||||||
|
// changing parameters from settings page
|
||||||
|
}
|
||||||
|
|
||||||
|
return configComplete;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t getId()
|
||||||
|
{
|
||||||
|
return USERMOD_ID_MAX17048;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// add more strings here to reduce flash memory usage
|
||||||
|
const char Usermod_MAX17048::_name[] PROGMEM = "Adafruit MAX17048 Battery Monitor";
|
||||||
|
const char Usermod_MAX17048::_enabled[] PROGMEM = "enabled";
|
||||||
|
const char Usermod_MAX17048::_maxReadInterval[] PROGMEM = "max-read-interval-ms";
|
||||||
|
const char Usermod_MAX17048::_minReadInterval[] PROGMEM = "min-read-interval-ms";
|
||||||
|
const char Usermod_MAX17048::_HomeAssistantDiscovery[] PROGMEM = "HomeAssistantDiscovery";
|
|
@ -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.
|
There are however plans to create a lightweight audioreactive for the 8266, with reduced features.
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
### using customised _arduinoFFT_ library for use with this usermod
|
### using latest _arduinoFFT_ library version 2.x
|
||||||
Add `-D USERMOD_AUDIOREACTIVE` to your PlatformIO environment `build_flags`, as well as `https://github.com/blazoncek/arduinoFFT.git` to your `lib_deps`.
|
The latest arduinoFFT release version should be used for audioreactive.
|
||||||
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.
|
|
||||||
|
|
||||||
Customised _arduinoFFT_ library for use with this usermod can be found at https://github.com/blazoncek/arduinoFFT.git
|
* `build_flags` = `-D USERMOD_AUDIOREACTIVE`
|
||||||
|
* `lib_deps`= `kosme/arduinoFFT @ 2.0.1`
|
||||||
### 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`
|
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
|
|
|
@ -667,7 +667,7 @@ void MultiRelay::addToJsonInfo(JsonObject &root) {
|
||||||
for (int i=0; i<MULTI_RELAY_MAX_RELAYS; i++) {
|
for (int i=0; i<MULTI_RELAY_MAX_RELAYS; i++) {
|
||||||
if (_relay[i].pin<0 || !_relay[i].external) continue;
|
if (_relay[i].pin<0 || !_relay[i].external) continue;
|
||||||
uiDomString = F("Relay "); uiDomString += i;
|
uiDomString = F("Relay "); uiDomString += i;
|
||||||
JsonArray infoArr = user.createNestedArray(uiDomString); // timer value
|
infoArr = user.createNestedArray(uiDomString); // timer value
|
||||||
|
|
||||||
uiDomString = F("<button class=\"btn btn-xs\" onclick=\"requestJson({");
|
uiDomString = F("<button class=\"btn btn-xs\" onclick=\"requestJson({");
|
||||||
uiDomString += FPSTR(_name);
|
uiDomString += FPSTR(_name);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# I2C 4 Line Display Usermod ALT
|
# I2C/SPI 4 Line Display Usermod ALT
|
||||||
|
|
||||||
Thank you to the authors of the original version of these usermods. It would not have been possible without them!
|
Thank you to the authors of the original version of these usermods. It would not have been possible without them!
|
||||||
"usermod_v2_four_line_display"
|
"usermod_v2_four_line_display"
|
||||||
|
@ -8,21 +8,20 @@ The core of these usermods are a copy of the originals. The main changes are to
|
||||||
The display usermod UI has been completely changed.
|
The display usermod UI has been completely changed.
|
||||||
|
|
||||||
|
|
||||||
The changes made to the RotaryEncoder usermod were made to support the new UI in the display usermod.
|
The changes made to the RotaryEncoder usermod were made to support the new UI in the display usermod.
|
||||||
Without the display it, functions identical to the original.
|
Without the display, it functions identical to the original.
|
||||||
The original "usermod_v2_auto_save" will not work with the display just yet.
|
The original "usermod_v2_auto_save" will not work with the display just yet.
|
||||||
|
|
||||||
Press the encoder to cycle through the options:
|
Press the encoder to cycle through the options:
|
||||||
*Brightness
|
* Brightness
|
||||||
*Speed
|
* Speed
|
||||||
*Intensity
|
* Intensity
|
||||||
*Palette
|
* Palette
|
||||||
*Effect
|
* Effect
|
||||||
*Main Color (only if display is used)
|
* Main Color (only if display is used)
|
||||||
*Saturation (only if display is used)
|
* Saturation (only if display is used)
|
||||||
|
|
||||||
Press and hold the encoder to display Network Info
|
Press and hold the encoder to display Network Info. If AP is active, it will display AP, SSID and password
|
||||||
if AP is active, it will display AP, SSID and password
|
|
||||||
|
|
||||||
Also shows if the timer is enabled
|
Also shows if the timer is enabled
|
||||||
|
|
||||||
|
@ -30,11 +29,47 @@ Also shows if the timer is enabled
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
Please refer to the original `usermod_v2_rotary_encoder_ui` readme for the main instructions
|
Please refer to the original `usermod_v2_rotary_encoder_ui` readme for the main instructions.
|
||||||
Then to activate this alternative usermod add `#define USE_ALT_DISPlAY` to the `usermods_list.cpp` file,
|
|
||||||
|
Copy the example `platformio_override.sample.ini` from the usermod_v2_rotary_encoder_ui_ALT folder to the root directory of your particular build and rename it to `platformio_override.ini`.
|
||||||
|
|
||||||
|
This file should be placed in the same directory as `platformio.ini`.
|
||||||
|
|
||||||
|
Then, to activate this alternative usermod, add `#define USE_ALT_DISPlAY` (NOTE: CASE SENSITIVE) to the `usermods_list.cpp` file,
|
||||||
or add `-D USE_ALT_DISPlAY` to the original `platformio_override.ini.sample` file
|
or add `-D USE_ALT_DISPlAY` to the original `platformio_override.ini.sample` file
|
||||||
|
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
These options are configurable in Config > Usermods
|
||||||
|
|
||||||
|
### Usermod Setup
|
||||||
|
|
||||||
|
* Global I2C GPIOs (HW) - Set the SDA and SCL pins
|
||||||
|
|
||||||
|
### 4LineDisplay
|
||||||
|
|
||||||
|
* `enabled` - enable/disable usermod
|
||||||
|
* `type` - display type in numeric format
|
||||||
|
* 1 = I2C SSD1306 128x32
|
||||||
|
* 2 = I2C SH1106 128x32
|
||||||
|
* 3 = I2C SSD1306 128x64 (4 double-height lines)
|
||||||
|
* 4 = I2C SSD1305 128x32
|
||||||
|
* 5 = I2C SSD1305 128x64 (4 double-height lines)
|
||||||
|
* 6 = SPI SSD1306 128x32
|
||||||
|
* 7 = SPI SSD1306 128x64 (4 double-height lines)
|
||||||
|
* 8 = SPI SSD1309 128x64 (4 double-height lines)
|
||||||
|
* 9 = I2C SSD1309 128x64 (4 double-height lines)
|
||||||
|
* `pin` - GPIO pins used for display; SPI displays can use SCK, MOSI, CS, DC & RST
|
||||||
|
* `flip` - flip/rotate display 180°
|
||||||
|
* `contrast` - set display contrast (higher contrast may reduce display lifetime)
|
||||||
|
* `screenTimeOutSec` - screen saver time-out in seconds
|
||||||
|
* `sleepMode` - enable/disable screen saver
|
||||||
|
* `clockMode` - enable/disable clock display in screen saver mode
|
||||||
|
* `showSeconds` - Show seconds on the clock display
|
||||||
|
* `i2c-freq-kHz` - I2C clock frequency in kHz (may help reduce dropped frames, range: 400-3400)
|
||||||
|
|
||||||
|
|
||||||
### PlatformIO requirements
|
### PlatformIO requirements
|
||||||
|
|
||||||
Note: the Four Line Display usermod requires the libraries `U8g2` and `Wire`.
|
Note: the Four Line Display usermod requires the libraries `U8g2` and `Wire`.
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
// for WLED.
|
// for WLED.
|
||||||
//
|
//
|
||||||
// Dependencies
|
// Dependencies
|
||||||
// * This Usermod works best, by far, when coupled
|
// * This Usermod works best, by far, when coupled
|
||||||
// with RotaryEncoderUI ALT Usermod.
|
// with RotaryEncoderUI ALT Usermod.
|
||||||
//
|
//
|
||||||
// Make sure to enable NTP and set your time zone in WLED Config | Time.
|
// Make sure to enable NTP and set your time zone in WLED Config | Time.
|
||||||
|
@ -89,7 +89,8 @@ typedef enum {
|
||||||
SSD1305_64, // U8X8_SSD1305_128X64_ADAFRUIT_HW_I2C
|
SSD1305_64, // U8X8_SSD1305_128X64_ADAFRUIT_HW_I2C
|
||||||
SSD1306_SPI, // U8X8_SSD1306_128X32_NONAME_HW_SPI
|
SSD1306_SPI, // U8X8_SSD1306_128X32_NONAME_HW_SPI
|
||||||
SSD1306_SPI64, // U8X8_SSD1306_128X64_NONAME_HW_SPI
|
SSD1306_SPI64, // U8X8_SSD1306_128X64_NONAME_HW_SPI
|
||||||
SSD1309_SPI64 // U8X8_SSD1309_128X64_NONAME0_4W_HW_SPI
|
SSD1309_SPI64, // U8X8_SSD1309_128X64_NONAME0_4W_HW_SPI
|
||||||
|
SSD1309_64 // U8X8_SSD1309_128X64_NONAME0_HW_I2C
|
||||||
} DisplayType;
|
} DisplayType;
|
||||||
|
|
||||||
|
|
||||||
|
@ -235,7 +236,7 @@ class FourLineDisplayUsermod : public Usermod {
|
||||||
void updateSpeed();
|
void updateSpeed();
|
||||||
void updateIntensity();
|
void updateIntensity();
|
||||||
void drawStatusIcons();
|
void drawStatusIcons();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* marks the position of the arrow showing
|
* marks the position of the arrow showing
|
||||||
* the current setting being changed
|
* the current setting being changed
|
||||||
|
@ -246,8 +247,8 @@ class FourLineDisplayUsermod : public Usermod {
|
||||||
//Draw the arrow for the current setting being changed
|
//Draw the arrow for the current setting being changed
|
||||||
void drawArrow();
|
void drawArrow();
|
||||||
|
|
||||||
//Display the current effect or palette (desiredEntry)
|
//Display the current effect or palette (desiredEntry)
|
||||||
// on the appropriate line (row).
|
// on the appropriate line (row).
|
||||||
void showCurrentEffectOrPalette(int inputEffPal, const char *qstring, uint8_t row);
|
void showCurrentEffectOrPalette(int inputEffPal, const char *qstring, uint8_t row);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -314,14 +315,14 @@ class FourLineDisplayUsermod : public Usermod {
|
||||||
* addToConfig() can be used to add custom persistent settings to the cfg.json file in the "um" (usermod) object.
|
* addToConfig() can be used to add custom persistent settings to the cfg.json file in the "um" (usermod) object.
|
||||||
* It will be called by WLED when settings are actually saved (for example, LED settings are saved)
|
* It will be called by WLED when settings are actually saved (for example, LED settings are saved)
|
||||||
* If you want to force saving the current state, use serializeConfig() in your loop().
|
* If you want to force saving the current state, use serializeConfig() in your loop().
|
||||||
*
|
*
|
||||||
* CAUTION: serializeConfig() will initiate a filesystem write operation.
|
* CAUTION: serializeConfig() will initiate a filesystem write operation.
|
||||||
* It might cause the LEDs to stutter and will cause flash wear if called too often.
|
* It might cause the LEDs to stutter and will cause flash wear if called too often.
|
||||||
* Use it sparingly and always in the loop, never in network callbacks!
|
* Use it sparingly and always in the loop, never in network callbacks!
|
||||||
*
|
*
|
||||||
* addToConfig() will also not yet add your setting to one of the settings pages automatically.
|
* addToConfig() will also not yet add your setting to one of the settings pages automatically.
|
||||||
* To make that work you still have to add the setting to the HTML, xml.cpp and set.cpp manually.
|
* To make that work you still have to add the setting to the HTML, xml.cpp and set.cpp manually.
|
||||||
*
|
*
|
||||||
* I highly recommend checking out the basics of ArduinoJson serialization and deserialization in order to use custom settings!
|
* I highly recommend checking out the basics of ArduinoJson serialization and deserialization in order to use custom settings!
|
||||||
*/
|
*/
|
||||||
void addToConfig(JsonObject& root) override;
|
void addToConfig(JsonObject& root) override;
|
||||||
|
@ -329,7 +330,7 @@ class FourLineDisplayUsermod : public Usermod {
|
||||||
/*
|
/*
|
||||||
* readFromConfig() can be used to read back the custom settings you added with addToConfig().
|
* readFromConfig() can be used to read back the custom settings you added with addToConfig().
|
||||||
* This is called by WLED when settings are loaded (currently this only happens once immediately after boot)
|
* This is called by WLED when settings are loaded (currently this only happens once immediately after boot)
|
||||||
*
|
*
|
||||||
* readFromConfig() is called BEFORE setup(). This means you can use your persistent values in setup() (e.g. pin assignments, buffer sizes),
|
* readFromConfig() is called BEFORE setup(). This means you can use your persistent values in setup() (e.g. pin assignments, buffer sizes),
|
||||||
* but also that if you want to write persistent values to a dynamic buffer, you'd need to allocate it here instead of in setup.
|
* but also that if you want to write persistent values to a dynamic buffer, you'd need to allocate it here instead of in setup.
|
||||||
* If you don't know what that is, don't fret. It most likely doesn't affect your use case :)
|
* If you don't know what that is, don't fret. It most likely doesn't affect your use case :)
|
||||||
|
@ -494,7 +495,7 @@ void FourLineDisplayUsermod::showTime() {
|
||||||
}
|
}
|
||||||
if (knownHour != hourCurrent) {
|
if (knownHour != hourCurrent) {
|
||||||
// only update date when hour changes
|
// only update date when hour changes
|
||||||
sprintf_P(lineBuffer, PSTR("%s %2d "), monthShortStr(month(localTime)), day(localTime));
|
sprintf_P(lineBuffer, PSTR("%s %2d "), monthShortStr(month(localTime)), day(localTime));
|
||||||
draw2x2String(2, lineHeight==1 ? 0 : lineHeight, lineBuffer); // adjust for 8 line displays, draw month and day
|
draw2x2String(2, lineHeight==1 ? 0 : lineHeight, lineBuffer); // adjust for 8 line displays, draw month and day
|
||||||
}
|
}
|
||||||
sprintf_P(lineBuffer,PSTR("%2d:%02d"), (useAMPM ? AmPmHour : hourCurrent), minuteCurrent);
|
sprintf_P(lineBuffer,PSTR("%2d:%02d"), (useAMPM ? AmPmHour : hourCurrent), minuteCurrent);
|
||||||
|
@ -556,6 +557,7 @@ void FourLineDisplayUsermod::setup() {
|
||||||
case SSD1306_64: u8x8 = (U8X8 *) new U8X8_SSD1306_128X64_NONAME_HW_I2C(); break;
|
case SSD1306_64: u8x8 = (U8X8 *) new U8X8_SSD1306_128X64_NONAME_HW_I2C(); break;
|
||||||
case SSD1305: u8x8 = (U8X8 *) new U8X8_SSD1305_128X32_ADAFRUIT_HW_I2C(); break;
|
case SSD1305: u8x8 = (U8X8 *) new U8X8_SSD1305_128X32_ADAFRUIT_HW_I2C(); break;
|
||||||
case SSD1305_64: u8x8 = (U8X8 *) new U8X8_SSD1305_128X64_ADAFRUIT_HW_I2C(); break;
|
case SSD1305_64: u8x8 = (U8X8 *) new U8X8_SSD1305_128X64_ADAFRUIT_HW_I2C(); break;
|
||||||
|
case SSD1309_64: u8x8 = (U8X8 *) new U8X8_SSD1309_128X64_NONAME0_HW_I2C(); break;
|
||||||
// U8X8 uses global SPI variable that is attached to VSPI bus on ESP32
|
// U8X8 uses global SPI variable that is attached to VSPI bus on ESP32
|
||||||
case SSD1306_SPI: u8x8 = (U8X8 *) new U8X8_SSD1306_128X32_UNIVISION_4W_HW_SPI(ioPin[0], ioPin[1], ioPin[2]); break; // Pins are cs, dc, reset
|
case SSD1306_SPI: u8x8 = (U8X8 *) new U8X8_SSD1306_128X32_UNIVISION_4W_HW_SPI(ioPin[0], ioPin[1], ioPin[2]); break; // Pins are cs, dc, reset
|
||||||
case SSD1306_SPI64: u8x8 = (U8X8 *) new U8X8_SSD1306_128X64_NONAME_4W_HW_SPI(ioPin[0], ioPin[1], ioPin[2]); break; // Pins are cs, dc, reset
|
case SSD1306_SPI64: u8x8 = (U8X8 *) new U8X8_SSD1306_128X64_NONAME_4W_HW_SPI(ioPin[0], ioPin[1], ioPin[2]); break; // Pins are cs, dc, reset
|
||||||
|
@ -581,7 +583,7 @@ void FourLineDisplayUsermod::setup() {
|
||||||
// gets called every time WiFi is (re-)connected. Initialize own network
|
// gets called every time WiFi is (re-)connected. Initialize own network
|
||||||
// interfaces here
|
// interfaces here
|
||||||
void FourLineDisplayUsermod::connected() {
|
void FourLineDisplayUsermod::connected() {
|
||||||
knownSsid = WiFi.SSID(); //apActive ? apSSID : WiFi.SSID(); //apActive ? WiFi.softAPSSID() :
|
knownSsid = WiFi.SSID(); //apActive ? apSSID : WiFi.SSID(); //apActive ? WiFi.softAPSSID() :
|
||||||
knownIp = Network.localIP(); //apActive ? IPAddress(4, 3, 2, 1) : Network.localIP();
|
knownIp = Network.localIP(); //apActive ? IPAddress(4, 3, 2, 1) : Network.localIP();
|
||||||
networkOverlay(PSTR("NETWORK INFO"),7000);
|
networkOverlay(PSTR("NETWORK INFO"),7000);
|
||||||
}
|
}
|
||||||
|
@ -637,7 +639,7 @@ void FourLineDisplayUsermod::redraw(bool forceRedraw) {
|
||||||
powerON = !powerON;
|
powerON = !powerON;
|
||||||
drawStatusIcons();
|
drawStatusIcons();
|
||||||
return;
|
return;
|
||||||
} else if (knownnightlight != nightlightActive) { //trigger moon icon
|
} else if (knownnightlight != nightlightActive) { //trigger moon icon
|
||||||
knownnightlight = nightlightActive;
|
knownnightlight = nightlightActive;
|
||||||
drawStatusIcons();
|
drawStatusIcons();
|
||||||
if (knownnightlight) {
|
if (knownnightlight) {
|
||||||
|
@ -652,7 +654,7 @@ void FourLineDisplayUsermod::redraw(bool forceRedraw) {
|
||||||
return;
|
return;
|
||||||
} else if (knownMode != effectCurrent || knownPalette != effectPalette) {
|
} else if (knownMode != effectCurrent || knownPalette != effectPalette) {
|
||||||
if (displayTurnedOff) needRedraw = true;
|
if (displayTurnedOff) needRedraw = true;
|
||||||
else {
|
else {
|
||||||
if (knownPalette != effectPalette) { showCurrentEffectOrPalette(effectPalette, JSON_palette_names, 2); knownPalette = effectPalette; }
|
if (knownPalette != effectPalette) { showCurrentEffectOrPalette(effectPalette, JSON_palette_names, 2); knownPalette = effectPalette; }
|
||||||
if (knownMode != effectCurrent) { showCurrentEffectOrPalette(effectCurrent, JSON_mode_names, 3); knownMode = effectCurrent; }
|
if (knownMode != effectCurrent) { showCurrentEffectOrPalette(effectCurrent, JSON_mode_names, 3); knownMode = effectCurrent; }
|
||||||
lastRedraw = now;
|
lastRedraw = now;
|
||||||
|
@ -703,7 +705,7 @@ void FourLineDisplayUsermod::redraw(bool forceRedraw) {
|
||||||
drawArrow();
|
drawArrow();
|
||||||
drawStatusIcons();
|
drawStatusIcons();
|
||||||
|
|
||||||
// Second row
|
// Second row
|
||||||
updateBrightness();
|
updateBrightness();
|
||||||
updateSpeed();
|
updateSpeed();
|
||||||
updateIntensity();
|
updateIntensity();
|
||||||
|
@ -805,8 +807,8 @@ void FourLineDisplayUsermod::drawArrow() {
|
||||||
lockRedraw = false;
|
lockRedraw = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Display the current effect or palette (desiredEntry)
|
//Display the current effect or palette (desiredEntry)
|
||||||
// on the appropriate line (row).
|
// on the appropriate line (row).
|
||||||
void FourLineDisplayUsermod::showCurrentEffectOrPalette(int inputEffPal, const char *qstring, uint8_t row) {
|
void FourLineDisplayUsermod::showCurrentEffectOrPalette(int inputEffPal, const char *qstring, uint8_t row) {
|
||||||
#if defined(ARDUINO_ARCH_ESP32) && defined(FLD_ESP32_USE_THREADS)
|
#if defined(ARDUINO_ARCH_ESP32) && defined(FLD_ESP32_USE_THREADS)
|
||||||
unsigned long now = millis();
|
unsigned long now = millis();
|
||||||
|
@ -857,7 +859,7 @@ void FourLineDisplayUsermod::showCurrentEffectOrPalette(int inputEffPal, const c
|
||||||
while (smallChars1 < (MAX_MODE_LINE_SPACE-1)) smallBuffer1[smallChars1++]=' ';
|
while (smallChars1 < (MAX_MODE_LINE_SPACE-1)) smallBuffer1[smallChars1++]=' ';
|
||||||
smallBuffer1[smallChars1] = 0;
|
smallBuffer1[smallChars1] = 0;
|
||||||
drawString(1, row*lineHeight, smallBuffer1, true);
|
drawString(1, row*lineHeight, smallBuffer1, true);
|
||||||
while (smallChars2 < (MAX_MODE_LINE_SPACE-1)) smallBuffer2[smallChars2++]=' ';
|
while (smallChars2 < (MAX_MODE_LINE_SPACE-1)) smallBuffer2[smallChars2++]=' ';
|
||||||
smallBuffer2[smallChars2] = 0;
|
smallBuffer2[smallChars2] = 0;
|
||||||
drawString(1, row*lineHeight+1, smallBuffer2, true);
|
drawString(1, row*lineHeight+1, smallBuffer2, true);
|
||||||
}
|
}
|
||||||
|
@ -1150,7 +1152,7 @@ void FourLineDisplayUsermod::onUpdateBegin(bool init) {
|
||||||
xTaskCreatePinnedToCore(
|
xTaskCreatePinnedToCore(
|
||||||
[](void * par) { // Function to implement the task
|
[](void * par) { // Function to implement the task
|
||||||
// see https://www.freertos.org/vtaskdelayuntil.html
|
// see https://www.freertos.org/vtaskdelayuntil.html
|
||||||
const TickType_t xFrequency = REFRESH_RATE_MS * portTICK_PERIOD_MS / 2;
|
const TickType_t xFrequency = REFRESH_RATE_MS * portTICK_PERIOD_MS / 2;
|
||||||
TickType_t xLastWakeTime = xTaskGetTickCount();
|
TickType_t xLastWakeTime = xTaskGetTickCount();
|
||||||
for(;;) {
|
for(;;) {
|
||||||
delay(1); // DO NOT DELETE THIS LINE! It is needed to give the IDLE(0) task enough time and to keep the watchdog happy.
|
delay(1); // DO NOT DELETE THIS LINE! It is needed to give the IDLE(0) task enough time and to keep the watchdog happy.
|
||||||
|
@ -1205,6 +1207,7 @@ void FourLineDisplayUsermod::appendConfigData() {
|
||||||
oappend(SET_F("addOption(dd,'SSD1306 128x64',3);"));
|
oappend(SET_F("addOption(dd,'SSD1306 128x64',3);"));
|
||||||
oappend(SET_F("addOption(dd,'SSD1305',4);"));
|
oappend(SET_F("addOption(dd,'SSD1305',4);"));
|
||||||
oappend(SET_F("addOption(dd,'SSD1305 128x64',5);"));
|
oappend(SET_F("addOption(dd,'SSD1305 128x64',5);"));
|
||||||
|
oappend(SET_F("addOption(dd,'SSD1309 128x64',9);"));
|
||||||
oappend(SET_F("addOption(dd,'SSD1306 SPI',6);"));
|
oappend(SET_F("addOption(dd,'SSD1306 SPI',6);"));
|
||||||
oappend(SET_F("addOption(dd,'SSD1306 SPI 128x64',7);"));
|
oappend(SET_F("addOption(dd,'SSD1306 SPI 128x64',7);"));
|
||||||
oappend(SET_F("addOption(dd,'SSD1309 SPI 128x64',8);"));
|
oappend(SET_F("addOption(dd,'SSD1309 SPI 128x64',8);"));
|
||||||
|
@ -1218,14 +1221,14 @@ void FourLineDisplayUsermod::appendConfigData() {
|
||||||
* addToConfig() can be used to add custom persistent settings to the cfg.json file in the "um" (usermod) object.
|
* addToConfig() can be used to add custom persistent settings to the cfg.json file in the "um" (usermod) object.
|
||||||
* It will be called by WLED when settings are actually saved (for example, LED settings are saved)
|
* It will be called by WLED when settings are actually saved (for example, LED settings are saved)
|
||||||
* If you want to force saving the current state, use serializeConfig() in your loop().
|
* If you want to force saving the current state, use serializeConfig() in your loop().
|
||||||
*
|
*
|
||||||
* CAUTION: serializeConfig() will initiate a filesystem write operation.
|
* CAUTION: serializeConfig() will initiate a filesystem write operation.
|
||||||
* It might cause the LEDs to stutter and will cause flash wear if called too often.
|
* It might cause the LEDs to stutter and will cause flash wear if called too often.
|
||||||
* Use it sparingly and always in the loop, never in network callbacks!
|
* Use it sparingly and always in the loop, never in network callbacks!
|
||||||
*
|
*
|
||||||
* addToConfig() will also not yet add your setting to one of the settings pages automatically.
|
* addToConfig() will also not yet add your setting to one of the settings pages automatically.
|
||||||
* To make that work you still have to add the setting to the HTML, xml.cpp and set.cpp manually.
|
* To make that work you still have to add the setting to the HTML, xml.cpp and set.cpp manually.
|
||||||
*
|
*
|
||||||
* I highly recommend checking out the basics of ArduinoJson serialization and deserialization in order to use custom settings!
|
* I highly recommend checking out the basics of ArduinoJson serialization and deserialization in order to use custom settings!
|
||||||
*/
|
*/
|
||||||
void FourLineDisplayUsermod::addToConfig(JsonObject& root) {
|
void FourLineDisplayUsermod::addToConfig(JsonObject& root) {
|
||||||
|
@ -1252,7 +1255,7 @@ void FourLineDisplayUsermod::addToConfig(JsonObject& root) {
|
||||||
/*
|
/*
|
||||||
* readFromConfig() can be used to read back the custom settings you added with addToConfig().
|
* readFromConfig() can be used to read back the custom settings you added with addToConfig().
|
||||||
* This is called by WLED when settings are loaded (currently this only happens once immediately after boot)
|
* This is called by WLED when settings are loaded (currently this only happens once immediately after boot)
|
||||||
*
|
*
|
||||||
* readFromConfig() is called BEFORE setup(). This means you can use your persistent values in setup() (e.g. pin assignments, buffer sizes),
|
* readFromConfig() is called BEFORE setup(). This means you can use your persistent values in setup() (e.g. pin assignments, buffer sizes),
|
||||||
* but also that if you want to write persistent values to a dynamic buffer, you'd need to allocate it here instead of in setup.
|
* but also that if you want to write persistent values to a dynamic buffer, you'd need to allocate it here instead of in setup.
|
||||||
* If you don't know what that is, don't fret. It most likely doesn't affect your use case :)
|
* If you don't know what that is, don't fret. It most likely doesn't affect your use case :)
|
||||||
|
@ -1346,6 +1349,10 @@ bool FourLineDisplayUsermod::readFromConfig(JsonObject& root) {
|
||||||
u8x8_Setup(u8x8->getU8x8(), u8x8_d_ssd1305_128x64_adafruit, u8x8_cad_ssd13xx_fast_i2c, u8x8_byte_arduino_hw_i2c, u8x8_gpio_and_delay_arduino);
|
u8x8_Setup(u8x8->getU8x8(), u8x8_d_ssd1305_128x64_adafruit, u8x8_cad_ssd13xx_fast_i2c, u8x8_byte_arduino_hw_i2c, u8x8_gpio_and_delay_arduino);
|
||||||
u8x8_SetPin_HW_I2C(u8x8->getU8x8(), U8X8_PIN_NONE, U8X8_PIN_NONE, U8X8_PIN_NONE);
|
u8x8_SetPin_HW_I2C(u8x8->getU8x8(), U8X8_PIN_NONE, U8X8_PIN_NONE, U8X8_PIN_NONE);
|
||||||
break;
|
break;
|
||||||
|
case SSD1309_64:
|
||||||
|
u8x8_Setup(u8x8->getU8x8(), u8x8_d_ssd1309_128x64_noname0, u8x8_cad_ssd13xx_fast_i2c, u8x8_byte_arduino_hw_i2c, u8x8_gpio_and_delay_arduino);
|
||||||
|
u8x8_SetPin_HW_I2C(u8x8->getU8x8(), U8X8_PIN_NONE, U8X8_PIN_NONE, U8X8_PIN_NONE);
|
||||||
|
break;
|
||||||
case SSD1306_SPI:
|
case SSD1306_SPI:
|
||||||
u8x8_Setup(u8x8->getU8x8(), u8x8_d_ssd1306_128x32_univision, u8x8_cad_001, u8x8_byte_arduino_hw_spi, u8x8_gpio_and_delay_arduino);
|
u8x8_Setup(u8x8->getU8x8(), u8x8_d_ssd1306_128x32_univision, u8x8_cad_001, u8x8_byte_arduino_hw_spi, u8x8_gpio_and_delay_arduino);
|
||||||
u8x8_SetPin_4Wire_HW_SPI(u8x8->getU8x8(), ioPin[0], ioPin[1], ioPin[2]); // Pins are cs, dc, reset
|
u8x8_SetPin_4Wire_HW_SPI(u8x8->getU8x8(), ioPin[0], ioPin[1], ioPin[2]); // Pins are cs, dc, reset
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
[platformio]
|
||||||
|
default_envs = esp32dev
|
||||||
|
|
||||||
|
[env:esp32dev]
|
||||||
|
board = esp32dev
|
||||||
|
platform = ${esp32.platform}
|
||||||
|
build_unflags = ${common.build_unflags}
|
||||||
|
build_flags =
|
||||||
|
${common.build_flags_esp32}
|
||||||
|
-D USERMOD_FOUR_LINE_DISPLAY -D USE_ALT_DISPlAY
|
||||||
|
-D USERMOD_ROTARY_ENCODER_UI -D ENCODER_DT_PIN=18 -D ENCODER_CLK_PIN=5 -D ENCODER_SW_PIN=19
|
||||||
|
upload_speed = 460800
|
||||||
|
lib_deps =
|
||||||
|
${esp32.lib_deps}
|
||||||
|
U8g2@~2.34.4
|
||||||
|
Wire
|
||||||
|
|
|
@ -8,18 +8,18 @@ The core of these usermods are a copy of the originals. The main changes are to
|
||||||
The display usermod UI has been completely changed.
|
The display usermod UI has been completely changed.
|
||||||
|
|
||||||
|
|
||||||
The changes made to the RotaryEncoder usermod were made to support the new UI in the display usermod.
|
The changes made to the RotaryEncoder usermod were made to support the new UI in the display usermod.
|
||||||
Without the display, it functions identical to the original.
|
Without the display, it functions identical to the original.
|
||||||
The original "usermod_v2_auto_save" will not work with the display just yet.
|
The original "usermod_v2_auto_save" will not work with the display just yet.
|
||||||
|
|
||||||
Press the encoder to cycle through the options:
|
Press the encoder to cycle through the options:
|
||||||
*Brightness
|
* Brightness
|
||||||
*Speed
|
* Speed
|
||||||
*Intensity
|
* Intensity
|
||||||
*Palette
|
* Palette
|
||||||
*Effect
|
* Effect
|
||||||
*Main Color (only if display is used)
|
* Main Color (only if display is used)
|
||||||
*Saturation (only if display is used)
|
* Saturation (only if display is used)
|
||||||
|
|
||||||
Press and hold the encoder to display Network Info
|
Press and hold the encoder to display Network Info
|
||||||
if AP is active, it will display the AP, SSID and Password
|
if AP is active, it will display the AP, SSID and Password
|
||||||
|
@ -30,10 +30,23 @@ Also shows if the timer is enabled.
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
Please refer to the original `usermod_v2_rotary_encoder_ui` readme for the main instructions.<br/>
|
Copy the example `platformio_override.sample.ini` to the root directory of your particular build and rename it to `platformio_override.ini`.
|
||||||
To activate this alternative usermod, add `#define USE_ALT_DISPlAY` to the `usermods_list.cpp` file,
|
|
||||||
or add `-D USE_ALT_DISPlAY` to the original `platformio_override.ini.sample` file.
|
|
||||||
|
|
||||||
|
To activate this alternative usermod, add `#define USE_ALT_DISPlAY` (NOTE: CASE SENSITIVE) to the `usermods_list.cpp` file, or add `-D USE_ALT_DISPlAY` to your `platformio_override.ini` file
|
||||||
|
|
||||||
|
### Define Your Options
|
||||||
|
|
||||||
|
* `USERMOD_ROTARY_ENCODER_UI` - define this to have this user mod included wled00\usermods_list.cpp
|
||||||
|
* `USERMOD_FOUR_LINE_DISPLAY` - define this to have this the Four Line Display mod included wled00\usermods_list.cpp
|
||||||
|
also tells this usermod that the display is available
|
||||||
|
(see the Four Line Display usermod `readme.md` for more details)
|
||||||
|
* `USE_ALT_DISPlAY` - Mandatory to use Four Line Display
|
||||||
|
* `ENCODER_DT_PIN` - defaults to 18
|
||||||
|
* `ENCODER_CLK_PIN` - defaults to 5
|
||||||
|
* `ENCODER_SW_PIN` - defaults to 19
|
||||||
|
* `USERMOD_ROTARY_ENCODER_GPIO` - GPIO functionality:
|
||||||
|
`INPUT_PULLUP` to use internal pull-up
|
||||||
|
`INPUT` to use pull-up on the PCB
|
||||||
|
|
||||||
### PlatformIO requirements
|
### PlatformIO requirements
|
||||||
|
|
||||||
|
|
|
@ -392,26 +392,26 @@ byte RotaryEncoderUIUsermod::readPin(uint8_t pin) {
|
||||||
* modes_alpha_indexes and palettes_alpha_indexes.
|
* modes_alpha_indexes and palettes_alpha_indexes.
|
||||||
*/
|
*/
|
||||||
void RotaryEncoderUIUsermod::sortModesAndPalettes() {
|
void RotaryEncoderUIUsermod::sortModesAndPalettes() {
|
||||||
DEBUG_PRINTLN(F("Sorting modes and palettes."));
|
DEBUG_PRINT(F("Sorting modes: ")); DEBUG_PRINTLN(strip.getModeCount());
|
||||||
//modes_qstrings = re_findModeStrings(JSON_mode_names, strip.getModeCount());
|
//modes_qstrings = re_findModeStrings(JSON_mode_names, strip.getModeCount());
|
||||||
modes_qstrings = strip.getModeDataSrc();
|
modes_qstrings = strip.getModeDataSrc();
|
||||||
modes_alpha_indexes = re_initIndexArray(strip.getModeCount());
|
modes_alpha_indexes = re_initIndexArray(strip.getModeCount());
|
||||||
re_sortModes(modes_qstrings, modes_alpha_indexes, strip.getModeCount(), MODE_SORT_SKIP_COUNT);
|
re_sortModes(modes_qstrings, modes_alpha_indexes, strip.getModeCount(), MODE_SORT_SKIP_COUNT);
|
||||||
|
|
||||||
palettes_qstrings = re_findModeStrings(JSON_palette_names, strip.getPaletteCount()+strip.customPalettes.size());
|
DEBUG_PRINT(F("Sorting palettes: ")); DEBUG_PRINT(strip.getPaletteCount()); DEBUG_PRINT('/'); DEBUG_PRINTLN(strip.customPalettes.size());
|
||||||
palettes_alpha_indexes = re_initIndexArray(strip.getPaletteCount()+strip.customPalettes.size());
|
palettes_qstrings = re_findModeStrings(JSON_palette_names, strip.getPaletteCount());
|
||||||
|
palettes_alpha_indexes = re_initIndexArray(strip.getPaletteCount());
|
||||||
if (strip.customPalettes.size()) {
|
if (strip.customPalettes.size()) {
|
||||||
for (int i=0; i<strip.customPalettes.size(); i++) {
|
for (int i=0; i<strip.customPalettes.size(); i++) {
|
||||||
palettes_alpha_indexes[strip.getPaletteCount()+i] = 255-i;
|
palettes_alpha_indexes[strip.getPaletteCount()-strip.customPalettes.size()+i] = 255-i;
|
||||||
palettes_qstrings[strip.getPaletteCount()+i] = PSTR("~Custom~");
|
palettes_qstrings[strip.getPaletteCount()-strip.customPalettes.size()+i] = PSTR("~Custom~");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// How many palette names start with '*' and should not be sorted?
|
// How many palette names start with '*' and should not be sorted?
|
||||||
// (Also skipping the first one, 'Default').
|
// (Also skipping the first one, 'Default').
|
||||||
int skipPaletteCount = 1;
|
int skipPaletteCount = 1;
|
||||||
while (pgm_read_byte_near(palettes_qstrings[skipPaletteCount++]) == '*') ;
|
while (pgm_read_byte_near(palettes_qstrings[skipPaletteCount]) == '*') skipPaletteCount++;
|
||||||
re_sortModes(palettes_qstrings, palettes_alpha_indexes, strip.getPaletteCount(), skipPaletteCount);
|
re_sortModes(palettes_qstrings, palettes_alpha_indexes, strip.getPaletteCount()-strip.customPalettes.size(), skipPaletteCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
byte *RotaryEncoderUIUsermod::re_initIndexArray(int numModes) {
|
byte *RotaryEncoderUIUsermod::re_initIndexArray(int numModes) {
|
||||||
|
|
|
@ -1125,57 +1125,62 @@ uint16_t mode_running_random(void) {
|
||||||
static const char _data_FX_MODE_RUNNING_RANDOM[] PROGMEM = "Stream@!,Zone size;;!";
|
static const char _data_FX_MODE_RUNNING_RANDOM[] PROGMEM = "Stream@!,Zone size;;!";
|
||||||
|
|
||||||
|
|
||||||
uint16_t larson_scanner(bool dual) {
|
|
||||||
if (SEGLEN == 1) return mode_static();
|
|
||||||
uint16_t counter = strip.now * ((SEGMENT.speed >> 2) +8);
|
|
||||||
uint16_t index = (counter * SEGLEN) >> 16;
|
|
||||||
|
|
||||||
SEGMENT.fade_out(SEGMENT.intensity);
|
|
||||||
|
|
||||||
if (SEGENV.step > index && SEGENV.step - index > SEGLEN/2) {
|
|
||||||
SEGENV.aux0 = !SEGENV.aux0;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = SEGENV.step; i < index; i++) {
|
|
||||||
uint16_t j = (SEGENV.aux0)?i:SEGLEN-1-i;
|
|
||||||
SEGMENT.setPixelColor( j, SEGMENT.color_from_palette(j, true, PALETTE_SOLID_WRAP, 0));
|
|
||||||
}
|
|
||||||
if (dual) {
|
|
||||||
uint32_t c;
|
|
||||||
if (SEGCOLOR(2) != 0) {
|
|
||||||
c = SEGCOLOR(2);
|
|
||||||
} else {
|
|
||||||
c = SEGMENT.color_from_palette(index, true, PALETTE_SOLID_WRAP, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = SEGENV.step; i < index; i++) {
|
|
||||||
uint16_t j = (SEGENV.aux0)?SEGLEN-1-i:i;
|
|
||||||
SEGMENT.setPixelColor(j, c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SEGENV.step = index;
|
|
||||||
return FRAMETIME;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* K.I.T.T.
|
* K.I.T.T.
|
||||||
*/
|
*/
|
||||||
uint16_t mode_larson_scanner(void){
|
uint16_t mode_larson_scanner(void){
|
||||||
return larson_scanner(false);
|
if (SEGLEN == 1) return mode_static();
|
||||||
}
|
|
||||||
static const char _data_FX_MODE_LARSON_SCANNER[] PROGMEM = "Scanner@!,Fade rate;!,!;!;;m12=0";
|
|
||||||
|
|
||||||
|
const unsigned speed = FRAMETIME * map(SEGMENT.speed, 0, 255, 96, 2); // map into useful range
|
||||||
|
const unsigned pixels = SEGLEN / speed; // how many pixels to advance per frame
|
||||||
|
|
||||||
|
SEGMENT.fade_out(255-SEGMENT.intensity);
|
||||||
|
|
||||||
|
if (SEGENV.step > strip.now) return FRAMETIME; // we have a pause
|
||||||
|
|
||||||
|
unsigned index = SEGENV.aux1 + pixels;
|
||||||
|
// are we slow enough to use frames per pixel?
|
||||||
|
if (pixels == 0) {
|
||||||
|
const unsigned frames = speed / SEGLEN; // how many frames per 1 pixel
|
||||||
|
if (SEGENV.step++ < frames) return FRAMETIME;
|
||||||
|
SEGENV.step = 0;
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index > SEGLEN) {
|
||||||
|
|
||||||
|
SEGENV.aux0 = !SEGENV.aux0; // change direction
|
||||||
|
SEGENV.aux1 = 0; // reset position
|
||||||
|
// set delay
|
||||||
|
if (SEGENV.aux0 || SEGMENT.check2) SEGENV.step = strip.now + SEGMENT.custom1 * 25; // multiply by 25ms
|
||||||
|
else SEGENV.step = 0;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// paint as many pixels as needed
|
||||||
|
for (unsigned i = SEGENV.aux1; i < index; i++) {
|
||||||
|
unsigned j = (SEGENV.aux0) ? i : SEGLEN - 1 - i;
|
||||||
|
uint32_t c = SEGMENT.color_from_palette(j, true, PALETTE_SOLID_WRAP, 0);
|
||||||
|
SEGMENT.setPixelColor(j, c);
|
||||||
|
if (SEGMENT.check1) {
|
||||||
|
SEGMENT.setPixelColor(SEGLEN - 1 - j, SEGCOLOR(2) ? SEGCOLOR(2) : c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SEGENV.aux1 = index;
|
||||||
|
}
|
||||||
|
return FRAMETIME;
|
||||||
|
}
|
||||||
|
static const char _data_FX_MODE_LARSON_SCANNER[] PROGMEM = "Scanner@!,Trail,Delay,,,Dual,Bi-delay;!,!,!;!;;m12=0,c1=0";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Creates two Larson scanners moving in opposite directions
|
* Creates two Larson scanners moving in opposite directions
|
||||||
* Custom mode by Keith Lord: https://github.com/kitesurfer1404/WS2812FX/blob/master/src/custom/DualLarson.h
|
* Custom mode by Keith Lord: https://github.com/kitesurfer1404/WS2812FX/blob/master/src/custom/DualLarson.h
|
||||||
*/
|
*/
|
||||||
uint16_t mode_dual_larson_scanner(void){
|
uint16_t mode_dual_larson_scanner(void){
|
||||||
return larson_scanner(true);
|
SEGMENT.check1 = true;
|
||||||
|
return mode_larson_scanner();
|
||||||
}
|
}
|
||||||
static const char _data_FX_MODE_DUAL_LARSON_SCANNER[] PROGMEM = "Scanner Dual@!,Fade rate;!,!,!;!;;m12=0";
|
static const char _data_FX_MODE_DUAL_LARSON_SCANNER[] PROGMEM = "Scanner Dual@!,Trail,Delay,,,Dual,Bi-delay;!,!,!;!;;m12=0,c1=0";
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -3013,8 +3018,12 @@ uint16_t mode_bouncing_balls(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int pos = roundf(balls[i].height * (SEGLEN - 1));
|
int pos = roundf(balls[i].height * (SEGLEN - 1));
|
||||||
|
#ifdef WLED_USE_AA_PIXELS
|
||||||
if (SEGLEN<32) SEGMENT.setPixelColor(indexToVStrip(pos, stripNr), color); // encode virtual strip into index
|
if (SEGLEN<32) SEGMENT.setPixelColor(indexToVStrip(pos, stripNr), color); // encode virtual strip into index
|
||||||
else SEGMENT.setPixelColor(balls[i].height + (stripNr+1)*10.0f, color);
|
else SEGMENT.setPixelColor(balls[i].height + (stripNr+1)*10.0f, color);
|
||||||
|
#else
|
||||||
|
SEGMENT.setPixelColor(indexToVStrip(pos, stripNr), color); // encode virtual strip into index
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -6047,8 +6056,8 @@ uint16_t mode_2Dfloatingblobs(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
uint32_t c = SEGMENT.color_from_palette(blob->color[i], false, false, 0);
|
uint32_t c = SEGMENT.color_from_palette(blob->color[i], false, false, 0);
|
||||||
if (blob->r[i] > 1.f) SEGMENT.fill_circle(blob->x[i], blob->y[i], roundf(blob->r[i]), c);
|
if (blob->r[i] > 1.f) SEGMENT.fill_circle(roundf(blob->x[i]), roundf(blob->y[i]), roundf(blob->r[i]), c);
|
||||||
else SEGMENT.setPixelColorXY(blob->x[i], blob->y[i], c);
|
else SEGMENT.setPixelColorXY((int)roundf(blob->x[i]), (int)roundf(blob->y[i]), c);
|
||||||
// move x
|
// move x
|
||||||
if (blob->x[i] + blob->r[i] >= cols - 1) blob->x[i] += (blob->sX[i] * ((cols - 1 - blob->x[i]) / blob->r[i] + 0.005f));
|
if (blob->x[i] + blob->r[i] >= cols - 1) blob->x[i] += (blob->sX[i] * ((cols - 1 - blob->x[i]) / blob->r[i] + 0.005f));
|
||||||
else if (blob->x[i] - blob->r[i] <= 0) blob->x[i] += (blob->sX[i] * (blob->x[i] / blob->r[i] + 0.005f));
|
else if (blob->x[i] - blob->r[i] <= 0) blob->x[i] += (blob->sX[i] * (blob->x[i] / blob->r[i] + 0.005f));
|
||||||
|
|
32
wled00/FX.h
32
wled00/FX.h
|
@ -59,13 +59,12 @@
|
||||||
/* Not used in all effects yet */
|
/* Not used in all effects yet */
|
||||||
#define WLED_FPS 42
|
#define WLED_FPS 42
|
||||||
#define FRAMETIME_FIXED (1000/WLED_FPS)
|
#define FRAMETIME_FIXED (1000/WLED_FPS)
|
||||||
//#define FRAMETIME _frametime
|
|
||||||
#define FRAMETIME strip.getFrameTime()
|
#define FRAMETIME strip.getFrameTime()
|
||||||
|
|
||||||
/* each segment uses 82 bytes of SRAM memory, so if you're application fails because of
|
/* each segment uses 82 bytes of SRAM memory, so if you're application fails because of
|
||||||
insufficient memory, decreasing MAX_NUM_SEGMENTS may help */
|
insufficient memory, decreasing MAX_NUM_SEGMENTS may help */
|
||||||
#ifdef ESP8266
|
#ifdef ESP8266
|
||||||
#define MAX_NUM_SEGMENTS 12
|
#define MAX_NUM_SEGMENTS 16
|
||||||
/* How much data bytes all segments combined may allocate */
|
/* How much data bytes all segments combined may allocate */
|
||||||
#define MAX_SEGMENT_DATA 5120
|
#define MAX_SEGMENT_DATA 5120
|
||||||
#else
|
#else
|
||||||
|
@ -73,11 +72,7 @@
|
||||||
#define MAX_NUM_SEGMENTS 32
|
#define MAX_NUM_SEGMENTS 32
|
||||||
#endif
|
#endif
|
||||||
#if defined(ARDUINO_ARCH_ESP32S2)
|
#if defined(ARDUINO_ARCH_ESP32S2)
|
||||||
#if defined(BOARD_HAS_PSRAM) && defined(WLED_USE_PSRAM)
|
#define MAX_SEGMENT_DATA MAX_NUM_SEGMENTS*768 // 24k by default (S2 is short on free RAM)
|
||||||
#define MAX_SEGMENT_DATA MAX_NUM_SEGMENTS*1024 // 32k by default
|
|
||||||
#else
|
|
||||||
#define MAX_SEGMENT_DATA MAX_NUM_SEGMENTS*768 // 24k by default
|
|
||||||
#endif
|
|
||||||
#else
|
#else
|
||||||
#define MAX_SEGMENT_DATA MAX_NUM_SEGMENTS*1280 // 40k by default
|
#define MAX_SEGMENT_DATA MAX_NUM_SEGMENTS*1280 // 40k by default
|
||||||
#endif
|
#endif
|
||||||
|
@ -187,7 +182,7 @@
|
||||||
#define FX_MODE_LIGHTNING 57
|
#define FX_MODE_LIGHTNING 57
|
||||||
#define FX_MODE_ICU 58
|
#define FX_MODE_ICU 58
|
||||||
#define FX_MODE_MULTI_COMET 59
|
#define FX_MODE_MULTI_COMET 59
|
||||||
#define FX_MODE_DUAL_LARSON_SCANNER 60
|
#define FX_MODE_DUAL_LARSON_SCANNER 60 // candidate for removal (use Scanner with with check 1)
|
||||||
#define FX_MODE_RANDOM_CHASE 61
|
#define FX_MODE_RANDOM_CHASE 61
|
||||||
#define FX_MODE_OSCILLATE 62
|
#define FX_MODE_OSCILLATE 62
|
||||||
#define FX_MODE_PRIDE_2015 63
|
#define FX_MODE_PRIDE_2015 63
|
||||||
|
@ -580,12 +575,14 @@ typedef struct Segment {
|
||||||
inline void setPixelColor(unsigned n, uint32_t c) { setPixelColor(int(n), c); }
|
inline void setPixelColor(unsigned n, uint32_t c) { setPixelColor(int(n), c); }
|
||||||
inline void setPixelColor(int n, byte r, byte g, byte b, byte w = 0) { setPixelColor(n, RGBW32(r,g,b,w)); }
|
inline void setPixelColor(int n, byte r, byte g, byte b, byte w = 0) { setPixelColor(n, RGBW32(r,g,b,w)); }
|
||||||
inline void setPixelColor(int n, CRGB c) { setPixelColor(n, RGBW32(c.r,c.g,c.b,0)); }
|
inline void setPixelColor(int n, CRGB c) { setPixelColor(n, RGBW32(c.r,c.g,c.b,0)); }
|
||||||
|
#ifdef WLED_USE_AA_PIXELS
|
||||||
void setPixelColor(float i, uint32_t c, bool aa = true);
|
void setPixelColor(float i, uint32_t c, bool aa = true);
|
||||||
inline void setPixelColor(float i, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0, bool aa = true) { setPixelColor(i, RGBW32(r,g,b,w), aa); }
|
inline void setPixelColor(float i, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0, bool aa = true) { setPixelColor(i, RGBW32(r,g,b,w), aa); }
|
||||||
inline void setPixelColor(float i, CRGB c, bool aa = true) { setPixelColor(i, RGBW32(c.r,c.g,c.b,0), aa); }
|
inline void setPixelColor(float i, CRGB c, bool aa = true) { setPixelColor(i, RGBW32(c.r,c.g,c.b,0), aa); }
|
||||||
|
#endif
|
||||||
uint32_t getPixelColor(int i);
|
uint32_t getPixelColor(int i);
|
||||||
// 1D support functions (some implement 2D as well)
|
// 1D support functions (some implement 2D as well)
|
||||||
void blur(uint8_t);
|
void blur(uint8_t, bool smear = false);
|
||||||
void fill(uint32_t c);
|
void fill(uint32_t c);
|
||||||
void fade_out(uint8_t r);
|
void fade_out(uint8_t r);
|
||||||
void fadeToBlackBy(uint8_t fadeBy);
|
void fadeToBlackBy(uint8_t fadeBy);
|
||||||
|
@ -608,10 +605,12 @@ typedef struct Segment {
|
||||||
inline void setPixelColorXY(unsigned x, unsigned y, uint32_t c) { setPixelColorXY(int(x), int(y), c); }
|
inline void setPixelColorXY(unsigned x, unsigned y, uint32_t c) { setPixelColorXY(int(x), int(y), c); }
|
||||||
inline void setPixelColorXY(int x, int y, byte r, byte g, byte b, byte w = 0) { setPixelColorXY(x, y, RGBW32(r,g,b,w)); }
|
inline void setPixelColorXY(int x, int y, byte r, byte g, byte b, byte w = 0) { setPixelColorXY(x, y, RGBW32(r,g,b,w)); }
|
||||||
inline void setPixelColorXY(int x, int y, CRGB c) { setPixelColorXY(x, y, RGBW32(c.r,c.g,c.b,0)); }
|
inline void setPixelColorXY(int x, int y, CRGB c) { setPixelColorXY(x, y, RGBW32(c.r,c.g,c.b,0)); }
|
||||||
|
#ifdef WLED_USE_AA_PIXELS
|
||||||
void setPixelColorXY(float x, float y, uint32_t c, bool aa = true);
|
void setPixelColorXY(float x, float y, uint32_t c, bool aa = true);
|
||||||
inline void setPixelColorXY(float x, float y, byte r, byte g, byte b, byte w = 0, bool aa = true) { setPixelColorXY(x, y, RGBW32(r,g,b,w), aa); }
|
inline void setPixelColorXY(float x, float y, byte r, byte g, byte b, byte w = 0, bool aa = true) { setPixelColorXY(x, y, RGBW32(r,g,b,w), aa); }
|
||||||
inline void setPixelColorXY(float x, float y, CRGB c, bool aa = true) { setPixelColorXY(x, y, RGBW32(c.r,c.g,c.b,0), aa); }
|
inline void setPixelColorXY(float x, float y, CRGB c, bool aa = true) { setPixelColorXY(x, y, RGBW32(c.r,c.g,c.b,0), aa); }
|
||||||
uint32_t getPixelColorXY(uint16_t x, uint16_t y);
|
#endif
|
||||||
|
uint32_t getPixelColorXY(int x, int y);
|
||||||
// 2D support functions
|
// 2D support functions
|
||||||
inline void blendPixelColorXY(uint16_t x, uint16_t y, uint32_t color, uint8_t blend) { setPixelColorXY(x, y, color_blend(getPixelColorXY(x,y), color, blend)); }
|
inline void blendPixelColorXY(uint16_t x, uint16_t y, uint32_t color, uint8_t blend) { setPixelColorXY(x, y, color_blend(getPixelColorXY(x,y), color, blend)); }
|
||||||
inline void blendPixelColorXY(uint16_t x, uint16_t y, CRGB c, uint8_t blend) { blendPixelColorXY(x, y, RGBW32(c.r,c.g,c.b,0), blend); }
|
inline void blendPixelColorXY(uint16_t x, uint16_t y, CRGB c, uint8_t blend) { blendPixelColorXY(x, y, RGBW32(c.r,c.g,c.b,0), blend); }
|
||||||
|
@ -620,8 +619,8 @@ typedef struct Segment {
|
||||||
inline void addPixelColorXY(int x, int y, CRGB c, bool fast = false) { addPixelColorXY(x, y, RGBW32(c.r,c.g,c.b,0), fast); }
|
inline void addPixelColorXY(int x, int y, CRGB c, bool fast = false) { addPixelColorXY(x, y, RGBW32(c.r,c.g,c.b,0), fast); }
|
||||||
inline void fadePixelColorXY(uint16_t x, uint16_t y, uint8_t fade) { setPixelColorXY(x, y, color_fade(getPixelColorXY(x,y), fade, true)); }
|
inline void fadePixelColorXY(uint16_t x, uint16_t y, uint8_t fade) { setPixelColorXY(x, y, color_fade(getPixelColorXY(x,y), fade, true)); }
|
||||||
void box_blur(uint16_t i, bool vertical, fract8 blur_amount); // 1D box blur (with weight)
|
void box_blur(uint16_t i, bool vertical, fract8 blur_amount); // 1D box blur (with weight)
|
||||||
void blurRow(uint16_t row, fract8 blur_amount);
|
void blurRow(uint32_t row, fract8 blur_amount, bool smear = false);
|
||||||
void blurCol(uint16_t col, fract8 blur_amount);
|
void blurCol(uint32_t col, fract8 blur_amount, bool smear = false);
|
||||||
void moveX(int8_t delta, bool wrap = false);
|
void moveX(int8_t delta, bool wrap = false);
|
||||||
void moveY(int8_t delta, bool wrap = false);
|
void moveY(int8_t delta, bool wrap = false);
|
||||||
void move(uint8_t dir, uint8_t delta, bool wrap = false);
|
void move(uint8_t dir, uint8_t delta, bool wrap = false);
|
||||||
|
@ -640,11 +639,14 @@ typedef struct Segment {
|
||||||
#else
|
#else
|
||||||
inline uint16_t XY(uint16_t x, uint16_t y) { return x; }
|
inline uint16_t XY(uint16_t x, uint16_t y) { return x; }
|
||||||
inline void setPixelColorXY(int x, int y, uint32_t c) { setPixelColor(x, c); }
|
inline void setPixelColorXY(int x, int y, uint32_t c) { setPixelColor(x, c); }
|
||||||
|
inline void setPixelColorXY(unsigned x, unsigned y, uint32_t c) { setPixelColor(int(x), c); }
|
||||||
inline void setPixelColorXY(int x, int y, byte r, byte g, byte b, byte w = 0) { setPixelColor(x, RGBW32(r,g,b,w)); }
|
inline void setPixelColorXY(int x, int y, byte r, byte g, byte b, byte w = 0) { setPixelColor(x, RGBW32(r,g,b,w)); }
|
||||||
inline void setPixelColorXY(int x, int y, CRGB c) { setPixelColor(x, RGBW32(c.r,c.g,c.b,0)); }
|
inline void setPixelColorXY(int x, int y, CRGB c) { setPixelColor(x, RGBW32(c.r,c.g,c.b,0)); }
|
||||||
|
#ifdef WLED_USE_AA_PIXELS
|
||||||
inline void setPixelColorXY(float x, float y, uint32_t c, bool aa = true) { setPixelColor(x, c, aa); }
|
inline void setPixelColorXY(float x, float y, uint32_t c, bool aa = true) { setPixelColor(x, c, aa); }
|
||||||
inline void setPixelColorXY(float x, float y, byte r, byte g, byte b, byte w = 0, bool aa = true) { setPixelColor(x, RGBW32(r,g,b,w), aa); }
|
inline void setPixelColorXY(float x, float y, byte r, byte g, byte b, byte w = 0, bool aa = true) { setPixelColor(x, RGBW32(r,g,b,w), aa); }
|
||||||
inline void setPixelColorXY(float x, float y, CRGB c, bool aa = true) { setPixelColor(x, RGBW32(c.r,c.g,c.b,0), aa); }
|
inline void setPixelColorXY(float x, float y, CRGB c, bool aa = true) { setPixelColor(x, RGBW32(c.r,c.g,c.b,0), aa); }
|
||||||
|
#endif
|
||||||
inline uint32_t getPixelColorXY(uint16_t x, uint16_t y) { return getPixelColor(x); }
|
inline uint32_t getPixelColorXY(uint16_t x, uint16_t y) { return getPixelColor(x); }
|
||||||
inline void blendPixelColorXY(uint16_t x, uint16_t y, uint32_t c, uint8_t blend) { blendPixelColor(x, c, blend); }
|
inline void blendPixelColorXY(uint16_t x, uint16_t y, uint32_t c, uint8_t blend) { blendPixelColor(x, c, blend); }
|
||||||
inline void blendPixelColorXY(uint16_t x, uint16_t y, CRGB c, uint8_t blend) { blendPixelColor(x, RGBW32(c.r,c.g,c.b,0), blend); }
|
inline void blendPixelColorXY(uint16_t x, uint16_t y, CRGB c, uint8_t blend) { blendPixelColor(x, RGBW32(c.r,c.g,c.b,0), blend); }
|
||||||
|
@ -653,8 +655,8 @@ typedef struct Segment {
|
||||||
inline void addPixelColorXY(int x, int y, CRGB c, bool fast = false) { addPixelColor(x, RGBW32(c.r,c.g,c.b,0), fast); }
|
inline void addPixelColorXY(int x, int y, CRGB c, bool fast = false) { addPixelColor(x, RGBW32(c.r,c.g,c.b,0), fast); }
|
||||||
inline void fadePixelColorXY(uint16_t x, uint16_t y, uint8_t fade) { fadePixelColor(x, fade); }
|
inline void fadePixelColorXY(uint16_t x, uint16_t y, uint8_t fade) { fadePixelColor(x, fade); }
|
||||||
inline void box_blur(uint16_t i, bool vertical, fract8 blur_amount) {}
|
inline void box_blur(uint16_t i, bool vertical, fract8 blur_amount) {}
|
||||||
inline void blurRow(uint16_t row, fract8 blur_amount) {}
|
inline void blurRow(uint32_t row, fract8 blur_amount, bool smear = false) {}
|
||||||
inline void blurCol(uint16_t col, fract8 blur_amount) {}
|
inline void blurCol(uint32_t col, fract8 blur_amount, bool smear = false) {}
|
||||||
inline void moveX(int8_t delta, bool wrap = false) {}
|
inline void moveX(int8_t delta, bool wrap = false) {}
|
||||||
inline void moveY(int8_t delta, bool wrap = false) {}
|
inline void moveY(int8_t delta, bool wrap = false) {}
|
||||||
inline void move(uint8_t dir, uint8_t delta, bool wrap = false) {}
|
inline void move(uint8_t dir, uint8_t delta, bool wrap = false) {}
|
||||||
|
@ -810,7 +812,7 @@ class WS2812FX { // 96 bytes
|
||||||
inline uint8_t getSegmentsNum(void) { return _segments.size(); } // returns currently present segments
|
inline uint8_t getSegmentsNum(void) { return _segments.size(); } // returns currently present segments
|
||||||
inline uint8_t getCurrSegmentId(void) { return _segment_index; } // returns current segment index (only valid while strip.isServicing())
|
inline uint8_t getCurrSegmentId(void) { return _segment_index; } // returns current segment index (only valid while strip.isServicing())
|
||||||
inline uint8_t getMainSegmentId(void) { return _mainSegment; } // returns main segment index
|
inline uint8_t getMainSegmentId(void) { return _mainSegment; } // returns main segment index
|
||||||
inline uint8_t getPaletteCount() { return 13 + GRADIENT_PALETTE_COUNT; } // will only return built-in palette count
|
inline uint8_t getPaletteCount() { return 13 + GRADIENT_PALETTE_COUNT + customPalettes.size(); }
|
||||||
inline uint8_t getTargetFps() { return _targetFps; } // returns rough FPS value for las 2s interval
|
inline uint8_t getTargetFps() { return _targetFps; } // returns rough FPS value for las 2s interval
|
||||||
inline uint8_t getModeCount() { return _modeCount; } // returns number of registered modes/effects
|
inline uint8_t getModeCount() { return _modeCount; } // returns number of registered modes/effects
|
||||||
|
|
||||||
|
|
|
@ -65,9 +65,10 @@ void WS2812FX::setUpMatrix() {
|
||||||
|
|
||||||
customMappingSize = 0; // prevent use of mapping if anything goes wrong
|
customMappingSize = 0; // prevent use of mapping if anything goes wrong
|
||||||
|
|
||||||
if (customMappingTable == nullptr) customMappingTable = new uint16_t[getLengthTotal()];
|
if (customMappingTable) delete[] customMappingTable;
|
||||||
|
customMappingTable = new uint16_t[getLengthTotal()];
|
||||||
|
|
||||||
if (customMappingTable != nullptr) {
|
if (customMappingTable) {
|
||||||
customMappingSize = getLengthTotal();
|
customMappingSize = getLengthTotal();
|
||||||
|
|
||||||
// fill with empty in case we don't fill the entire matrix
|
// fill with empty in case we don't fill the entire matrix
|
||||||
|
@ -138,7 +139,7 @@ void WS2812FX::setUpMatrix() {
|
||||||
DEBUG_PRINTLN();
|
DEBUG_PRINTLN();
|
||||||
#endif
|
#endif
|
||||||
} else { // memory allocation error
|
} else { // memory allocation error
|
||||||
DEBUG_PRINTLN(F("Ledmap alloc error."));
|
DEBUG_PRINTLN(F("ERROR 2D LED map allocation error."));
|
||||||
isMatrix = false;
|
isMatrix = false;
|
||||||
panels = 0;
|
panels = 0;
|
||||||
panel.clear();
|
panel.clear();
|
||||||
|
@ -174,11 +175,7 @@ void IRAM_ATTR Segment::setPixelColorXY(int x, int y, uint32_t col)
|
||||||
|
|
||||||
uint8_t _bri_t = currentBri();
|
uint8_t _bri_t = currentBri();
|
||||||
if (_bri_t < 255) {
|
if (_bri_t < 255) {
|
||||||
byte r = scale8(R(col), _bri_t);
|
col = color_fade(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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reverse ) x = virtualWidth() - x - 1;
|
if (reverse ) x = virtualWidth() - x - 1;
|
||||||
|
@ -217,6 +214,7 @@ void IRAM_ATTR Segment::setPixelColorXY(int x, int y, uint32_t col)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WLED_USE_AA_PIXELS
|
||||||
// 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)
|
||||||
{
|
{
|
||||||
|
@ -260,9 +258,10 @@ void Segment::setPixelColorXY(float x, float y, uint32_t col, bool aa)
|
||||||
setPixelColorXY(uint16_t(roundf(fX)), uint16_t(roundf(fY)), col);
|
setPixelColorXY(uint16_t(roundf(fX)), uint16_t(roundf(fY)), col);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// returns RGBW values of pixel
|
// 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 (!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 (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;
|
||||||
|
@ -275,59 +274,71 @@ uint32_t IRAM_ATTR Segment::getPixelColorXY(uint16_t x, uint16_t y) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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(uint32_t row, fract8 blur_amount, bool smear){
|
||||||
if (!isActive() || blur_amount == 0) return; // not active
|
if (!isActive() || blur_amount == 0) 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();
|
||||||
|
|
||||||
if (row >= rows) return;
|
if (row >= rows) return;
|
||||||
// blur one row
|
// blur one row
|
||||||
uint8_t keep = 255 - blur_amount;
|
uint8_t keep = smear ? 255 : 255 - blur_amount;
|
||||||
uint8_t seep = blur_amount >> 1;
|
uint8_t seep = blur_amount >> 1;
|
||||||
CRGB carryover = CRGB::Black;
|
uint32_t carryover = BLACK;
|
||||||
|
uint32_t lastnew;
|
||||||
|
uint32_t last;
|
||||||
|
uint32_t curnew;
|
||||||
for (unsigned x = 0; x < cols; x++) {
|
for (unsigned x = 0; x < cols; x++) {
|
||||||
CRGB cur = getPixelColorXY(x, row);
|
uint32_t cur = getPixelColorXY(x, row);
|
||||||
CRGB before = cur; // remember color before blur
|
uint32_t part = color_fade(cur, seep);
|
||||||
CRGB part = cur;
|
curnew = color_fade(cur, keep);
|
||||||
part.nscale8(seep);
|
if (x > 0) {
|
||||||
cur.nscale8(keep);
|
if (carryover)
|
||||||
cur += carryover;
|
curnew = color_add(curnew, carryover, true);
|
||||||
if (x>0) {
|
uint32_t prev = color_add(lastnew, part, true);
|
||||||
CRGB prev = CRGB(getPixelColorXY(x-1, row)) + part;
|
if (last != prev) // optimization: only set pixel if color has changed
|
||||||
setPixelColorXY(x-1, row, prev);
|
setPixelColorXY(x - 1, row, prev);
|
||||||
}
|
}
|
||||||
if (before != cur) // optimization: only set pixel if color has changed
|
else // first pixel
|
||||||
setPixelColorXY(x, row, cur);
|
setPixelColorXY(x, row, curnew);
|
||||||
|
lastnew = curnew;
|
||||||
|
last = cur; // save original value for comparison on next iteration
|
||||||
carryover = part;
|
carryover = part;
|
||||||
}
|
}
|
||||||
|
setPixelColorXY(cols-1, row, curnew); // set last pixel
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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(uint32_t col, fract8 blur_amount, bool smear) {
|
||||||
if (!isActive() || blur_amount == 0) return; // not active
|
if (!isActive() || blur_amount == 0) 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();
|
||||||
|
|
||||||
if (col >= cols) return;
|
if (col >= cols) return;
|
||||||
// blur one column
|
// blur one column
|
||||||
uint8_t keep = 255 - blur_amount;
|
uint8_t keep = smear ? 255 : 255 - blur_amount;
|
||||||
uint8_t seep = blur_amount >> 1;
|
uint8_t seep = blur_amount >> 1;
|
||||||
CRGB carryover = CRGB::Black;
|
uint32_t carryover = BLACK;
|
||||||
|
uint32_t lastnew;
|
||||||
|
uint32_t last;
|
||||||
|
uint32_t curnew;
|
||||||
for (unsigned y = 0; y < rows; y++) {
|
for (unsigned y = 0; y < rows; y++) {
|
||||||
CRGB cur = getPixelColorXY(col, y);
|
uint32_t cur = getPixelColorXY(col, y);
|
||||||
CRGB part = cur;
|
uint32_t part = color_fade(cur, seep);
|
||||||
CRGB before = cur; // remember color before blur
|
curnew = color_fade(cur, keep);
|
||||||
part.nscale8(seep);
|
if (y > 0) {
|
||||||
cur.nscale8(keep);
|
if (carryover)
|
||||||
cur += carryover;
|
curnew = color_add(curnew, carryover, true);
|
||||||
if (y>0) {
|
uint32_t prev = color_add(lastnew, part, true);
|
||||||
CRGB prev = CRGB(getPixelColorXY(col, y-1)) + part;
|
if (last != prev) // optimization: only set pixel if color has changed
|
||||||
setPixelColorXY(col, y-1, prev);
|
setPixelColorXY(col, y - 1, prev);
|
||||||
}
|
}
|
||||||
if (before != cur) // optimization: only set pixel if color has changed
|
else // first pixel
|
||||||
setPixelColorXY(col, y, cur);
|
setPixelColorXY(col, y, curnew);
|
||||||
carryover = part;
|
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])
|
// 1D Box blur (with added weight - blur_amount: [0=no blur, 255=max blur])
|
||||||
|
|
|
@ -455,18 +455,18 @@ CRGBPalette16 IRAM_ATTR &Segment::currentPalette(CRGBPalette16 &targetPalette, u
|
||||||
// relies on WS2812FX::service() to call it for each frame
|
// relies on WS2812FX::service() to call it for each frame
|
||||||
void Segment::handleRandomPalette() {
|
void Segment::handleRandomPalette() {
|
||||||
// is it time to generate a new palette?
|
// is it time to generate a new palette?
|
||||||
if ((millis()/1000U) - _lastPaletteChange > randomPaletteChangeTime) {
|
if ((uint16_t)((uint16_t)(millis() / 1000U) - _lastPaletteChange) > randomPaletteChangeTime){
|
||||||
_newRandomPalette = useHarmonicRandomPalette ? generateHarmonicRandomPalette(_randomPalette) : generateRandomPalette();
|
_newRandomPalette = useHarmonicRandomPalette ? generateHarmonicRandomPalette(_randomPalette) : generateRandomPalette();
|
||||||
_lastPaletteChange = millis()/1000U;
|
_lastPaletteChange = (uint16_t)(millis() / 1000U);
|
||||||
_lastPaletteBlend = (uint16_t)(millis() & 0xFFFF)-512; // starts blending immediately
|
_lastPaletteBlend = (uint16_t)((uint16_t)millis() - 512); // starts blending immediately
|
||||||
}
|
}
|
||||||
|
|
||||||
// if palette transitions is enabled, blend it according to Transition Time (if longer than minimum given by service calls)
|
// if palette transitions is enabled, blend it according to Transition Time (if longer than minimum given by service calls)
|
||||||
if (strip.paletteFade) {
|
if (strip.paletteFade) {
|
||||||
// assumes that 128 updates are sufficient to blend a palette, so shift by 7 (can be more, can be less)
|
// assumes that 128 updates are sufficient to blend a palette, so shift by 7 (can be more, can be less)
|
||||||
// in reality there need to be 255 blends to fully blend two entirely different palettes
|
// in reality there need to be 255 blends to fully blend two entirely different palettes
|
||||||
if ((millis() & 0xFFFF) - _lastPaletteBlend < strip.getTransition() >> 7) return; // not yet time to fade, delay the update
|
if ((uint16_t)((uint16_t)millis() - _lastPaletteBlend) < strip.getTransition() >> 7) return; // not yet time to fade, delay the update
|
||||||
_lastPaletteBlend = millis();
|
_lastPaletteBlend = (uint16_t)millis();
|
||||||
}
|
}
|
||||||
nblendPaletteTowardPalette(_randomPalette, _newRandomPalette, 48);
|
nblendPaletteTowardPalette(_randomPalette, _newRandomPalette, 48);
|
||||||
}
|
}
|
||||||
|
@ -735,11 +735,7 @@ void IRAM_ATTR Segment::setPixelColor(int i, uint32_t col)
|
||||||
uint16_t len = length();
|
uint16_t len = length();
|
||||||
uint8_t _bri_t = currentBri();
|
uint8_t _bri_t = currentBri();
|
||||||
if (_bri_t < 255) {
|
if (_bri_t < 255) {
|
||||||
byte r = scale8(R(col), _bri_t);
|
col = color_fade(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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// expand pixel (taking into account start, grouping, spacing [and offset])
|
// expand pixel (taking into account start, grouping, spacing [and offset])
|
||||||
|
@ -777,6 +773,7 @@ void IRAM_ATTR Segment::setPixelColor(int i, uint32_t col)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WLED_USE_AA_PIXELS
|
||||||
// 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)
|
||||||
{
|
{
|
||||||
|
@ -809,6 +806,7 @@ void Segment::setPixelColor(float i, uint32_t col, bool aa)
|
||||||
setPixelColor(uint16_t(roundf(fC)) | (vStrip<<16), col);
|
setPixelColor(uint16_t(roundf(fC)) | (vStrip<<16), col);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
uint32_t IRAM_ATTR Segment::getPixelColor(int i)
|
uint32_t IRAM_ATTR Segment::getPixelColor(int i)
|
||||||
{
|
{
|
||||||
|
@ -993,33 +991,43 @@ void Segment::fadeToBlackBy(uint8_t fadeBy) {
|
||||||
/*
|
/*
|
||||||
* blurs segment content, source: FastLED colorutils.cpp
|
* 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"
|
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
|
||||||
const unsigned cols = virtualWidth();
|
const unsigned cols = virtualWidth();
|
||||||
const unsigned rows = virtualHeight();
|
const unsigned rows = virtualHeight();
|
||||||
for (unsigned i = 0; i < rows; i++) blurRow(i, blur_amount); // blur all rows
|
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); // blur all columns
|
for (unsigned k = 0; k < cols; k++) blurCol(k, blur_amount, smear); // blur all columns
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
uint8_t keep = 255 - blur_amount;
|
uint8_t keep = smear ? 255 : 255 - blur_amount;
|
||||||
uint8_t seep = blur_amount >> 1;
|
uint8_t seep = blur_amount >> 1;
|
||||||
uint32_t carryover = BLACK;
|
|
||||||
unsigned vlength = virtualLength();
|
unsigned vlength = virtualLength();
|
||||||
|
uint32_t carryover = BLACK;
|
||||||
|
uint32_t lastnew;
|
||||||
|
uint32_t last;
|
||||||
|
uint32_t curnew;
|
||||||
for (unsigned i = 0; i < vlength; i++) {
|
for (unsigned i = 0; i < vlength; i++) {
|
||||||
uint32_t cur = getPixelColor(i);
|
uint32_t cur = getPixelColor(i);
|
||||||
uint32_t part = color_fade(cur, seep);
|
uint32_t part = color_fade(cur, seep);
|
||||||
cur = color_add(color_fade(cur, keep), carryover, true);
|
curnew = color_fade(cur, keep);
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
uint32_t c = getPixelColor(i-1);
|
if (carryover)
|
||||||
setPixelColor(i-1, color_add(c, part, true));
|
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;
|
carryover = part;
|
||||||
}
|
}
|
||||||
|
setPixelColor(vlength - 1, curnew);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1098,6 +1106,12 @@ void WS2812FX::finalizeInit(void) {
|
||||||
uint16_t prevLen = 0;
|
uint16_t prevLen = 0;
|
||||||
for (int i = 0; i < defNumBusses && i < WLED_MAX_BUSSES+WLED_MIN_VIRTUAL_BUSSES; i++) {
|
for (int i = 0; i < defNumBusses && i < WLED_MAX_BUSSES+WLED_MIN_VIRTUAL_BUSSES; i++) {
|
||||||
uint8_t defPin[] = {defDataPins[i]};
|
uint8_t defPin[] = {defDataPins[i]};
|
||||||
|
// 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 start = prevLen;
|
||||||
uint16_t count = defCounts[(i < defNumCounts) ? i : defNumCounts -1];
|
uint16_t count = defCounts[(i < defNumCounts) ? i : defNumCounts -1];
|
||||||
prevLen += count;
|
prevLen += count;
|
||||||
|
@ -1162,12 +1176,16 @@ void WS2812FX::service() {
|
||||||
uint16_t delay = FRAMETIME;
|
uint16_t delay = FRAMETIME;
|
||||||
|
|
||||||
if (!seg.freeze) { //only run effect function if not frozen
|
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)
|
||||||
_virtualSegmentLength = seg.virtualLength(); //SEGLEN
|
_virtualSegmentLength = seg.virtualLength(); //SEGLEN
|
||||||
_colors_t[0] = gamma32(seg.currentColor(0));
|
_colors_t[0] = gamma32(seg.currentColor(0));
|
||||||
_colors_t[1] = gamma32(seg.currentColor(1));
|
_colors_t[1] = gamma32(seg.currentColor(1));
|
||||||
_colors_t[2] = gamma32(seg.currentColor(2));
|
_colors_t[2] = gamma32(seg.currentColor(2));
|
||||||
seg.currentPalette(_currentPalette, seg.palette); // we need to pass reference
|
seg.currentPalette(_currentPalette, seg.palette); // we need to pass reference
|
||||||
if (!cctFromRgb || correctWB) BusManager::setSegmentCCT(seg.currentBri(true), correctWB);
|
// when correctWB is true we need to correct/adjust RGB value according to desired CCT value, but it will also affect actual WW/CW ratio
|
||||||
|
// when cctFromRgb is true we implicitly calculate WW and CW from RGB values
|
||||||
|
if (cctFromRgb) BusManager::setSegmentCCT(-1);
|
||||||
|
else BusManager::setSegmentCCT(seg.currentBri(true), correctWB);
|
||||||
// Effect blending
|
// Effect blending
|
||||||
// When two effects are being blended, each may have different segment data, this
|
// When two effects are being blended, each may have different segment data, this
|
||||||
// data needs to be saved first and then restored before running previous mode.
|
// data needs to be saved first and then restored before running previous mode.
|
||||||
|
@ -1190,20 +1208,19 @@ void WS2812FX::service() {
|
||||||
#endif
|
#endif
|
||||||
seg.call++;
|
seg.call++;
|
||||||
if (seg.isInTransition() && delay > FRAMETIME) delay = FRAMETIME; // force faster updates during transition
|
if (seg.isInTransition() && delay > FRAMETIME) delay = FRAMETIME; // force faster updates during transition
|
||||||
|
BusManager::setSegmentCCT(oldCCT); // restore old CCT for ABL adjustments
|
||||||
}
|
}
|
||||||
|
|
||||||
seg.next_time = nowUp + delay;
|
seg.next_time = nowUp + delay;
|
||||||
}
|
}
|
||||||
// if (_segment_index == _queuedChangesSegId) setUpSegmentFromQueuedChanges();
|
|
||||||
_segment_index++;
|
_segment_index++;
|
||||||
}
|
}
|
||||||
_virtualSegmentLength = 0;
|
_virtualSegmentLength = 0;
|
||||||
BusManager::setSegmentCCT(-1);
|
|
||||||
_isServicing = false;
|
_isServicing = false;
|
||||||
_triggered = false;
|
_triggered = false;
|
||||||
|
|
||||||
#ifdef WLED_DEBUG
|
#ifdef WLED_DEBUG
|
||||||
if (millis() - nowUp > _frametime) DEBUG_PRINTLN(F("Slow effects."));
|
if (millis() - nowUp > _frametime) DEBUG_PRINTF_P(PSTR("Slow effects %u/%d.\n"), (unsigned)(millis()-nowUp), (int)_frametime);
|
||||||
#endif
|
#endif
|
||||||
if (doShow) {
|
if (doShow) {
|
||||||
yield();
|
yield();
|
||||||
|
@ -1211,7 +1228,7 @@ void WS2812FX::service() {
|
||||||
show();
|
show();
|
||||||
}
|
}
|
||||||
#ifdef WLED_DEBUG
|
#ifdef WLED_DEBUG
|
||||||
if (millis() - nowUp > _frametime) DEBUG_PRINTLN(F("Slow strip."));
|
if (millis() - nowUp > _frametime) DEBUG_PRINTF_P(PSTR("Slow strip %u/%d.\n"), (unsigned)(millis()-nowUp), (int)_frametime);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1390,11 +1407,7 @@ bool WS2812FX::hasCCTBus(void) {
|
||||||
for (size_t b = 0; b < BusManager::getNumBusses(); b++) {
|
for (size_t b = 0; b < BusManager::getNumBusses(); b++) {
|
||||||
Bus *bus = BusManager::getBus(b);
|
Bus *bus = BusManager::getBus(b);
|
||||||
if (bus == nullptr || bus->getLength()==0) break;
|
if (bus == nullptr || bus->getLength()==0) break;
|
||||||
switch (bus->getType()) {
|
if (bus->hasCCT()) return true;
|
||||||
case TYPE_ANALOG_5CH:
|
|
||||||
case TYPE_ANALOG_2CH:
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1425,31 +1438,12 @@ void WS2812FX::setSegment(uint8_t segId, uint16_t i1, uint16_t i2, uint8_t group
|
||||||
appendSegment(Segment(0, strip.getLengthTotal()));
|
appendSegment(Segment(0, strip.getLengthTotal()));
|
||||||
segId = getSegmentsNum()-1; // segments are added at the end of list
|
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;
|
|
||||||
DEBUG_PRINT(F("Segment queued: ")); DEBUG_PRINTLN(segId);
|
|
||||||
return; // queued changes are applied immediately after effect function returns
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
suspend();
|
suspend();
|
||||||
_segments[segId].setUp(i1, i2, grouping, spacing, offset, startY, stopY);
|
_segments[segId].setUp(i1, i2, grouping, spacing, offset, startY, stopY);
|
||||||
resume();
|
resume();
|
||||||
if (segId > 0 && segId == getSegmentsNum()-1 && i2 <= i1) _segments.pop_back(); // if last segment was deleted remove it from vector
|
if (segId > 0 && segId == getSegmentsNum()-1 && i2 <= i1) _segments.pop_back(); // if last segment was deleted remove it from vector
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
void WS2812FX::setUpSegmentFromQueuedChanges() {
|
|
||||||
if (_queuedChangesSegId >= getSegmentsNum()) return;
|
|
||||||
_segments[_queuedChangesSegId].setUp(_qStart, _qStop, _qGrouping, _qSpacing, _qOffset, _qStartY, _qStopY);
|
|
||||||
_queuedChangesSegId = 255;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
void WS2812FX::resetSegments() {
|
void WS2812FX::resetSegments() {
|
||||||
_segments.clear(); // destructs all Segment as part of clearing
|
_segments.clear(); // destructs all Segment as part of clearing
|
||||||
#ifndef WLED_DISABLE_2D
|
#ifndef WLED_DISABLE_2D
|
||||||
|
@ -1670,19 +1664,23 @@ bool WS2812FX::deserializeMap(uint8_t n) {
|
||||||
return false; // if file does not load properly then exit
|
return false; // if file does not load properly then exit
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG_PRINT(F("Reading LED map from ")); DEBUG_PRINTLN(fileName);
|
if (customMappingTable) delete[] customMappingTable;
|
||||||
|
customMappingTable = new uint16_t[getLengthTotal()];
|
||||||
|
|
||||||
if (customMappingTable == nullptr) customMappingTable = new uint16_t[getLengthTotal()];
|
if (customMappingTable) {
|
||||||
|
DEBUG_PRINT(F("Reading LED map from ")); DEBUG_PRINTLN(fileName);
|
||||||
JsonObject root = pDoc->as<JsonObject>();
|
JsonObject root = pDoc->as<JsonObject>();
|
||||||
JsonArray map = root[F("map")];
|
JsonArray map = root[F("map")];
|
||||||
if (!map.isNull() && map.size()) { // not an empty map
|
if (!map.isNull() && map.size()) { // not an empty map
|
||||||
customMappingSize = min((unsigned)map.size(), (unsigned)getLengthTotal());
|
customMappingSize = min((unsigned)map.size(), (unsigned)getLengthTotal());
|
||||||
for (unsigned i=0; i<customMappingSize; i++) customMappingTable[i] = (uint16_t) (map[i]<0 ? 0xFFFFU : map[i]);
|
for (unsigned i=0; i<customMappingSize; i++) customMappingTable[i] = (uint16_t) (map[i]<0 ? 0xFFFFU : map[i]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
DEBUG_PRINTLN(F("ERROR LED map allocation error."));
|
||||||
}
|
}
|
||||||
|
|
||||||
releaseJSONBufferLock();
|
releaseJSONBufferLock();
|
||||||
return true;
|
return (customMappingSize > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t IRAM_ATTR WS2812FX::getMappedPixelIndex(uint16_t index) {
|
uint16_t IRAM_ATTR WS2812FX::getMappedPixelIndex(uint16_t index) {
|
||||||
|
|
|
@ -9,9 +9,10 @@
|
||||||
#include "bus_wrapper.h"
|
#include "bus_wrapper.h"
|
||||||
#include "bus_manager.h"
|
#include "bus_manager.h"
|
||||||
|
|
||||||
|
extern bool cctICused;
|
||||||
|
|
||||||
//colors.cpp
|
//colors.cpp
|
||||||
uint32_t colorBalanceFromKelvin(uint16_t kelvin, uint32_t rgb);
|
uint32_t colorBalanceFromKelvin(uint16_t kelvin, uint32_t rgb);
|
||||||
uint16_t approximateKelvinFromRGB(uint32_t rgb);
|
|
||||||
|
|
||||||
//udp.cpp
|
//udp.cpp
|
||||||
uint8_t realtimeBroadcast(uint8_t type, IPAddress client, uint16_t length, byte *buffer, uint8_t bri=255, bool isRGBW=false);
|
uint8_t realtimeBroadcast(uint8_t type, IPAddress client, uint16_t length, byte *buffer, uint8_t bri=255, bool isRGBW=false);
|
||||||
|
@ -122,13 +123,13 @@ BusDigital::BusDigital(BusConfig &bc, uint8_t nr, const ColorOrderMap &com)
|
||||||
}
|
}
|
||||||
_iType = PolyBus::getI(bc.type, _pins, nr);
|
_iType = PolyBus::getI(bc.type, _pins, nr);
|
||||||
if (_iType == I_NONE) return;
|
if (_iType == I_NONE) return;
|
||||||
if (bc.doubleBuffer && !allocData(bc.count * (Bus::hasWhite(_type) + 3*Bus::hasRGB(_type)))) return; //warning: hardcoded channel count
|
if (bc.doubleBuffer && !allocData(bc.count * Bus::getNumberOfChannels(bc.type))) return;
|
||||||
//_buffering = bc.doubleBuffer;
|
//_buffering = bc.doubleBuffer;
|
||||||
uint16_t lenToCreate = bc.count;
|
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
|
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);
|
_busPtr = PolyBus::create(_iType, _pins, lenToCreate + _skip, nr, _frequencykHz);
|
||||||
_valid = (_busPtr != nullptr);
|
_valid = (_busPtr != nullptr);
|
||||||
DEBUG_PRINTF("%successfully inited strip %u (len %u) with type %u and pins %u,%u (itype %u). mA=%d/%d\n", _valid?"S":"Uns", nr, bc.count, bc.type, _pins[0], _pins[1], _iType, _milliAmpsPerLed, _milliAmpsMax);
|
DEBUG_PRINTF_P(PSTR("%successfully inited strip %u (len %u) with type %u and pins %u,%u (itype %u). mA=%d/%d\n"), _valid?"S":"Uns", nr, bc.count, bc.type, _pins[0], IS_2PIN(bc.type)?_pins[1]:255, _iType, _milliAmpsPerLed, _milliAmpsMax);
|
||||||
}
|
}
|
||||||
|
|
||||||
//fine tune power estimation constants for your setup
|
//fine tune power estimation constants for your setup
|
||||||
|
@ -205,13 +206,15 @@ void BusDigital::show() {
|
||||||
_milliAmpsTotal = 0;
|
_milliAmpsTotal = 0;
|
||||||
if (!_valid) return;
|
if (!_valid) return;
|
||||||
|
|
||||||
|
uint8_t cctWW = 0, cctCW = 0;
|
||||||
uint8_t newBri = estimateCurrentAndLimitBri(); // will fill _milliAmpsTotal
|
uint8_t newBri = estimateCurrentAndLimitBri(); // will fill _milliAmpsTotal
|
||||||
if (newBri < _bri) PolyBus::setBrightness(_busPtr, _iType, newBri); // limit brightness to stay within current limits
|
if (newBri < _bri) PolyBus::setBrightness(_busPtr, _iType, newBri); // limit brightness to stay within current limits
|
||||||
|
|
||||||
if (_data) { // use _buffering this causes ~20% FPS drop
|
if (_data) {
|
||||||
size_t channels = Bus::hasWhite(_type) + 3*Bus::hasRGB(_type);
|
size_t channels = getNumberOfChannels();
|
||||||
|
int16_t oldCCT = Bus::_cct; // temporarily save bus CCT
|
||||||
for (size_t i=0; i<_len; i++) {
|
for (size_t i=0; i<_len; i++) {
|
||||||
size_t offset = i*channels;
|
size_t offset = i * channels;
|
||||||
uint8_t co = _colorOrderMap.getPixelColorOrder(i+_start, _colorOrder);
|
uint8_t co = _colorOrderMap.getPixelColorOrder(i+_start, _colorOrder);
|
||||||
uint32_t c;
|
uint32_t c;
|
||||||
if (_type == TYPE_WS2812_1CH_X3) { // map to correct IC, each controls 3 LEDs (_len is always a multiple of 3)
|
if (_type == TYPE_WS2812_1CH_X3) { // map to correct IC, each controls 3 LEDs (_len is always a multiple of 3)
|
||||||
|
@ -221,17 +224,26 @@ void BusDigital::show() {
|
||||||
case 2: c = RGBW32(_data[offset-2], _data[offset-1], _data[offset] , 0); break;
|
case 2: c = RGBW32(_data[offset-2], _data[offset-1], _data[offset] , 0); break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
c = RGBW32(_data[offset],_data[offset+1],_data[offset+2],(Bus::hasWhite(_type)?_data[offset+3]:0));
|
if (hasRGB()) c = RGBW32(_data[offset], _data[offset+1], _data[offset+2], hasWhite() ? _data[offset+3] : 0);
|
||||||
|
else c = RGBW32(0, 0, 0, _data[offset]);
|
||||||
|
}
|
||||||
|
if (hasCCT()) {
|
||||||
|
// unfortunately as a segment may span multiple buses or a bus may contain multiple segments and each segment may have different CCT
|
||||||
|
// we need to extract and appy CCT value for each pixel individually even though all buses share the same _cct variable
|
||||||
|
// TODO: there is an issue if CCT is calculated from RGB value (_cct==-1), we cannot do that with double buffer
|
||||||
|
Bus::_cct = _data[offset+channels-1];
|
||||||
|
Bus::calculateCCT(c, cctWW, cctCW);
|
||||||
}
|
}
|
||||||
uint16_t pix = i;
|
uint16_t pix = i;
|
||||||
if (_reversed) pix = _len - pix -1;
|
if (_reversed) pix = _len - pix -1;
|
||||||
pix += _skip;
|
pix += _skip;
|
||||||
PolyBus::setPixelColor(_busPtr, _iType, pix, c, co);
|
PolyBus::setPixelColor(_busPtr, _iType, pix, c, co, (cctCW<<8) | cctWW);
|
||||||
}
|
}
|
||||||
#if !defined(STATUSLED) || STATUSLED>=0
|
#if !defined(STATUSLED) || STATUSLED>=0
|
||||||
if (_skip) PolyBus::setPixelColor(_busPtr, _iType, 0, 0, _colorOrderMap.getPixelColorOrder(_start, _colorOrder)); // paint skipped pixels black
|
if (_skip) PolyBus::setPixelColor(_busPtr, _iType, 0, 0, _colorOrderMap.getPixelColorOrder(_start, _colorOrder)); // paint skipped pixels black
|
||||||
#endif
|
#endif
|
||||||
for (int i=1; i<_skip; i++) PolyBus::setPixelColor(_busPtr, _iType, i, 0, _colorOrderMap.getPixelColorOrder(_start, _colorOrder)); // paint skipped pixels black
|
for (int i=1; i<_skip; i++) PolyBus::setPixelColor(_busPtr, _iType, i, 0, _colorOrderMap.getPixelColorOrder(_start, _colorOrder)); // paint skipped pixels black
|
||||||
|
Bus::_cct = oldCCT;
|
||||||
} else {
|
} else {
|
||||||
if (newBri < _bri) {
|
if (newBri < _bri) {
|
||||||
uint16_t hwLen = _len;
|
uint16_t hwLen = _len;
|
||||||
|
@ -239,7 +251,8 @@ void BusDigital::show() {
|
||||||
for (unsigned i = 0; i < hwLen; i++) {
|
for (unsigned 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
|
// 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), _bri);
|
uint32_t c = restoreColorLossy(PolyBus::getPixelColor(_busPtr, _iType, i, 0), _bri);
|
||||||
PolyBus::setPixelColor(_busPtr, _iType, i, c, 0); // repaint all pixels with new brightness
|
if (hasCCT()) Bus::calculateCCT(c, cctWW, cctCW); // this will unfortunately corrupt (segment) CCT data on every bus
|
||||||
|
PolyBus::setPixelColor(_busPtr, _iType, i, c, 0, (cctCW<<8) | cctWW); // repaint all pixels with new brightness
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -278,17 +291,20 @@ void BusDigital::setStatusPixel(uint32_t c) {
|
||||||
|
|
||||||
void IRAM_ATTR BusDigital::setPixelColor(uint16_t pix, uint32_t c) {
|
void IRAM_ATTR BusDigital::setPixelColor(uint16_t pix, uint32_t c) {
|
||||||
if (!_valid) return;
|
if (!_valid) return;
|
||||||
if (Bus::hasWhite(_type)) c = autoWhiteCalc(c);
|
uint8_t cctWW = 0, cctCW = 0;
|
||||||
if (_cct >= 1900) c = colorBalanceFromKelvin(_cct, c); //color correction from CCT
|
if (hasWhite()) c = autoWhiteCalc(c);
|
||||||
if (_data) { // use _buffering this causes ~20% FPS drop
|
if (Bus::_cct >= 1900) c = colorBalanceFromKelvin(Bus::_cct, c); //color correction from CCT
|
||||||
size_t channels = Bus::hasWhite(_type) + 3*Bus::hasRGB(_type);
|
if (_data) {
|
||||||
size_t offset = pix*channels;
|
size_t offset = pix * getNumberOfChannels();
|
||||||
if (Bus::hasRGB(_type)) {
|
if (hasRGB()) {
|
||||||
_data[offset++] = R(c);
|
_data[offset++] = R(c);
|
||||||
_data[offset++] = G(c);
|
_data[offset++] = G(c);
|
||||||
_data[offset++] = B(c);
|
_data[offset++] = B(c);
|
||||||
}
|
}
|
||||||
if (Bus::hasWhite(_type)) _data[offset] = W(c);
|
if (hasWhite()) _data[offset++] = W(c);
|
||||||
|
// unfortunately as a segment may span multiple buses or a bus may contain multiple segments and each segment may have different CCT
|
||||||
|
// we need to store CCT value for each pixel (if there is a color correction in play, convert K in CCT ratio)
|
||||||
|
if (hasCCT()) _data[offset] = Bus::_cct >= 1900 ? (Bus::_cct - 1900) >> 5 : (Bus::_cct < 0 ? 127 : Bus::_cct); // TODO: if _cct == -1 we simply ignore it
|
||||||
} else {
|
} else {
|
||||||
if (_reversed) pix = _len - pix -1;
|
if (_reversed) pix = _len - pix -1;
|
||||||
pix += _skip;
|
pix += _skip;
|
||||||
|
@ -303,21 +319,21 @@ void IRAM_ATTR BusDigital::setPixelColor(uint16_t pix, uint32_t c) {
|
||||||
case 2: c = RGBW32(R(cOld), G(cOld), W(c) , 0); break;
|
case 2: c = RGBW32(R(cOld), G(cOld), W(c) , 0); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PolyBus::setPixelColor(_busPtr, _iType, pix, c, co);
|
if (hasCCT()) Bus::calculateCCT(c, cctWW, cctCW);
|
||||||
|
PolyBus::setPixelColor(_busPtr, _iType, pix, c, co, (cctCW<<8) | cctWW);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns original color if global buffering is enabled, else returns lossly restored color from bus
|
// returns original color if global buffering is enabled, else returns lossly restored color from bus
|
||||||
uint32_t IRAM_ATTR BusDigital::getPixelColor(uint16_t pix) {
|
uint32_t IRAM_ATTR BusDigital::getPixelColor(uint16_t pix) {
|
||||||
if (!_valid) return 0;
|
if (!_valid) return 0;
|
||||||
if (_data) { // use _buffering this causes ~20% FPS drop
|
if (_data) {
|
||||||
size_t channels = Bus::hasWhite(_type) + 3*Bus::hasRGB(_type);
|
size_t offset = pix * getNumberOfChannels();
|
||||||
size_t offset = pix*channels;
|
|
||||||
uint32_t c;
|
uint32_t c;
|
||||||
if (!Bus::hasRGB(_type)) {
|
if (!hasRGB()) {
|
||||||
c = RGBW32(_data[offset], _data[offset], _data[offset], _data[offset]);
|
c = RGBW32(_data[offset], _data[offset], _data[offset], _data[offset]);
|
||||||
} else {
|
} else {
|
||||||
c = RGBW32(_data[offset], _data[offset+1], _data[offset+2], Bus::hasWhite(_type) ? _data[offset+3] : 0);
|
c = RGBW32(_data[offset], _data[offset+1], _data[offset+2], hasWhite() ? _data[offset+3] : 0);
|
||||||
}
|
}
|
||||||
return c;
|
return c;
|
||||||
} else {
|
} else {
|
||||||
|
@ -414,48 +430,31 @@ BusPwm::BusPwm(BusConfig &bc)
|
||||||
void BusPwm::setPixelColor(uint16_t pix, uint32_t c) {
|
void BusPwm::setPixelColor(uint16_t pix, uint32_t c) {
|
||||||
if (pix != 0 || !_valid) return; //only react to first pixel
|
if (pix != 0 || !_valid) return; //only react to first pixel
|
||||||
if (_type != TYPE_ANALOG_3CH) c = autoWhiteCalc(c);
|
if (_type != TYPE_ANALOG_3CH) c = autoWhiteCalc(c);
|
||||||
if (_cct >= 1900 && (_type == TYPE_ANALOG_3CH || _type == TYPE_ANALOG_4CH)) {
|
if (Bus::_cct >= 1900 && (_type == TYPE_ANALOG_3CH || _type == TYPE_ANALOG_4CH)) {
|
||||||
c = colorBalanceFromKelvin(_cct, c); //color correction from CCT
|
c = colorBalanceFromKelvin(Bus::_cct, c); //color correction from CCT
|
||||||
}
|
}
|
||||||
uint8_t r = R(c);
|
uint8_t r = R(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);
|
||||||
uint8_t cct = 0; //0 - full warm white, 255 - full cold white
|
|
||||||
if (_cct > -1) {
|
|
||||||
if (_cct >= 1900) cct = (_cct - 1900) >> 5;
|
|
||||||
else if (_cct < 256) cct = _cct;
|
|
||||||
} else {
|
|
||||||
cct = (approximateKelvinFromRGB(c) - 1900) >> 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t ww, cw;
|
|
||||||
#ifdef WLED_USE_IC_CCT
|
|
||||||
ww = w;
|
|
||||||
cw = cct;
|
|
||||||
#else
|
|
||||||
//0 - linear (CCT 127 = 50% warm, 50% cold), 127 - additive CCT blending (CCT 127 = 100% warm, 100% cold)
|
|
||||||
if (cct < _cctBlend) ww = 255;
|
|
||||||
else ww = ((255-cct) * 255) / (255 - _cctBlend);
|
|
||||||
|
|
||||||
if ((255-cct) < _cctBlend) cw = 255;
|
|
||||||
else cw = (cct * 255) / (255 - _cctBlend);
|
|
||||||
|
|
||||||
ww = (w * ww) / 255; //brightness scaling
|
|
||||||
cw = (w * cw) / 255;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
switch (_type) {
|
switch (_type) {
|
||||||
case TYPE_ANALOG_1CH: //one channel (white), relies on auto white calculation
|
case TYPE_ANALOG_1CH: //one channel (white), relies on auto white calculation
|
||||||
_data[0] = w;
|
_data[0] = w;
|
||||||
break;
|
break;
|
||||||
case TYPE_ANALOG_2CH: //warm white + cold white
|
case TYPE_ANALOG_2CH: //warm white + cold white
|
||||||
_data[1] = cw;
|
if (cctICused) {
|
||||||
_data[0] = ww;
|
_data[0] = w;
|
||||||
|
_data[1] = Bus::_cct < 0 || Bus::_cct > 255 ? 127 : Bus::_cct;
|
||||||
|
} else {
|
||||||
|
Bus::calculateCCT(c, _data[0], _data[1]);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case TYPE_ANALOG_5CH: //RGB + warm white + cold white
|
case TYPE_ANALOG_5CH: //RGB + warm white + cold white
|
||||||
_data[4] = cw;
|
if (cctICused)
|
||||||
w = ww;
|
_data[4] = Bus::_cct < 0 || Bus::_cct > 255 ? 127 : Bus::_cct;
|
||||||
|
else
|
||||||
|
Bus::calculateCCT(c, w, _data[4]);
|
||||||
case TYPE_ANALOG_4CH: //RGBW
|
case TYPE_ANALOG_4CH: //RGBW
|
||||||
_data[3] = w;
|
_data[3] = w;
|
||||||
case TYPE_ANALOG_3CH: //standard dumb RGB
|
case TYPE_ANALOG_3CH: //standard dumb RGB
|
||||||
|
@ -506,7 +505,7 @@ void BusPwm::show() {
|
||||||
uint8_t numPins = NUM_PWM_PINS(_type);
|
uint8_t numPins = NUM_PWM_PINS(_type);
|
||||||
unsigned maxBri = (1<<_depth) - 1;
|
unsigned maxBri = (1<<_depth) - 1;
|
||||||
#ifdef ESP8266
|
#ifdef ESP8266
|
||||||
unsigned pwmBri = (unsigned)(roundf(powf((float)_bri / 255.0f, 1.7f) * (float)maxBri + 0.5f)); // using gamma 1.7 to extrapolate PWM duty cycle
|
unsigned pwmBri = (unsigned)(roundf(powf((float)_bri / 255.0f, 1.7f) * (float)maxBri)); // using gamma 1.7 to extrapolate PWM duty cycle
|
||||||
#else
|
#else
|
||||||
unsigned pwmBri = cieLUT[_bri] >> (12 - _depth); // use CIE LUT
|
unsigned pwmBri = cieLUT[_bri] >> (12 - _depth); // use CIE LUT
|
||||||
#endif
|
#endif
|
||||||
|
@ -620,7 +619,7 @@ BusNetwork::BusNetwork(BusConfig &bc)
|
||||||
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 (_rgbw) c = autoWhiteCalc(c);
|
if (_rgbw) c = autoWhiteCalc(c);
|
||||||
if (_cct >= 1900) c = colorBalanceFromKelvin(_cct, c); //color correction from CCT
|
if (Bus::_cct >= 1900) c = colorBalanceFromKelvin(Bus::_cct, c); //color correction from CCT
|
||||||
uint16_t offset = pix * _UDPchannels;
|
uint16_t offset = pix * _UDPchannels;
|
||||||
_data[offset] = R(c);
|
_data[offset] = R(c);
|
||||||
_data[offset+1] = G(c);
|
_data[offset+1] = G(c);
|
||||||
|
@ -660,25 +659,18 @@ uint32_t BusManager::memUsage(BusConfig &bc) {
|
||||||
if (bc.type == TYPE_ONOFF || IS_PWM(bc.type)) return 5;
|
if (bc.type == TYPE_ONOFF || IS_PWM(bc.type)) return 5;
|
||||||
|
|
||||||
uint16_t len = bc.count + bc.skipAmount;
|
uint16_t len = bc.count + bc.skipAmount;
|
||||||
uint16_t channels = 3;
|
uint16_t channels = Bus::getNumberOfChannels(bc.type);
|
||||||
uint16_t multiplier = 1;
|
uint16_t multiplier = 1;
|
||||||
if (IS_DIGITAL(bc.type)) { // digital types
|
if (IS_DIGITAL(bc.type)) { // digital types
|
||||||
if (IS_16BIT(bc.type)) len *= 2; // 16-bit LEDs
|
if (IS_16BIT(bc.type)) len *= 2; // 16-bit LEDs
|
||||||
#ifdef ESP8266
|
#ifdef ESP8266
|
||||||
if (bc.type > 28) channels = 4; //RGBW
|
|
||||||
if (bc.pins[0] == 3) { //8266 DMA uses 5x the mem
|
if (bc.pins[0] == 3) { //8266 DMA uses 5x the mem
|
||||||
multiplier = 5;
|
multiplier = 5;
|
||||||
}
|
}
|
||||||
#else //ESP32 RMT uses double buffer, I2S uses 5x buffer
|
#else //ESP32 RMT uses double buffer, I2S uses 5x buffer
|
||||||
if (bc.type > 28) channels = 4; //RGBW
|
|
||||||
multiplier = 2;
|
multiplier = 2;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
if (IS_VIRTUAL(bc.type)) {
|
|
||||||
switch (bc.type) {
|
|
||||||
case TYPE_NET_DDP_RGBW: channels = 4; break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return len * channels * multiplier; //RGB
|
return len * channels * multiplier; //RGB
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -740,7 +732,7 @@ void BusManager::setSegmentCCT(int16_t cct, bool allowWBCorrection) {
|
||||||
if (cct >= 0) {
|
if (cct >= 0) {
|
||||||
//if white balance correction allowed, save as kelvin value instead of 0-255
|
//if white balance correction allowed, save as kelvin value instead of 0-255
|
||||||
if (allowWBCorrection) cct = 1900 + (cct << 5);
|
if (allowWBCorrection) cct = 1900 + (cct << 5);
|
||||||
} else cct = -1;
|
} else cct = -1; // will use kelvin approximation from RGB
|
||||||
Bus::setCCT(cct);
|
Bus::setCCT(cct);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,9 @@
|
||||||
|
|
||||||
#include "const.h"
|
#include "const.h"
|
||||||
|
|
||||||
|
//colors.cpp
|
||||||
|
uint16_t approximateKelvinFromRGB(uint32_t rgb);
|
||||||
|
|
||||||
#define GET_BIT(var,bit) (((var)>>(bit))&0x01)
|
#define GET_BIT(var,bit) (((var)>>(bit))&0x01)
|
||||||
#define SET_BIT(var,bit) ((var)|=(uint16_t)(0x0001<<(bit)))
|
#define SET_BIT(var,bit) ((var)|=(uint16_t)(0x0001<<(bit)))
|
||||||
#define UNSET_BIT(var,bit) ((var)&=(~(uint16_t)(0x0001<<(bit))))
|
#define UNSET_BIT(var,bit) ((var)&=(~(uint16_t)(0x0001<<(bit))))
|
||||||
|
@ -32,7 +35,7 @@ struct BusConfig {
|
||||||
uint8_t skipAmount;
|
uint8_t skipAmount;
|
||||||
bool refreshReq;
|
bool refreshReq;
|
||||||
uint8_t autoWhite;
|
uint8_t autoWhite;
|
||||||
uint8_t pins[5] = {LEDPIN, 255, 255, 255, 255};
|
uint8_t pins[5] = {255, 255, 255, 255, 255};
|
||||||
uint16_t frequency;
|
uint16_t frequency;
|
||||||
bool doubleBuffer;
|
bool doubleBuffer;
|
||||||
uint8_t milliAmpsPerLed;
|
uint8_t milliAmpsPerLed;
|
||||||
|
@ -53,9 +56,9 @@ struct BusConfig {
|
||||||
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)
|
||||||
size_t nPins = 1;
|
size_t nPins = 1;
|
||||||
if (type >= TYPE_NET_DDP_RGB && type < 96) nPins = 4; //virtual network bus. 4 "pins" store IP address
|
if (IS_VIRTUAL(type)) nPins = 4; //virtual network bus. 4 "pins" store IP address
|
||||||
else if (type > 47) nPins = 2;
|
else if (IS_2PIN(type)) nPins = 2;
|
||||||
else if (type > 40 && type < 46) nPins = NUM_PWM_PINS(type);
|
else if (IS_PWM(type)) nPins = NUM_PWM_PINS(type);
|
||||||
for (size_t i = 0; i < nPins; i++) pins[i] = ppins[i];
|
for (size_t i = 0; i < nPins; i++) pins[i] = ppins[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,6 +141,8 @@ class Bus {
|
||||||
virtual uint16_t getLEDCurrent() { return 0; }
|
virtual uint16_t getLEDCurrent() { return 0; }
|
||||||
virtual uint16_t getUsedCurrent() { return 0; }
|
virtual uint16_t getUsedCurrent() { return 0; }
|
||||||
virtual uint16_t getMaxCurrent() { return 0; }
|
virtual uint16_t getMaxCurrent() { return 0; }
|
||||||
|
virtual uint8_t getNumberOfChannels() { return hasWhite(_type) + 3*hasRGB(_type) + hasCCT(_type); }
|
||||||
|
static inline uint8_t getNumberOfChannels(uint8_t type) { return hasWhite(type) + 3*hasRGB(type) + hasCCT(type); }
|
||||||
inline void setReversed(bool reversed) { _reversed = reversed; }
|
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; }
|
||||||
|
@ -154,18 +159,22 @@ class Bus {
|
||||||
}
|
}
|
||||||
virtual bool hasWhite(void) { 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 || type == TYPE_UCS8904) return true; // digital types with white channel
|
if ((type >= TYPE_WS2812_1CH && type <= TYPE_WS2812_WWA) ||
|
||||||
|
type == TYPE_SK6812_RGBW || type == TYPE_TM1814 || type == TYPE_UCS8904 ||
|
||||||
|
type == TYPE_FW1906 || type == TYPE_WS2805) 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 || type == TYPE_NET_ARTNET_RGBW) return true; // network types with white channel
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
virtual bool hasCCT(void) { return Bus::hasCCT(_type); }
|
virtual bool hasCCT(void) { return Bus::hasCCT(_type); }
|
||||||
static bool hasCCT(uint8_t type) {
|
static bool hasCCT(uint8_t type) {
|
||||||
if (type == TYPE_WS2812_2CH_X3 || type == TYPE_WS2812_WWA ||
|
if (type == TYPE_WS2812_2CH_X3 || type == TYPE_WS2812_WWA ||
|
||||||
type == TYPE_ANALOG_2CH || type == TYPE_ANALOG_5CH) return true;
|
type == TYPE_ANALOG_2CH || type == TYPE_ANALOG_5CH ||
|
||||||
|
type == TYPE_FW1906 || type == TYPE_WS2805 ) return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
static void setCCT(uint16_t cct) {
|
static int16_t getCCT() { return _cct; }
|
||||||
|
static void setCCT(int16_t cct) {
|
||||||
_cct = cct;
|
_cct = cct;
|
||||||
}
|
}
|
||||||
static void setCCTBlend(uint8_t b) {
|
static void setCCTBlend(uint8_t b) {
|
||||||
|
@ -176,6 +185,26 @@ class Bus {
|
||||||
if (_cctBlend > WLED_MAX_CCT_BLEND) _cctBlend = WLED_MAX_CCT_BLEND;
|
if (_cctBlend > WLED_MAX_CCT_BLEND) _cctBlend = WLED_MAX_CCT_BLEND;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
static void calculateCCT(uint32_t c, uint8_t &ww, uint8_t &cw) {
|
||||||
|
uint8_t cct = 0; //0 - full warm white, 255 - full cold white
|
||||||
|
uint8_t w = byte(c >> 24);
|
||||||
|
|
||||||
|
if (_cct > -1) {
|
||||||
|
if (_cct >= 1900) cct = (_cct - 1900) >> 5;
|
||||||
|
else if (_cct < 256) cct = _cct;
|
||||||
|
} else {
|
||||||
|
cct = (approximateKelvinFromRGB(c) - 1900) >> 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
//0 - linear (CCT 127 = 50% warm, 50% cold), 127 - additive CCT blending (CCT 127 = 100% warm, 100% cold)
|
||||||
|
if (cct < _cctBlend) ww = 255;
|
||||||
|
else ww = ((255-cct) * 255) / (255 - _cctBlend);
|
||||||
|
if ((255-cct) < _cctBlend) cw = 255;
|
||||||
|
else cw = (cct * 255) / (255 - _cctBlend);
|
||||||
|
|
||||||
|
ww = (w * ww) / 255; //brightness scaling
|
||||||
|
cw = (w * cw) / 255;
|
||||||
|
}
|
||||||
inline void setAutoWhiteMode(uint8_t m) { if (m < 5) _autoWhiteMode = m; }
|
inline void setAutoWhiteMode(uint8_t m) { if (m < 5) _autoWhiteMode = m; }
|
||||||
inline uint8_t getAutoWhiteMode() { return _autoWhiteMode; }
|
inline uint8_t getAutoWhiteMode() { return _autoWhiteMode; }
|
||||||
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; }
|
||||||
|
@ -191,8 +220,17 @@ class Bus {
|
||||||
bool _needsRefresh;
|
bool _needsRefresh;
|
||||||
uint8_t _autoWhiteMode;
|
uint8_t _autoWhiteMode;
|
||||||
uint8_t *_data;
|
uint8_t *_data;
|
||||||
|
// global Auto White Calculation override
|
||||||
static uint8_t _gAWM;
|
static uint8_t _gAWM;
|
||||||
|
// _cct has the following menaings (see calculateCCT() & BusManager::setSegmentCCT()):
|
||||||
|
// -1 means to extract approximate CCT value in K from RGB (in calcualteCCT())
|
||||||
|
// [0,255] is the exact CCT value where 0 means warm and 255 cold
|
||||||
|
// [1900,10060] only for color correction expressed in K (colorBalanceFromKelvin())
|
||||||
static int16_t _cct;
|
static int16_t _cct;
|
||||||
|
// _cctBlend determines WW/CW blending:
|
||||||
|
// 0 - linear (CCT 127 => 50% warm, 50% cold)
|
||||||
|
// 63 - semi additive/nonlinear (CCT 127 => 66% warm, 66% cold)
|
||||||
|
// 127 - additive CCT blending (CCT 127 => 100% warm, 100% cold)
|
||||||
static uint8_t _cctBlend;
|
static uint8_t _cctBlend;
|
||||||
|
|
||||||
uint32_t autoWhiteCalc(uint32_t c);
|
uint32_t autoWhiteCalc(uint32_t c);
|
||||||
|
@ -334,9 +372,12 @@ class BusManager {
|
||||||
static void setStatusPixel(uint32_t c);
|
static void setStatusPixel(uint32_t c);
|
||||||
static void setPixelColor(uint16_t pix, uint32_t c);
|
static void setPixelColor(uint16_t pix, uint32_t c);
|
||||||
static void setBrightness(uint8_t b);
|
static void setBrightness(uint8_t b);
|
||||||
|
// for setSegmentCCT(), cct can only be in [-1,255] range; allowWBCorrection will convert it to K
|
||||||
|
// WARNING: setSegmentCCT() is a misleading name!!! much better would be setGlobalCCT() or just setCCT()
|
||||||
static void setSegmentCCT(int16_t cct, bool allowWBCorrection = false);
|
static void setSegmentCCT(int16_t cct, bool allowWBCorrection = false);
|
||||||
static void setMilliampsMax(uint16_t max) { _milliAmpsMax = max;}
|
static void setMilliampsMax(uint16_t max) { _milliAmpsMax = max;}
|
||||||
static uint32_t getPixelColor(uint16_t pix);
|
static uint32_t getPixelColor(uint16_t pix);
|
||||||
|
static inline int16_t getSegmentCCT() { return Bus::getCCT(); }
|
||||||
|
|
||||||
static Bus* getBus(uint8_t busNr);
|
static Bus* getBus(uint8_t busNr);
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define BusWrapper_h
|
#define BusWrapper_h
|
||||||
|
|
||||||
#include "NeoPixelBusLg.h"
|
#include "NeoPixelBusLg.h"
|
||||||
|
#include "bus_manager.h"
|
||||||
|
|
||||||
// temporary - these defines should actually be set in platformio.ini
|
// temporary - these defines should actually be set in platformio.ini
|
||||||
// C3: I2S0 and I2S1 methods not supported (has one I2S bus)
|
// C3: I2S0 and I2S1 methods not supported (has one I2S bus)
|
||||||
|
@ -63,52 +64,64 @@
|
||||||
#define I_8266_U1_UCS_4 54
|
#define I_8266_U1_UCS_4 54
|
||||||
#define I_8266_DM_UCS_4 55
|
#define I_8266_DM_UCS_4 55
|
||||||
#define I_8266_BB_UCS_4 56
|
#define I_8266_BB_UCS_4 56
|
||||||
|
//FW1906 GRBCW
|
||||||
|
#define I_8266_U0_FW6_5 66
|
||||||
|
#define I_8266_U1_FW6_5 67
|
||||||
|
#define I_8266_DM_FW6_5 68
|
||||||
|
#define I_8266_BB_FW6_5 69
|
||||||
//ESP8266 APA106
|
//ESP8266 APA106
|
||||||
#define I_8266_U0_APA106_3 81
|
#define I_8266_U0_APA106_3 81
|
||||||
#define I_8266_U1_APA106_3 82
|
#define I_8266_U1_APA106_3 82
|
||||||
#define I_8266_DM_APA106_3 83
|
#define I_8266_DM_APA106_3 83
|
||||||
#define I_8266_BB_APA106_3 84
|
#define I_8266_BB_APA106_3 84
|
||||||
|
//WS2805
|
||||||
|
#define I_8266_U0_2805_5 89
|
||||||
|
#define I_8266_U1_2805_5 90
|
||||||
|
#define I_8266_DM_2805_5 91
|
||||||
|
#define I_8266_BB_2805_5 92
|
||||||
|
|
||||||
/*** ESP32 Neopixel methods ***/
|
/*** ESP32 Neopixel methods ***/
|
||||||
//RGB
|
//RGB
|
||||||
#define I_32_RN_NEO_3 21
|
#define I_32_RN_NEO_3 21
|
||||||
#define I_32_I0_NEO_3 22
|
#define I_32_I0_NEO_3 22
|
||||||
#define I_32_I1_NEO_3 23
|
#define I_32_I1_NEO_3 23
|
||||||
#define I_32_BB_NEO_3 24 // bitbanging on ESP32 not recommended
|
|
||||||
//RGBW
|
//RGBW
|
||||||
#define I_32_RN_NEO_4 25
|
#define I_32_RN_NEO_4 25
|
||||||
#define I_32_I0_NEO_4 26
|
#define I_32_I0_NEO_4 26
|
||||||
#define I_32_I1_NEO_4 27
|
#define I_32_I1_NEO_4 27
|
||||||
#define I_32_BB_NEO_4 28 // bitbanging on ESP32 not recommended
|
|
||||||
//400Kbps
|
//400Kbps
|
||||||
#define I_32_RN_400_3 29
|
#define I_32_RN_400_3 29
|
||||||
#define I_32_I0_400_3 30
|
#define I_32_I0_400_3 30
|
||||||
#define I_32_I1_400_3 31
|
#define I_32_I1_400_3 31
|
||||||
#define I_32_BB_400_3 32 // bitbanging on ESP32 not recommended
|
|
||||||
//TM1814 (RGBW)
|
//TM1814 (RGBW)
|
||||||
#define I_32_RN_TM1_4 33
|
#define I_32_RN_TM1_4 33
|
||||||
#define I_32_I0_TM1_4 34
|
#define I_32_I0_TM1_4 34
|
||||||
#define I_32_I1_TM1_4 35
|
#define I_32_I1_TM1_4 35
|
||||||
//Bit Bang theoratically possible, but very undesirable and not needed (no pin restrictions on RMT and I2S)
|
|
||||||
//TM1829 (RGB)
|
//TM1829 (RGB)
|
||||||
#define I_32_RN_TM2_3 36
|
#define I_32_RN_TM2_3 36
|
||||||
#define I_32_I0_TM2_3 37
|
#define I_32_I0_TM2_3 37
|
||||||
#define I_32_I1_TM2_3 38
|
#define I_32_I1_TM2_3 38
|
||||||
//Bit Bang theoratically possible, but very undesirable and not needed (no pin restrictions on RMT and I2S)
|
|
||||||
//UCS8903 (RGB)
|
//UCS8903 (RGB)
|
||||||
#define I_32_RN_UCS_3 57
|
#define I_32_RN_UCS_3 57
|
||||||
#define I_32_I0_UCS_3 58
|
#define I_32_I0_UCS_3 58
|
||||||
#define I_32_I1_UCS_3 59
|
#define I_32_I1_UCS_3 59
|
||||||
//Bit Bang theoratically possible, but very undesirable and not needed (no pin restrictions on RMT and I2S)
|
|
||||||
//UCS8904 (RGBW)
|
//UCS8904 (RGBW)
|
||||||
#define I_32_RN_UCS_4 60
|
#define I_32_RN_UCS_4 60
|
||||||
#define I_32_I0_UCS_4 61
|
#define I_32_I0_UCS_4 61
|
||||||
#define I_32_I1_UCS_4 62
|
#define I_32_I1_UCS_4 62
|
||||||
//Bit Bang theoratically possible, but very undesirable and not needed (no pin restrictions on RMT and I2S)
|
//FW1906 GRBCW
|
||||||
|
#define I_32_RN_FW6_5 63
|
||||||
|
#define I_32_I0_FW6_5 64
|
||||||
|
#define I_32_I1_FW6_5 65
|
||||||
|
//APA106
|
||||||
#define I_32_RN_APA106_3 85
|
#define I_32_RN_APA106_3 85
|
||||||
#define I_32_I0_APA106_3 86
|
#define I_32_I0_APA106_3 86
|
||||||
#define I_32_I1_APA106_3 87
|
#define I_32_I1_APA106_3 87
|
||||||
#define I_32_BB_APA106_3 88 // bitbangging on ESP32 not recommended
|
//WS2805
|
||||||
|
#define I_32_RN_2805_5 93
|
||||||
|
#define I_32_I0_2805_5 94
|
||||||
|
#define I_32_I1_2805_5 95
|
||||||
|
|
||||||
|
|
||||||
//APA102
|
//APA102
|
||||||
#define I_HS_DOT_3 39 //hardware SPI
|
#define I_HS_DOT_3 39 //hardware SPI
|
||||||
|
@ -176,6 +189,16 @@
|
||||||
#define B_8266_U1_APA106_3 NeoPixelBusLg<NeoRbgFeature, NeoEsp8266Uart1Apa106Method, NeoGammaNullMethod> //3 chan, esp8266, gpio2
|
#define B_8266_U1_APA106_3 NeoPixelBusLg<NeoRbgFeature, NeoEsp8266Uart1Apa106Method, NeoGammaNullMethod> //3 chan, esp8266, gpio2
|
||||||
#define B_8266_DM_APA106_3 NeoPixelBusLg<NeoGrbFeature, NeoEsp8266DmaApa106Method, NeoGammaNullMethod> //3 chan, esp8266, gpio3
|
#define B_8266_DM_APA106_3 NeoPixelBusLg<NeoGrbFeature, NeoEsp8266DmaApa106Method, NeoGammaNullMethod> //3 chan, esp8266, gpio3
|
||||||
#define B_8266_BB_APA106_3 NeoPixelBusLg<NeoGrbFeature, NeoEsp8266BitBangApa106Method, NeoGammaNullMethod> //3 chan, esp8266, bb (any pin but 16)
|
#define B_8266_BB_APA106_3 NeoPixelBusLg<NeoGrbFeature, NeoEsp8266BitBangApa106Method, NeoGammaNullMethod> //3 chan, esp8266, bb (any pin but 16)
|
||||||
|
//FW1906 GRBCW
|
||||||
|
#define B_8266_U0_FW6_5 NeoPixelBusLg<NeoGrbcwxFeature, NeoEsp8266Uart0Ws2813Method, NeoGammaNullMethod> //esp8266, gpio1
|
||||||
|
#define B_8266_U1_FW6_5 NeoPixelBusLg<NeoGrbcwxFeature, NeoEsp8266Uart1Ws2813Method, NeoGammaNullMethod> //esp8266, gpio2
|
||||||
|
#define B_8266_DM_FW6_5 NeoPixelBusLg<NeoGrbcwxFeature, NeoEsp8266Dma800KbpsMethod, NeoGammaNullMethod> //esp8266, gpio3
|
||||||
|
#define B_8266_BB_FW6_5 NeoPixelBusLg<NeoGrbcwxFeature, NeoEsp8266BitBang800KbpsMethod, NeoGammaNullMethod> //esp8266, bb
|
||||||
|
//WS2805 GRBCW
|
||||||
|
#define B_8266_U0_2805_5 NeoPixelBusLg<NeoGrbwwFeature, NeoEsp8266Uart0Ws2805Method, NeoGammaNullMethod> //esp8266, gpio1
|
||||||
|
#define B_8266_U1_2805_5 NeoPixelBusLg<NeoGrbwwFeature, NeoEsp8266Uart1Ws2805Method, NeoGammaNullMethod> //esp8266, gpio2
|
||||||
|
#define B_8266_DM_2805_5 NeoPixelBusLg<NeoGrbwwFeature, NeoEsp8266DmaWs2805Method, NeoGammaNullMethod> //esp8266, gpio3
|
||||||
|
#define B_8266_BB_2805_5 NeoPixelBusLg<NeoGrbwwFeature, NeoEsp8266BitBangWs2805Method, NeoGammaNullMethod> //esp8266, bb
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*** ESP32 Neopixel methods ***/
|
/*** ESP32 Neopixel methods ***/
|
||||||
|
@ -183,75 +206,102 @@
|
||||||
//RGB
|
//RGB
|
||||||
#define B_32_RN_NEO_3 NeoPixelBusLg<NeoGrbFeature, NeoEsp32RmtNWs2812xMethod, NeoGammaNullMethod>
|
#define B_32_RN_NEO_3 NeoPixelBusLg<NeoGrbFeature, NeoEsp32RmtNWs2812xMethod, NeoGammaNullMethod>
|
||||||
#ifndef WLED_NO_I2S0_PIXELBUS
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
#define B_32_I0_NEO_3 NeoPixelBusLg<NeoGrbFeature, NeoEsp32I2s0800KbpsMethod, NeoGammaNullMethod>
|
#define B_32_I0_NEO_3 NeoPixelBusLg<NeoGrbFeature, NeoEsp32I2s0Ws2812xMethod, NeoGammaNullMethod>
|
||||||
|
//#define B_32_I0_NEO_3 NeoPixelBusLg<NeoGrbFeature, NeoEsp32I2s0X8Ws2812xMethod, NeoGammaNullMethod> // parallel I2S
|
||||||
#endif
|
#endif
|
||||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
#define B_32_I1_NEO_3 NeoPixelBusLg<NeoGrbFeature, NeoEsp32I2s1800KbpsMethod, NeoGammaNullMethod>
|
#define B_32_I1_NEO_3 NeoPixelBusLg<NeoGrbFeature, NeoEsp32I2s1Ws2812xMethod, NeoGammaNullMethod>
|
||||||
|
//#define B_32_I1_NEO_3 NeoPixelBusLg<NeoGrbFeature, NeoEsp32I2s1X8Ws2812xMethod, NeoGammaNullMethod> // parallel I2S
|
||||||
#endif
|
#endif
|
||||||
//#define B_32_BB_NEO_3 NeoPixelBusLg<NeoGrbFeature, NeoEsp32BitBang800KbpsMethod, NeoGammaNullMethod> // NeoEsp8266BitBang800KbpsMethod
|
|
||||||
//RGBW
|
//RGBW
|
||||||
#define B_32_RN_NEO_4 NeoPixelBusLg<NeoGrbwFeature, NeoEsp32RmtNWs2812xMethod, NeoGammaNullMethod>
|
#define B_32_RN_NEO_4 NeoPixelBusLg<NeoGrbwFeature, NeoEsp32RmtNSk6812Method, NeoGammaNullMethod>
|
||||||
#ifndef WLED_NO_I2S0_PIXELBUS
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
#define B_32_I0_NEO_4 NeoPixelBusLg<NeoGrbwFeature, NeoEsp32I2s0800KbpsMethod, NeoGammaNullMethod>
|
#define B_32_I0_NEO_4 NeoPixelBusLg<NeoGrbwFeature, NeoEsp32I2s0Sk6812Method, NeoGammaNullMethod>
|
||||||
|
//#define B_32_I0_NEO_4 NeoPixelBusLg<NeoGrbwFeature, NeoEsp32I2s0X8Sk6812Method, NeoGammaNullMethod> // parallel I2S
|
||||||
#endif
|
#endif
|
||||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
#define B_32_I1_NEO_4 NeoPixelBusLg<NeoGrbwFeature, NeoEsp32I2s1800KbpsMethod, NeoGammaNullMethod>
|
#define B_32_I1_NEO_4 NeoPixelBusLg<NeoGrbwFeature, NeoEsp32I2s1Sk6812Method, NeoGammaNullMethod>
|
||||||
|
//#define B_32_I1_NEO_4 NeoPixelBusLg<NeoGrbwFeature, NeoEsp32I2s1X8Sk6812Method, NeoGammaNullMethod> // parallel I2S
|
||||||
#endif
|
#endif
|
||||||
//#define B_32_BB_NEO_4 NeoPixelBusLg<NeoGrbwFeature, NeoEsp32BitBang800KbpsMethod, NeoGammaNullMethod> // NeoEsp8266BitBang800KbpsMethod
|
|
||||||
//400Kbps
|
//400Kbps
|
||||||
#define B_32_RN_400_3 NeoPixelBusLg<NeoGrbFeature, NeoEsp32RmtN400KbpsMethod, NeoGammaNullMethod>
|
#define B_32_RN_400_3 NeoPixelBusLg<NeoGrbFeature, NeoEsp32RmtN400KbpsMethod, NeoGammaNullMethod>
|
||||||
#ifndef WLED_NO_I2S0_PIXELBUS
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
#define B_32_I0_400_3 NeoPixelBusLg<NeoGrbFeature, NeoEsp32I2s0400KbpsMethod, NeoGammaNullMethod>
|
#define B_32_I0_400_3 NeoPixelBusLg<NeoGrbFeature, NeoEsp32I2s0400KbpsMethod, NeoGammaNullMethod>
|
||||||
|
//#define B_32_I0_400_3 NeoPixelBusLg<NeoGrbFeature, NeoEsp32I2s0X8400KbpsMethod, NeoGammaNullMethod> // parallel I2S
|
||||||
#endif
|
#endif
|
||||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
#define B_32_I1_400_3 NeoPixelBusLg<NeoGrbFeature, NeoEsp32I2s1400KbpsMethod, NeoGammaNullMethod>
|
#define B_32_I1_400_3 NeoPixelBusLg<NeoGrbFeature, NeoEsp32I2s1400KbpsMethod, NeoGammaNullMethod>
|
||||||
|
//#define B_32_I1_400_3 NeoPixelBusLg<NeoGrbFeature, NeoEsp32I2s1X8400KbpsMethod, NeoGammaNullMethod> // parallel I2S
|
||||||
#endif
|
#endif
|
||||||
//#define B_32_BB_400_3 NeoPixelBusLg<NeoGrbFeature, NeoEsp32BitBang400KbpsMethod, NeoGammaNullMethod> // NeoEsp8266BitBang400KbpsMethod
|
|
||||||
//TM1814 (RGBW)
|
//TM1814 (RGBW)
|
||||||
#define B_32_RN_TM1_4 NeoPixelBusLg<NeoWrgbTm1814Feature, NeoEsp32RmtNTm1814Method, NeoGammaNullMethod>
|
#define B_32_RN_TM1_4 NeoPixelBusLg<NeoWrgbTm1814Feature, NeoEsp32RmtNTm1814Method, NeoGammaNullMethod>
|
||||||
#ifndef WLED_NO_I2S0_PIXELBUS
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
#define B_32_I0_TM1_4 NeoPixelBusLg<NeoWrgbTm1814Feature, NeoEsp32I2s0Tm1814Method, NeoGammaNullMethod>
|
#define B_32_I0_TM1_4 NeoPixelBusLg<NeoWrgbTm1814Feature, NeoEsp32I2s0Tm1814Method, NeoGammaNullMethod>
|
||||||
|
//#define B_32_I0_TM1_4 NeoPixelBusLg<NeoWrgbTm1814Feature, NeoEsp32I2s0X8Tm1814Method, NeoGammaNullMethod> // parallel I2S
|
||||||
#endif
|
#endif
|
||||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
#define B_32_I1_TM1_4 NeoPixelBusLg<NeoWrgbTm1814Feature, NeoEsp32I2s1Tm1814Method, NeoGammaNullMethod>
|
#define B_32_I1_TM1_4 NeoPixelBusLg<NeoWrgbTm1814Feature, NeoEsp32I2s1Tm1814Method, NeoGammaNullMethod>
|
||||||
|
//#define B_32_I1_TM1_4 NeoPixelBusLg<NeoWrgbTm1814Feature, NeoEsp32I2s1X8Tm1814Method, NeoGammaNullMethod> // parallel I2S
|
||||||
#endif
|
#endif
|
||||||
//Bit Bang theoratically possible, but very undesirable and not needed (no pin restrictions on RMT and I2S)
|
|
||||||
//TM1829 (RGB)
|
//TM1829 (RGB)
|
||||||
#define B_32_RN_TM2_3 NeoPixelBusLg<NeoBrgFeature, NeoEsp32RmtNTm1829Method, NeoGammaNullMethod>
|
#define B_32_RN_TM2_3 NeoPixelBusLg<NeoBrgFeature, NeoEsp32RmtNTm1829Method, NeoGammaNullMethod>
|
||||||
#ifndef WLED_NO_I2S0_PIXELBUS
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
#define B_32_I0_TM2_3 NeoPixelBusLg<NeoBrgFeature, NeoEsp32I2s0Tm1829Method, NeoGammaNullMethod>
|
#define B_32_I0_TM2_3 NeoPixelBusLg<NeoBrgFeature, NeoEsp32I2s0Tm1829Method, NeoGammaNullMethod>
|
||||||
|
//#define B_32_I0_TM2_3 NeoPixelBusLg<NeoBrgFeature, NeoEsp32I2s0X8Tm1829Method, NeoGammaNullMethod> // parallel I2S
|
||||||
#endif
|
#endif
|
||||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
#define B_32_I1_TM2_3 NeoPixelBusLg<NeoBrgFeature, NeoEsp32I2s1Tm1829Method, NeoGammaNullMethod>
|
#define B_32_I1_TM2_3 NeoPixelBusLg<NeoBrgFeature, NeoEsp32I2s1Tm1829Method, NeoGammaNullMethod>
|
||||||
|
//#define B_32_I1_TM2_3 NeoPixelBusLg<NeoBrgFeature, NeoEsp32I2s1X8Tm1829Method, NeoGammaNullMethod> // parallel I2S
|
||||||
#endif
|
#endif
|
||||||
//Bit Bang theoratically possible, but very undesirable and not needed (no pin restrictions on RMT and I2S)
|
|
||||||
//UCS8903
|
//UCS8903
|
||||||
#define B_32_RN_UCS_3 NeoPixelBusLg<NeoRgbUcs8903Feature, NeoEsp32RmtNWs2812xMethod, NeoGammaNullMethod>
|
#define B_32_RN_UCS_3 NeoPixelBusLg<NeoRgbUcs8903Feature, NeoEsp32RmtNWs2812xMethod, NeoGammaNullMethod>
|
||||||
#ifndef WLED_NO_I2S0_PIXELBUS
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
#define B_32_I0_UCS_3 NeoPixelBusLg<NeoRgbUcs8903Feature, NeoEsp32I2s0800KbpsMethod, NeoGammaNullMethod>
|
#define B_32_I0_UCS_3 NeoPixelBusLg<NeoRgbUcs8903Feature, NeoEsp32I2s0800KbpsMethod, NeoGammaNullMethod>
|
||||||
|
//#define B_32_I0_UCS_3 NeoPixelBusLg<NeoRgbUcs8903Feature, NeoEsp32I2s0X8800KbpsMethod, NeoGammaNullMethod> // parallel I2S
|
||||||
#endif
|
#endif
|
||||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
#define B_32_I1_UCS_3 NeoPixelBusLg<NeoRgbUcs8903Feature, NeoEsp32I2s1800KbpsMethod, NeoGammaNullMethod>
|
#define B_32_I1_UCS_3 NeoPixelBusLg<NeoRgbUcs8903Feature, NeoEsp32I2s1800KbpsMethod, NeoGammaNullMethod>
|
||||||
|
//#define B_32_I1_UCS_3 NeoPixelBusLg<NeoRgbUcs8903Feature, NeoEsp32I2s1X8800KbpsMethod, NeoGammaNullMethod> // parallel I2S
|
||||||
#endif
|
#endif
|
||||||
//Bit Bang theoratically possible, but very undesirable and not needed (no pin restrictions on RMT and I2S)
|
|
||||||
//UCS8904
|
//UCS8904
|
||||||
#define B_32_RN_UCS_4 NeoPixelBusLg<NeoRgbwUcs8904Feature, NeoEsp32RmtNWs2812xMethod, NeoGammaNullMethod>
|
#define B_32_RN_UCS_4 NeoPixelBusLg<NeoRgbwUcs8904Feature, NeoEsp32RmtNWs2812xMethod, NeoGammaNullMethod>
|
||||||
#ifndef WLED_NO_I2S0_PIXELBUS
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
#define B_32_I0_UCS_4 NeoPixelBusLg<NeoRgbwUcs8904Feature, NeoEsp32I2s0800KbpsMethod, NeoGammaNullMethod>
|
#define B_32_I0_UCS_4 NeoPixelBusLg<NeoRgbwUcs8904Feature, NeoEsp32I2s0800KbpsMethod, NeoGammaNullMethod>
|
||||||
|
//#define B_32_I0_UCS_4 NeoPixelBusLg<NeoRgbwUcs8904Feature, NeoEsp32I2s0X8800KbpsMethod, NeoGammaNullMethod>// parallel I2S
|
||||||
#endif
|
#endif
|
||||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
#define B_32_I1_UCS_4 NeoPixelBusLg<NeoRgbwUcs8904Feature, NeoEsp32I2s1800KbpsMethod, NeoGammaNullMethod>
|
#define B_32_I1_UCS_4 NeoPixelBusLg<NeoRgbwUcs8904Feature, NeoEsp32I2s1800KbpsMethod, NeoGammaNullMethod>
|
||||||
|
//#define B_32_I1_UCS_4 NeoPixelBusLg<NeoRgbwUcs8904Feature, NeoEsp32I2s1X8800KbpsMethod, NeoGammaNullMethod>// parallel I2S
|
||||||
#endif
|
#endif
|
||||||
//Bit Bang theoratically possible, but very undesirable and not needed (no pin restrictions on RMT and I2S)
|
|
||||||
#define B_32_RN_APA106_3 NeoPixelBusLg<NeoGrbFeature, NeoEsp32RmtNApa106Method, NeoGammaNullMethod>
|
#define B_32_RN_APA106_3 NeoPixelBusLg<NeoGrbFeature, NeoEsp32RmtNApa106Method, NeoGammaNullMethod>
|
||||||
#ifndef WLED_NO_I2S0_PIXELBUS
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
#define B_32_I0_APA106_3 NeoPixelBusLg<NeoGrbFeature, NeoEsp32I2s0Apa106Method, NeoGammaNullMethod>
|
#define B_32_I0_APA106_3 NeoPixelBusLg<NeoGrbFeature, NeoEsp32I2s0Apa106Method, NeoGammaNullMethod>
|
||||||
|
//#define B_32_I0_APA106_3 NeoPixelBusLg<NeoGrbFeature, NeoEsp32I2s0X8Apa106Method, NeoGammaNullMethod> // parallel I2S
|
||||||
#endif
|
#endif
|
||||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
#define B_32_I1_APA106_3 NeoPixelBusLg<NeoGrbFeature, NeoEsp32I2s1Apa106Method, NeoGammaNullMethod>
|
#define B_32_I1_APA106_3 NeoPixelBusLg<NeoGrbFeature, NeoEsp32I2s1Apa106Method, NeoGammaNullMethod>
|
||||||
|
//#define B_32_I1_APA106_3 NeoPixelBusLg<NeoGrbFeature, NeoEsp32I2s1X8Apa106Method, NeoGammaNullMethod> // parallel I2S
|
||||||
|
#endif
|
||||||
|
//FW1906 GRBCW
|
||||||
|
#define B_32_RN_FW6_5 NeoPixelBusLg<NeoGrbcwxFeature, NeoEsp32RmtNWs2812xMethod, NeoGammaNullMethod>
|
||||||
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
|
#define B_32_I0_FW6_5 NeoPixelBusLg<NeoGrbcwxFeature, NeoEsp32I2s0800KbpsMethod, NeoGammaNullMethod>
|
||||||
|
//#define B_32_I0_FW6_5 NeoPixelBusLg<NeoGrbcwxFeature, NeoEsp32I2s0X8800KbpsMethod, NeoGammaNullMethod> // parallel I2S
|
||||||
|
#endif
|
||||||
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
|
#define B_32_I1_FW6_5 NeoPixelBusLg<NeoGrbcwxFeature, NeoEsp32I2s1800KbpsMethod, NeoGammaNullMethod>
|
||||||
|
//#define B_32_I1_FW6_5 NeoPixelBusLg<NeoGrbcwxFeature, NeoEsp32I2s1X8800KbpsMethod, NeoGammaNullMethod> // parallel I2S
|
||||||
|
#endif
|
||||||
|
//WS2805 RGBWC
|
||||||
|
#define B_32_RN_2805_5 NeoPixelBusLg<NeoGrbwwFeature, NeoEsp32RmtNWs2805Method, NeoGammaNullMethod>
|
||||||
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
|
#define B_32_I0_2805_5 NeoPixelBusLg<NeoGrbwwFeature, NeoEsp32I2s0Ws2805Method, NeoGammaNullMethod>
|
||||||
|
//#define B_32_I0_2805_5 NeoPixelBusLg<NeoGrbwwFeature, NeoEsp32I2s0X8Ws2805Method, NeoGammaNullMethod> // parallel I2S
|
||||||
|
#endif
|
||||||
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
|
#define B_32_I1_2805_5 NeoPixelBusLg<NeoGrbwwFeature, NeoEsp32I2s1Ws2805Method, NeoGammaNullMethod>
|
||||||
|
//#define B_32_I1_2805_5 NeoPixelBusLg<NeoGrbwwFeature, NeoEsp32I2s1X8Ws2805Method, NeoGammaNullMethod> // parallel I2S
|
||||||
#endif
|
#endif
|
||||||
//#define B_32_BB_APA106_3 NeoPixelBusLg<NeoGrbFeature, NeoEsp8266BitBangApa106Method, NeoGammaNullMethod> // NeoEsp8266BitBang800KbpsMethod
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//APA102
|
//APA102
|
||||||
|
@ -290,6 +340,7 @@
|
||||||
//handles pointer type conversion for all possible bus types
|
//handles pointer type conversion for all possible bus types
|
||||||
class PolyBus {
|
class PolyBus {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// initialize SPI bus speed for DotStar methods
|
// initialize SPI bus speed for DotStar methods
|
||||||
template <class T>
|
template <class T>
|
||||||
static void beginDotStar(void* busPtr, int8_t sck, int8_t miso, int8_t mosi, int8_t ss, uint16_t clock_kHz = 0U) {
|
static void beginDotStar(void* busPtr, int8_t sck, int8_t miso, int8_t mosi, int8_t ss, uint16_t clock_kHz = 0U) {
|
||||||
|
@ -353,6 +404,14 @@ class PolyBus {
|
||||||
case I_8266_U1_APA106_3: (static_cast<B_8266_U1_APA106_3*>(busPtr))->Begin(); break;
|
case I_8266_U1_APA106_3: (static_cast<B_8266_U1_APA106_3*>(busPtr))->Begin(); break;
|
||||||
case I_8266_DM_APA106_3: (static_cast<B_8266_DM_APA106_3*>(busPtr))->Begin(); break;
|
case I_8266_DM_APA106_3: (static_cast<B_8266_DM_APA106_3*>(busPtr))->Begin(); break;
|
||||||
case I_8266_BB_APA106_3: (static_cast<B_8266_BB_APA106_3*>(busPtr))->Begin(); break;
|
case I_8266_BB_APA106_3: (static_cast<B_8266_BB_APA106_3*>(busPtr))->Begin(); break;
|
||||||
|
case I_8266_U0_FW6_5: (static_cast<B_8266_U0_FW6_5*>(busPtr))->Begin(); break;
|
||||||
|
case I_8266_U1_FW6_5: (static_cast<B_8266_U1_FW6_5*>(busPtr))->Begin(); break;
|
||||||
|
case I_8266_DM_FW6_5: (static_cast<B_8266_DM_FW6_5*>(busPtr))->Begin(); break;
|
||||||
|
case I_8266_BB_FW6_5: (static_cast<B_8266_BB_FW6_5*>(busPtr))->Begin(); break;
|
||||||
|
case I_8266_U0_2805_5: (static_cast<B_8266_U0_2805_5*>(busPtr))->Begin(); break;
|
||||||
|
case I_8266_U1_2805_5: (static_cast<B_8266_U1_2805_5*>(busPtr))->Begin(); break;
|
||||||
|
case I_8266_DM_2805_5: (static_cast<B_8266_DM_2805_5*>(busPtr))->Begin(); break;
|
||||||
|
case I_8266_BB_2805_5: (static_cast<B_8266_BB_2805_5*>(busPtr))->Begin(); 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))->Begin(); break;
|
case I_32_RN_NEO_3: (static_cast<B_32_RN_NEO_3*>(busPtr))->Begin(); break;
|
||||||
|
@ -362,7 +421,6 @@ class PolyBus {
|
||||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
case I_32_I1_NEO_3: (static_cast<B_32_I1_NEO_3*>(busPtr))->Begin(); break;
|
case I_32_I1_NEO_3: (static_cast<B_32_I1_NEO_3*>(busPtr))->Begin(); break;
|
||||||
#endif
|
#endif
|
||||||
// case I_32_BB_NEO_3: (static_cast<B_32_BB_NEO_3*>(busPtr))->Begin(); break;
|
|
||||||
case I_32_RN_NEO_4: (static_cast<B_32_RN_NEO_4*>(busPtr))->Begin(); break;
|
case I_32_RN_NEO_4: (static_cast<B_32_RN_NEO_4*>(busPtr))->Begin(); 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))->Begin(); break;
|
case I_32_I0_NEO_4: (static_cast<B_32_I0_NEO_4*>(busPtr))->Begin(); break;
|
||||||
|
@ -370,7 +428,6 @@ class PolyBus {
|
||||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
case I_32_I1_NEO_4: (static_cast<B_32_I1_NEO_4*>(busPtr))->Begin(); break;
|
case I_32_I1_NEO_4: (static_cast<B_32_I1_NEO_4*>(busPtr))->Begin(); break;
|
||||||
#endif
|
#endif
|
||||||
// case I_32_BB_NEO_4: (static_cast<B_32_BB_NEO_4*>(busPtr))->Begin(); break;
|
|
||||||
case I_32_RN_400_3: (static_cast<B_32_RN_400_3*>(busPtr))->Begin(); break;
|
case I_32_RN_400_3: (static_cast<B_32_RN_400_3*>(busPtr))->Begin(); 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))->Begin(); break;
|
case I_32_I0_400_3: (static_cast<B_32_I0_400_3*>(busPtr))->Begin(); break;
|
||||||
|
@ -378,7 +435,6 @@ class PolyBus {
|
||||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
case I_32_I1_400_3: (static_cast<B_32_I1_400_3*>(busPtr))->Begin(); break;
|
case I_32_I1_400_3: (static_cast<B_32_I1_400_3*>(busPtr))->Begin(); break;
|
||||||
#endif
|
#endif
|
||||||
// case I_32_BB_400_3: (static_cast<B_32_BB_400_3*>(busPtr))->Begin(); break;
|
|
||||||
case I_32_RN_TM1_4: beginTM1814<B_32_RN_TM1_4*>(busPtr); break;
|
case I_32_RN_TM1_4: beginTM1814<B_32_RN_TM1_4*>(busPtr); break;
|
||||||
case I_32_RN_TM2_3: (static_cast<B_32_RN_TM2_3*>(busPtr))->Begin(); break;
|
case I_32_RN_TM2_3: (static_cast<B_32_RN_TM2_3*>(busPtr))->Begin(); break;
|
||||||
#ifndef WLED_NO_I2S0_PIXELBUS
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
|
@ -396,7 +452,6 @@ class PolyBus {
|
||||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
case I_32_I1_UCS_3: (static_cast<B_32_I1_UCS_3*>(busPtr))->Begin(); break;
|
case I_32_I1_UCS_3: (static_cast<B_32_I1_UCS_3*>(busPtr))->Begin(); break;
|
||||||
#endif
|
#endif
|
||||||
// case I_32_BB_UCS_3: (static_cast<B_32_BB_UCS_3*>(busPtr))->Begin(); break;
|
|
||||||
case I_32_RN_UCS_4: (static_cast<B_32_RN_UCS_4*>(busPtr))->Begin(); break;
|
case I_32_RN_UCS_4: (static_cast<B_32_RN_UCS_4*>(busPtr))->Begin(); 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))->Begin(); break;
|
case I_32_I0_UCS_4: (static_cast<B_32_I0_UCS_4*>(busPtr))->Begin(); break;
|
||||||
|
@ -404,7 +459,13 @@ class PolyBus {
|
||||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
case I_32_I1_UCS_4: (static_cast<B_32_I1_UCS_4*>(busPtr))->Begin(); break;
|
case I_32_I1_UCS_4: (static_cast<B_32_I1_UCS_4*>(busPtr))->Begin(); break;
|
||||||
#endif
|
#endif
|
||||||
// case I_32_BB_UCS_4: (static_cast<B_32_BB_UCS_4*>(busPtr))->Begin(); break;
|
case I_32_RN_FW6_5: (static_cast<B_32_RN_FW6_5*>(busPtr))->Begin(); break;
|
||||||
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
|
case I_32_I0_FW6_5: (static_cast<B_32_I0_FW6_5*>(busPtr))->Begin(); break;
|
||||||
|
#endif
|
||||||
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
|
case I_32_I1_FW6_5: (static_cast<B_32_I1_FW6_5*>(busPtr))->Begin(); break;
|
||||||
|
#endif
|
||||||
case I_32_RN_APA106_3: (static_cast<B_32_RN_APA106_3*>(busPtr))->Begin(); break;
|
case I_32_RN_APA106_3: (static_cast<B_32_RN_APA106_3*>(busPtr))->Begin(); break;
|
||||||
#ifndef WLED_NO_I2S0_PIXELBUS
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
case I_32_I0_APA106_3: (static_cast<B_32_I0_APA106_3*>(busPtr))->Begin(); break;
|
case I_32_I0_APA106_3: (static_cast<B_32_I0_APA106_3*>(busPtr))->Begin(); break;
|
||||||
|
@ -412,7 +473,13 @@ class PolyBus {
|
||||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
case I_32_I1_APA106_3: (static_cast<B_32_I1_APA106_3*>(busPtr))->Begin(); break;
|
case I_32_I1_APA106_3: (static_cast<B_32_I1_APA106_3*>(busPtr))->Begin(); break;
|
||||||
#endif
|
#endif
|
||||||
// case I_32_BB_APA106_3: (static_cast<B_32_BB_APA106_3*>(busPtr))->Begin(); break;
|
case I_32_RN_2805_5: (static_cast<B_32_RN_2805_5*>(busPtr))->Begin(); break;
|
||||||
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
|
case I_32_I0_2805_5: (static_cast<B_32_I0_2805_5*>(busPtr))->Begin(); break;
|
||||||
|
#endif
|
||||||
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
|
case I_32_I1_2805_5: (static_cast<B_32_I1_2805_5*>(busPtr))->Begin(); break;
|
||||||
|
#endif
|
||||||
// ESP32 can (and should, to avoid inadvertantly driving the chip select signal) specify the pins used for SPI, but only in begin()
|
// ESP32 can (and should, to avoid inadvertantly driving the chip select signal) specify the pins used for SPI, but only in begin()
|
||||||
case I_HS_DOT_3: beginDotStar<B_HS_DOT_3*>(busPtr, pins[1], -1, pins[0], -1, clock_kHz); break;
|
case I_HS_DOT_3: beginDotStar<B_HS_DOT_3*>(busPtr, pins[1], -1, pins[0], -1, clock_kHz); break;
|
||||||
case I_HS_LPD_3: beginDotStar<B_HS_LPD_3*>(busPtr, pins[1], -1, pins[0], -1, clock_kHz); break;
|
case I_HS_LPD_3: beginDotStar<B_HS_LPD_3*>(busPtr, pins[1], -1, pins[0], -1, clock_kHz); break;
|
||||||
|
@ -465,6 +532,14 @@ class PolyBus {
|
||||||
case I_8266_U1_APA106_3: busPtr = new B_8266_U1_APA106_3(len, pins[0]); break;
|
case I_8266_U1_APA106_3: busPtr = new B_8266_U1_APA106_3(len, pins[0]); break;
|
||||||
case I_8266_DM_APA106_3: busPtr = new B_8266_DM_APA106_3(len, pins[0]); break;
|
case I_8266_DM_APA106_3: busPtr = new B_8266_DM_APA106_3(len, pins[0]); break;
|
||||||
case I_8266_BB_APA106_3: busPtr = new B_8266_BB_APA106_3(len, pins[0]); break;
|
case I_8266_BB_APA106_3: busPtr = new B_8266_BB_APA106_3(len, pins[0]); break;
|
||||||
|
case I_8266_U0_FW6_5: busPtr = new B_8266_U0_FW6_5(len, pins[0]); break;
|
||||||
|
case I_8266_U1_FW6_5: busPtr = new B_8266_U1_FW6_5(len, pins[0]); break;
|
||||||
|
case I_8266_DM_FW6_5: busPtr = new B_8266_DM_FW6_5(len, pins[0]); break;
|
||||||
|
case I_8266_BB_FW6_5: busPtr = new B_8266_BB_FW6_5(len, pins[0]); break;
|
||||||
|
case I_8266_U0_2805_5: busPtr = new B_8266_U0_2805_5(len, pins[0]); break;
|
||||||
|
case I_8266_U1_2805_5: busPtr = new B_8266_U1_2805_5(len, pins[0]); break;
|
||||||
|
case I_8266_DM_2805_5: busPtr = new B_8266_DM_2805_5(len, pins[0]); break;
|
||||||
|
case I_8266_BB_2805_5: busPtr = new B_8266_BB_2805_5(len, pins[0]); break;
|
||||||
#endif
|
#endif
|
||||||
#ifdef ARDUINO_ARCH_ESP32
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
case I_32_RN_NEO_3: busPtr = new B_32_RN_NEO_3(len, pins[0], (NeoBusChannel)channel); break;
|
case I_32_RN_NEO_3: busPtr = new B_32_RN_NEO_3(len, pins[0], (NeoBusChannel)channel); break;
|
||||||
|
@ -474,7 +549,6 @@ class PolyBus {
|
||||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
case I_32_I1_NEO_3: busPtr = new B_32_I1_NEO_3(len, pins[0]); break;
|
case I_32_I1_NEO_3: busPtr = new B_32_I1_NEO_3(len, pins[0]); break;
|
||||||
#endif
|
#endif
|
||||||
// case I_32_BB_NEO_3: busPtr = new B_32_BB_NEO_3(len, pins[0], (NeoBusChannel)channel); break;
|
|
||||||
case I_32_RN_NEO_4: busPtr = new B_32_RN_NEO_4(len, pins[0], (NeoBusChannel)channel); break;
|
case I_32_RN_NEO_4: busPtr = new B_32_RN_NEO_4(len, pins[0], (NeoBusChannel)channel); break;
|
||||||
#ifndef WLED_NO_I2S0_PIXELBUS
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
case I_32_I0_NEO_4: busPtr = new B_32_I0_NEO_4(len, pins[0]); break;
|
case I_32_I0_NEO_4: busPtr = new B_32_I0_NEO_4(len, pins[0]); break;
|
||||||
|
@ -482,7 +556,6 @@ class PolyBus {
|
||||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
case I_32_I1_NEO_4: busPtr = new B_32_I1_NEO_4(len, pins[0]); break;
|
case I_32_I1_NEO_4: busPtr = new B_32_I1_NEO_4(len, pins[0]); break;
|
||||||
#endif
|
#endif
|
||||||
// case I_32_BB_NEO_4: busPtr = new B_32_BB_NEO_4(len, pins[0], (NeoBusChannel)channel); break;
|
|
||||||
case I_32_RN_400_3: busPtr = new B_32_RN_400_3(len, pins[0], (NeoBusChannel)channel); break;
|
case I_32_RN_400_3: busPtr = new B_32_RN_400_3(len, pins[0], (NeoBusChannel)channel); break;
|
||||||
#ifndef WLED_NO_I2S0_PIXELBUS
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
case I_32_I0_400_3: busPtr = new B_32_I0_400_3(len, pins[0]); break;
|
case I_32_I0_400_3: busPtr = new B_32_I0_400_3(len, pins[0]); break;
|
||||||
|
@ -490,7 +563,6 @@ class PolyBus {
|
||||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
case I_32_I1_400_3: busPtr = new B_32_I1_400_3(len, pins[0]); break;
|
case I_32_I1_400_3: busPtr = new B_32_I1_400_3(len, pins[0]); break;
|
||||||
#endif
|
#endif
|
||||||
// case I_32_BB_400_3: busPtr = new B_32_BB_400_3(len, pins[0], (NeoBusChannel)channel); break;
|
|
||||||
case I_32_RN_TM1_4: busPtr = new B_32_RN_TM1_4(len, pins[0], (NeoBusChannel)channel); break;
|
case I_32_RN_TM1_4: busPtr = new B_32_RN_TM1_4(len, pins[0], (NeoBusChannel)channel); break;
|
||||||
case I_32_RN_TM2_3: busPtr = new B_32_RN_TM2_3(len, pins[0], (NeoBusChannel)channel); break;
|
case I_32_RN_TM2_3: busPtr = new B_32_RN_TM2_3(len, pins[0], (NeoBusChannel)channel); break;
|
||||||
#ifndef WLED_NO_I2S0_PIXELBUS
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
|
@ -508,7 +580,6 @@ class PolyBus {
|
||||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
case I_32_I1_UCS_3: busPtr = new B_32_I1_UCS_3(len, pins[0]); break;
|
case I_32_I1_UCS_3: busPtr = new B_32_I1_UCS_3(len, pins[0]); break;
|
||||||
#endif
|
#endif
|
||||||
// case I_32_BB_UCS_3: busPtr = new B_32_BB_UCS_3(len, pins[0], (NeoBusChannel)channel); break;
|
|
||||||
case I_32_RN_UCS_4: busPtr = new B_32_RN_UCS_4(len, pins[0], (NeoBusChannel)channel); break;
|
case I_32_RN_UCS_4: busPtr = new B_32_RN_UCS_4(len, pins[0], (NeoBusChannel)channel); break;
|
||||||
#ifndef WLED_NO_I2S0_PIXELBUS
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
case I_32_I0_UCS_4: busPtr = new B_32_I0_UCS_4(len, pins[0]); break;
|
case I_32_I0_UCS_4: busPtr = new B_32_I0_UCS_4(len, pins[0]); break;
|
||||||
|
@ -516,7 +587,6 @@ class PolyBus {
|
||||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
case I_32_I1_UCS_4: busPtr = new B_32_I1_UCS_4(len, pins[0]); break;
|
case I_32_I1_UCS_4: busPtr = new B_32_I1_UCS_4(len, pins[0]); break;
|
||||||
#endif
|
#endif
|
||||||
// case I_32_BB_UCS_4: busPtr = new B_32_BB_UCS_4(len, pins[0], (NeoBusChannel)channel); break;
|
|
||||||
case I_32_RN_APA106_3: busPtr = new B_32_RN_APA106_3(len, pins[0], (NeoBusChannel)channel); break;
|
case I_32_RN_APA106_3: busPtr = new B_32_RN_APA106_3(len, pins[0], (NeoBusChannel)channel); break;
|
||||||
#ifndef WLED_NO_I2S0_PIXELBUS
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
case I_32_I0_APA106_3: busPtr = new B_32_I0_APA106_3(len, pins[0]); break;
|
case I_32_I0_APA106_3: busPtr = new B_32_I0_APA106_3(len, pins[0]); break;
|
||||||
|
@ -524,7 +594,20 @@ class PolyBus {
|
||||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
case I_32_I1_APA106_3: busPtr = new B_32_I1_APA106_3(len, pins[0]); break;
|
case I_32_I1_APA106_3: busPtr = new B_32_I1_APA106_3(len, pins[0]); break;
|
||||||
#endif
|
#endif
|
||||||
// case I_32_BB_APA106_3: busPtr = new B_32_BB_APA106_3(len, pins[0], (NeoBusChannel)channel); break;
|
case I_32_RN_FW6_5: busPtr = new B_32_RN_FW6_5(len, pins[0], (NeoBusChannel)channel); break;
|
||||||
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
|
case I_32_I0_FW6_5: busPtr = new B_32_I0_FW6_5(len, pins[0]); break;
|
||||||
|
#endif
|
||||||
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
|
case I_32_I1_FW6_5: busPtr = new B_32_I1_FW6_5(len, pins[0]); break;
|
||||||
|
#endif
|
||||||
|
case I_32_RN_2805_5: busPtr = new B_32_RN_2805_5(len, pins[0], (NeoBusChannel)channel); break;
|
||||||
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
|
case I_32_I0_2805_5: busPtr = new B_32_I0_2805_5(len, pins[0]); break;
|
||||||
|
#endif
|
||||||
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
|
case I_32_I1_2805_5: busPtr = new B_32_I1_2805_5(len, pins[0]); break;
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
// for 2-wire: pins[1] is clk, pins[0] is dat. begin expects (len, clk, dat)
|
// for 2-wire: pins[1] is clk, pins[0] is dat. begin expects (len, clk, dat)
|
||||||
case I_HS_DOT_3: busPtr = new B_HS_DOT_3(len, pins[1], pins[0]); break;
|
case I_HS_DOT_3: busPtr = new B_HS_DOT_3(len, pins[1], pins[0]); break;
|
||||||
|
@ -578,6 +661,14 @@ class PolyBus {
|
||||||
case I_8266_U1_APA106_3: (static_cast<B_8266_U1_APA106_3*>(busPtr))->Show(consistent); break;
|
case I_8266_U1_APA106_3: (static_cast<B_8266_U1_APA106_3*>(busPtr))->Show(consistent); break;
|
||||||
case I_8266_DM_APA106_3: (static_cast<B_8266_DM_APA106_3*>(busPtr))->Show(consistent); break;
|
case I_8266_DM_APA106_3: (static_cast<B_8266_DM_APA106_3*>(busPtr))->Show(consistent); break;
|
||||||
case I_8266_BB_APA106_3: (static_cast<B_8266_BB_APA106_3*>(busPtr))->Show(consistent); break;
|
case I_8266_BB_APA106_3: (static_cast<B_8266_BB_APA106_3*>(busPtr))->Show(consistent); break;
|
||||||
|
case I_8266_U0_FW6_5: (static_cast<B_8266_U0_FW6_5*>(busPtr))->Show(consistent); break;
|
||||||
|
case I_8266_U1_FW6_5: (static_cast<B_8266_U1_FW6_5*>(busPtr))->Show(consistent); break;
|
||||||
|
case I_8266_DM_FW6_5: (static_cast<B_8266_DM_FW6_5*>(busPtr))->Show(consistent); break;
|
||||||
|
case I_8266_BB_FW6_5: (static_cast<B_8266_BB_FW6_5*>(busPtr))->Show(consistent); break;
|
||||||
|
case I_8266_U0_2805_5: (static_cast<B_8266_U0_2805_5*>(busPtr))->Show(consistent); break;
|
||||||
|
case I_8266_U1_2805_5: (static_cast<B_8266_U1_2805_5*>(busPtr))->Show(consistent); break;
|
||||||
|
case I_8266_DM_2805_5: (static_cast<B_8266_DM_2805_5*>(busPtr))->Show(consistent); break;
|
||||||
|
case I_8266_BB_2805_5: (static_cast<B_8266_BB_2805_5*>(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(consistent); break;
|
case I_32_RN_NEO_3: (static_cast<B_32_RN_NEO_3*>(busPtr))->Show(consistent); break;
|
||||||
|
@ -587,7 +678,6 @@ class PolyBus {
|
||||||
#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(consistent); 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(consistent); break;
|
|
||||||
case I_32_RN_NEO_4: (static_cast<B_32_RN_NEO_4*>(busPtr))->Show(consistent); 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(consistent); break;
|
case I_32_I0_NEO_4: (static_cast<B_32_I0_NEO_4*>(busPtr))->Show(consistent); break;
|
||||||
|
@ -595,7 +685,6 @@ class PolyBus {
|
||||||
#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(consistent); 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(consistent); break;
|
|
||||||
case I_32_RN_400_3: (static_cast<B_32_RN_400_3*>(busPtr))->Show(consistent); 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(consistent); break;
|
case I_32_I0_400_3: (static_cast<B_32_I0_400_3*>(busPtr))->Show(consistent); break;
|
||||||
|
@ -603,7 +692,6 @@ class PolyBus {
|
||||||
#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(consistent); 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(consistent); break;
|
|
||||||
case I_32_RN_TM1_4: (static_cast<B_32_RN_TM1_4*>(busPtr))->Show(consistent); 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(consistent); 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
|
||||||
|
@ -621,7 +709,6 @@ class PolyBus {
|
||||||
#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(consistent); 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(consistent); break;
|
|
||||||
case I_32_RN_UCS_4: (static_cast<B_32_RN_UCS_4*>(busPtr))->Show(consistent); 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(consistent); break;
|
case I_32_I0_UCS_4: (static_cast<B_32_I0_UCS_4*>(busPtr))->Show(consistent); break;
|
||||||
|
@ -629,7 +716,6 @@ class PolyBus {
|
||||||
#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(consistent); 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(consistent); break;
|
|
||||||
case I_32_RN_APA106_3: (static_cast<B_32_RN_APA106_3*>(busPtr))->Show(consistent); break;
|
case I_32_RN_APA106_3: (static_cast<B_32_RN_APA106_3*>(busPtr))->Show(consistent); break;
|
||||||
#ifndef WLED_NO_I2S0_PIXELBUS
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
case I_32_I0_APA106_3: (static_cast<B_32_I0_APA106_3*>(busPtr))->Show(consistent); break;
|
case I_32_I0_APA106_3: (static_cast<B_32_I0_APA106_3*>(busPtr))->Show(consistent); break;
|
||||||
|
@ -637,7 +723,20 @@ class PolyBus {
|
||||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
case I_32_I1_APA106_3: (static_cast<B_32_I1_APA106_3*>(busPtr))->Show(consistent); break;
|
case I_32_I1_APA106_3: (static_cast<B_32_I1_APA106_3*>(busPtr))->Show(consistent); break;
|
||||||
#endif
|
#endif
|
||||||
// case I_32_BB_APA106_3: (static_cast<B_32_BB_APA106_3*>(busPtr))->Show(consistent); break;
|
case I_32_RN_FW6_5: (static_cast<B_32_RN_FW6_5*>(busPtr))->Show(consistent); break;
|
||||||
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
|
case I_32_I0_FW6_5: (static_cast<B_32_I0_FW6_5*>(busPtr))->Show(consistent); break;
|
||||||
|
#endif
|
||||||
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
|
case I_32_I1_FW6_5: (static_cast<B_32_I1_FW6_5*>(busPtr))->Show(consistent); break;
|
||||||
|
#endif
|
||||||
|
case I_32_RN_2805_5: (static_cast<B_32_RN_2805_5*>(busPtr))->Show(consistent); break;
|
||||||
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
|
case I_32_I0_2805_5: (static_cast<B_32_I0_2805_5*>(busPtr))->Show(consistent); break;
|
||||||
|
#endif
|
||||||
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
|
case I_32_I1_2805_5: (static_cast<B_32_I1_2805_5*>(busPtr))->Show(consistent); break;
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
case I_HS_DOT_3: (static_cast<B_HS_DOT_3*>(busPtr))->Show(consistent); 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(consistent); break;
|
case I_SS_DOT_3: (static_cast<B_SS_DOT_3*>(busPtr))->Show(consistent); break;
|
||||||
|
@ -687,6 +786,14 @@ class PolyBus {
|
||||||
case I_8266_U1_APA106_3: return (static_cast<B_8266_U1_APA106_3*>(busPtr))->CanShow(); break;
|
case I_8266_U1_APA106_3: return (static_cast<B_8266_U1_APA106_3*>(busPtr))->CanShow(); break;
|
||||||
case I_8266_DM_APA106_3: return (static_cast<B_8266_DM_APA106_3*>(busPtr))->CanShow(); break;
|
case I_8266_DM_APA106_3: return (static_cast<B_8266_DM_APA106_3*>(busPtr))->CanShow(); break;
|
||||||
case I_8266_BB_APA106_3: return (static_cast<B_8266_BB_APA106_3*>(busPtr))->CanShow(); break;
|
case I_8266_BB_APA106_3: return (static_cast<B_8266_BB_APA106_3*>(busPtr))->CanShow(); break;
|
||||||
|
case I_8266_U0_FW6_5: return (static_cast<B_8266_U0_FW6_5*>(busPtr))->CanShow(); break;
|
||||||
|
case I_8266_U1_FW6_5: return (static_cast<B_8266_U1_FW6_5*>(busPtr))->CanShow(); break;
|
||||||
|
case I_8266_DM_FW6_5: return (static_cast<B_8266_DM_FW6_5*>(busPtr))->CanShow(); break;
|
||||||
|
case I_8266_BB_FW6_5: return (static_cast<B_8266_BB_FW6_5*>(busPtr))->CanShow(); break;
|
||||||
|
case I_8266_U0_2805_5: return (static_cast<B_8266_U0_2805_5*>(busPtr))->CanShow(); break;
|
||||||
|
case I_8266_U1_2805_5: return (static_cast<B_8266_U1_2805_5*>(busPtr))->CanShow(); break;
|
||||||
|
case I_8266_DM_2805_5: return (static_cast<B_8266_DM_2805_5*>(busPtr))->CanShow(); break;
|
||||||
|
case I_8266_BB_2805_5: return (static_cast<B_8266_BB_2805_5*>(busPtr))->CanShow(); break;
|
||||||
#endif
|
#endif
|
||||||
#ifdef ARDUINO_ARCH_ESP32
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
case I_32_RN_NEO_3: return (static_cast<B_32_RN_NEO_3*>(busPtr))->CanShow(); break;
|
case I_32_RN_NEO_3: return (static_cast<B_32_RN_NEO_3*>(busPtr))->CanShow(); break;
|
||||||
|
@ -696,7 +803,6 @@ class PolyBus {
|
||||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
case I_32_I1_NEO_3: return (static_cast<B_32_I1_NEO_3*>(busPtr))->CanShow(); break;
|
case I_32_I1_NEO_3: return (static_cast<B_32_I1_NEO_3*>(busPtr))->CanShow(); break;
|
||||||
#endif
|
#endif
|
||||||
// case I_32_BB_NEO_3: return (static_cast<B_32_BB_NEO_3*>(busPtr))->CanShow(); break;
|
|
||||||
case I_32_RN_NEO_4: return (static_cast<B_32_RN_NEO_4*>(busPtr))->CanShow(); break;
|
case I_32_RN_NEO_4: return (static_cast<B_32_RN_NEO_4*>(busPtr))->CanShow(); break;
|
||||||
#ifndef WLED_NO_I2S0_PIXELBUS
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
case I_32_I0_NEO_4: return (static_cast<B_32_I0_NEO_4*>(busPtr))->CanShow(); break;
|
case I_32_I0_NEO_4: return (static_cast<B_32_I0_NEO_4*>(busPtr))->CanShow(); break;
|
||||||
|
@ -704,7 +810,6 @@ class PolyBus {
|
||||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
case I_32_I1_NEO_4: return (static_cast<B_32_I1_NEO_4*>(busPtr))->CanShow(); break;
|
case I_32_I1_NEO_4: return (static_cast<B_32_I1_NEO_4*>(busPtr))->CanShow(); break;
|
||||||
#endif
|
#endif
|
||||||
// case I_32_BB_NEO_4: return (static_cast<B_32_BB_NEO_4*>(busPtr))->CanShow(); break;
|
|
||||||
case I_32_RN_400_3: return (static_cast<B_32_RN_400_3*>(busPtr))->CanShow(); break;
|
case I_32_RN_400_3: return (static_cast<B_32_RN_400_3*>(busPtr))->CanShow(); break;
|
||||||
#ifndef WLED_NO_I2S0_PIXELBUS
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
case I_32_I0_400_3: return (static_cast<B_32_I0_400_3*>(busPtr))->CanShow(); break;
|
case I_32_I0_400_3: return (static_cast<B_32_I0_400_3*>(busPtr))->CanShow(); break;
|
||||||
|
@ -712,7 +817,6 @@ class PolyBus {
|
||||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
case I_32_I1_400_3: return (static_cast<B_32_I1_400_3*>(busPtr))->CanShow(); break;
|
case I_32_I1_400_3: return (static_cast<B_32_I1_400_3*>(busPtr))->CanShow(); break;
|
||||||
#endif
|
#endif
|
||||||
// case I_32_BB_400_3: return (static_cast<B_32_BB_400_3*>(busPtr))->CanShow(); break;
|
|
||||||
case I_32_RN_TM1_4: return (static_cast<B_32_RN_TM1_4*>(busPtr))->CanShow(); break;
|
case I_32_RN_TM1_4: return (static_cast<B_32_RN_TM1_4*>(busPtr))->CanShow(); break;
|
||||||
case I_32_RN_TM2_3: return (static_cast<B_32_RN_TM2_3*>(busPtr))->CanShow(); break;
|
case I_32_RN_TM2_3: return (static_cast<B_32_RN_TM2_3*>(busPtr))->CanShow(); break;
|
||||||
#ifndef WLED_NO_I2S0_PIXELBUS
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
|
@ -730,7 +834,6 @@ class PolyBus {
|
||||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
case I_32_I1_UCS_3: return (static_cast<B_32_I1_UCS_3*>(busPtr))->CanShow(); break;
|
case I_32_I1_UCS_3: return (static_cast<B_32_I1_UCS_3*>(busPtr))->CanShow(); break;
|
||||||
#endif
|
#endif
|
||||||
// case I_32_BB_UCS_3: return (static_cast<B_32_BB_UCS_3*>(busPtr))->CanShow(); break;
|
|
||||||
case I_32_RN_UCS_4: return (static_cast<B_32_RN_UCS_4*>(busPtr))->CanShow(); break;
|
case I_32_RN_UCS_4: return (static_cast<B_32_RN_UCS_4*>(busPtr))->CanShow(); break;
|
||||||
#ifndef WLED_NO_I2S0_PIXELBUS
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
case I_32_I0_UCS_4: return (static_cast<B_32_I0_UCS_4*>(busPtr))->CanShow(); break;
|
case I_32_I0_UCS_4: return (static_cast<B_32_I0_UCS_4*>(busPtr))->CanShow(); break;
|
||||||
|
@ -738,7 +841,6 @@ class PolyBus {
|
||||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
case I_32_I1_UCS_4: return (static_cast<B_32_I1_UCS_4*>(busPtr))->CanShow(); break;
|
case I_32_I1_UCS_4: return (static_cast<B_32_I1_UCS_4*>(busPtr))->CanShow(); break;
|
||||||
#endif
|
#endif
|
||||||
// case I_32_BB_UCS_4: return (static_cast<B_32_BB_UCS_4*>(busPtr))->CanShow(); break;
|
|
||||||
case I_32_RN_APA106_3: return (static_cast<B_32_RN_APA106_3*>(busPtr))->CanShow(); break;
|
case I_32_RN_APA106_3: return (static_cast<B_32_RN_APA106_3*>(busPtr))->CanShow(); break;
|
||||||
#ifndef WLED_NO_I2S0_PIXELBUS
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
case I_32_I0_APA106_3: return (static_cast<B_32_I0_APA106_3*>(busPtr))->CanShow(); break;
|
case I_32_I0_APA106_3: return (static_cast<B_32_I0_APA106_3*>(busPtr))->CanShow(); break;
|
||||||
|
@ -746,7 +848,20 @@ class PolyBus {
|
||||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
case I_32_I1_APA106_3: return (static_cast<B_32_I1_APA106_3*>(busPtr))->CanShow(); break;
|
case I_32_I1_APA106_3: return (static_cast<B_32_I1_APA106_3*>(busPtr))->CanShow(); break;
|
||||||
#endif
|
#endif
|
||||||
// case I_32_BB_APA106_3: return (static_cast<B_32_BB_APA106_3*>(busPtr))->CanShow(); break;
|
case I_32_RN_FW6_5: return (static_cast<B_32_RN_FW6_5*>(busPtr))->CanShow(); break;
|
||||||
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
|
case I_32_I0_FW6_5: return (static_cast<B_32_I0_FW6_5*>(busPtr))->CanShow(); break;
|
||||||
|
#endif
|
||||||
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
|
case I_32_I1_FW6_5: return (static_cast<B_32_I1_FW6_5*>(busPtr))->CanShow(); break;
|
||||||
|
#endif
|
||||||
|
case I_32_RN_2805_5: return (static_cast<B_32_RN_2805_5*>(busPtr))->CanShow(); break;
|
||||||
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
|
case I_32_I0_2805_5: return (static_cast<B_32_I0_2805_5*>(busPtr))->CanShow(); break;
|
||||||
|
#endif
|
||||||
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
|
case I_32_I1_2805_5: return (static_cast<B_32_I1_2805_5*>(busPtr))->CanShow(); break;
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
case I_HS_DOT_3: return (static_cast<B_HS_DOT_3*>(busPtr))->CanShow(); break;
|
case I_HS_DOT_3: return (static_cast<B_HS_DOT_3*>(busPtr))->CanShow(); break;
|
||||||
case I_SS_DOT_3: return (static_cast<B_SS_DOT_3*>(busPtr))->CanShow(); break;
|
case I_SS_DOT_3: return (static_cast<B_SS_DOT_3*>(busPtr))->CanShow(); break;
|
||||||
|
@ -762,12 +877,13 @@ class PolyBus {
|
||||||
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, uint16_t wwcw = 0) {
|
||||||
uint8_t r = c >> 16;
|
uint8_t r = c >> 16;
|
||||||
uint8_t g = c >> 8;
|
uint8_t g = c >> 8;
|
||||||
uint8_t b = c >> 0;
|
uint8_t b = c >> 0;
|
||||||
uint8_t w = c >> 24;
|
uint8_t w = c >> 24;
|
||||||
RgbwColor col;
|
RgbwColor col;
|
||||||
|
uint8_t cctWW = wwcw & 0xFF, cctCW = (wwcw>>8) & 0xFF;
|
||||||
|
|
||||||
// reorder channels to selected order
|
// reorder channels to selected order
|
||||||
switch (co & 0x0F) {
|
switch (co & 0x0F) {
|
||||||
|
@ -821,6 +937,14 @@ class PolyBus {
|
||||||
case I_8266_U1_APA106_3: (static_cast<B_8266_U1_APA106_3*>(busPtr))->SetPixelColor(pix, RgbColor(col)); break;
|
case I_8266_U1_APA106_3: (static_cast<B_8266_U1_APA106_3*>(busPtr))->SetPixelColor(pix, RgbColor(col)); break;
|
||||||
case I_8266_DM_APA106_3: (static_cast<B_8266_DM_APA106_3*>(busPtr))->SetPixelColor(pix, RgbColor(col)); break;
|
case I_8266_DM_APA106_3: (static_cast<B_8266_DM_APA106_3*>(busPtr))->SetPixelColor(pix, RgbColor(col)); break;
|
||||||
case I_8266_BB_APA106_3: (static_cast<B_8266_BB_APA106_3*>(busPtr))->SetPixelColor(pix, RgbColor(col)); break;
|
case I_8266_BB_APA106_3: (static_cast<B_8266_BB_APA106_3*>(busPtr))->SetPixelColor(pix, RgbColor(col)); break;
|
||||||
|
case I_8266_U0_FW6_5: (static_cast<B_8266_U0_FW6_5*>(busPtr))->SetPixelColor(pix, RgbwwColor(col.R, col.G, col.B, cctWW, cctCW)); break;
|
||||||
|
case I_8266_U1_FW6_5: (static_cast<B_8266_U1_FW6_5*>(busPtr))->SetPixelColor(pix, RgbwwColor(col.R, col.G, col.B, cctWW, cctCW)); break;
|
||||||
|
case I_8266_DM_FW6_5: (static_cast<B_8266_DM_FW6_5*>(busPtr))->SetPixelColor(pix, RgbwwColor(col.R, col.G, col.B, cctWW, cctCW)); break;
|
||||||
|
case I_8266_BB_FW6_5: (static_cast<B_8266_BB_FW6_5*>(busPtr))->SetPixelColor(pix, RgbwwColor(col.R, col.G, col.B, cctWW, cctCW)); break;
|
||||||
|
case I_8266_U0_2805_5: (static_cast<B_8266_U0_2805_5*>(busPtr))->SetPixelColor(pix, RgbwwColor(col.R, col.G, col.B, cctWW, cctCW)); break;
|
||||||
|
case I_8266_U1_2805_5: (static_cast<B_8266_U1_2805_5*>(busPtr))->SetPixelColor(pix, RgbwwColor(col.R, col.G, col.B, cctWW, cctCW)); break;
|
||||||
|
case I_8266_DM_2805_5: (static_cast<B_8266_DM_2805_5*>(busPtr))->SetPixelColor(pix, RgbwwColor(col.R, col.G, col.B, cctWW, cctCW)); break;
|
||||||
|
case I_8266_BB_2805_5: (static_cast<B_8266_BB_2805_5*>(busPtr))->SetPixelColor(pix, RgbwwColor(col.R, col.G, col.B, cctWW, cctCW)); 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))->SetPixelColor(pix, RgbColor(col)); break;
|
case I_32_RN_NEO_3: (static_cast<B_32_RN_NEO_3*>(busPtr))->SetPixelColor(pix, RgbColor(col)); break;
|
||||||
|
@ -830,7 +954,6 @@ class PolyBus {
|
||||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
case I_32_I1_NEO_3: (static_cast<B_32_I1_NEO_3*>(busPtr))->SetPixelColor(pix, RgbColor(col)); break;
|
case I_32_I1_NEO_3: (static_cast<B_32_I1_NEO_3*>(busPtr))->SetPixelColor(pix, RgbColor(col)); break;
|
||||||
#endif
|
#endif
|
||||||
// case I_32_BB_NEO_3: (static_cast<B_32_BB_NEO_3*>(busPtr))->SetPixelColor(pix, RgbColor(col)); break;
|
|
||||||
case I_32_RN_NEO_4: (static_cast<B_32_RN_NEO_4*>(busPtr))->SetPixelColor(pix, col); break;
|
case I_32_RN_NEO_4: (static_cast<B_32_RN_NEO_4*>(busPtr))->SetPixelColor(pix, col); 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))->SetPixelColor(pix, col); break;
|
case I_32_I0_NEO_4: (static_cast<B_32_I0_NEO_4*>(busPtr))->SetPixelColor(pix, col); break;
|
||||||
|
@ -838,7 +961,6 @@ class PolyBus {
|
||||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
case I_32_I1_NEO_4: (static_cast<B_32_I1_NEO_4*>(busPtr))->SetPixelColor(pix, col); break;
|
case I_32_I1_NEO_4: (static_cast<B_32_I1_NEO_4*>(busPtr))->SetPixelColor(pix, col); break;
|
||||||
#endif
|
#endif
|
||||||
// case I_32_BB_NEO_4: (static_cast<B_32_BB_NEO_4*>(busPtr))->SetPixelColor(pix, col); break;
|
|
||||||
case I_32_RN_400_3: (static_cast<B_32_RN_400_3*>(busPtr))->SetPixelColor(pix, RgbColor(col)); break;
|
case I_32_RN_400_3: (static_cast<B_32_RN_400_3*>(busPtr))->SetPixelColor(pix, RgbColor(col)); 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))->SetPixelColor(pix, RgbColor(col)); break;
|
case I_32_I0_400_3: (static_cast<B_32_I0_400_3*>(busPtr))->SetPixelColor(pix, RgbColor(col)); break;
|
||||||
|
@ -846,7 +968,6 @@ class PolyBus {
|
||||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
case I_32_I1_400_3: (static_cast<B_32_I1_400_3*>(busPtr))->SetPixelColor(pix, RgbColor(col)); break;
|
case I_32_I1_400_3: (static_cast<B_32_I1_400_3*>(busPtr))->SetPixelColor(pix, RgbColor(col)); break;
|
||||||
#endif
|
#endif
|
||||||
// case I_32_BB_400_3: (static_cast<B_32_BB_400_3*>(busPtr))->SetPixelColor(pix, RgbColor(colB)); break;
|
|
||||||
case I_32_RN_TM1_4: (static_cast<B_32_RN_TM1_4*>(busPtr))->SetPixelColor(pix, col); break;
|
case I_32_RN_TM1_4: (static_cast<B_32_RN_TM1_4*>(busPtr))->SetPixelColor(pix, col); break;
|
||||||
case I_32_RN_TM2_3: (static_cast<B_32_RN_TM2_3*>(busPtr))->SetPixelColor(pix, RgbColor(col)); break;
|
case I_32_RN_TM2_3: (static_cast<B_32_RN_TM2_3*>(busPtr))->SetPixelColor(pix, RgbColor(col)); break;
|
||||||
#ifndef WLED_NO_I2S0_PIXELBUS
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
|
@ -864,7 +985,6 @@ class PolyBus {
|
||||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
case I_32_I1_UCS_3: (static_cast<B_32_I1_UCS_3*>(busPtr))->SetPixelColor(pix, Rgb48Color(RgbColor(col))); break;
|
case I_32_I1_UCS_3: (static_cast<B_32_I1_UCS_3*>(busPtr))->SetPixelColor(pix, Rgb48Color(RgbColor(col))); break;
|
||||||
#endif
|
#endif
|
||||||
// case I_32_BB_UCS_3: (static_cast<B_32_BB_UCS_3*>(busPtr))->SetPixelColor(pix, Rgb48Color(RgbColor(col))); break;
|
|
||||||
case I_32_RN_UCS_4: (static_cast<B_32_RN_UCS_4*>(busPtr))->SetPixelColor(pix, Rgbw64Color(col)); break;
|
case I_32_RN_UCS_4: (static_cast<B_32_RN_UCS_4*>(busPtr))->SetPixelColor(pix, Rgbw64Color(col)); 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))->SetPixelColor(pix, Rgbw64Color(col)); break;
|
case I_32_I0_UCS_4: (static_cast<B_32_I0_UCS_4*>(busPtr))->SetPixelColor(pix, Rgbw64Color(col)); break;
|
||||||
|
@ -872,7 +992,6 @@ class PolyBus {
|
||||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
case I_32_I1_UCS_4: (static_cast<B_32_I1_UCS_4*>(busPtr))->SetPixelColor(pix, Rgbw64Color(col)); break;
|
case I_32_I1_UCS_4: (static_cast<B_32_I1_UCS_4*>(busPtr))->SetPixelColor(pix, Rgbw64Color(col)); break;
|
||||||
#endif
|
#endif
|
||||||
// case I_32_BB_UCS_4: (static_cast<B_32_BB_UCS_4*>(busPtr))->SetPixelColor(pix, Rgbw64Color(col)); break;
|
|
||||||
case I_32_RN_APA106_3: (static_cast<B_32_RN_APA106_3*>(busPtr))->SetPixelColor(pix, RgbColor(col)); break;
|
case I_32_RN_APA106_3: (static_cast<B_32_RN_APA106_3*>(busPtr))->SetPixelColor(pix, RgbColor(col)); break;
|
||||||
#ifndef WLED_NO_I2S0_PIXELBUS
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
case I_32_I0_APA106_3: (static_cast<B_32_I0_APA106_3*>(busPtr))->SetPixelColor(pix, RgbColor(col)); break;
|
case I_32_I0_APA106_3: (static_cast<B_32_I0_APA106_3*>(busPtr))->SetPixelColor(pix, RgbColor(col)); break;
|
||||||
|
@ -880,7 +999,20 @@ class PolyBus {
|
||||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
case I_32_I1_APA106_3: (static_cast<B_32_I1_APA106_3*>(busPtr))->SetPixelColor(pix, RgbColor(col)); break;
|
case I_32_I1_APA106_3: (static_cast<B_32_I1_APA106_3*>(busPtr))->SetPixelColor(pix, RgbColor(col)); break;
|
||||||
#endif
|
#endif
|
||||||
// case I_32_BB_APA106_3: (static_cast<B_32_BB_APA106_3*>(busPtr))->SetPixelColor(pix, RgbColor(col)); break;
|
case I_32_RN_FW6_5: (static_cast<B_32_RN_FW6_5*>(busPtr))->SetPixelColor(pix, RgbwwColor(col.R, col.G, col.B, cctWW, cctCW)); break;
|
||||||
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
|
case I_32_I0_FW6_5: (static_cast<B_32_I0_FW6_5*>(busPtr))->SetPixelColor(pix, RgbwwColor(col.R, col.G, col.B, cctWW, cctCW)); break;
|
||||||
|
#endif
|
||||||
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
|
case I_32_I1_FW6_5: (static_cast<B_32_I1_FW6_5*>(busPtr))->SetPixelColor(pix, RgbwwColor(col.R, col.G, col.B, cctWW, cctCW)); break;
|
||||||
|
#endif
|
||||||
|
case I_32_RN_2805_5: (static_cast<B_32_RN_2805_5*>(busPtr))->SetPixelColor(pix, RgbwwColor(col.R, col.G, col.B, cctWW, cctCW)); break;
|
||||||
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
|
case I_32_I0_2805_5: (static_cast<B_32_I0_2805_5*>(busPtr))->SetPixelColor(pix, RgbwwColor(col.R, col.G, col.B, cctWW, cctCW)); break;
|
||||||
|
#endif
|
||||||
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
|
case I_32_I1_2805_5: (static_cast<B_32_I1_2805_5*>(busPtr))->SetPixelColor(pix, RgbwwColor(col.R, col.G, col.B, cctWW, cctCW)); break;
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
case I_HS_DOT_3: (static_cast<B_HS_DOT_3*>(busPtr))->SetPixelColor(pix, RgbColor(col)); break;
|
case I_HS_DOT_3: (static_cast<B_HS_DOT_3*>(busPtr))->SetPixelColor(pix, RgbColor(col)); break;
|
||||||
case I_SS_DOT_3: (static_cast<B_SS_DOT_3*>(busPtr))->SetPixelColor(pix, RgbColor(col)); break;
|
case I_SS_DOT_3: (static_cast<B_SS_DOT_3*>(busPtr))->SetPixelColor(pix, RgbColor(col)); break;
|
||||||
|
@ -931,6 +1063,14 @@ class PolyBus {
|
||||||
case I_8266_U1_APA106_3: (static_cast<B_8266_U1_APA106_3*>(busPtr))->SetLuminance(b); break;
|
case I_8266_U1_APA106_3: (static_cast<B_8266_U1_APA106_3*>(busPtr))->SetLuminance(b); break;
|
||||||
case I_8266_DM_APA106_3: (static_cast<B_8266_DM_APA106_3*>(busPtr))->SetLuminance(b); break;
|
case I_8266_DM_APA106_3: (static_cast<B_8266_DM_APA106_3*>(busPtr))->SetLuminance(b); break;
|
||||||
case I_8266_BB_APA106_3: (static_cast<B_8266_BB_APA106_3*>(busPtr))->SetLuminance(b); break;
|
case I_8266_BB_APA106_3: (static_cast<B_8266_BB_APA106_3*>(busPtr))->SetLuminance(b); break;
|
||||||
|
case I_8266_U0_FW6_5: (static_cast<B_8266_U0_FW6_5*>(busPtr))->SetLuminance(b); break;
|
||||||
|
case I_8266_U1_FW6_5: (static_cast<B_8266_U1_FW6_5*>(busPtr))->SetLuminance(b); break;
|
||||||
|
case I_8266_DM_FW6_5: (static_cast<B_8266_DM_FW6_5*>(busPtr))->SetLuminance(b); break;
|
||||||
|
case I_8266_BB_FW6_5: (static_cast<B_8266_BB_FW6_5*>(busPtr))->SetLuminance(b); break;
|
||||||
|
case I_8266_U0_2805_5: (static_cast<B_8266_U0_2805_5*>(busPtr))->SetLuminance(b); break;
|
||||||
|
case I_8266_U1_2805_5: (static_cast<B_8266_U1_2805_5*>(busPtr))->SetLuminance(b); break;
|
||||||
|
case I_8266_DM_2805_5: (static_cast<B_8266_DM_2805_5*>(busPtr))->SetLuminance(b); break;
|
||||||
|
case I_8266_BB_2805_5: (static_cast<B_8266_BB_2805_5*>(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); break;
|
case I_32_RN_NEO_3: (static_cast<B_32_RN_NEO_3*>(busPtr))->SetLuminance(b); break;
|
||||||
|
@ -940,7 +1080,6 @@ class PolyBus {
|
||||||
#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); 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); break;
|
|
||||||
case I_32_RN_NEO_4: (static_cast<B_32_RN_NEO_4*>(busPtr))->SetLuminance(b); 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); break;
|
case I_32_I0_NEO_4: (static_cast<B_32_I0_NEO_4*>(busPtr))->SetLuminance(b); break;
|
||||||
|
@ -948,7 +1087,6 @@ class PolyBus {
|
||||||
#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); 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); break;
|
|
||||||
case I_32_RN_400_3: (static_cast<B_32_RN_400_3*>(busPtr))->SetLuminance(b); 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); break;
|
case I_32_I0_400_3: (static_cast<B_32_I0_400_3*>(busPtr))->SetLuminance(b); break;
|
||||||
|
@ -956,7 +1094,6 @@ class PolyBus {
|
||||||
#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); 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); break;
|
|
||||||
case I_32_RN_TM1_4: (static_cast<B_32_RN_TM1_4*>(busPtr))->SetLuminance(b); 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); 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
|
||||||
|
@ -974,7 +1111,6 @@ class PolyBus {
|
||||||
#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); 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); break;
|
|
||||||
case I_32_RN_UCS_4: (static_cast<B_32_RN_UCS_4*>(busPtr))->SetLuminance(b); 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); break;
|
case I_32_I0_UCS_4: (static_cast<B_32_I0_UCS_4*>(busPtr))->SetLuminance(b); break;
|
||||||
|
@ -982,7 +1118,6 @@ class PolyBus {
|
||||||
#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); 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); break;
|
|
||||||
case I_32_RN_APA106_3: (static_cast<B_32_RN_APA106_3*>(busPtr))->SetLuminance(b); break;
|
case I_32_RN_APA106_3: (static_cast<B_32_RN_APA106_3*>(busPtr))->SetLuminance(b); break;
|
||||||
#ifndef WLED_NO_I2S0_PIXELBUS
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
case I_32_I0_APA106_3: (static_cast<B_32_I0_APA106_3*>(busPtr))->SetLuminance(b); break;
|
case I_32_I0_APA106_3: (static_cast<B_32_I0_APA106_3*>(busPtr))->SetLuminance(b); break;
|
||||||
|
@ -990,7 +1125,20 @@ class PolyBus {
|
||||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
case I_32_I1_APA106_3: (static_cast<B_32_I1_APA106_3*>(busPtr))->SetLuminance(b); break;
|
case I_32_I1_APA106_3: (static_cast<B_32_I1_APA106_3*>(busPtr))->SetLuminance(b); break;
|
||||||
#endif
|
#endif
|
||||||
// case I_32_BB_APA106_3: (static_cast<B_32_BB_APA106_3*>(busPtr))->SetLuminance(b); break;
|
case I_32_RN_FW6_5: (static_cast<B_32_RN_FW6_5*>(busPtr))->SetLuminance(b); break;
|
||||||
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
|
case I_32_I0_FW6_5: (static_cast<B_32_I0_FW6_5*>(busPtr))->SetLuminance(b); break;
|
||||||
|
#endif
|
||||||
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
|
case I_32_I1_FW6_5: (static_cast<B_32_I1_FW6_5*>(busPtr))->SetLuminance(b); break;
|
||||||
|
#endif
|
||||||
|
case I_32_RN_2805_5: (static_cast<B_32_RN_2805_5*>(busPtr))->SetLuminance(b); break;
|
||||||
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
|
case I_32_I0_2805_5: (static_cast<B_32_I0_2805_5*>(busPtr))->SetLuminance(b); break;
|
||||||
|
#endif
|
||||||
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
|
case I_32_I1_2805_5: (static_cast<B_32_I1_2805_5*>(busPtr))->SetLuminance(b); break;
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
case I_HS_DOT_3: (static_cast<B_HS_DOT_3*>(busPtr))->SetLuminance(b); 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); break;
|
case I_SS_DOT_3: (static_cast<B_SS_DOT_3*>(busPtr))->SetLuminance(b); break;
|
||||||
|
@ -1042,6 +1190,14 @@ class PolyBus {
|
||||||
case I_8266_U1_APA106_3: col = (static_cast<B_8266_U1_APA106_3*>(busPtr))->GetPixelColor(pix); break;
|
case I_8266_U1_APA106_3: col = (static_cast<B_8266_U1_APA106_3*>(busPtr))->GetPixelColor(pix); break;
|
||||||
case I_8266_DM_APA106_3: col = (static_cast<B_8266_DM_APA106_3*>(busPtr))->GetPixelColor(pix); break;
|
case I_8266_DM_APA106_3: col = (static_cast<B_8266_DM_APA106_3*>(busPtr))->GetPixelColor(pix); break;
|
||||||
case I_8266_BB_APA106_3: col = (static_cast<B_8266_BB_APA106_3*>(busPtr))->GetPixelColor(pix); break;
|
case I_8266_BB_APA106_3: col = (static_cast<B_8266_BB_APA106_3*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
case I_8266_U0_FW6_5: { RgbwwColor c = (static_cast<B_8266_U0_FW6_5*>(busPtr))->GetPixelColor(pix); col = RGBW32(c.R,c.G,c.B,max(c.WW,c.CW)); } break; // will not return original W
|
||||||
|
case I_8266_U1_FW6_5: { RgbwwColor c = (static_cast<B_8266_U1_FW6_5*>(busPtr))->GetPixelColor(pix); col = RGBW32(c.R,c.G,c.B,max(c.WW,c.CW)); } break; // will not return original W
|
||||||
|
case I_8266_DM_FW6_5: { RgbwwColor c = (static_cast<B_8266_DM_FW6_5*>(busPtr))->GetPixelColor(pix); col = RGBW32(c.R,c.G,c.B,max(c.WW,c.CW)); } break; // will not return original W
|
||||||
|
case I_8266_BB_FW6_5: { RgbwwColor c = (static_cast<B_8266_BB_FW6_5*>(busPtr))->GetPixelColor(pix); col = RGBW32(c.R,c.G,c.B,max(c.WW,c.CW)); } break; // will not return original W
|
||||||
|
case I_8266_U0_2805_5: { RgbwwColor c = (static_cast<B_8266_U0_2805_5*>(busPtr))->GetPixelColor(pix); col = RGBW32(c.R,c.G,c.B,max(c.WW,c.CW)); } break; // will not return original W
|
||||||
|
case I_8266_U1_2805_5: { RgbwwColor c = (static_cast<B_8266_U1_2805_5*>(busPtr))->GetPixelColor(pix); col = RGBW32(c.R,c.G,c.B,max(c.WW,c.CW)); } break; // will not return original W
|
||||||
|
case I_8266_DM_2805_5: { RgbwwColor c = (static_cast<B_8266_DM_2805_5*>(busPtr))->GetPixelColor(pix); col = RGBW32(c.R,c.G,c.B,max(c.WW,c.CW)); } break; // will not return original W
|
||||||
|
case I_8266_BB_2805_5: { RgbwwColor c = (static_cast<B_8266_BB_2805_5*>(busPtr))->GetPixelColor(pix); col = RGBW32(c.R,c.G,c.B,max(c.WW,c.CW)); } break; // will not return original W
|
||||||
#endif
|
#endif
|
||||||
#ifdef ARDUINO_ARCH_ESP32
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
case I_32_RN_NEO_3: col = (static_cast<B_32_RN_NEO_3*>(busPtr))->GetPixelColor(pix); break;
|
case I_32_RN_NEO_3: col = (static_cast<B_32_RN_NEO_3*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
@ -1051,7 +1207,6 @@ class PolyBus {
|
||||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
case I_32_I1_NEO_3: col = (static_cast<B_32_I1_NEO_3*>(busPtr))->GetPixelColor(pix); break;
|
case I_32_I1_NEO_3: col = (static_cast<B_32_I1_NEO_3*>(busPtr))->GetPixelColor(pix); break;
|
||||||
#endif
|
#endif
|
||||||
// case I_32_BB_NEO_3: col = (static_cast<B_32_BB_NEO_3*>(busPtr))->GetPixelColor(pix); break;
|
|
||||||
case I_32_RN_NEO_4: col = (static_cast<B_32_RN_NEO_4*>(busPtr))->GetPixelColor(pix); break;
|
case I_32_RN_NEO_4: col = (static_cast<B_32_RN_NEO_4*>(busPtr))->GetPixelColor(pix); break;
|
||||||
#ifndef WLED_NO_I2S0_PIXELBUS
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
case I_32_I0_NEO_4: col = (static_cast<B_32_I0_NEO_4*>(busPtr))->GetPixelColor(pix); break;
|
case I_32_I0_NEO_4: col = (static_cast<B_32_I0_NEO_4*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
@ -1059,7 +1214,6 @@ class PolyBus {
|
||||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
case I_32_I1_NEO_4: col = (static_cast<B_32_I1_NEO_4*>(busPtr))->GetPixelColor(pix); break;
|
case I_32_I1_NEO_4: col = (static_cast<B_32_I1_NEO_4*>(busPtr))->GetPixelColor(pix); break;
|
||||||
#endif
|
#endif
|
||||||
// case I_32_BB_NEO_4: col = (static_cast<B_32_BB_NEO_4*>(busPtr))->GetPixelColor(pix); break;
|
|
||||||
case I_32_RN_400_3: col = (static_cast<B_32_RN_400_3*>(busPtr))->GetPixelColor(pix); break;
|
case I_32_RN_400_3: col = (static_cast<B_32_RN_400_3*>(busPtr))->GetPixelColor(pix); break;
|
||||||
#ifndef WLED_NO_I2S0_PIXELBUS
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
case I_32_I0_400_3: col = (static_cast<B_32_I0_400_3*>(busPtr))->GetPixelColor(pix); break;
|
case I_32_I0_400_3: col = (static_cast<B_32_I0_400_3*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
@ -1067,7 +1221,6 @@ class PolyBus {
|
||||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
case I_32_I1_400_3: col = (static_cast<B_32_I1_400_3*>(busPtr))->GetPixelColor(pix); break;
|
case I_32_I1_400_3: col = (static_cast<B_32_I1_400_3*>(busPtr))->GetPixelColor(pix); break;
|
||||||
#endif
|
#endif
|
||||||
// case I_32_BB_400_3: col = (static_cast<B_32_BB_400_3*>(busPtr))->GetPixelColor(pix); break;
|
|
||||||
case I_32_RN_TM1_4: col = (static_cast<B_32_RN_TM1_4*>(busPtr))->GetPixelColor(pix); break;
|
case I_32_RN_TM1_4: col = (static_cast<B_32_RN_TM1_4*>(busPtr))->GetPixelColor(pix); break;
|
||||||
case I_32_RN_TM2_3: col = (static_cast<B_32_RN_TM2_3*>(busPtr))->GetPixelColor(pix); break;
|
case I_32_RN_TM2_3: col = (static_cast<B_32_RN_TM2_3*>(busPtr))->GetPixelColor(pix); break;
|
||||||
#ifndef WLED_NO_I2S0_PIXELBUS
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
|
@ -1085,7 +1238,6 @@ class PolyBus {
|
||||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
case I_32_I1_UCS_3: { Rgb48Color c = (static_cast<B_32_I1_UCS_3*>(busPtr))->GetPixelColor(pix); col = RGBW32(c.R>>8,c.G>>8,c.B>>8,0); } break;
|
case I_32_I1_UCS_3: { Rgb48Color c = (static_cast<B_32_I1_UCS_3*>(busPtr))->GetPixelColor(pix); col = RGBW32(c.R>>8,c.G>>8,c.B>>8,0); } break;
|
||||||
#endif
|
#endif
|
||||||
// case I_32_BB_UCS_3: col = (static_cast<B_32_BB_UCS_3*>(busPtr))->GetPixelColor(pix); break;
|
|
||||||
case I_32_RN_UCS_4: { Rgbw64Color c = (static_cast<B_32_RN_UCS_4*>(busPtr))->GetPixelColor(pix); col = RGBW32(c.R>>8,c.G>>8,c.B>>8,c.W>>8); } break;
|
case I_32_RN_UCS_4: { Rgbw64Color c = (static_cast<B_32_RN_UCS_4*>(busPtr))->GetPixelColor(pix); col = RGBW32(c.R>>8,c.G>>8,c.B>>8,c.W>>8); } break;
|
||||||
#ifndef WLED_NO_I2S0_PIXELBUS
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
case I_32_I0_UCS_4: { Rgbw64Color c = (static_cast<B_32_I0_UCS_4*>(busPtr))->GetPixelColor(pix); col = RGBW32(c.R>>8,c.G>>8,c.B>>8,c.W>>8); } break;
|
case I_32_I0_UCS_4: { Rgbw64Color c = (static_cast<B_32_I0_UCS_4*>(busPtr))->GetPixelColor(pix); col = RGBW32(c.R>>8,c.G>>8,c.B>>8,c.W>>8); } break;
|
||||||
|
@ -1093,7 +1245,6 @@ class PolyBus {
|
||||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
case I_32_I1_UCS_4: { Rgbw64Color c = (static_cast<B_32_I1_UCS_4*>(busPtr))->GetPixelColor(pix); col = RGBW32(c.R>>8,c.G>>8,c.B>>8,c.W>>8); } break;
|
case I_32_I1_UCS_4: { Rgbw64Color c = (static_cast<B_32_I1_UCS_4*>(busPtr))->GetPixelColor(pix); col = RGBW32(c.R>>8,c.G>>8,c.B>>8,c.W>>8); } break;
|
||||||
#endif
|
#endif
|
||||||
// case I_32_BB_UCS_4: col = (static_cast<B_32_BB_UCS_4*>(busPtr))->GetPixelColor(pix); break;
|
|
||||||
case I_32_RN_APA106_3: col = (static_cast<B_32_RN_APA106_3*>(busPtr))->GetPixelColor(pix); break;
|
case I_32_RN_APA106_3: col = (static_cast<B_32_RN_APA106_3*>(busPtr))->GetPixelColor(pix); break;
|
||||||
#ifndef WLED_NO_I2S0_PIXELBUS
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
case I_32_I0_APA106_3: col = (static_cast<B_32_I0_APA106_3*>(busPtr))->GetPixelColor(pix); break;
|
case I_32_I0_APA106_3: col = (static_cast<B_32_I0_APA106_3*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
@ -1101,7 +1252,20 @@ class PolyBus {
|
||||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
case I_32_I1_APA106_3: col = (static_cast<B_32_I1_APA106_3*>(busPtr))->GetPixelColor(pix); break;
|
case I_32_I1_APA106_3: col = (static_cast<B_32_I1_APA106_3*>(busPtr))->GetPixelColor(pix); break;
|
||||||
#endif
|
#endif
|
||||||
// case I_32_BB_APA106_3: col = (static_cast<B_32_BB_APA106_3*>(busPtr))->GetPixelColor(pix); break;
|
case I_32_RN_FW6_5: { RgbwwColor c = (static_cast<B_32_RN_FW6_5*>(busPtr))->GetPixelColor(pix); col = RGBW32(c.R,c.G,c.B,max(c.WW,c.CW)); } break; // will not return original W
|
||||||
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
|
case I_32_I0_FW6_5: { RgbwwColor c = (static_cast<B_32_I0_FW6_5*>(busPtr))->GetPixelColor(pix); col = RGBW32(c.R,c.G,c.B,max(c.WW,c.CW)); } break; // will not return original W
|
||||||
|
#endif
|
||||||
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
|
case I_32_I1_FW6_5: { RgbwwColor c = (static_cast<B_32_I1_FW6_5*>(busPtr))->GetPixelColor(pix); col = RGBW32(c.R,c.G,c.B,max(c.WW,c.CW)); } break; // will not return original W
|
||||||
|
#endif
|
||||||
|
case I_32_RN_2805_5: { RgbwwColor c = (static_cast<B_32_RN_2805_5*>(busPtr))->GetPixelColor(pix); col = RGBW32(c.R,c.G,c.B,max(c.WW,c.CW)); } break; // will not return original W
|
||||||
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
|
case I_32_I0_2805_5: { RgbwwColor c = (static_cast<B_32_I0_2805_5*>(busPtr))->GetPixelColor(pix); col = RGBW32(c.R,c.G,c.B,max(c.WW,c.CW)); } break; // will not return original W
|
||||||
|
#endif
|
||||||
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
|
case I_32_I1_2805_5: { RgbwwColor c = (static_cast<B_32_I1_2805_5*>(busPtr))->GetPixelColor(pix); col = RGBW32(c.R,c.G,c.B,max(c.WW,c.CW)); } break; // will not return original W
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
case I_HS_DOT_3: col = (static_cast<B_HS_DOT_3*>(busPtr))->GetPixelColor(pix); break;
|
case I_HS_DOT_3: col = (static_cast<B_HS_DOT_3*>(busPtr))->GetPixelColor(pix); break;
|
||||||
case I_SS_DOT_3: col = (static_cast<B_SS_DOT_3*>(busPtr))->GetPixelColor(pix); break;
|
case I_SS_DOT_3: col = (static_cast<B_SS_DOT_3*>(busPtr))->GetPixelColor(pix); break;
|
||||||
|
@ -1171,6 +1335,14 @@ class PolyBus {
|
||||||
case I_8266_U1_APA106_3: delete (static_cast<B_8266_U1_APA106_3*>(busPtr)); break;
|
case I_8266_U1_APA106_3: delete (static_cast<B_8266_U1_APA106_3*>(busPtr)); break;
|
||||||
case I_8266_DM_APA106_3: delete (static_cast<B_8266_DM_APA106_3*>(busPtr)); break;
|
case I_8266_DM_APA106_3: delete (static_cast<B_8266_DM_APA106_3*>(busPtr)); break;
|
||||||
case I_8266_BB_APA106_3: delete (static_cast<B_8266_BB_APA106_3*>(busPtr)); break;
|
case I_8266_BB_APA106_3: delete (static_cast<B_8266_BB_APA106_3*>(busPtr)); break;
|
||||||
|
case I_8266_U0_FW6_5: delete (static_cast<B_8266_U0_FW6_5*>(busPtr)); break;
|
||||||
|
case I_8266_U1_FW6_5: delete (static_cast<B_8266_U1_FW6_5*>(busPtr)); break;
|
||||||
|
case I_8266_DM_FW6_5: delete (static_cast<B_8266_DM_FW6_5*>(busPtr)); break;
|
||||||
|
case I_8266_BB_FW6_5: delete (static_cast<B_8266_BB_FW6_5*>(busPtr)); break;
|
||||||
|
case I_8266_U0_2805_5: delete (static_cast<B_8266_U0_2805_5*>(busPtr)); break;
|
||||||
|
case I_8266_U1_2805_5: delete (static_cast<B_8266_U1_2805_5*>(busPtr)); break;
|
||||||
|
case I_8266_DM_2805_5: delete (static_cast<B_8266_DM_2805_5*>(busPtr)); break;
|
||||||
|
case I_8266_BB_2805_5: delete (static_cast<B_8266_BB_2805_5*>(busPtr)); break;
|
||||||
#endif
|
#endif
|
||||||
#ifdef ARDUINO_ARCH_ESP32
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
case I_32_RN_NEO_3: delete (static_cast<B_32_RN_NEO_3*>(busPtr)); break;
|
case I_32_RN_NEO_3: delete (static_cast<B_32_RN_NEO_3*>(busPtr)); break;
|
||||||
|
@ -1180,7 +1352,6 @@ class PolyBus {
|
||||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
case I_32_I1_NEO_3: delete (static_cast<B_32_I1_NEO_3*>(busPtr)); break;
|
case I_32_I1_NEO_3: delete (static_cast<B_32_I1_NEO_3*>(busPtr)); break;
|
||||||
#endif
|
#endif
|
||||||
// case I_32_BB_NEO_3: delete (static_cast<B_32_BB_NEO_3*>(busPtr)); break;
|
|
||||||
case I_32_RN_NEO_4: delete (static_cast<B_32_RN_NEO_4*>(busPtr)); break;
|
case I_32_RN_NEO_4: delete (static_cast<B_32_RN_NEO_4*>(busPtr)); break;
|
||||||
#ifndef WLED_NO_I2S0_PIXELBUS
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
case I_32_I0_NEO_4: delete (static_cast<B_32_I0_NEO_4*>(busPtr)); break;
|
case I_32_I0_NEO_4: delete (static_cast<B_32_I0_NEO_4*>(busPtr)); break;
|
||||||
|
@ -1188,7 +1359,6 @@ class PolyBus {
|
||||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
case I_32_I1_NEO_4: delete (static_cast<B_32_I1_NEO_4*>(busPtr)); break;
|
case I_32_I1_NEO_4: delete (static_cast<B_32_I1_NEO_4*>(busPtr)); break;
|
||||||
#endif
|
#endif
|
||||||
// case I_32_BB_NEO_4: delete (static_cast<B_32_BB_NEO_4*>(busPtr)); break;
|
|
||||||
case I_32_RN_400_3: delete (static_cast<B_32_RN_400_3*>(busPtr)); break;
|
case I_32_RN_400_3: delete (static_cast<B_32_RN_400_3*>(busPtr)); break;
|
||||||
#ifndef WLED_NO_I2S0_PIXELBUS
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
case I_32_I0_400_3: delete (static_cast<B_32_I0_400_3*>(busPtr)); break;
|
case I_32_I0_400_3: delete (static_cast<B_32_I0_400_3*>(busPtr)); break;
|
||||||
|
@ -1196,7 +1366,6 @@ class PolyBus {
|
||||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
case I_32_I1_400_3: delete (static_cast<B_32_I1_400_3*>(busPtr)); break;
|
case I_32_I1_400_3: delete (static_cast<B_32_I1_400_3*>(busPtr)); break;
|
||||||
#endif
|
#endif
|
||||||
// case I_32_BB_400_3: delete (static_cast<B_32_BB_400_3*>(busPtr)); break;
|
|
||||||
case I_32_RN_TM1_4: delete (static_cast<B_32_RN_TM1_4*>(busPtr)); break;
|
case I_32_RN_TM1_4: delete (static_cast<B_32_RN_TM1_4*>(busPtr)); break;
|
||||||
case I_32_RN_TM2_3: delete (static_cast<B_32_RN_TM2_3*>(busPtr)); break;
|
case I_32_RN_TM2_3: delete (static_cast<B_32_RN_TM2_3*>(busPtr)); break;
|
||||||
#ifndef WLED_NO_I2S0_PIXELBUS
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
|
@ -1214,7 +1383,6 @@ class PolyBus {
|
||||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
case I_32_I1_UCS_3: delete (static_cast<B_32_I1_UCS_3*>(busPtr)); break;
|
case I_32_I1_UCS_3: delete (static_cast<B_32_I1_UCS_3*>(busPtr)); break;
|
||||||
#endif
|
#endif
|
||||||
// case I_32_BB_UCS_3: delete (static_cast<B_32_BB_UCS_3*>(busPtr)); break;
|
|
||||||
case I_32_RN_UCS_4: delete (static_cast<B_32_RN_UCS_4*>(busPtr)); break;
|
case I_32_RN_UCS_4: delete (static_cast<B_32_RN_UCS_4*>(busPtr)); break;
|
||||||
#ifndef WLED_NO_I2S0_PIXELBUS
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
case I_32_I0_UCS_4: delete (static_cast<B_32_I0_UCS_4*>(busPtr)); break;
|
case I_32_I0_UCS_4: delete (static_cast<B_32_I0_UCS_4*>(busPtr)); break;
|
||||||
|
@ -1222,7 +1390,6 @@ class PolyBus {
|
||||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
case I_32_I1_UCS_4: delete (static_cast<B_32_I1_UCS_4*>(busPtr)); break;
|
case I_32_I1_UCS_4: delete (static_cast<B_32_I1_UCS_4*>(busPtr)); break;
|
||||||
#endif
|
#endif
|
||||||
// case I_32_BB_UCS_4: delete (static_cast<B_32_BB_UCS_4*>(busPtr)); break;
|
|
||||||
case I_32_RN_APA106_3: delete (static_cast<B_32_RN_APA106_3*>(busPtr)); break;
|
case I_32_RN_APA106_3: delete (static_cast<B_32_RN_APA106_3*>(busPtr)); break;
|
||||||
#ifndef WLED_NO_I2S0_PIXELBUS
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
case I_32_I0_APA106_3: delete (static_cast<B_32_I0_APA106_3*>(busPtr)); break;
|
case I_32_I0_APA106_3: delete (static_cast<B_32_I0_APA106_3*>(busPtr)); break;
|
||||||
|
@ -1230,7 +1397,20 @@ class PolyBus {
|
||||||
#ifndef WLED_NO_I2S1_PIXELBUS
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
case I_32_I1_APA106_3: delete (static_cast<B_32_I1_APA106_3*>(busPtr)); break;
|
case I_32_I1_APA106_3: delete (static_cast<B_32_I1_APA106_3*>(busPtr)); break;
|
||||||
#endif
|
#endif
|
||||||
// case I_32_BB_APA106_3: delete (static_cast<B_32_BB_APA106_3*>(busPtr)); break;
|
case I_32_RN_FW6_5: delete (static_cast<B_32_RN_FW6_5*>(busPtr)); break;
|
||||||
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
|
case I_32_I0_FW6_5: delete (static_cast<B_32_I0_FW6_5*>(busPtr)); break;
|
||||||
|
#endif
|
||||||
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
|
case I_32_I1_FW6_5: delete (static_cast<B_32_I1_FW6_5*>(busPtr)); break;
|
||||||
|
#endif
|
||||||
|
case I_32_RN_2805_5: delete (static_cast<B_32_RN_2805_5*>(busPtr)); break;
|
||||||
|
#ifndef WLED_NO_I2S0_PIXELBUS
|
||||||
|
case I_32_I0_2805_5: delete (static_cast<B_32_I0_2805_5*>(busPtr)); break;
|
||||||
|
#endif
|
||||||
|
#ifndef WLED_NO_I2S1_PIXELBUS
|
||||||
|
case I_32_I1_2805_5: delete (static_cast<B_32_I1_2805_5*>(busPtr)); break;
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
case I_HS_DOT_3: delete (static_cast<B_HS_DOT_3*>(busPtr)); break;
|
case I_HS_DOT_3: delete (static_cast<B_HS_DOT_3*>(busPtr)); break;
|
||||||
case I_SS_DOT_3: delete (static_cast<B_SS_DOT_3*>(busPtr)); break;
|
case I_SS_DOT_3: delete (static_cast<B_SS_DOT_3*>(busPtr)); break;
|
||||||
|
@ -1292,13 +1472,17 @@ class PolyBus {
|
||||||
return I_8266_U0_UCS_4 + offset;
|
return I_8266_U0_UCS_4 + offset;
|
||||||
case TYPE_APA106:
|
case TYPE_APA106:
|
||||||
return I_8266_U0_APA106_3 + offset;
|
return I_8266_U0_APA106_3 + offset;
|
||||||
|
case TYPE_FW1906:
|
||||||
|
return I_8266_U0_FW6_5 + offset;
|
||||||
|
case TYPE_WS2805:
|
||||||
|
return I_8266_U0_2805_5 + offset;
|
||||||
}
|
}
|
||||||
#else //ESP32
|
#else //ESP32
|
||||||
uint8_t offset = 0; //0 = RMT (num 0-7) 8 = I2S0 9 = I2S1
|
uint8_t offset = 0; // 0 = RMT (num 1-8), 1 = I2S0 (used by Audioreactive), 2 = I2S1
|
||||||
#if defined(CONFIG_IDF_TARGET_ESP32S2)
|
#if defined(CONFIG_IDF_TARGET_ESP32S2)
|
||||||
// ESP32-S2 only has 4 RMT channels
|
// ESP32-S2 only has 4 RMT channels
|
||||||
if (num > 4) return I_NONE;
|
if (num > 4) return I_NONE;
|
||||||
if (num > 3) offset = 1; // only one I2S
|
if (num > 3) offset = 1; // only one I2S (use last to allow Audioreactive)
|
||||||
#elif defined(CONFIG_IDF_TARGET_ESP32C3)
|
#elif defined(CONFIG_IDF_TARGET_ESP32C3)
|
||||||
// On ESP32-C3 only the first 2 RMT channels are usable for transmitting
|
// On ESP32-C3 only the first 2 RMT channels are usable for transmitting
|
||||||
if (num > 1) return I_NONE;
|
if (num > 1) return I_NONE;
|
||||||
|
@ -1310,7 +1494,8 @@ class PolyBus {
|
||||||
#else
|
#else
|
||||||
// standard ESP32 has 8 RMT and 2 I2S channels
|
// standard ESP32 has 8 RMT and 2 I2S channels
|
||||||
if (num > 9) return I_NONE;
|
if (num > 9) return I_NONE;
|
||||||
if (num > 7) offset = num -7;
|
if (num > 8) offset = 1;
|
||||||
|
if (num == 0) offset = 2; // prefer I2S1 for 1st bus (less flickering but more RAM needed)
|
||||||
#endif
|
#endif
|
||||||
switch (busType) {
|
switch (busType) {
|
||||||
case TYPE_WS2812_1CH_X3:
|
case TYPE_WS2812_1CH_X3:
|
||||||
|
@ -1332,11 +1517,14 @@ class PolyBus {
|
||||||
return I_32_RN_UCS_4 + offset;
|
return I_32_RN_UCS_4 + offset;
|
||||||
case TYPE_APA106:
|
case TYPE_APA106:
|
||||||
return I_32_RN_APA106_3 + offset;
|
return I_32_RN_APA106_3 + offset;
|
||||||
|
case TYPE_FW1906:
|
||||||
|
return I_32_RN_FW6_5 + offset;
|
||||||
|
case TYPE_WS2805:
|
||||||
|
return I_32_RN_2805_5 + offset;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
return I_NONE;
|
return I_NONE;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
#endif
|
|
||||||
|
|
|
@ -96,9 +96,13 @@ bool isButtonPressed(uint8_t i)
|
||||||
case BTN_TYPE_TOUCH:
|
case BTN_TYPE_TOUCH:
|
||||||
case BTN_TYPE_TOUCH_SWITCH:
|
case BTN_TYPE_TOUCH_SWITCH:
|
||||||
#if defined(ARDUINO_ARCH_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32C3)
|
#if defined(ARDUINO_ARCH_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32C3)
|
||||||
if (digitalPinToTouchChannel(btnPin[i]) >= 0 && touchRead(pin) <= touchThreshold) return true;
|
#ifdef SOC_TOUCH_VERSION_2 //ESP32 S2 and S3 provide a function to check touch state (state is updated in interrupt)
|
||||||
|
if (touchInterruptGetLastStatus(pin)) return true;
|
||||||
|
#else
|
||||||
|
if (digitalPinToTouchChannel(btnPin[i]) >= 0 && touchRead(pin) <= touchThreshold) return true;
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -403,3 +407,8 @@ void handleIO()
|
||||||
offMode = true;
|
offMode = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IRAM_ATTR touchButtonISR()
|
||||||
|
{
|
||||||
|
// used for ESP32 S2 and S3: nothing to do, ISR is just used to update registers of HAL driver
|
||||||
|
}
|
||||||
|
|
|
@ -110,6 +110,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
||||||
Bus::setGlobalAWMode(hw_led[F("rgbwm")] | AW_GLOBAL_DISABLED);
|
Bus::setGlobalAWMode(hw_led[F("rgbwm")] | AW_GLOBAL_DISABLED);
|
||||||
CJSON(correctWB, hw_led["cct"]);
|
CJSON(correctWB, hw_led["cct"]);
|
||||||
CJSON(cctFromRgb, hw_led[F("cr")]);
|
CJSON(cctFromRgb, hw_led[F("cr")]);
|
||||||
|
CJSON(cctICused, hw_led[F("ic")]);
|
||||||
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
|
||||||
|
@ -185,7 +186,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
||||||
uint8_t maPerLed = elm[F("ledma")] | 55;
|
uint8_t maPerLed = elm[F("ledma")] | 55;
|
||||||
uint16_t maMax = elm[F("maxpwr")] | (ablMilliampsMax * length) / total; // rough (incorrect?) per strip ABL calculation when no config exists
|
uint16_t maMax = elm[F("maxpwr")] | (ablMilliampsMax * length) / total; // rough (incorrect?) per strip ABL calculation when no config exists
|
||||||
// To disable brightness limiter we either set output max current to 0 or single LED current to 0 (we choose output max current)
|
// To disable brightness limiter we either set output max current to 0 or single LED current to 0 (we choose output max current)
|
||||||
if ((ledType > TYPE_TM1814 && ledType < TYPE_WS2801) || ledType >= TYPE_NET_DDP_RGB) { // analog and virtual
|
if (IS_PWM(ledType) || IS_ONOFF(ledType) || IS_VIRTUAL(ledType)) { // analog and virtual
|
||||||
maPerLed = 0;
|
maPerLed = 0;
|
||||||
maMax = 0;
|
maMax = 0;
|
||||||
}
|
}
|
||||||
|
@ -228,6 +229,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
||||||
|
|
||||||
// read multiple button configuration
|
// read multiple button configuration
|
||||||
JsonObject btn_obj = hw["btn"];
|
JsonObject btn_obj = hw["btn"];
|
||||||
|
CJSON(touchThreshold, btn_obj[F("tt")]);
|
||||||
bool pull = btn_obj[F("pull")] | (!disablePullUp); // if true, pullup is enabled
|
bool pull = btn_obj[F("pull")] | (!disablePullUp); // if true, pullup is enabled
|
||||||
disablePullUp = !pull;
|
disablePullUp = !pull;
|
||||||
JsonArray hw_btn_ins = btn_obj["ins"];
|
JsonArray hw_btn_ins = btn_obj["ins"];
|
||||||
|
@ -252,6 +254,13 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
||||||
btnPin[s] = -1;
|
btnPin[s] = -1;
|
||||||
pinManager.deallocatePin(pin,PinOwner::Button);
|
pinManager.deallocatePin(pin,PinOwner::Button);
|
||||||
}
|
}
|
||||||
|
//if touch pin, enable the touch interrupt on ESP32 S2 & S3
|
||||||
|
#ifdef SOC_TOUCH_VERSION_2 // ESP32 S2 and S3 have a fucntion to check touch state but need to attach an interrupt to do so
|
||||||
|
if ((buttonType[s] == BTN_TYPE_TOUCH || buttonType[s] == BTN_TYPE_TOUCH_SWITCH))
|
||||||
|
{
|
||||||
|
touchAttachInterrupt(btnPin[s], touchButtonISR, 256 + (touchThreshold << 4)); // threshold on Touch V2 is much higher (1500 is a value given by Espressif example, I measured changes of over 5000)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
@ -308,7 +317,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CJSON(touchThreshold,btn_obj[F("tt")]);
|
|
||||||
CJSON(buttonPublishMqtt,btn_obj["mqtt"]);
|
CJSON(buttonPublishMqtt,btn_obj["mqtt"]);
|
||||||
|
|
||||||
#ifndef WLED_DISABLE_INFRARED
|
#ifndef WLED_DISABLE_INFRARED
|
||||||
|
@ -632,12 +641,12 @@ static const char s_cfg_json[] PROGMEM = "/cfg.json";
|
||||||
|
|
||||||
void deserializeConfigFromFS() {
|
void deserializeConfigFromFS() {
|
||||||
bool success = deserializeConfigSec();
|
bool success = deserializeConfigSec();
|
||||||
|
#ifdef WLED_ADD_EEPROM_SUPPORT
|
||||||
if (!success) { //if file does not exist, try reading from EEPROM
|
if (!success) { //if file does not exist, try reading from EEPROM
|
||||||
#ifdef WLED_ADD_EEPROM_SUPPORT
|
|
||||||
deEEPSettings();
|
deEEPSettings();
|
||||||
return;
|
return;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!requestJSONBufferLock(1)) return;
|
if (!requestJSONBufferLock(1)) return;
|
||||||
|
|
||||||
|
@ -767,6 +776,7 @@ void serializeConfig() {
|
||||||
hw_led[F("ledma")] = 0; // no longer used
|
hw_led[F("ledma")] = 0; // no longer used
|
||||||
hw_led["cct"] = correctWB;
|
hw_led["cct"] = correctWB;
|
||||||
hw_led[F("cr")] = cctFromRgb;
|
hw_led[F("cr")] = cctFromRgb;
|
||||||
|
hw_led[F("ic")] = cctICused;
|
||||||
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
|
||||||
|
|
|
@ -65,24 +65,30 @@ uint32_t color_add(uint32_t c1, uint32_t c2, bool fast)
|
||||||
* fades color toward black
|
* fades color toward black
|
||||||
* if using "video" method the resulting color will never become black unless it is already 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)
|
uint32_t color_fade(uint32_t c1, uint8_t amount, bool video)
|
||||||
{
|
{
|
||||||
uint8_t r = R(c1);
|
uint32_t scaledcolor; // color order is: W R G B from MSB to LSB
|
||||||
uint8_t g = G(c1);
|
uint32_t r = R(c1);
|
||||||
uint8_t b = B(c1);
|
uint32_t g = G(c1);
|
||||||
uint8_t w = W(c1);
|
uint32_t b = B(c1);
|
||||||
if (video) {
|
uint32_t w = W(c1);
|
||||||
r = scale8_video(r, amount);
|
if (video) {
|
||||||
g = scale8_video(g, amount);
|
uint32_t scale = amount; // 32bit for faster calculation
|
||||||
b = scale8_video(b, amount);
|
scaledcolor = (((r * scale) >> 8) << 16) + ((r && scale) ? 1 : 0);
|
||||||
w = scale8_video(w, amount);
|
scaledcolor |= (((g * scale) >> 8) << 8) + ((g && scale) ? 1 : 0);
|
||||||
} else {
|
scaledcolor |= ((b * scale) >> 8) + ((b && scale) ? 1 : 0);
|
||||||
r = scale8(r, amount);
|
scaledcolor |= (((w * scale) >> 8) << 24) + ((w && scale) ? 1 : 0);
|
||||||
g = scale8(g, amount);
|
return scaledcolor;
|
||||||
b = scale8(b, amount);
|
}
|
||||||
w = scale8(w, amount);
|
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)
|
void setRandomColor(byte* rgb)
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
#define WLED_BRAND "WLED"
|
#define WLED_BRAND "WLED"
|
||||||
#endif
|
#endif
|
||||||
#ifndef WLED_PRODUCT_NAME
|
#ifndef WLED_PRODUCT_NAME
|
||||||
#define WLED_PRODUCT_NAME "FOSS"
|
#define WLED_PRODUCT_NAME "DIY"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//Defaults
|
//Defaults
|
||||||
|
@ -53,24 +53,16 @@
|
||||||
#define WLED_MAX_BUSSES 3 // will allow 2 digital & 1 analog (or the other way around)
|
#define WLED_MAX_BUSSES 3 // will allow 2 digital & 1 analog (or the other way around)
|
||||||
#define WLED_MIN_VIRTUAL_BUSSES 3
|
#define WLED_MIN_VIRTUAL_BUSSES 3
|
||||||
#elif defined(CONFIG_IDF_TARGET_ESP32S2) // 4 RMT, 8 LEDC, only has 1 I2S bus, supported in NPB
|
#elif defined(CONFIG_IDF_TARGET_ESP32S2) // 4 RMT, 8 LEDC, only has 1 I2S bus, supported in NPB
|
||||||
#if defined(USERMOD_AUDIOREACTIVE) // requested by @softhack007 https://github.com/blazoncek/WLED/issues/33
|
// the 5th bus (I2S) will prevent Audioreactive usermod from functioning (it is last used though)
|
||||||
#define WLED_MAX_BUSSES 6 // will allow 4 digital & 2 analog
|
#define WLED_MAX_BUSSES 7 // will allow 5 digital & 2 analog
|
||||||
#define WLED_MIN_VIRTUAL_BUSSES 4
|
#define WLED_MIN_VIRTUAL_BUSSES 3
|
||||||
#else
|
|
||||||
#define WLED_MAX_BUSSES 7 // will allow 5 digital & 2 analog
|
|
||||||
#define WLED_MIN_VIRTUAL_BUSSES 3
|
|
||||||
#endif
|
|
||||||
#elif defined(CONFIG_IDF_TARGET_ESP32S3) // 4 RMT, 8 LEDC, has 2 I2S but NPB does not support them ATM
|
#elif defined(CONFIG_IDF_TARGET_ESP32S3) // 4 RMT, 8 LEDC, has 2 I2S but NPB does not support them ATM
|
||||||
#define WLED_MAX_BUSSES 6 // will allow 4 digital & 2 analog
|
#define WLED_MAX_BUSSES 6 // will allow 4 digital & 2 analog
|
||||||
#define WLED_MIN_VIRTUAL_BUSSES 4
|
#define WLED_MIN_VIRTUAL_BUSSES 4
|
||||||
#else
|
#else
|
||||||
#if defined(USERMOD_AUDIOREACTIVE) // requested by @softhack007 https://github.com/blazoncek/WLED/issues/33
|
// the 10th digital bus (I2S0) will prevent Audioreactive usermod from functioning (it is last used though)
|
||||||
#define WLED_MAX_BUSSES 8
|
#define WLED_MAX_BUSSES 10
|
||||||
#define WLED_MIN_VIRTUAL_BUSSES 2
|
#define WLED_MIN_VIRTUAL_BUSSES 0
|
||||||
#else
|
|
||||||
#define WLED_MAX_BUSSES 10
|
|
||||||
#define WLED_MIN_VIRTUAL_BUSSES 0
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
|
@ -181,6 +173,7 @@
|
||||||
#define USERMOD_ID_ANIMARTRIX 45 //Usermod "usermod_v2_animartrix.h"
|
#define USERMOD_ID_ANIMARTRIX 45 //Usermod "usermod_v2_animartrix.h"
|
||||||
#define USERMOD_ID_HTTP_PULL_LIGHT_CONTROL 46 //usermod "usermod_v2_HttpPullLightControl.h"
|
#define USERMOD_ID_HTTP_PULL_LIGHT_CONTROL 46 //usermod "usermod_v2_HttpPullLightControl.h"
|
||||||
#define USERMOD_ID_TETRISAI 47 //Usermod "usermod_v2_tetris.h"
|
#define USERMOD_ID_TETRISAI 47 //Usermod "usermod_v2_tetris.h"
|
||||||
|
#define USERMOD_ID_MAX17048 48 //Usermod "usermod_max17048.h"
|
||||||
|
|
||||||
//Access point behavior
|
//Access point behavior
|
||||||
#define AP_BEHAVIOR_BOOT_NO_CONN 0 //Open AP when no connection after boot
|
#define AP_BEHAVIOR_BOOT_NO_CONN 0 //Open AP when no connection after boot
|
||||||
|
@ -270,9 +263,11 @@
|
||||||
#define TYPE_TM1829 25
|
#define TYPE_TM1829 25
|
||||||
#define TYPE_UCS8903 26
|
#define TYPE_UCS8903 26
|
||||||
#define TYPE_APA106 27
|
#define TYPE_APA106 27
|
||||||
|
#define TYPE_FW1906 28 //RGB + CW + WW + unused channel (6 channels per IC)
|
||||||
#define TYPE_UCS8904 29 //first RGBW digital type (hardcoded in busmanager.cpp, memUsage())
|
#define TYPE_UCS8904 29 //first RGBW digital type (hardcoded in busmanager.cpp, memUsage())
|
||||||
#define TYPE_SK6812_RGBW 30
|
#define TYPE_SK6812_RGBW 30
|
||||||
#define TYPE_TM1814 31
|
#define TYPE_TM1814 31
|
||||||
|
#define TYPE_WS2805 32 //RGB + WW + CW
|
||||||
//"Analog" types (40-47)
|
//"Analog" types (40-47)
|
||||||
#define TYPE_ONOFF 40 //binary output (relays etc.; NOT PWM)
|
#define TYPE_ONOFF 40 //binary output (relays etc.; NOT PWM)
|
||||||
#define TYPE_ANALOG_1CH 41 //single channel PWM. Uses value of brightest RGBW channel
|
#define TYPE_ANALOG_1CH 41 //single channel PWM. Uses value of brightest RGBW channel
|
||||||
|
@ -297,6 +292,7 @@
|
||||||
#define IS_DIGITAL(t) (((t) > 15 && (t) < 40) || ((t) > 47 && (t) < 64)) //digital are 16-39 and 48-63
|
#define IS_DIGITAL(t) (((t) > 15 && (t) < 40) || ((t) > 47 && (t) < 64)) //digital are 16-39 and 48-63
|
||||||
#define IS_2PIN(t) ((t) > 47 && (t) < 64)
|
#define IS_2PIN(t) ((t) > 47 && (t) < 64)
|
||||||
#define IS_16BIT(t) ((t) == TYPE_UCS8903 || (t) == TYPE_UCS8904)
|
#define IS_16BIT(t) ((t) == TYPE_UCS8903 || (t) == TYPE_UCS8904)
|
||||||
|
#define IS_ONOFF(t) ((t) == 40)
|
||||||
#define IS_PWM(t) ((t) > 40 && (t) < 46) //does not include on/Off type
|
#define IS_PWM(t) ((t) > 40 && (t) < 46) //does not include on/Off type
|
||||||
#define NUM_PWM_PINS(t) ((t) - 40) //for analog PWM 41-45 only
|
#define NUM_PWM_PINS(t) ((t) - 40) //for analog PWM 41-45 only
|
||||||
#define IS_VIRTUAL(t) ((t) >= 80 && (t) < 96) //this was a poor choice a better would be 96-111
|
#define IS_VIRTUAL(t) ((t) >= 80 && (t) < 96) //this was a poor choice a better would be 96-111
|
||||||
|
@ -374,6 +370,7 @@
|
||||||
|
|
||||||
//Playlist option byte
|
//Playlist option byte
|
||||||
#define PL_OPTION_SHUFFLE 0x01
|
#define PL_OPTION_SHUFFLE 0x01
|
||||||
|
#define PL_OPTION_RESTORE 0x02
|
||||||
|
|
||||||
// Segment capability byte
|
// Segment capability byte
|
||||||
#define SEG_CAPABILITY_RGB 0x01
|
#define SEG_CAPABILITY_RGB 0x01
|
||||||
|
@ -511,10 +508,10 @@
|
||||||
|
|
||||||
//this is merely a default now and can be changed at runtime
|
//this is merely a default now and can be changed at runtime
|
||||||
#ifndef LEDPIN
|
#ifndef LEDPIN
|
||||||
#if defined(ESP8266) || (defined(ARDUINO_ARCH_ESP32) && defined(WLED_USE_PSRAM)) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(ARDUINO_ESP32_PICO)
|
#if defined(ESP8266) || defined(CONFIG_IDF_TARGET_ESP32C3) //|| (defined(ARDUINO_ARCH_ESP32) && defined(BOARD_HAS_PSRAM)) || defined(ARDUINO_ESP32_PICO)
|
||||||
#define LEDPIN 2 // GPIO2 (D4) on Wemos D1 mini compatible boards, and on boards where GPIO16 is not available
|
#define LEDPIN 2 // GPIO2 (D4) on Wemos D1 mini compatible boards, safe to use on any board
|
||||||
#else
|
#else
|
||||||
#define LEDPIN 16 // aligns with GPIO2 (D4) on Wemos D1 mini32 compatible boards
|
#define LEDPIN 16 // aligns with GPIO2 (D4) on Wemos D1 mini32 compatible boards (if it is unusable it will be reassigned in WS2812FX::finalizeInit())
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -358,7 +358,7 @@ button {
|
||||||
|
|
||||||
#putil, #segutil, #segutil2 {
|
#putil, #segutil, #segutil2 {
|
||||||
min-height: 42px;
|
min-height: 42px;
|
||||||
margin: 13px auto 0;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
#segutil .segin {
|
#segutil .segin {
|
||||||
|
|
|
@ -694,8 +694,6 @@ function parseInfo(i) {
|
||||||
function populateInfo(i)
|
function populateInfo(i)
|
||||||
{
|
{
|
||||||
var cn="";
|
var cn="";
|
||||||
var heap = i.freeheap/1024;
|
|
||||||
heap = heap.toFixed(1);
|
|
||||||
var pwr = i.leds.pwr;
|
var pwr = i.leds.pwr;
|
||||||
var pwru = "Not calculated";
|
var pwru = "Not calculated";
|
||||||
if (pwr > 1000) {pwr /= 1000; pwr = pwr.toFixed((pwr > 10) ? 0 : 1); pwru = pwr + " A";}
|
if (pwr > 1000) {pwr /= 1000; pwr = pwr.toFixed((pwr > 10) ? 0 : 1); pwru = pwr + " A";}
|
||||||
|
@ -720,11 +718,13 @@ ${inforow("Build",i.vid)}
|
||||||
${inforow("Signal strength",i.wifi.signal +"% ("+ i.wifi.rssi, " dBm)")}
|
${inforow("Signal strength",i.wifi.signal +"% ("+ i.wifi.rssi, " dBm)")}
|
||||||
${inforow("Uptime",getRuntimeStr(i.uptime))}
|
${inforow("Uptime",getRuntimeStr(i.uptime))}
|
||||||
${inforow("Time",i.time)}
|
${inforow("Time",i.time)}
|
||||||
${inforow("Free heap",heap," kB")}
|
${inforow("Free heap",(i.freeheap/1024).toFixed(1)," kB")}
|
||||||
${i.psram?inforow("Free PSRAM",(i.psram/1024).toFixed(1)," kB"):""}
|
${i.psram?inforow("Free PSRAM",(i.psram/1024).toFixed(1)," kB"):""}
|
||||||
${inforow("Estimated current",pwru)}
|
${inforow("Estimated current",pwru)}
|
||||||
${inforow("Average FPS",i.leds.fps)}
|
${inforow("Average FPS",i.leds.fps)}
|
||||||
${inforow("MAC address",i.mac)}
|
${inforow("MAC address",i.mac)}
|
||||||
|
${inforow("CPU clock",i.clock," MHz")}
|
||||||
|
${inforow("Flash size",i.flash," MB")}
|
||||||
${inforow("Filesystem",i.fs.u + "/" + i.fs.t + " kB (" +Math.round(i.fs.u*100/i.fs.t) + "%)")}
|
${inforow("Filesystem",i.fs.u + "/" + i.fs.t + " kB (" +Math.round(i.fs.u*100/i.fs.t) + "%)")}
|
||||||
${inforow("Environment",i.arch + " " + i.core + " (" + i.lwip + ")")}
|
${inforow("Environment",i.arch + " " + i.core + " (" + i.lwip + ")")}
|
||||||
</table>`;
|
</table>`;
|
||||||
|
@ -863,14 +863,11 @@ function populateSegments(s)
|
||||||
gId("segcont").classList.remove("hide");
|
gId("segcont").classList.remove("hide");
|
||||||
let noNewSegs = (lowestUnused >= maxSeg);
|
let noNewSegs = (lowestUnused >= maxSeg);
|
||||||
resetUtil(noNewSegs);
|
resetUtil(noNewSegs);
|
||||||
if (gId('selall')) gId('selall').checked = true;
|
|
||||||
for (var i = 0; i <= lSeg; i++) {
|
for (var i = 0; i <= lSeg; i++) {
|
||||||
if (!gId(`seg${i}`)) continue;
|
if (!gId(`seg${i}`)) continue;
|
||||||
updateLen(i);
|
updateLen(i);
|
||||||
updateTrail(gId(`seg${i}bri`));
|
updateTrail(gId(`seg${i}bri`));
|
||||||
gId(`segr${i}`).classList.add("hide");
|
gId(`segr${i}`).classList.add("hide");
|
||||||
//if (i<lSeg) gId(`segd${i}`).classList.add("hide"); // hide delete button for all but last
|
|
||||||
if (!gId(`seg${i}sel`).checked && gId('selall')) gId('selall').checked = false; // uncheck if at least one is unselected.
|
|
||||||
}
|
}
|
||||||
if (segCount < 2) {
|
if (segCount < 2) {
|
||||||
gId(`segd${lSeg}`).classList.add("hide"); // hide delete if only one segment
|
gId(`segd${lSeg}`).classList.add("hide"); // hide delete if only one segment
|
||||||
|
@ -1462,8 +1459,6 @@ function readState(s,command=false)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s.seg.length>2) d.querySelectorAll(".pop").forEach((e)=>{e.classList.remove("hide");});
|
|
||||||
|
|
||||||
var cd = gId('csl').querySelectorAll("button");
|
var cd = gId('csl').querySelectorAll("button");
|
||||||
for (let e = cd.length-1; e >= 0; e--) {
|
for (let e = cd.length-1; e >= 0; e--) {
|
||||||
cd[e].dataset.r = i.col[e][0];
|
cd[e].dataset.r = i.col[e][0];
|
||||||
|
@ -1838,7 +1833,7 @@ function makeSeg()
|
||||||
});
|
});
|
||||||
var cn = `<div class="seg lstI expanded">`+
|
var cn = `<div class="seg lstI expanded">`+
|
||||||
`<div class="segin">`+
|
`<div class="segin">`+
|
||||||
`<input type="text" id="seg${lu}t" autocomplete="off" maxlength=32 value="" placeholder="New segment ${lu}"/>`+
|
`<input class="ptxt show" type="text" id="seg${lu}t" autocomplete="off" maxlength=32 value="" placeholder="New segment ${lu}"/>`+
|
||||||
`<table class="segt">`+
|
`<table class="segt">`+
|
||||||
`<tr>`+
|
`<tr>`+
|
||||||
`<td width="38%">${isM?'Start X':'Start LED'}</td>`+
|
`<td width="38%">${isM?'Start X':'Start LED'}</td>`+
|
||||||
|
@ -1864,13 +1859,19 @@ function makeSeg()
|
||||||
|
|
||||||
function resetUtil(off=false)
|
function resetUtil(off=false)
|
||||||
{
|
{
|
||||||
gId('segutil').innerHTML = `<div class="seg btn btn-s${off?' off':''}" style="padding:0;">`
|
gId('segutil').innerHTML = `<div class="seg btn btn-s${off?' off':''}" style="padding:0;margin-bottom:12px;">`
|
||||||
+ '<label class="check schkl"><input type="checkbox" id="selall" onchange="selSegAll(this)"><span class="checkmark"></span></label>'
|
+ '<label class="check schkl"><input type="checkbox" id="selall" onchange="selSegAll(this)"><span class="checkmark"></span></label>'
|
||||||
+ `<div class="segname" ${off?'':'onclick="makeSeg()"'}><i class="icons btn-icon"></i>Add segment</div>`
|
+ `<div class="segname" ${off?'':'onclick="makeSeg()"'}><i class="icons btn-icon"></i>Add segment</div>`
|
||||||
+ '<div class="pop hide" onclick="event.stopPropagation();">'
|
+ '<div class="pop hide" onclick="event.stopPropagation();">'
|
||||||
+ `<i class="icons g-icon" title="Select group" onclick="this.nextElementSibling.classList.toggle('hide');"></i>`
|
+ `<i class="icons g-icon" title="Select group" onclick="this.nextElementSibling.classList.toggle('hide');"></i>`
|
||||||
+ '<div class="pop-c hide"><span style="color:var(--c-f);" onclick="selGrp(0);">➊</span><span style="color:var(--c-r);" onclick="selGrp(1);">➋</span><span style="color:var(--c-g);" onclick="selGrp(2);">➌</span><span style="color:var(--c-l);" onclick="selGrp(3);">➍</span></div>'
|
+ '<div class="pop-c hide"><span style="color:var(--c-f);" onclick="selGrp(0);">➊</span><span style="color:var(--c-r);" onclick="selGrp(1);">➋</span><span style="color:var(--c-g);" onclick="selGrp(2);">➌</span><span style="color:var(--c-l);" onclick="selGrp(3);">➍</span></div>'
|
||||||
+ '</div></div>';
|
+ '</div></div>';
|
||||||
|
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)
|
function makePlSel(el, incPl=false)
|
||||||
|
@ -1984,7 +1985,7 @@ function makeP(i,pl)
|
||||||
<div class="sel">End preset:<br>
|
<div class="sel">End preset:<br>
|
||||||
<div class="sel-p"><select class="sel-ple" id="pl${i}selEnd" onchange="plR(${i})" data-val=${plJson[i].end?plJson[i].end:0}>
|
<div class="sel-p"><select class="sel-ple" id="pl${i}selEnd" onchange="plR(${i})" data-val=${plJson[i].end?plJson[i].end:0}>
|
||||||
<option value="0">None</option>
|
<option value="0">None</option>
|
||||||
<option value="255">Restore preset</option>
|
<option value="255" ${plJson[i].end && plJson[i].end==255?"selected":""}>Restore preset</option>
|
||||||
${makePlSel(plJson[i].end?plJson[i].end:0, true)}
|
${makePlSel(plJson[i].end?plJson[i].end:0, true)}
|
||||||
</select></div></div>
|
</select></div></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -23,6 +23,8 @@
|
||||||
function isD2P(t) { return t > 47 && t < 64; } // is digital 2 pin type
|
function isD2P(t) { return t > 47 && t < 64; } // is digital 2 pin type
|
||||||
function is16b(t) { return t == 26 || t == 29 } // is digital 16 bit type
|
function is16b(t) { return t == 26 || t == 29 } // is digital 16 bit type
|
||||||
function isVir(t) { return t >= 80 && t < 96; } // is virtual type
|
function isVir(t) { return t >= 80 && t < 96; } // is virtual type
|
||||||
|
function hasW(t) { return (t >= 18 && t <= 21) || (t >= 28 && t <= 32) || (t >= 44 && t <= 45) || (t >= 88 && t <= 89); }
|
||||||
|
function hasCCT(t) { return t == 20 || t == 21 || t == 42 || t == 45 || t == 28 || t == 32; }
|
||||||
// https://www.educative.io/edpresso/how-to-dynamically-load-a-js-file-in-javascript
|
// https://www.educative.io/edpresso/how-to-dynamically-load-a-js-file-in-javascript
|
||||||
function loadJS(FILE_URL, async = true) {
|
function loadJS(FILE_URL, async = true) {
|
||||||
let scE = d.createElement("script");
|
let scE = d.createElement("script");
|
||||||
|
@ -151,7 +153,7 @@
|
||||||
{
|
{
|
||||||
const t = parseInt(d.Sf["LT"+n].value); // LED type SELECT
|
const t = parseInt(d.Sf["LT"+n].value); // LED type SELECT
|
||||||
gId('LAdis'+n).style.display = s.selectedIndex==5 ? "inline" : "none";
|
gId('LAdis'+n).style.display = s.selectedIndex==5 ? "inline" : "none";
|
||||||
d.Sf["LA"+n].value = s.value==="0" ? 55 : s.value;
|
if (s.value!=="0") d.Sf["LA"+n].value = s.value;
|
||||||
d.Sf["LA"+n].min = (isVir(t) || isAna(t)) ? 0 : 1;
|
d.Sf["LA"+n].min = (isVir(t) || isAna(t)) ? 0 : 1;
|
||||||
}
|
}
|
||||||
function setABL()
|
function setABL()
|
||||||
|
@ -188,6 +190,7 @@
|
||||||
if (isDig(t)) {
|
if (isDig(t)) {
|
||||||
if (is16b(t)) len *= 2; // 16 bit LEDs
|
if (is16b(t)) len *= 2; // 16 bit LEDs
|
||||||
if (t > 28 && t < 40) ch = 4; //RGBW
|
if (t > 28 && t < 40) ch = 4; //RGBW
|
||||||
|
if (t == 28) ch = 5; //GRBCW
|
||||||
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
|
||||||
mul = 5;
|
mul = 5;
|
||||||
}
|
}
|
||||||
|
@ -202,7 +205,7 @@
|
||||||
|
|
||||||
function UI(change=false)
|
function UI(change=false)
|
||||||
{
|
{
|
||||||
let isRGBW = false, gRGBW = false, memu = 0;
|
let gRGBW = false, memu = 0;
|
||||||
let busMA = 0;
|
let busMA = 0;
|
||||||
let sLC = 0, sPC = 0, sDI = 0, maxLC = 0;
|
let sLC = 0, sPC = 0, sDI = 0, maxLC = 0;
|
||||||
const ablEN = d.Sf.ABL.checked;
|
const ablEN = d.Sf.ABL.checked;
|
||||||
|
@ -242,15 +245,15 @@
|
||||||
d.Sf["MA"+n].min = (isVir(t) || isAna(t)) ? 0 : 250;
|
d.Sf["MA"+n].min = (isVir(t) || isAna(t)) ? 0 : 250;
|
||||||
}
|
}
|
||||||
gId("rf"+n).onclick = (t == 31) ? (()=>{return false}) : (()=>{}); // prevent change for TM1814
|
gId("rf"+n).onclick = (t == 31) ? (()=>{return false}) : (()=>{}); // prevent change for TM1814
|
||||||
gRGBW |= isRGBW = ((t > 17 && t < 22) || (t > 28 && t < 32) || (t > 40 && t < 46 && t != 43) || t == 88); // RGBW checkbox, TYPE_xxxx values from const.h
|
gRGBW |= hasW(t); // RGBW checkbox, TYPE_xxxx values from const.h
|
||||||
gId("co"+n).style.display = (isVir(t) || isAna(t)) ? "none":"inline"; // hide color order for PWM
|
gId("co"+n).style.display = (isVir(t) || isAna(t)) ? "none":"inline"; // hide color order for PWM
|
||||||
gId("dig"+n+"w").style.display = (isDig(t) && isRGBW) ? "inline":"none"; // show swap channels dropdown
|
gId("dig"+n+"w").style.display = (isDig(t) && hasW(t)) ? "inline":"none"; // show swap channels dropdown
|
||||||
if (!(isDig(t) && isRGBW)) d.Sf["WO"+n].value = 0; // reset swapping
|
if (!(isDig(t) && hasW(t))) d.Sf["WO"+n].value = 0; // reset swapping
|
||||||
gId("dig"+n+"c").style.display = (isAna(t)) ? "none":"inline"; // hide count for analog
|
gId("dig"+n+"c").style.display = (isAna(t)) ? "none":"inline"; // hide count for analog
|
||||||
gId("dig"+n+"r").style.display = (isVir(t)) ? "none":"inline"; // hide reversed for virtual
|
gId("dig"+n+"r").style.display = (isVir(t)) ? "none":"inline"; // hide reversed for virtual
|
||||||
gId("dig"+n+"s").style.display = (isVir(t) || isAna(t)) ? "none":"inline"; // hide skip 1st for virtual & analog
|
gId("dig"+n+"s").style.display = (isVir(t) || isAna(t)) ? "none":"inline"; // hide skip 1st for virtual & analog
|
||||||
gId("dig"+n+"f").style.display = (isDig(t)) ? "inline":"none"; // hide refresh
|
gId("dig"+n+"f").style.display = (isDig(t)) ? "inline":"none"; // hide refresh
|
||||||
gId("dig"+n+"a").style.display = (isRGBW) ? "inline":"none"; // auto calculate white
|
gId("dig"+n+"a").style.display = (hasW(t)) ? "inline":"none"; // auto calculate white
|
||||||
gId("dig"+n+"l").style.display = (isD2P(t) || isPWM(t)) ? "inline":"none"; // bus clock speed / PWM speed (relative) (not On/Off)
|
gId("dig"+n+"l").style.display = (isD2P(t) || isPWM(t)) ? "inline":"none"; // bus clock speed / PWM speed (relative) (not On/Off)
|
||||||
gId("rev"+n).innerHTML = isAna(t) ? "Inverted output":"Reversed (rotated 180°)"; // change reverse text for analog
|
gId("rev"+n).innerHTML = isAna(t) ? "Inverted output":"Reversed (rotated 180°)"; // change reverse text for analog
|
||||||
//gId("psd"+n).innerHTML = isAna(t) ? "Index:":"Start:"; // change analog start description
|
//gId("psd"+n).innerHTML = isAna(t) ? "Index:":"Start:"; // change analog start description
|
||||||
|
@ -383,7 +386,9 @@ ${i+1}:
|
||||||
<option value="25">TM1829</option>\
|
<option value="25">TM1829</option>\
|
||||||
<option value="26">UCS8903</option>\
|
<option value="26">UCS8903</option>\
|
||||||
<option value="27">APA106/PL9823</option>\
|
<option value="27">APA106/PL9823</option>\
|
||||||
|
<option value="28">FW1906 GRBCW</option>\
|
||||||
<option value="29">UCS8904 RGBW</option>\
|
<option value="29">UCS8904 RGBW</option>\
|
||||||
|
<option value="32">WS2805 RGBCW</option>\
|
||||||
<option value="50">WS2801</option>\
|
<option value="50">WS2801</option>\
|
||||||
<option value="51">APA102</option>\
|
<option value="51">APA102</option>\
|
||||||
<option value="52">LPD8806</option>\
|
<option value="52">LPD8806</option>\
|
||||||
|
@ -412,7 +417,7 @@ mA/LED: <select name="LAsel${i}" onchange="enLA(this,${i});UI();">
|
||||||
<option value="15">15mA (seed/fairy pixels)</option>
|
<option value="15">15mA (seed/fairy pixels)</option>
|
||||||
<option value="0">Custom</option>
|
<option value="0">Custom</option>
|
||||||
</select><br>
|
</select><br>
|
||||||
<div id="LAdis${i}" style="display: none;">max. mA/LED: <input name="LA${i}" type="number" min="1" max="254" oninput="UI()"> mA<br></div>
|
<div id="LAdis${i}" style="display: none;">max. mA/LED: <input name="LA${i}" type="number" min="1" max="255" oninput="UI()"> mA<br></div>
|
||||||
<div id="PSU${i}">PSU: <input name="MA${i}" type="number" class="xl" min="250" max="65000" oninput="UI()" value="250"> mA<br></div>
|
<div id="PSU${i}">PSU: <input name="MA${i}" type="number" class="xl" min="250" max="65000" oninput="UI()" value="250"> mA<br></div>
|
||||||
</div>
|
</div>
|
||||||
<div id="co${i}" style="display:inline">Color Order:
|
<div id="co${i}" style="display:inline">Color Order:
|
||||||
|
@ -861,6 +866,7 @@ Swap: <select id="xw${i}" name="XW${i}">
|
||||||
</select>
|
</select>
|
||||||
<br>
|
<br>
|
||||||
Calculate CCT from RGB: <input type="checkbox" name="CR"><br>
|
Calculate CCT from RGB: <input type="checkbox" name="CR"><br>
|
||||||
|
CCT IC used (Athom 15W): <input type="checkbox" name="IC"><br>
|
||||||
CCT additive blending: <input type="number" class="s" min="0" max="100" name="CB" required> %
|
CCT additive blending: <input type="number" class="s" min="0" max="100" name="CB" required> %
|
||||||
</div>
|
</div>
|
||||||
<h3>Advanced</h3>
|
<h3>Advanced</h3>
|
||||||
|
|
|
@ -84,7 +84,7 @@
|
||||||
option.textContent = "Other network...";
|
option.textContent = "Other network...";
|
||||||
select.appendChild(option);
|
select.appendChild(option);
|
||||||
|
|
||||||
if (input.value === "" || found) input.replaceWith(select);
|
if (input.value === "" || input.value === "Your_Network" || found) input.replaceWith(select);
|
||||||
else select.remove();
|
else select.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ void doublePressAction(uint8_t b=0);
|
||||||
bool isButtonPressed(uint8_t b=0);
|
bool isButtonPressed(uint8_t b=0);
|
||||||
void handleButton();
|
void handleButton();
|
||||||
void handleIO();
|
void handleIO();
|
||||||
|
void IRAM_ATTR touchButtonISR();
|
||||||
|
|
||||||
//cfg.cpp
|
//cfg.cpp
|
||||||
bool deserializeConfig(JsonObject doc, bool fromFS = false);
|
bool deserializeConfig(JsonObject doc, bool fromFS = false);
|
||||||
|
@ -233,6 +234,7 @@ const char *getPresetsFileName(bool persistent = true);
|
||||||
void initPresetsFile();
|
void initPresetsFile();
|
||||||
void handlePresets();
|
void handlePresets();
|
||||||
bool applyPreset(byte index, byte callMode = CALL_MODE_DIRECT_CHANGE);
|
bool applyPreset(byte index, byte callMode = CALL_MODE_DIRECT_CHANGE);
|
||||||
|
bool applyPresetFromPlaylist(byte index);
|
||||||
void applyPresetWithFallback(uint8_t presetID, uint8_t callMode, uint8_t effectID = 0, uint8_t paletteID = 0);
|
void applyPresetWithFallback(uint8_t presetID, uint8_t callMode, uint8_t effectID = 0, uint8_t paletteID = 0);
|
||||||
inline bool applyTemporaryPreset() {return applyPreset(255);};
|
inline bool applyTemporaryPreset() {return applyPreset(255);};
|
||||||
void savePreset(byte index, const char* pname = nullptr, JsonObject saveobj = JsonObject());
|
void savePreset(byte index, const char* pname = nullptr, JsonObject saveobj = JsonObject());
|
||||||
|
@ -434,7 +436,6 @@ void handleSerial();
|
||||||
void updateBaudRate(uint32_t rate);
|
void updateBaudRate(uint32_t rate);
|
||||||
|
|
||||||
//wled_server.cpp
|
//wled_server.cpp
|
||||||
String getFileContentType(String &filename);
|
|
||||||
void createEditHandler(bool enable);
|
void createEditHandler(bool enable);
|
||||||
void initServer();
|
void initServer();
|
||||||
void serveMessage(AsyncWebServerRequest* request, uint16_t code, const String& headl, const String& subl="", byte optionT=255);
|
void serveMessage(AsyncWebServerRequest* request, uint16_t code, const String& headl, const String& subl="", byte optionT=255);
|
||||||
|
|
|
@ -375,20 +375,16 @@ void updateFSInfo() {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(BOARD_HAS_PSRAM) && defined(WLED_USE_PSRAM)
|
|
||||||
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
// caching presets in PSRAM may prevent occasional flashes seen when HomeAssitant polls WLED
|
// caching presets in PSRAM may prevent occasional flashes seen when HomeAssitant polls WLED
|
||||||
// original idea by @akaricchi (https://github.com/Akaricchi)
|
// original idea by @akaricchi (https://github.com/Akaricchi)
|
||||||
// returns a pointer to the PSRAM buffer updates size parameter
|
// returns a pointer to the PSRAM buffer, updates size parameter
|
||||||
static const uint8_t *getPresetCache(size_t &size) {
|
static const uint8_t *getPresetCache(size_t &size) {
|
||||||
static unsigned long presetsCachedTime;
|
static unsigned long presetsCachedTime;
|
||||||
static uint8_t *presetsCached;
|
static uint8_t *presetsCached;
|
||||||
static size_t presetsCachedSize;
|
static size_t presetsCachedSize;
|
||||||
|
|
||||||
if (!psramFound()) {
|
|
||||||
size = 0;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (presetsModifiedTime != presetsCachedTime) {
|
if (presetsModifiedTime != presetsCachedTime) {
|
||||||
if (presetsCached) {
|
if (presetsCached) {
|
||||||
free(presetsCached);
|
free(presetsCached);
|
||||||
|
@ -420,26 +416,19 @@ bool handleFileRead(AsyncWebServerRequest* request, String path){
|
||||||
DEBUG_PRINT(F("WS FileRead: ")); DEBUG_PRINTLN(path);
|
DEBUG_PRINT(F("WS FileRead: ")); DEBUG_PRINTLN(path);
|
||||||
if(path.endsWith("/")) path += "index.htm";
|
if(path.endsWith("/")) path += "index.htm";
|
||||||
if(path.indexOf(F("sec")) > -1) return false;
|
if(path.indexOf(F("sec")) > -1) return false;
|
||||||
String contentType = getFileContentType(path);
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
if(request->hasArg(F("download"))) contentType = F("application/octet-stream");
|
if (psramSafe && psramFound() && path.endsWith(FPSTR(getPresetsFileName()))) {
|
||||||
/*String pathWithGz = path + ".gz";
|
|
||||||
if(WLED_FS.exists(pathWithGz)){
|
|
||||||
request->send(WLED_FS, pathWithGz, contentType);
|
|
||||||
return true;
|
|
||||||
}*/
|
|
||||||
#if defined(BOARD_HAS_PSRAM) && defined(WLED_USE_PSRAM)
|
|
||||||
if (path.endsWith(FPSTR(getPresetsFileName()))) {
|
|
||||||
size_t psize;
|
size_t psize;
|
||||||
const uint8_t *presets = getPresetCache(psize);
|
const uint8_t *presets = getPresetCache(psize);
|
||||||
if (presets) {
|
if (presets) {
|
||||||
AsyncWebServerResponse *response = request->beginResponse_P(200, contentType, presets, psize);
|
AsyncWebServerResponse *response = request->beginResponse_P(200, FPSTR(CONTENT_TYPE_JSON), presets, psize);
|
||||||
request->send(response);
|
request->send(response);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if(WLED_FS.exists(path)) {
|
if(WLED_FS.exists(path) || WLED_FS.exists(path + ".gz")) {
|
||||||
request->send(WLED_FS, path, contentType);
|
request->send(WLED_FS, path, String(), request->hasArg(F("download")));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -210,7 +210,7 @@ void sendImprovInfoResponse() {
|
||||||
//Use serverDescription if it has been changed from the default "WLED", else mDNS name
|
//Use serverDescription if it has been changed from the default "WLED", else mDNS name
|
||||||
bool useMdnsName = (strcmp(serverDescription, "WLED") == 0 && strlen(cmDNS) > 0);
|
bool useMdnsName = (strcmp(serverDescription, "WLED") == 0 && strlen(cmDNS) > 0);
|
||||||
char vString[20];
|
char vString[20];
|
||||||
sprintf_P(vString, PSTR("0.15.0-b1/%i"), VERSION);
|
sprintf_P(vString, PSTR("0.15.0-b3/%i"), VERSION);
|
||||||
const char *str[4] = {"WLED", vString, bString, useMdnsName ? cmDNS : serverDescription};
|
const char *str[4] = {"WLED", vString, bString, useMdnsName ? cmDNS : serverDescription};
|
||||||
|
|
||||||
sendImprovRPCResult(ImprovRPCType::Request_Info, 4, str);
|
sendImprovRPCResult(ImprovRPCType::Request_Info, 4, str);
|
||||||
|
|
|
@ -142,28 +142,42 @@ bool deserializeSegment(JsonObject elem, byte it, byte presetId)
|
||||||
{
|
{
|
||||||
if (seg.getLightCapabilities() & 3) {
|
if (seg.getLightCapabilities() & 3) {
|
||||||
// segment has RGB or White
|
// segment has RGB or White
|
||||||
for (size_t i = 0; i < 3; i++)
|
for (size_t i = 0; i < NUM_COLORS; i++) {
|
||||||
{
|
// JSON "col" array can contain the following values for each of segment's colors (primary, background, custom):
|
||||||
|
// "col":[int|string|object|array, int|string|object|array, int|string|object|array]
|
||||||
|
// int = Kelvin temperature or 0 for black
|
||||||
|
// string = hex representation of [WW]RRGGBB
|
||||||
|
// object = individual channel control {"r":0,"g":127,"b":255,"w":255}, each being optional (valid to send {})
|
||||||
|
// array = direct channel values [r,g,b,w] (w element being optional)
|
||||||
int rgbw[] = {0,0,0,0};
|
int rgbw[] = {0,0,0,0};
|
||||||
bool colValid = false;
|
bool colValid = false;
|
||||||
JsonArray colX = colarr[i];
|
JsonArray colX = colarr[i];
|
||||||
if (colX.isNull()) {
|
if (colX.isNull()) {
|
||||||
byte brgbw[] = {0,0,0,0};
|
JsonObject oCol = colarr[i];
|
||||||
const char* hexCol = colarr[i];
|
if (!oCol.isNull()) {
|
||||||
if (hexCol == nullptr) { //Kelvin color temperature (or invalid), e.g 2400
|
// we have a JSON object for color {"w":123,"r":123,...}; allows individual channel control
|
||||||
int kelvin = colarr[i] | -1;
|
rgbw[0] = oCol["r"] | R(seg.colors[i]);
|
||||||
if (kelvin < 0) continue;
|
rgbw[1] = oCol["g"] | G(seg.colors[i]);
|
||||||
if (kelvin == 0) seg.setColor(i, 0);
|
rgbw[2] = oCol["b"] | B(seg.colors[i]);
|
||||||
if (kelvin > 0) colorKtoRGB(kelvin, brgbw);
|
rgbw[3] = oCol["w"] | W(seg.colors[i]);
|
||||||
colValid = true;
|
colValid = true;
|
||||||
} else { //HEX string, e.g. "FFAA00"
|
} else {
|
||||||
colValid = colorFromHexString(brgbw, hexCol);
|
byte brgbw[] = {0,0,0,0};
|
||||||
|
const char* hexCol = colarr[i];
|
||||||
|
if (hexCol == nullptr) { //Kelvin color temperature (or invalid), e.g 2400
|
||||||
|
int kelvin = colarr[i] | -1;
|
||||||
|
if (kelvin < 0) continue;
|
||||||
|
if (kelvin == 0) seg.setColor(i, 0);
|
||||||
|
if (kelvin > 0) colorKtoRGB(kelvin, brgbw);
|
||||||
|
colValid = true;
|
||||||
|
} else { //HEX string, e.g. "FFAA00"
|
||||||
|
colValid = colorFromHexString(brgbw, hexCol);
|
||||||
|
}
|
||||||
|
for (size_t c = 0; c < 4; c++) rgbw[c] = brgbw[c];
|
||||||
}
|
}
|
||||||
for (size_t c = 0; c < 4; c++) rgbw[c] = brgbw[c];
|
|
||||||
} else { //Array of ints (RGB or RGBW color), e.g. [255,160,0]
|
} else { //Array of ints (RGB or RGBW color), e.g. [255,160,0]
|
||||||
byte sz = colX.size();
|
byte sz = colX.size();
|
||||||
if (sz == 0) continue; //do nothing on empty array
|
if (sz == 0) continue; //do nothing on empty array
|
||||||
|
|
||||||
copyArray(colX, rgbw, 4);
|
copyArray(colX, rgbw, 4);
|
||||||
colValid = true;
|
colValid = true;
|
||||||
}
|
}
|
||||||
|
@ -226,14 +240,19 @@ bool deserializeSegment(JsonObject elem, byte it, byte presetId)
|
||||||
getVal(elem["ix"], &seg.intensity);
|
getVal(elem["ix"], &seg.intensity);
|
||||||
|
|
||||||
uint8_t pal = seg.palette;
|
uint8_t pal = seg.palette;
|
||||||
|
last = strip.getPaletteCount();
|
||||||
|
if (!elem["pal"].isNull() && elem["pal"].is<const char*>()) {
|
||||||
|
const char *tmp = elem["pal"].as<const char *>();
|
||||||
|
if (strlen(tmp) > 3 && (strchr(tmp,'r') || strchr(tmp,'~') != strrchr(tmp,'~'))) last = 0; // we have "X~Y(r|[w]~[-])" form
|
||||||
|
}
|
||||||
if (seg.getLightCapabilities() & 1) { // ignore palette for White and On/Off segments
|
if (seg.getLightCapabilities() & 1) { // ignore palette for White and On/Off segments
|
||||||
if (getVal(elem["pal"], &pal)) seg.setPalette(pal);
|
if (getVal(elem["pal"], &pal, 0, last)) seg.setPalette(pal);
|
||||||
}
|
}
|
||||||
|
|
||||||
getVal(elem["c1"], &seg.custom1);
|
getVal(elem["c1"], &seg.custom1);
|
||||||
getVal(elem["c2"], &seg.custom2);
|
getVal(elem["c2"], &seg.custom2);
|
||||||
uint8_t cust3 = seg.custom3;
|
uint8_t cust3 = seg.custom3;
|
||||||
getVal(elem["c3"], &cust3); // we can't pass reference to bitfield
|
getVal(elem["c3"], &cust3, 0, 31); // we can't pass reference to bitfield
|
||||||
seg.custom3 = constrain(cust3, 0, 31);
|
seg.custom3 = constrain(cust3, 0, 31);
|
||||||
|
|
||||||
seg.check1 = getBoolVal(elem["o1"], seg.check1);
|
seg.check1 = getBoolVal(elem["o1"], seg.check1);
|
||||||
|
@ -257,8 +276,8 @@ bool deserializeSegment(JsonObject elem, byte it, byte presetId)
|
||||||
seg.fill(BLACK);
|
seg.fill(BLACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t start = 0, stop = 0;
|
start = 0, stop = 0;
|
||||||
byte set = 0; //0 nothing set, 1 start set, 2 range set
|
set = 0; //0 nothing set, 1 start set, 2 range set
|
||||||
|
|
||||||
for (size_t i = 0; i < iarr.size(); i++) {
|
for (size_t i = 0; i < iarr.size(); i++) {
|
||||||
if(iarr[i].is<JsonInteger>()) {
|
if(iarr[i].is<JsonInteger>()) {
|
||||||
|
@ -298,7 +317,7 @@ bool deserializeSegment(JsonObject elem, byte it, byte presetId)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// deserializes WLED state (fileDoc points to doc object if called from web server)
|
// deserializes WLED state
|
||||||
// presetId is non-0 if called from handlePreset()
|
// presetId is non-0 if called from handlePreset()
|
||||||
bool deserializeState(JsonObject root, byte callMode, byte presetId)
|
bool deserializeState(JsonObject root, byte callMode, byte presetId)
|
||||||
{
|
{
|
||||||
|
@ -730,6 +749,8 @@ void serializeInfo(JsonObject root)
|
||||||
root[F("arch")] = ESP.getChipModel();
|
root[F("arch")] = ESP.getChipModel();
|
||||||
#endif
|
#endif
|
||||||
root[F("core")] = ESP.getSdkVersion();
|
root[F("core")] = ESP.getSdkVersion();
|
||||||
|
root[F("clock")] = ESP.getCpuFreqMHz();
|
||||||
|
root[F("flash")] = (ESP.getFlashChipSize()/1024)/1024;
|
||||||
#ifdef WLED_DEBUG
|
#ifdef WLED_DEBUG
|
||||||
root[F("maxalloc")] = ESP.getMaxAllocHeap();
|
root[F("maxalloc")] = ESP.getMaxAllocHeap();
|
||||||
root[F("resetReason0")] = (int)rtc_get_reset_reason(0);
|
root[F("resetReason0")] = (int)rtc_get_reset_reason(0);
|
||||||
|
@ -739,6 +760,8 @@ void serializeInfo(JsonObject root)
|
||||||
#else
|
#else
|
||||||
root[F("arch")] = "esp8266";
|
root[F("arch")] = "esp8266";
|
||||||
root[F("core")] = ESP.getCoreVersion();
|
root[F("core")] = ESP.getCoreVersion();
|
||||||
|
root[F("clock")] = ESP.getCpuFreqMHz();
|
||||||
|
root[F("flash")] = (ESP.getFlashChipSize()/1024)/1024;
|
||||||
#ifdef WLED_DEBUG
|
#ifdef WLED_DEBUG
|
||||||
root[F("maxalloc")] = ESP.getMaxFreeBlockSize();
|
root[F("maxalloc")] = ESP.getMaxFreeBlockSize();
|
||||||
root[F("resetReason")] = (int)ESP.getResetInfoPtr()->reason;
|
root[F("resetReason")] = (int)ESP.getResetInfoPtr()->reason;
|
||||||
|
@ -747,8 +770,8 @@ void serializeInfo(JsonObject root)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
root[F("freeheap")] = ESP.getFreeHeap();
|
root[F("freeheap")] = ESP.getFreeHeap();
|
||||||
#if defined(ARDUINO_ARCH_ESP32) && defined(BOARD_HAS_PSRAM)
|
#if defined(ARDUINO_ARCH_ESP32)
|
||||||
if (psramFound()) root[F("psram")] = ESP.getFreePsram();
|
if (psramSafe && psramFound()) root[F("psram")] = ESP.getFreePsram();
|
||||||
#endif
|
#endif
|
||||||
root[F("uptime")] = millis()/1000 + rolloverMillis*4294967;
|
root[F("uptime")] = millis()/1000 + rolloverMillis*4294967;
|
||||||
|
|
||||||
|
@ -850,8 +873,8 @@ void serializePalettes(JsonObject root, int page)
|
||||||
int itemPerPage = 8;
|
int itemPerPage = 8;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int palettesCount = strip.getPaletteCount();
|
|
||||||
int customPalettes = strip.customPalettes.size();
|
int customPalettes = strip.customPalettes.size();
|
||||||
|
int palettesCount = strip.getPaletteCount() - customPalettes;
|
||||||
|
|
||||||
int maxPage = (palettesCount + customPalettes -1) / itemPerPage;
|
int maxPage = (palettesCount + customPalettes -1) / itemPerPage;
|
||||||
if (page > maxPage) page = maxPage;
|
if (page > maxPage) page = maxPage;
|
||||||
|
@ -1063,7 +1086,7 @@ void serveJson(AsyncWebServerRequest* request)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
else if (url.indexOf("pal") > 0) {
|
else if (url.indexOf("pal") > 0) {
|
||||||
request->send_P(200, "application/json", JSON_palette_names); // contentType defined in AsyncJson-v6.h
|
request->send_P(200, FPSTR(CONTENT_TYPE_JSON), JSON_palette_names);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (url.indexOf(F("cfg")) > 0 && handleFileRead(request, F("/cfg.json"))) {
|
else if (url.indexOf(F("cfg")) > 0 && handleFileRead(request, F("/cfg.json"))) {
|
||||||
|
@ -1150,10 +1173,10 @@ bool serveLiveLeds(AsyncWebServerRequest* request, uint32_t wsClient)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
char buffer[2048]; // shoud be enough for 256 LEDs [RRGGBB] + all other text (9+25)
|
DynamicBuffer buffer(9 + (9*(1+(used/n))) + 7 + 5 + 6 + 5 + 6 + 5 + 2);
|
||||||
strcpy_P(buffer, PSTR("{\"leds\":["));
|
char* buf = buffer.data(); // assign buffer for oappnd() functions
|
||||||
obuf = buffer; // assign buffer for oappnd() functions
|
strncpy_P(buffer.data(), PSTR("{\"leds\":["), buffer.size());
|
||||||
olen = 9;
|
buf += 9; // sizeof(PSTR()) from last line
|
||||||
|
|
||||||
for (size_t i = 0; i < used; i += n)
|
for (size_t i = 0; i < used; i += n)
|
||||||
{
|
{
|
||||||
|
@ -1168,29 +1191,27 @@ bool serveLiveLeds(AsyncWebServerRequest* request, uint32_t wsClient)
|
||||||
r = scale8(qadd8(w, r), strip.getBrightness()); //R, add white channel to RGB channels as a simple RGBW -> RGB map
|
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
|
g = scale8(qadd8(w, g), strip.getBrightness()); //G
|
||||||
b = scale8(qadd8(w, b), strip.getBrightness()); //B
|
b = scale8(qadd8(w, b), strip.getBrightness()); //B
|
||||||
olen += sprintf_P(obuf + olen, PSTR("\"%06X\","), RGBW32(r,g,b,0));
|
buf += sprintf_P(buf, PSTR("\"%06X\","), RGBW32(r,g,b,0));
|
||||||
}
|
}
|
||||||
olen -= 1;
|
buf--; // remove last comma
|
||||||
oappend((const char*)F("],\"n\":"));
|
buf += sprintf_P(buf, PSTR("],\"n\":%d"), n);
|
||||||
oappendi(n);
|
|
||||||
#ifndef WLED_DISABLE_2D
|
#ifndef WLED_DISABLE_2D
|
||||||
if (strip.isMatrix) {
|
if (strip.isMatrix) {
|
||||||
oappend((const char*)F(",\"w\":"));
|
buf += sprintf_P(buf, PSTR(",\"w\":%d"), Segment::maxWidth/n);
|
||||||
oappendi(Segment::maxWidth/n);
|
buf += sprintf_P(buf, PSTR(",\"h\":%d"), Segment::maxHeight/n);
|
||||||
oappend((const char*)F(",\"h\":"));
|
|
||||||
oappendi(Segment::maxHeight/n);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
oappend("}");
|
(*buf++) = '}';
|
||||||
|
(*buf++) = 0;
|
||||||
|
|
||||||
if (request) {
|
if (request) {
|
||||||
request->send(200, "application/json", buffer); // contentType defined in AsyncJson-v6.h
|
request->send(200, FPSTR(CONTENT_TYPE_JSON), toString(std::move(buffer)));
|
||||||
}
|
}
|
||||||
#ifdef WLED_ENABLE_WEBSOCKETS
|
#ifdef WLED_ENABLE_WEBSOCKETS
|
||||||
else {
|
else {
|
||||||
wsc->text(obuf, olen);
|
wsc->text(toString(std::move(buffer)));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
obuf = nullptr;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -209,11 +209,10 @@ bool PinManagerClass::allocatePin(byte gpio, bool output, PinOwner tag)
|
||||||
|
|
||||||
// if tag is set to PinOwner::None, checks for ANY owner of the pin.
|
// if tag is set to PinOwner::None, checks for ANY owner of the pin.
|
||||||
// if tag is set to any other value, checks if that tag is the current owner of the pin.
|
// if tag is set to any other value, checks if that tag is the current owner of the pin.
|
||||||
bool PinManagerClass::isPinAllocated(byte gpio, PinOwner tag)
|
bool PinManagerClass::isPinAllocated(byte gpio, PinOwner tag) const
|
||||||
{
|
{
|
||||||
if (!isPinOk(gpio, false)) return true;
|
if (!isPinOk(gpio, false)) return true;
|
||||||
if ((tag != PinOwner::None) && (ownerTag[gpio] != tag)) return false;
|
if ((tag != PinOwner::None) && (ownerTag[gpio] != tag)) return false;
|
||||||
if (gpio >= WLED_NUM_PINS) return false; // catch error case, to avoid array out-of-bounds access
|
|
||||||
byte by = gpio >> 3;
|
byte by = gpio >> 3;
|
||||||
byte bi = gpio - (by<<3);
|
byte bi = gpio - (by<<3);
|
||||||
return bitRead(pinAlloc[by], bi);
|
return bitRead(pinAlloc[by], bi);
|
||||||
|
@ -236,8 +235,9 @@ bool PinManagerClass::isPinAllocated(byte gpio, PinOwner tag)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Check if supplied GPIO is ok to use
|
// Check if supplied GPIO is ok to use
|
||||||
bool PinManagerClass::isPinOk(byte gpio, bool output)
|
bool PinManagerClass::isPinOk(byte gpio, bool output) const
|
||||||
{
|
{
|
||||||
|
if (gpio >= WLED_NUM_PINS) return false; // catch error case, to avoid array out-of-bounds access
|
||||||
#ifdef ARDUINO_ARCH_ESP32
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
if (digitalPinIsValid(gpio)) {
|
if (digitalPinIsValid(gpio)) {
|
||||||
#if defined(CONFIG_IDF_TARGET_ESP32C3)
|
#if defined(CONFIG_IDF_TARGET_ESP32C3)
|
||||||
|
@ -248,7 +248,7 @@ bool PinManagerClass::isPinOk(byte gpio, bool output)
|
||||||
// 00 to 18 are for general use. Be careful about straping pins GPIO0 and GPIO3 - these may be pulled-up or pulled-down on your board.
|
// 00 to 18 are for general use. Be careful about straping pins GPIO0 and GPIO3 - these may be pulled-up or pulled-down on your board.
|
||||||
if (gpio > 18 && gpio < 21) return false; // 19 + 20 = USB-JTAG. Not recommended for other uses.
|
if (gpio > 18 && gpio < 21) return false; // 19 + 20 = USB-JTAG. Not recommended for other uses.
|
||||||
if (gpio > 21 && gpio < 33) return false; // 22 to 32: not connected + SPI FLASH
|
if (gpio > 21 && gpio < 33) return false; // 22 to 32: not connected + SPI FLASH
|
||||||
//if (gpio > 32 && gpio < 38) return false; // 33 to 37: not available if using _octal_ SPI Flash or _octal_ PSRAM
|
if (gpio > 32 && gpio < 38) return !psramFound(); // 33 to 37: not available if using _octal_ SPI Flash or _octal_ PSRAM
|
||||||
// 38 to 48 are for general use. Be careful about straping pins GPIO45 and GPIO46 - these may be pull-up or pulled-down on your board.
|
// 38 to 48 are for general use. Be careful about straping pins GPIO45 and GPIO46 - these may be pull-up or pulled-down on your board.
|
||||||
#elif defined(CONFIG_IDF_TARGET_ESP32S2)
|
#elif defined(CONFIG_IDF_TARGET_ESP32S2)
|
||||||
// strapping pins: 0, 45 & 46
|
// strapping pins: 0, 45 & 46
|
||||||
|
@ -257,9 +257,8 @@ bool PinManagerClass::isPinOk(byte gpio, bool output)
|
||||||
// GPIO46 is input only and pulled down
|
// GPIO46 is input only and pulled down
|
||||||
#else
|
#else
|
||||||
if (gpio > 5 && gpio < 12) return false; //SPI flash pins
|
if (gpio > 5 && gpio < 12) return false; //SPI flash pins
|
||||||
#ifdef BOARD_HAS_PSRAM
|
if (strncmp_P(PSTR("ESP32-PICO"), ESP.getChipModel(), 10) == 0 && (gpio == 16 || gpio == 17)) return false; // PICO-D4: gpio16+17 are in use for onboard SPI FLASH
|
||||||
if (gpio == 16 || gpio == 17) return false; //PSRAM pins
|
if (gpio == 16 || gpio == 17) return !psramFound(); //PSRAM pins on ESP32 (these are IO)
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
if (output) return digitalPinCanOutput(gpio);
|
if (output) return digitalPinCanOutput(gpio);
|
||||||
else return true;
|
else return true;
|
||||||
|
@ -272,8 +271,8 @@ bool PinManagerClass::isPinOk(byte gpio, bool output)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
PinOwner PinManagerClass::getPinOwner(byte gpio) {
|
PinOwner PinManagerClass::getPinOwner(byte gpio) const
|
||||||
if (gpio >= WLED_NUM_PINS) return PinOwner::None; // catch error case, to avoid array out-of-bounds access
|
{
|
||||||
if (!isPinOk(gpio, false)) return PinOwner::None;
|
if (!isPinOk(gpio, false)) return PinOwner::None;
|
||||||
return ownerTag[gpio];
|
return ownerTag[gpio];
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,7 +61,8 @@ enum struct PinOwner : uint8_t {
|
||||||
UM_Audioreactive = USERMOD_ID_AUDIOREACTIVE, // 0x20 // Usermod "audio_reactive.h"
|
UM_Audioreactive = USERMOD_ID_AUDIOREACTIVE, // 0x20 // Usermod "audio_reactive.h"
|
||||||
UM_SdCard = USERMOD_ID_SD_CARD, // 0x25 // Usermod "usermod_sd_card.h"
|
UM_SdCard = USERMOD_ID_SD_CARD, // 0x25 // Usermod "usermod_sd_card.h"
|
||||||
UM_PWM_OUTPUTS = USERMOD_ID_PWM_OUTPUTS, // 0x26 // Usermod "usermod_pwm_outputs.h"
|
UM_PWM_OUTPUTS = USERMOD_ID_PWM_OUTPUTS, // 0x26 // Usermod "usermod_pwm_outputs.h"
|
||||||
UM_LDR_DUSK_DAWN = USERMOD_ID_LDR_DUSK_DAWN // 0x2B // Usermod "usermod_LDR_Dusk_Dawn_v2.h"
|
UM_LDR_DUSK_DAWN = USERMOD_ID_LDR_DUSK_DAWN, // 0x2B // Usermod "usermod_LDR_Dusk_Dawn_v2.h"
|
||||||
|
UM_MAX17048 = USERMOD_ID_MAX17048 // 0x2F // Usermod "usermod_max17048.h"
|
||||||
};
|
};
|
||||||
static_assert(0u == static_cast<uint8_t>(PinOwner::None), "PinOwner::None must be zero, so default array initialization works as expected");
|
static_assert(0u == static_cast<uint8_t>(PinOwner::None), "PinOwner::None must be zero, so default array initialization works as expected");
|
||||||
|
|
||||||
|
@ -108,11 +109,11 @@ class PinManagerClass {
|
||||||
inline void deallocatePin(byte gpio) { deallocatePin(gpio, PinOwner::None); }
|
inline void deallocatePin(byte gpio) { deallocatePin(gpio, PinOwner::None); }
|
||||||
|
|
||||||
// will return true for reserved pins
|
// will return true for reserved pins
|
||||||
bool isPinAllocated(byte gpio, PinOwner tag = PinOwner::None);
|
bool isPinAllocated(byte gpio, PinOwner tag = PinOwner::None) const;
|
||||||
// will return false for reserved pins
|
// will return false for reserved pins
|
||||||
bool isPinOk(byte gpio, bool output = true);
|
bool isPinOk(byte gpio, bool output = true) const;
|
||||||
|
|
||||||
PinOwner getPinOwner(byte gpio);
|
PinOwner getPinOwner(byte gpio) const;
|
||||||
|
|
||||||
#ifdef ARDUINO_ARCH_ESP32
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
byte allocateLedc(byte channels);
|
byte allocateLedc(byte channels);
|
||||||
|
|
|
@ -109,7 +109,10 @@ int16_t loadPlaylist(JsonObject playlistObj, byte presetId) {
|
||||||
if (playlistRepeat > 0) playlistRepeat++; //add one extra repetition immediately since it will be deducted on first start
|
if (playlistRepeat > 0) playlistRepeat++; //add one extra repetition immediately since it will be deducted on first start
|
||||||
playlistEndPreset = playlistObj["end"] | 0;
|
playlistEndPreset = playlistObj["end"] | 0;
|
||||||
// if end preset is 255 restore original preset (if any running) upon playlist end
|
// if end preset is 255 restore original preset (if any running) upon playlist end
|
||||||
if (playlistEndPreset == 255 && currentPreset > 0) playlistEndPreset = currentPreset;
|
if (playlistEndPreset == 255 && currentPreset > 0) {
|
||||||
|
playlistEndPreset = currentPreset;
|
||||||
|
playlistOptions |= PL_OPTION_RESTORE; // for async save operation
|
||||||
|
}
|
||||||
if (playlistEndPreset > 250) playlistEndPreset = 0;
|
if (playlistEndPreset > 250) playlistEndPreset = 0;
|
||||||
shuffle = shuffle || playlistObj["r"];
|
shuffle = shuffle || playlistObj["r"];
|
||||||
if (shuffle) playlistOptions |= PL_OPTION_SHUFFLE;
|
if (shuffle) playlistOptions |= PL_OPTION_SHUFFLE;
|
||||||
|
@ -122,8 +125,7 @@ int16_t loadPlaylist(JsonObject playlistObj, byte presetId) {
|
||||||
|
|
||||||
void handlePlaylist() {
|
void handlePlaylist() {
|
||||||
static unsigned long presetCycledTime = 0;
|
static unsigned long presetCycledTime = 0;
|
||||||
// if fileDoc is not null JSON buffer is in use so just quit
|
if (currentPlaylist < 0 || playlistEntries == nullptr) return;
|
||||||
if (currentPlaylist < 0 || playlistEntries == nullptr || fileDoc != nullptr) return;
|
|
||||||
|
|
||||||
if (millis() - presetCycledTime > (100*playlistEntryDur)) {
|
if (millis() - presetCycledTime > (100*playlistEntryDur)) {
|
||||||
presetCycledTime = millis();
|
presetCycledTime = millis();
|
||||||
|
@ -135,7 +137,7 @@ void handlePlaylist() {
|
||||||
if (!playlistIndex) {
|
if (!playlistIndex) {
|
||||||
if (playlistRepeat == 1) { //stop if all repetitions are done
|
if (playlistRepeat == 1) { //stop if all repetitions are done
|
||||||
unloadPlaylist();
|
unloadPlaylist();
|
||||||
if (playlistEndPreset) applyPreset(playlistEndPreset);
|
if (playlistEndPreset) applyPresetFromPlaylist(playlistEndPreset);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (playlistRepeat > 1) playlistRepeat--; // decrease repeat count on each index reset if not an endless playlist
|
if (playlistRepeat > 1) playlistRepeat--; // decrease repeat count on each index reset if not an endless playlist
|
||||||
|
@ -146,7 +148,7 @@ void handlePlaylist() {
|
||||||
jsonTransitionOnce = true;
|
jsonTransitionOnce = true;
|
||||||
strip.setTransition(fadeTransition ? playlistEntries[playlistIndex].tr * 100 : 0);
|
strip.setTransition(fadeTransition ? playlistEntries[playlistIndex].tr * 100 : 0);
|
||||||
playlistEntryDur = playlistEntries[playlistIndex].dur;
|
playlistEntryDur = playlistEntries[playlistIndex].dur;
|
||||||
applyPreset(playlistEntries[playlistIndex].preset);
|
applyPresetFromPlaylist(playlistEntries[playlistIndex].preset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,7 +159,7 @@ void serializePlaylist(JsonObject sObj) {
|
||||||
JsonArray dur = playlist.createNestedArray("dur");
|
JsonArray dur = playlist.createNestedArray("dur");
|
||||||
JsonArray transition = playlist.createNestedArray(F("transition"));
|
JsonArray transition = playlist.createNestedArray(F("transition"));
|
||||||
playlist[F("repeat")] = (playlistIndex < 0 && playlistRepeat > 0) ? playlistRepeat - 1 : playlistRepeat; // remove added repetition count (if not yet running)
|
playlist[F("repeat")] = (playlistIndex < 0 && playlistRepeat > 0) ? playlistRepeat - 1 : playlistRepeat; // remove added repetition count (if not yet running)
|
||||||
playlist["end"] = playlistEndPreset;
|
playlist["end"] = playlistOptions & PL_OPTION_RESTORE ? 255 : playlistEndPreset;
|
||||||
playlist["r"] = playlistOptions & PL_OPTION_SHUFFLE;
|
playlist["r"] = playlistOptions & PL_OPTION_SHUFFLE;
|
||||||
for (int i=0; i<playlistLen; i++) {
|
for (int i=0; i<playlistLen; i++) {
|
||||||
ps.add(playlistEntries[i].preset);
|
ps.add(playlistEntries[i].preset);
|
||||||
|
|
|
@ -27,7 +27,7 @@ static void doSaveState() {
|
||||||
|
|
||||||
unsigned long start = millis();
|
unsigned long start = millis();
|
||||||
while (strip.isUpdating() && millis()-start < (2*FRAMETIME_FIXED)+1) yield(); // wait 2 frames
|
while (strip.isUpdating() && millis()-start < (2*FRAMETIME_FIXED)+1) yield(); // wait 2 frames
|
||||||
if (!requestJSONBufferLock(10)) return; // will set fileDoc
|
if (!requestJSONBufferLock(10)) return;
|
||||||
|
|
||||||
initPresetsFile(); // just in case if someone deleted presets.json using /edit
|
initPresetsFile(); // just in case if someone deleted presets.json using /edit
|
||||||
JsonObject sObj = pDoc->to<JsonObject>();
|
JsonObject sObj = pDoc->to<JsonObject>();
|
||||||
|
@ -53,23 +53,21 @@ static void doSaveState() {
|
||||||
#if defined(ARDUINO_ARCH_ESP32)
|
#if defined(ARDUINO_ARCH_ESP32)
|
||||||
if (!persist) {
|
if (!persist) {
|
||||||
if (tmpRAMbuffer!=nullptr) free(tmpRAMbuffer);
|
if (tmpRAMbuffer!=nullptr) free(tmpRAMbuffer);
|
||||||
size_t len = measureJson(*fileDoc) + 1;
|
size_t len = measureJson(*pDoc) + 1;
|
||||||
DEBUG_PRINTLN(len);
|
DEBUG_PRINTLN(len);
|
||||||
// if possible use SPI RAM on ESP32
|
// if possible use SPI RAM on ESP32
|
||||||
#if defined(BOARD_HAS_PSRAM) && defined(WLED_USE_PSRAM)
|
if (psramSafe && psramFound())
|
||||||
if (psramFound())
|
|
||||||
tmpRAMbuffer = (char*) ps_malloc(len);
|
tmpRAMbuffer = (char*) ps_malloc(len);
|
||||||
else
|
else
|
||||||
#endif
|
|
||||||
tmpRAMbuffer = (char*) malloc(len);
|
tmpRAMbuffer = (char*) malloc(len);
|
||||||
if (tmpRAMbuffer!=nullptr) {
|
if (tmpRAMbuffer!=nullptr) {
|
||||||
serializeJson(*fileDoc, tmpRAMbuffer, len);
|
serializeJson(*pDoc, tmpRAMbuffer, len);
|
||||||
} else {
|
} else {
|
||||||
writeObjectToFileUsingId(getPresetsFileName(persist), presetToSave, fileDoc);
|
writeObjectToFileUsingId(getPresetsFileName(persist), presetToSave, pDoc);
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
writeObjectToFileUsingId(getPresetsFileName(persist), presetToSave, fileDoc);
|
writeObjectToFileUsingId(getPresetsFileName(persist), presetToSave, pDoc);
|
||||||
|
|
||||||
if (persist) presetsModifiedTime = toki.second(); //unix time
|
if (persist) presetsModifiedTime = toki.second(); //unix time
|
||||||
releaseJSONBufferLock();
|
releaseJSONBufferLock();
|
||||||
|
@ -117,6 +115,15 @@ void initPresetsFile()
|
||||||
f.close();
|
f.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool applyPresetFromPlaylist(byte index)
|
||||||
|
{
|
||||||
|
DEBUG_PRINT(F("Request to apply preset: "));
|
||||||
|
DEBUG_PRINTLN(index);
|
||||||
|
presetToApply = index;
|
||||||
|
callModeToApply = CALL_MODE_DIRECT_CHANGE;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool applyPreset(byte index, byte callMode)
|
bool applyPreset(byte index, byte callMode)
|
||||||
{
|
{
|
||||||
unloadPlaylist(); // applying a preset unloads the playlist (#3827)
|
unloadPlaylist(); // applying a preset unloads the playlist (#3827)
|
||||||
|
@ -145,7 +152,7 @@ void handlePresets()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (presetToApply == 0 || fileDoc) return; // no preset waiting to apply, or JSON buffer is already allocated, return to loop until free
|
if (presetToApply == 0 || !requestJSONBufferLock(9)) return; // no preset waiting to apply, or JSON buffer is already allocated, return to loop until free
|
||||||
|
|
||||||
bool changePreset = false;
|
bool changePreset = false;
|
||||||
uint8_t tmpPreset = presetToApply; // store temporary since deserializeState() may call applyPreset()
|
uint8_t tmpPreset = presetToApply; // store temporary since deserializeState() may call applyPreset()
|
||||||
|
@ -153,9 +160,6 @@ void handlePresets()
|
||||||
|
|
||||||
JsonObject fdo;
|
JsonObject fdo;
|
||||||
|
|
||||||
// allocate buffer
|
|
||||||
if (!requestJSONBufferLock(9)) return; // will also assign fileDoc
|
|
||||||
|
|
||||||
presetToApply = 0; //clear request for preset
|
presetToApply = 0; //clear request for preset
|
||||||
callModeToApply = 0;
|
callModeToApply = 0;
|
||||||
|
|
||||||
|
@ -164,14 +168,14 @@ void handlePresets()
|
||||||
|
|
||||||
#ifdef ARDUINO_ARCH_ESP32
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
if (tmpPreset==255 && tmpRAMbuffer!=nullptr) {
|
if (tmpPreset==255 && tmpRAMbuffer!=nullptr) {
|
||||||
deserializeJson(*fileDoc,tmpRAMbuffer);
|
deserializeJson(*pDoc,tmpRAMbuffer);
|
||||||
errorFlag = ERR_NONE;
|
errorFlag = ERR_NONE;
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
errorFlag = readObjectFromFileUsingId(getPresetsFileName(tmpPreset < 255), tmpPreset, fileDoc) ? ERR_NONE : ERR_FS_PLOAD;
|
errorFlag = readObjectFromFileUsingId(getPresetsFileName(tmpPreset < 255), tmpPreset, pDoc) ? ERR_NONE : ERR_FS_PLOAD;
|
||||||
}
|
}
|
||||||
fdo = fileDoc->as<JsonObject>();
|
fdo = pDoc->as<JsonObject>();
|
||||||
|
|
||||||
//HTTP API commands
|
//HTTP API commands
|
||||||
const char* httpwin = fdo["win"];
|
const char* httpwin = fdo["win"];
|
||||||
|
@ -198,13 +202,13 @@ void handlePresets()
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
releaseJSONBufferLock(); // will also clear fileDoc
|
releaseJSONBufferLock();
|
||||||
if (changePreset) notify(tmpMode); // force UDP notification
|
if (changePreset) notify(tmpMode); // force UDP notification
|
||||||
stateUpdated(tmpMode); // was colorUpdated() if anything breaks
|
stateUpdated(tmpMode); // was colorUpdated() if anything breaks
|
||||||
updateInterfaces(tmpMode);
|
updateInterfaces(tmpMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
//called from handleSet(PS=) [network callback (fileDoc==nullptr), IR (irrational), deserializeState, UDP] and deserializeState() [network callback (filedoc!=nullptr)]
|
//called from handleSet(PS=) [network callback (sObj is empty), IR (irrational), deserializeState, UDP] and deserializeState() [network callback (filedoc!=nullptr)]
|
||||||
void savePreset(byte index, const char* pname, JsonObject sObj)
|
void savePreset(byte index, const char* pname, JsonObject sObj)
|
||||||
{
|
{
|
||||||
if (!saveName) saveName = new char[33];
|
if (!saveName) saveName = new char[33];
|
||||||
|
@ -242,7 +246,7 @@ void savePreset(byte index, const char* pname, JsonObject sObj)
|
||||||
if (sObj[F("playlist")].isNull()) {
|
if (sObj[F("playlist")].isNull()) {
|
||||||
// we will save API call immediately (often causes presets.json corruption)
|
// we will save API call immediately (often causes presets.json corruption)
|
||||||
presetToSave = 0;
|
presetToSave = 0;
|
||||||
if (index <= 250 && fileDoc) { // cannot save API calls to temporary preset (255)
|
if (index <= 250) { // cannot save API calls to temporary preset (255)
|
||||||
sObj.remove("o");
|
sObj.remove("o");
|
||||||
sObj.remove("v");
|
sObj.remove("v");
|
||||||
sObj.remove("time");
|
sObj.remove("time");
|
||||||
|
@ -250,7 +254,7 @@ void savePreset(byte index, const char* pname, JsonObject sObj)
|
||||||
sObj.remove(F("psave"));
|
sObj.remove(F("psave"));
|
||||||
if (sObj["n"].isNull()) sObj["n"] = saveName;
|
if (sObj["n"].isNull()) sObj["n"] = saveName;
|
||||||
initPresetsFile(); // just in case if someone deleted presets.json using /edit
|
initPresetsFile(); // just in case if someone deleted presets.json using /edit
|
||||||
writeObjectToFileUsingId(getPresetsFileName(), index, fileDoc);
|
writeObjectToFileUsingId(getPresetsFileName(), index, pDoc);
|
||||||
presetsModifiedTime = toki.second(); //unix time
|
presetsModifiedTime = toki.second(); //unix time
|
||||||
updateFSInfo();
|
updateFSInfo();
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,6 +110,10 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
||||||
for (uint8_t s=0; s<WLED_MAX_BUTTONS; s++) {
|
for (uint8_t s=0; s<WLED_MAX_BUTTONS; s++) {
|
||||||
if (btnPin[s]>=0 && pinManager.isPinAllocated(btnPin[s], PinOwner::Button)) {
|
if (btnPin[s]>=0 && pinManager.isPinAllocated(btnPin[s], PinOwner::Button)) {
|
||||||
pinManager.deallocatePin(btnPin[s], PinOwner::Button);
|
pinManager.deallocatePin(btnPin[s], PinOwner::Button);
|
||||||
|
#ifdef SOC_TOUCH_VERSION_2 // ESP32 S2 and S3 have a function to check touch state, detach interrupt
|
||||||
|
if (digitalPinToTouchChannel(btnPin[s]) >= 0) // if touch capable pin
|
||||||
|
touchDetachInterrupt(btnPin[s]); // if not assigned previously, this will do nothing
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,6 +127,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
||||||
autoSegments = request->hasArg(F("MS"));
|
autoSegments = request->hasArg(F("MS"));
|
||||||
correctWB = request->hasArg(F("CCT"));
|
correctWB = request->hasArg(F("CCT"));
|
||||||
cctFromRgb = request->hasArg(F("CR"));
|
cctFromRgb = request->hasArg(F("CR"));
|
||||||
|
cctICused = request->hasArg(F("IC"));
|
||||||
strip.cctBlending = request->arg(F("CB")).toInt();
|
strip.cctBlending = request->arg(F("CB")).toInt();
|
||||||
Bus::setCCTBlend(strip.cctBlending);
|
Bus::setCCTBlend(strip.cctBlending);
|
||||||
Bus::setGlobalAWMode(request->arg(F("AW")).toInt());
|
Bus::setGlobalAWMode(request->arg(F("AW")).toInt());
|
||||||
|
@ -240,6 +245,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
||||||
rlyMde = (bool)request->hasArg(F("RM"));
|
rlyMde = (bool)request->hasArg(F("RM"));
|
||||||
|
|
||||||
disablePullUp = (bool)request->hasArg(F("IP"));
|
disablePullUp = (bool)request->hasArg(F("IP"));
|
||||||
|
touchThreshold = request->arg(F("TT")).toInt();
|
||||||
for (uint8_t i=0; i<WLED_MAX_BUTTONS; i++) {
|
for (uint8_t i=0; i<WLED_MAX_BUTTONS; i++) {
|
||||||
char bt[4] = "BT"; bt[2] = (i<10?48:55)+i; bt[3] = 0; // button pin (use A,B,C,... if WLED_MAX_BUTTONS>10)
|
char bt[4] = "BT"; bt[2] = (i<10?48:55)+i; bt[3] = 0; // button pin (use A,B,C,... if WLED_MAX_BUTTONS>10)
|
||||||
char be[4] = "BE"; be[2] = (i<10?48:55)+i; be[3] = 0; // button type (use A,B,C,... if WLED_MAX_BUTTONS>10)
|
char be[4] = "BE"; be[2] = (i<10?48:55)+i; be[3] = 0; // button type (use A,B,C,... if WLED_MAX_BUTTONS>10)
|
||||||
|
@ -256,12 +262,21 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
||||||
btnPin[i] = -1;
|
btnPin[i] = -1;
|
||||||
pinManager.deallocatePin(hw_btn_pin,PinOwner::Button);
|
pinManager.deallocatePin(hw_btn_pin,PinOwner::Button);
|
||||||
}
|
}
|
||||||
else if ((buttonType[i] == BTN_TYPE_TOUCH || buttonType[i] == BTN_TYPE_TOUCH_SWITCH) && digitalPinToTouchChannel(btnPin[i]) < 0)
|
else if ((buttonType[i] == BTN_TYPE_TOUCH || buttonType[i] == BTN_TYPE_TOUCH_SWITCH))
|
||||||
{
|
{
|
||||||
// not a touch pin
|
if (digitalPinToTouchChannel(btnPin[i]) < 0)
|
||||||
DEBUG_PRINTF_P(PSTR("PIN ALLOC error: GPIO%d for touch button #%d is not an touch pin!\n"), btnPin[i], i);
|
{
|
||||||
btnPin[i] = -1;
|
// not a touch pin
|
||||||
pinManager.deallocatePin(hw_btn_pin,PinOwner::Button);
|
DEBUG_PRINTF_P(PSTR("PIN ALLOC error: GPIO%d for touch button #%d is not an touch pin!\n"), btnPin[i], i);
|
||||||
|
btnPin[i] = -1;
|
||||||
|
pinManager.deallocatePin(hw_btn_pin,PinOwner::Button);
|
||||||
|
}
|
||||||
|
#ifdef SOC_TOUCH_VERSION_2 // ESP32 S2 and S3 have a fucntion to check touch state but need to attach an interrupt to do so
|
||||||
|
else
|
||||||
|
{
|
||||||
|
touchAttachInterrupt(btnPin[i], touchButtonISR, 256 + (touchThreshold << 4)); // threshold on Touch V2 is much higher (1500 is a value given by Espressif example, I measured changes of over 5000)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
|
@ -281,7 +296,6 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
||||||
buttonType[i] = BTN_TYPE_NONE;
|
buttonType[i] = BTN_TYPE_NONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
touchThreshold = request->arg(F("TT")).toInt();
|
|
||||||
|
|
||||||
briS = request->arg(F("CA")).toInt();
|
briS = request->arg(F("CA")).toInt();
|
||||||
|
|
||||||
|
|
|
@ -21,8 +21,6 @@
|
||||||
#define DYNAMIC_JSON_DOCUMENT_SIZE 16384
|
#define DYNAMIC_JSON_DOCUMENT_SIZE 16384
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
constexpr const char* JSON_MIMETYPE = "application/json";
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Json Response
|
* Json Response
|
||||||
* */
|
* */
|
||||||
|
@ -66,7 +64,7 @@ class AsyncJsonResponse: public AsyncAbstractResponse {
|
||||||
|
|
||||||
AsyncJsonResponse(JsonDocument *ref, bool isArray=false) : _jsonBuffer(1), _isValid{false} {
|
AsyncJsonResponse(JsonDocument *ref, bool isArray=false) : _jsonBuffer(1), _isValid{false} {
|
||||||
_code = 200;
|
_code = 200;
|
||||||
_contentType = JSON_MIMETYPE;
|
_contentType = FPSTR(CONTENT_TYPE_JSON);
|
||||||
if(isArray)
|
if(isArray)
|
||||||
_root = ref->to<JsonArray>();
|
_root = ref->to<JsonArray>();
|
||||||
else
|
else
|
||||||
|
@ -75,7 +73,7 @@ class AsyncJsonResponse: public AsyncAbstractResponse {
|
||||||
|
|
||||||
AsyncJsonResponse(size_t maxJsonBufferSize = DYNAMIC_JSON_DOCUMENT_SIZE, bool isArray=false) : _jsonBuffer(maxJsonBufferSize), _isValid{false} {
|
AsyncJsonResponse(size_t maxJsonBufferSize = DYNAMIC_JSON_DOCUMENT_SIZE, bool isArray=false) : _jsonBuffer(maxJsonBufferSize), _isValid{false} {
|
||||||
_code = 200;
|
_code = 200;
|
||||||
_contentType = JSON_MIMETYPE;
|
_contentType = FPSTR(CONTENT_TYPE_JSON);
|
||||||
if(isArray)
|
if(isArray)
|
||||||
_root = _jsonBuffer.createNestedArray();
|
_root = _jsonBuffer.createNestedArray();
|
||||||
else
|
else
|
||||||
|
|
|
@ -209,8 +209,12 @@
|
||||||
#include "../usermods/stairway_wipe_basic/stairway-wipe-usermod-v2.h"
|
#include "../usermods/stairway_wipe_basic/stairway-wipe-usermod-v2.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef USERMOD_MAX17048
|
||||||
|
#include "../usermods/MAX17048_v2/usermod_max17048.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef USERMOD_TETRISAI
|
#ifdef USERMOD_TETRISAI
|
||||||
#include "../usermods/TetrisAI_v2/usermod_v2_tetrisai.h"
|
#include "../usermods/TetrisAI_v2/usermod_v2_tetrisai.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void registerUsermods()
|
void registerUsermods()
|
||||||
|
@ -410,6 +414,10 @@ void registerUsermods()
|
||||||
usermods.add(new StairwayWipeUsermod());
|
usermods.add(new StairwayWipeUsermod());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef USERMOD_MAX17048
|
||||||
|
usermods.add(new Usermod_MAX17048());
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef USERMOD_TETRISAI
|
#ifdef USERMOD_TETRISAI
|
||||||
usermods.add(new TetrisAIUsermod());
|
usermods.add(new TetrisAIUsermod());
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -228,7 +228,6 @@ bool requestJSONBufferLock(uint8_t module)
|
||||||
DEBUG_PRINT(F("JSON buffer locked. ("));
|
DEBUG_PRINT(F("JSON buffer locked. ("));
|
||||||
DEBUG_PRINT(jsonBufferLock);
|
DEBUG_PRINT(jsonBufferLock);
|
||||||
DEBUG_PRINTLN(")");
|
DEBUG_PRINTLN(")");
|
||||||
fileDoc = pDoc; // used for applying presets (presets.cpp)
|
|
||||||
pDoc->clear();
|
pDoc->clear();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -239,7 +238,6 @@ void releaseJSONBufferLock()
|
||||||
DEBUG_PRINT(F("JSON buffer released. ("));
|
DEBUG_PRINT(F("JSON buffer released. ("));
|
||||||
DEBUG_PRINT(jsonBufferLock);
|
DEBUG_PRINT(jsonBufferLock);
|
||||||
DEBUG_PRINTLN(")");
|
DEBUG_PRINTLN(")");
|
||||||
fileDoc = nullptr;
|
|
||||||
jsonBufferLock = 0;
|
jsonBufferLock = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -265,8 +263,8 @@ uint8_t extractModeName(uint8_t mode, const char *src, char *dest, uint8_t maxLe
|
||||||
} else return 0;
|
} else return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (src == JSON_palette_names && mode > GRADIENT_PALETTE_COUNT) {
|
if (src == JSON_palette_names && mode > (GRADIENT_PALETTE_COUNT + 13)) {
|
||||||
snprintf_P(dest, maxLen, PSTR("~ Custom %d~"), 255-mode);
|
snprintf_P(dest, maxLen, PSTR("~ Custom %d ~"), 255-mode);
|
||||||
dest[maxLen-1] = '\0';
|
dest[maxLen-1] = '\0';
|
||||||
return strlen(dest);
|
return strlen(dest);
|
||||||
}
|
}
|
||||||
|
|
|
@ -240,10 +240,11 @@ void WLED::loop()
|
||||||
DEBUG_PRINT(F("Runtime: ")); DEBUG_PRINTLN(millis());
|
DEBUG_PRINT(F("Runtime: ")); DEBUG_PRINTLN(millis());
|
||||||
DEBUG_PRINT(F("Unix time: ")); toki.printTime(toki.getTime());
|
DEBUG_PRINT(F("Unix time: ")); toki.printTime(toki.getTime());
|
||||||
DEBUG_PRINT(F("Free heap: ")); DEBUG_PRINTLN(ESP.getFreeHeap());
|
DEBUG_PRINT(F("Free heap: ")); DEBUG_PRINTLN(ESP.getFreeHeap());
|
||||||
#if defined(ARDUINO_ARCH_ESP32) && defined(BOARD_HAS_PSRAM)
|
#if defined(ARDUINO_ARCH_ESP32)
|
||||||
if (psramFound()) {
|
if (psramFound()) {
|
||||||
DEBUG_PRINT(F("Total PSRAM: ")); DEBUG_PRINT(ESP.getPsramSize()/1024); DEBUG_PRINTLN("kB");
|
DEBUG_PRINT(F("Total PSRAM: ")); DEBUG_PRINT(ESP.getPsramSize()/1024); DEBUG_PRINTLN("kB");
|
||||||
DEBUG_PRINT(F("Free PSRAM: ")); DEBUG_PRINT(ESP.getFreePsram()/1024); DEBUG_PRINTLN("kB");
|
DEBUG_PRINT(F("Free PSRAM: ")); DEBUG_PRINT(ESP.getFreePsram()/1024); DEBUG_PRINTLN("kB");
|
||||||
|
if (!psramSafe) DEBUG_PRINTLN(F("Not using PSRAM."));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
DEBUG_PRINT(F("Wifi state: ")); DEBUG_PRINTLN(WiFi.status());
|
DEBUG_PRINT(F("Wifi state: ")); DEBUG_PRINTLN(WiFi.status());
|
||||||
|
@ -361,56 +362,26 @@ void WLED::setup()
|
||||||
DEBUG_PRINT(F(", speed ")); DEBUG_PRINT(ESP.getFlashChipSpeed()/1000000);DEBUG_PRINTLN(F("MHz."));
|
DEBUG_PRINT(F(", speed ")); DEBUG_PRINT(ESP.getFlashChipSpeed()/1000000);DEBUG_PRINTLN(F("MHz."));
|
||||||
|
|
||||||
#else
|
#else
|
||||||
DEBUG_PRINT(F("esp8266 "));
|
DEBUG_PRINT(F("esp8266 @ ")); DEBUG_PRINT(ESP.getCpuFreqMHz()); DEBUG_PRINT(F("MHz.\nCore: "));
|
||||||
DEBUG_PRINTLN(ESP.getCoreVersion());
|
DEBUG_PRINTLN(ESP.getCoreVersion());
|
||||||
|
DEBUG_PRINT(F("FLASH: ")); DEBUG_PRINT((ESP.getFlashChipSize()/1024)/1024); DEBUG_PRINTLN(F(" MB"));
|
||||||
#endif
|
#endif
|
||||||
DEBUG_PRINT(F("heap ")); DEBUG_PRINTLN(ESP.getFreeHeap());
|
DEBUG_PRINT(F("heap ")); DEBUG_PRINTLN(ESP.getFreeHeap());
|
||||||
|
|
||||||
#if defined(ARDUINO_ARCH_ESP32) && defined(BOARD_HAS_PSRAM)
|
#if defined(ARDUINO_ARCH_ESP32)
|
||||||
/*
|
// BOARD_HAS_PSRAM also means that a compiler flag "-mfix-esp32-psram-cache-issue" was used and so PSRAM is safe to use on rev.1 ESP32
|
||||||
* The following code is obsolete as PinManager::isPinOK() will return false for reserved GPIO.
|
#if !defined(BOARD_HAS_PSRAM) && !(defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32C3))
|
||||||
* Additionally xml.cpp will inform UI about reserved GPIO.
|
if (psramFound() && ESP.getChipRevision() < 3) psramSafe = false;
|
||||||
*
|
if (!psramSafe) DEBUG_PRINTLN(F("Not using PSRAM."));
|
||||||
|
|
||||||
#if defined(CONFIG_IDF_TARGET_ESP32S3)
|
|
||||||
// S3: reserve GPIO 33-37 for "octal" PSRAM
|
|
||||||
managed_pin_type pins[] = { {33, true}, {34, true}, {35, true}, {36, true}, {37, true} };
|
|
||||||
pinManager.allocateMultiplePins(pins, sizeof(pins)/sizeof(managed_pin_type), PinOwner::SPI_RAM);
|
|
||||||
#elif defined(CONFIG_IDF_TARGET_ESP32S2)
|
|
||||||
// S2: reserve GPIO 26-32 for PSRAM (may fail due to isPinOk() but that will also prevent other allocation)
|
|
||||||
managed_pin_type pins[] = { {26, true}, {27, true}, {28, true}, {29, true}, {30, true}, {31, true}, {32, true} };
|
|
||||||
pinManager.allocateMultiplePins(pins, sizeof(pins)/sizeof(managed_pin_type), PinOwner::SPI_RAM);
|
|
||||||
#elif defined(CONFIG_IDF_TARGET_ESP32C3)
|
|
||||||
// C3: reserve GPIO 12-17 for PSRAM (may fail due to isPinOk() but that will also prevent other allocation)
|
|
||||||
managed_pin_type pins[] = { {12, true}, {13, true}, {14, true}, {15, true}, {16, true}, {17, true} };
|
|
||||||
pinManager.allocateMultiplePins(pins, sizeof(pins)/sizeof(managed_pin_type), PinOwner::SPI_RAM);
|
|
||||||
#else
|
|
||||||
// GPIO16/GPIO17 reserved for SPI RAM
|
|
||||||
managed_pin_type pins[] = { {16, true}, {17, true} };
|
|
||||||
pinManager.allocateMultiplePins(pins, sizeof(pins)/sizeof(managed_pin_type), PinOwner::SPI_RAM);
|
|
||||||
#endif
|
#endif
|
||||||
*/
|
pDoc = new PSRAMDynamicJsonDocument((psramSafe && psramFound() ? 2 : 1)*JSON_BUFFER_SIZE);
|
||||||
#if defined(BOARD_HAS_PSRAM) && defined(WLED_USE_PSRAM)
|
DEBUG_PRINT(F("JSON buffer allocated: ")); DEBUG_PRINTLN((psramSafe && psramFound() ? 2 : 1)*JSON_BUFFER_SIZE);
|
||||||
pDoc = new PSRAMDynamicJsonDocument(2*JSON_BUFFER_SIZE);
|
// if the above fails requestJsonBufferLock() will always return false preventing crashes
|
||||||
if (!pDoc) pDoc = new PSRAMDynamicJsonDocument(JSON_BUFFER_SIZE); // falback if double sized buffer could not be allocated
|
|
||||||
// if the above still fails requestJsonBufferLock() will always return false preventing crashes
|
|
||||||
if (psramFound()) {
|
if (psramFound()) {
|
||||||
DEBUG_PRINT(F("Total PSRAM: ")); DEBUG_PRINT(ESP.getPsramSize()/1024); DEBUG_PRINTLN("kB");
|
DEBUG_PRINT(F("Total PSRAM: ")); DEBUG_PRINT(ESP.getPsramSize()/1024); DEBUG_PRINTLN("kB");
|
||||||
DEBUG_PRINT(F("Free PSRAM : ")); DEBUG_PRINT(ESP.getFreePsram()/1024); DEBUG_PRINTLN("kB");
|
DEBUG_PRINT(F("Free PSRAM : ")); DEBUG_PRINT(ESP.getFreePsram()/1024); DEBUG_PRINTLN("kB");
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
if (!pDoc) pDoc = &gDoc; // just in case ... (it should be globally assigned)
|
|
||||||
DEBUG_PRINTLN(F("PSRAM not used."));
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
#if defined(ARDUINO_ESP32_PICO)
|
|
||||||
// special handling for PICO-D4: gpio16+17 are in use for onboard SPI FLASH (not PSRAM)
|
|
||||||
managed_pin_type pins[] = { {16, true}, {17, true} };
|
|
||||||
pinManager.allocateMultiplePins(pins, sizeof(pins)/sizeof(managed_pin_type), PinOwner::SPI_RAM);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//DEBUG_PRINT(F("LEDs inited. heap usage ~"));
|
|
||||||
//DEBUG_PRINTLN(heapPreAlloc - ESP.getFreeHeap());
|
|
||||||
|
|
||||||
#if defined(WLED_DEBUG) && !defined(WLED_DEBUG_HOST)
|
#if defined(WLED_DEBUG) && !defined(WLED_DEBUG_HOST)
|
||||||
pinManager.allocatePin(hardwareTX, true, PinOwner::DebugOut); // TX (GPIO1 on ESP32) reserved for debug output
|
pinManager.allocatePin(hardwareTX, true, PinOwner::DebugOut); // TX (GPIO1 on ESP32) reserved for debug output
|
||||||
|
@ -452,6 +423,7 @@ void WLED::setup()
|
||||||
|
|
||||||
DEBUG_PRINTLN(F("Reading config"));
|
DEBUG_PRINTLN(F("Reading config"));
|
||||||
deserializeConfigFromFS();
|
deserializeConfigFromFS();
|
||||||
|
DEBUG_PRINT(F("heap ")); DEBUG_PRINTLN(ESP.getFreeHeap());
|
||||||
|
|
||||||
#if defined(STATUSLED) && STATUSLED>=0
|
#if defined(STATUSLED) && STATUSLED>=0
|
||||||
if (!pinManager.isPinAllocated(STATUSLED)) {
|
if (!pinManager.isPinAllocated(STATUSLED)) {
|
||||||
|
@ -555,7 +527,7 @@ void WLED::setup()
|
||||||
void WLED::beginStrip()
|
void WLED::beginStrip()
|
||||||
{
|
{
|
||||||
// Initialize NeoPixel Strip and button
|
// Initialize NeoPixel Strip and button
|
||||||
strip.finalizeInit(); // busses created during deserializeConfig()
|
strip.finalizeInit(); // busses created during deserializeConfig() if config existed
|
||||||
strip.makeAutoSegments();
|
strip.makeAutoSegments();
|
||||||
strip.setBrightness(0);
|
strip.setBrightness(0);
|
||||||
strip.setShowCallback(handleOverlayDraw);
|
strip.setShowCallback(handleOverlayDraw);
|
||||||
|
|
|
@ -3,12 +3,12 @@
|
||||||
/*
|
/*
|
||||||
Main sketch, global variable declarations
|
Main sketch, global variable declarations
|
||||||
@title WLED project sketch
|
@title WLED project sketch
|
||||||
@version 0.15.0-b1
|
@version 0.15.0-b3
|
||||||
@author Christian Schwinne
|
@author Christian Schwinne
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// version code in format yymmddb (b = daily build)
|
// version code in format yymmddb (b = daily build)
|
||||||
#define VERSION 2403190
|
#define VERSION 2404120
|
||||||
|
|
||||||
//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
|
||||||
|
@ -158,15 +158,16 @@
|
||||||
// The following is a construct to enable code to compile without it.
|
// The following is a construct to enable code to compile without it.
|
||||||
// There is a code that will still not use PSRAM though:
|
// There is a code that will still not use PSRAM though:
|
||||||
// AsyncJsonResponse is a derived class that implements DynamicJsonDocument (AsyncJson-v6.h)
|
// AsyncJsonResponse is a derived class that implements DynamicJsonDocument (AsyncJson-v6.h)
|
||||||
#if defined(ARDUINO_ARCH_ESP32) && defined(BOARD_HAS_PSRAM) && defined(WLED_USE_PSRAM)
|
#if defined(ARDUINO_ARCH_ESP32)
|
||||||
|
extern bool psramSafe;
|
||||||
struct PSRAM_Allocator {
|
struct PSRAM_Allocator {
|
||||||
void* allocate(size_t size) {
|
void* allocate(size_t size) {
|
||||||
if (psramFound()) return ps_malloc(size); // use PSRAM if it exists
|
if (psramSafe && psramFound()) return ps_malloc(size); // use PSRAM if it exists
|
||||||
else return malloc(size); // fallback
|
else return malloc(size); // fallback
|
||||||
}
|
}
|
||||||
void* reallocate(void* ptr, size_t new_size) {
|
void* reallocate(void* ptr, size_t new_size) {
|
||||||
if (psramFound()) return ps_realloc(ptr, new_size); // use PSRAM if it exists
|
if (psramSafe && psramFound()) return ps_realloc(ptr, new_size); // use PSRAM if it exists
|
||||||
else return realloc(ptr, new_size); // fallback
|
else return realloc(ptr, new_size); // fallback
|
||||||
}
|
}
|
||||||
void deallocate(void* pointer) {
|
void deallocate(void* pointer) {
|
||||||
free(pointer);
|
free(pointer);
|
||||||
|
@ -348,6 +349,11 @@ WLED_GLOBAL bool useGlobalLedBuffer _INIT(true); // double buffering enabled on
|
||||||
#endif
|
#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
|
||||||
|
#ifdef WLED_USE_IC_CCT
|
||||||
|
WLED_GLOBAL bool cctICused _INIT(true); // CCT IC used (Athom 15W bulbs)
|
||||||
|
#else
|
||||||
|
WLED_GLOBAL bool cctICused _INIT(false); // CCT IC used (Athom 15W bulbs)
|
||||||
|
#endif
|
||||||
WLED_GLOBAL bool gammaCorrectCol _INIT(true); // use gamma correction on colors
|
WLED_GLOBAL bool gammaCorrectCol _INIT(true); // use gamma correction on colors
|
||||||
WLED_GLOBAL bool gammaCorrectBri _INIT(false); // use gamma correction on brightness
|
WLED_GLOBAL bool gammaCorrectBri _INIT(false); // use gamma correction on brightness
|
||||||
WLED_GLOBAL float gammaCorrectVal _INIT(2.8f); // gamma correction value
|
WLED_GLOBAL float gammaCorrectVal _INIT(2.8f); // gamma correction value
|
||||||
|
@ -692,7 +698,6 @@ WLED_GLOBAL uint16_t olen _INIT(0);
|
||||||
WLED_GLOBAL size_t fsBytesUsed _INIT(0);
|
WLED_GLOBAL size_t fsBytesUsed _INIT(0);
|
||||||
WLED_GLOBAL size_t fsBytesTotal _INIT(0);
|
WLED_GLOBAL size_t fsBytesTotal _INIT(0);
|
||||||
WLED_GLOBAL unsigned long presetsModifiedTime _INIT(0L);
|
WLED_GLOBAL unsigned long presetsModifiedTime _INIT(0L);
|
||||||
WLED_GLOBAL JsonDocument* fileDoc;
|
|
||||||
WLED_GLOBAL bool doCloseFile _INIT(false);
|
WLED_GLOBAL bool doCloseFile _INIT(false);
|
||||||
|
|
||||||
// presets
|
// presets
|
||||||
|
@ -706,6 +711,8 @@ WLED_GLOBAL byte optionType;
|
||||||
WLED_GLOBAL bool doSerializeConfig _INIT(false); // flag to initiate saving of config
|
WLED_GLOBAL bool doSerializeConfig _INIT(false); // flag to initiate saving of config
|
||||||
WLED_GLOBAL bool doReboot _INIT(false); // flag to initiate reboot from async handlers
|
WLED_GLOBAL bool doReboot _INIT(false); // flag to initiate reboot from async handlers
|
||||||
|
|
||||||
|
WLED_GLOBAL bool psramSafe _INIT(true); // is it safe to use PSRAM (on ESP32 rev.1; compiler fix used "-mfix-esp32-psram-cache-issue")
|
||||||
|
|
||||||
// status led
|
// status led
|
||||||
#if defined(STATUSLED)
|
#if defined(STATUSLED)
|
||||||
WLED_GLOBAL unsigned long ledStatusLastMillis _INIT(0);
|
WLED_GLOBAL unsigned long ledStatusLastMillis _INIT(0);
|
||||||
|
@ -781,7 +788,7 @@ WLED_GLOBAL int8_t spi_sclk _INIT(SPISCLKPIN);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// global ArduinoJson buffer
|
// global ArduinoJson buffer
|
||||||
#if defined(ARDUINO_ARCH_ESP32) && defined(BOARD_HAS_PSRAM) && defined(WLED_USE_PSRAM)
|
#if defined(ARDUINO_ARCH_ESP32)
|
||||||
WLED_GLOBAL JsonDocument *pDoc _INIT(nullptr);
|
WLED_GLOBAL JsonDocument *pDoc _INIT(nullptr);
|
||||||
#else
|
#else
|
||||||
WLED_GLOBAL StaticJsonDocument<JSON_BUFFER_SIZE> gDoc;
|
WLED_GLOBAL StaticJsonDocument<JSON_BUFFER_SIZE> gDoc;
|
||||||
|
|
|
@ -18,36 +18,6 @@ static const char s_unlock_ota [] PROGMEM = "Please unlock OTA in security setti
|
||||||
static const char s_unlock_cfg [] PROGMEM = "Please unlock settings using PIN code!";
|
static const char s_unlock_cfg [] PROGMEM = "Please unlock settings using PIN code!";
|
||||||
static const char s_notimplemented[] PROGMEM = "Not implemented";
|
static const char s_notimplemented[] PROGMEM = "Not implemented";
|
||||||
static const char s_accessdenied[] PROGMEM = "Access Denied";
|
static const char s_accessdenied[] PROGMEM = "Access Denied";
|
||||||
static const char s_javascript[] PROGMEM = "application/javascript";
|
|
||||||
static const char s_json[] = "application/json"; // AsyncJson-v6.h
|
|
||||||
static const char s_html[] PROGMEM = "text/html";
|
|
||||||
static const char s_plain[] = "text/plain"; // Espalexa.h
|
|
||||||
static const char s_css[] PROGMEM = "text/css";
|
|
||||||
static const char s_png[] PROGMEM = "image/png";
|
|
||||||
static const char s_gif[] PROGMEM = "image/gif";
|
|
||||||
static const char s_jpg[] PROGMEM = "image/jpeg";
|
|
||||||
static const char s_ico[] PROGMEM = "image/x-icon";
|
|
||||||
//static const char s_xml[] PROGMEM = "text/xml";
|
|
||||||
//static const char s_pdf[] PROGMEM = "application/x-pdf";
|
|
||||||
//static const char s_zip[] PROGMEM = "application/x-zip";
|
|
||||||
//static const char s_gz[] PROGMEM = "application/x-gzip";
|
|
||||||
|
|
||||||
String getFileContentType(String &filename) {
|
|
||||||
if (filename.endsWith(F(".htm"))) return FPSTR(s_html);
|
|
||||||
else if (filename.endsWith(F(".html"))) return FPSTR(s_html);
|
|
||||||
else if (filename.endsWith(F(".css"))) return FPSTR(s_css);
|
|
||||||
else if (filename.endsWith(F(".js"))) return FPSTR(s_javascript);
|
|
||||||
else if (filename.endsWith(F(".json"))) return s_json;
|
|
||||||
else if (filename.endsWith(F(".png"))) return FPSTR(s_png);
|
|
||||||
else if (filename.endsWith(F(".gif"))) return FPSTR(s_gif);
|
|
||||||
else if (filename.endsWith(F(".jpg"))) return FPSTR(s_jpg);
|
|
||||||
else if (filename.endsWith(F(".ico"))) return FPSTR(s_ico);
|
|
||||||
// else if (filename.endsWith(F(".xml"))) return FPSTR(s_xml);
|
|
||||||
// else if (filename.endsWith(F(".pdf"))) return FPSTR(s_pdf);
|
|
||||||
// else if (filename.endsWith(F(".zip"))) return FPSTR(s_zip);
|
|
||||||
// else if (filename.endsWith(F(".gz"))) return FPSTR(s_gz);
|
|
||||||
return s_plain;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Is this an IP?
|
//Is this an IP?
|
||||||
static bool isIp(String str) {
|
static bool isIp(String str) {
|
||||||
|
@ -183,7 +153,7 @@ static String msgProcessor(const String& var)
|
||||||
|
|
||||||
static void handleUpload(AsyncWebServerRequest *request, const String& filename, size_t index, uint8_t *data, size_t len, bool final) {
|
static void handleUpload(AsyncWebServerRequest *request, const String& filename, size_t index, uint8_t *data, size_t len, bool final) {
|
||||||
if (!correctPIN) {
|
if (!correctPIN) {
|
||||||
if (final) request->send(401, FPSTR(s_plain), FPSTR(s_unlock_cfg));
|
if (final) request->send(401, FPSTR(CONTENT_TYPE_PLAIN), FPSTR(s_unlock_cfg));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!index) {
|
if (!index) {
|
||||||
|
@ -204,10 +174,10 @@ static void handleUpload(AsyncWebServerRequest *request, const String& filename,
|
||||||
request->_tempFile.close();
|
request->_tempFile.close();
|
||||||
if (filename.indexOf(F("cfg.json")) >= 0) { // check for filename with or without slash
|
if (filename.indexOf(F("cfg.json")) >= 0) { // check for filename with or without slash
|
||||||
doReboot = true;
|
doReboot = true;
|
||||||
request->send(200, FPSTR(s_plain), F("Configuration restore successful.\nRebooting..."));
|
request->send(200, FPSTR(CONTENT_TYPE_PLAIN), F("Configuration restore successful.\nRebooting..."));
|
||||||
} else {
|
} else {
|
||||||
if (filename.indexOf(F("palette")) >= 0 && filename.indexOf(F(".json")) >= 0) strip.loadCustomPalettes();
|
if (filename.indexOf(F("palette")) >= 0 && filename.indexOf(F(".json")) >= 0) strip.loadCustomPalettes();
|
||||||
request->send(200, FPSTR(s_plain), F("File Uploaded!"));
|
request->send(200, FPSTR(CONTENT_TYPE_PLAIN), F("File Uploaded!"));
|
||||||
}
|
}
|
||||||
cacheInvalidate++;
|
cacheInvalidate++;
|
||||||
}
|
}
|
||||||
|
@ -259,24 +229,24 @@ void initServer()
|
||||||
|
|
||||||
#ifdef WLED_ENABLE_WEBSOCKETS
|
#ifdef WLED_ENABLE_WEBSOCKETS
|
||||||
#ifndef WLED_DISABLE_2D
|
#ifndef WLED_DISABLE_2D
|
||||||
server.on(SET_F("/liveview2D"), HTTP_GET, [](AsyncWebServerRequest *request) {
|
server.on(F("/liveview2D"), HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||||
handleStaticContent(request, "", 200, FPSTR(s_html), PAGE_liveviewws2D, PAGE_liveviewws2D_length);
|
handleStaticContent(request, "", 200, FPSTR(CONTENT_TYPE_HTML), PAGE_liveviewws2D, PAGE_liveviewws2D_length);
|
||||||
});
|
});
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
server.on(SET_F("/liveview"), HTTP_GET, [](AsyncWebServerRequest *request) {
|
server.on(F("/liveview"), HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||||
handleStaticContent(request, "", 200, FPSTR(s_html), PAGE_liveview, PAGE_liveview_length);
|
handleStaticContent(request, "", 200, FPSTR(CONTENT_TYPE_HTML), PAGE_liveview, PAGE_liveview_length);
|
||||||
});
|
});
|
||||||
|
|
||||||
//settings page
|
//settings page
|
||||||
server.on(SET_F("/settings"), HTTP_GET, [](AsyncWebServerRequest *request){
|
server.on(F("/settings"), HTTP_GET, [](AsyncWebServerRequest *request){
|
||||||
serveSettings(request);
|
serveSettings(request);
|
||||||
});
|
});
|
||||||
|
|
||||||
// "/settings/settings.js&p=x" request also handled by serveSettings()
|
// "/settings/settings.js&p=x" request also handled by serveSettings()
|
||||||
static const char _style_css[] PROGMEM = "/style.css";
|
static const char _style_css[] PROGMEM = "/style.css";
|
||||||
server.on(_style_css, HTTP_GET, [](AsyncWebServerRequest *request) {
|
server.on(_style_css, HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||||
handleStaticContent(request, FPSTR(_style_css), 200, FPSTR(s_css), PAGE_settingsCss, PAGE_settingsCss_length);
|
handleStaticContent(request, FPSTR(_style_css), 200, FPSTR(CONTENT_TYPE_CSS), PAGE_settingsCss, PAGE_settingsCss_length);
|
||||||
});
|
});
|
||||||
|
|
||||||
static const char _favicon_ico[] PROGMEM = "/favicon.ico";
|
static const char _favicon_ico[] PROGMEM = "/favicon.ico";
|
||||||
|
@ -287,28 +257,29 @@ void initServer()
|
||||||
static const char _skin_css[] PROGMEM = "/skin.css";
|
static const char _skin_css[] PROGMEM = "/skin.css";
|
||||||
server.on(_skin_css, HTTP_GET, [](AsyncWebServerRequest *request) {
|
server.on(_skin_css, HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||||
if (handleFileRead(request, FPSTR(_skin_css))) return;
|
if (handleFileRead(request, FPSTR(_skin_css))) return;
|
||||||
AsyncWebServerResponse *response = request->beginResponse(200, FPSTR(s_css));
|
AsyncWebServerResponse *response = request->beginResponse(200, FPSTR(CONTENT_TYPE_CSS));
|
||||||
request->send(response);
|
request->send(response);
|
||||||
});
|
});
|
||||||
|
|
||||||
server.on(SET_F("/welcome"), HTTP_GET, [](AsyncWebServerRequest *request){
|
server.on(F("/welcome"), HTTP_GET, [](AsyncWebServerRequest *request){
|
||||||
serveSettings(request);
|
serveSettings(request);
|
||||||
});
|
});
|
||||||
|
|
||||||
server.on(SET_F("/reset"), HTTP_GET, [](AsyncWebServerRequest *request){
|
server.on(F("/reset"), HTTP_GET, [](AsyncWebServerRequest *request){
|
||||||
serveMessage(request, 200,F("Rebooting now..."),F("Please wait ~10 seconds..."),129);
|
serveMessage(request, 200,F("Rebooting now..."),F("Please wait ~10 seconds..."),129);
|
||||||
doReboot = true;
|
doReboot = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
server.on(SET_F("/settings"), HTTP_POST, [](AsyncWebServerRequest *request){
|
server.on(F("/settings"), HTTP_POST, [](AsyncWebServerRequest *request){
|
||||||
serveSettings(request, true);
|
serveSettings(request, true);
|
||||||
});
|
});
|
||||||
|
|
||||||
server.on(SET_F("/json"), HTTP_GET, [](AsyncWebServerRequest *request){
|
const static char _json[] PROGMEM = "/json";
|
||||||
|
server.on(FPSTR(_json), HTTP_GET, [](AsyncWebServerRequest *request){
|
||||||
serveJson(request);
|
serveJson(request);
|
||||||
});
|
});
|
||||||
|
|
||||||
AsyncCallbackJsonWebHandler* handler = new AsyncCallbackJsonWebHandler(F("/json"), [](AsyncWebServerRequest *request) {
|
AsyncCallbackJsonWebHandler* handler = new AsyncCallbackJsonWebHandler(FPSTR(_json), [](AsyncWebServerRequest *request) {
|
||||||
bool verboseResponse = false;
|
bool verboseResponse = false;
|
||||||
bool isConfig = false;
|
bool isConfig = false;
|
||||||
|
|
||||||
|
@ -356,33 +327,33 @@ void initServer()
|
||||||
doSerializeConfig = true; //serializeConfig(); //Save new settings to FS
|
doSerializeConfig = true; //serializeConfig(); //Save new settings to FS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
request->send(200, s_json, F("{\"success\":true}"));
|
request->send(200, CONTENT_TYPE_JSON, F("{\"success\":true}"));
|
||||||
}, JSON_BUFFER_SIZE);
|
}, JSON_BUFFER_SIZE);
|
||||||
server.addHandler(handler);
|
server.addHandler(handler);
|
||||||
|
|
||||||
server.on(SET_F("/version"), HTTP_GET, [](AsyncWebServerRequest *request){
|
server.on(F("/version"), HTTP_GET, [](AsyncWebServerRequest *request){
|
||||||
request->send(200, FPSTR(s_plain), (String)VERSION);
|
request->send(200, FPSTR(CONTENT_TYPE_PLAIN), (String)VERSION);
|
||||||
});
|
});
|
||||||
|
|
||||||
server.on(SET_F("/uptime"), HTTP_GET, [](AsyncWebServerRequest *request){
|
server.on(F("/uptime"), HTTP_GET, [](AsyncWebServerRequest *request){
|
||||||
request->send(200, FPSTR(s_plain), (String)millis());
|
request->send(200, FPSTR(CONTENT_TYPE_PLAIN), (String)millis());
|
||||||
});
|
});
|
||||||
|
|
||||||
server.on(SET_F("/freeheap"), HTTP_GET, [](AsyncWebServerRequest *request){
|
server.on(F("/freeheap"), HTTP_GET, [](AsyncWebServerRequest *request){
|
||||||
request->send(200, FPSTR(s_plain), (String)ESP.getFreeHeap());
|
request->send(200, FPSTR(CONTENT_TYPE_PLAIN), (String)ESP.getFreeHeap());
|
||||||
});
|
});
|
||||||
|
|
||||||
#ifdef WLED_ENABLE_USERMOD_PAGE
|
#ifdef WLED_ENABLE_USERMOD_PAGE
|
||||||
server.on("/u", HTTP_GET, [](AsyncWebServerRequest *request) {
|
server.on("/u", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||||
handleStaticContent(request, "", 200, FPSTR(s_html), PAGE_usermod, PAGE_usermod_length);
|
handleStaticContent(request, "", 200, FPSTR(CONTENT_TYPE_HTML), PAGE_usermod, PAGE_usermod_length);
|
||||||
});
|
});
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
server.on(SET_F("/teapot"), HTTP_GET, [](AsyncWebServerRequest *request){
|
server.on(F("/teapot"), HTTP_GET, [](AsyncWebServerRequest *request){
|
||||||
serveMessage(request, 418, F("418. I'm a teapot."), F("(Tangible Embedded Advanced Project Of Twinkling)"), 254);
|
serveMessage(request, 418, F("418. I'm a teapot."), F("(Tangible Embedded Advanced Project Of Twinkling)"), 254);
|
||||||
});
|
});
|
||||||
|
|
||||||
server.on(SET_F("/upload"), HTTP_POST, [](AsyncWebServerRequest *request) {},
|
server.on(F("/upload"), HTTP_POST, [](AsyncWebServerRequest *request) {},
|
||||||
[](AsyncWebServerRequest *request, const String& filename, size_t index, uint8_t *data,
|
[](AsyncWebServerRequest *request, const String& filename, size_t index, uint8_t *data,
|
||||||
size_t len, bool final) {handleUpload(request, filename, index, data, len, final);}
|
size_t len, bool final) {handleUpload(request, filename, index, data, len, final);}
|
||||||
);
|
);
|
||||||
|
@ -453,7 +424,7 @@ void initServer()
|
||||||
|
|
||||||
#ifdef WLED_ENABLE_DMX
|
#ifdef WLED_ENABLE_DMX
|
||||||
server.on(SET_F("/dmxmap"), HTTP_GET, [](AsyncWebServerRequest *request){
|
server.on(SET_F("/dmxmap"), HTTP_GET, [](AsyncWebServerRequest *request){
|
||||||
request->send_P(200, FPSTR(s_html), PAGE_dmxmap , dmxProcessor);
|
request->send_P(200, FPSTR(CONTENT_TYPE_HTML), PAGE_dmxmap , dmxProcessor);
|
||||||
});
|
});
|
||||||
#else
|
#else
|
||||||
server.on(SET_F("/dmxmap"), HTTP_GET, [](AsyncWebServerRequest *request){
|
server.on(SET_F("/dmxmap"), HTTP_GET, [](AsyncWebServerRequest *request){
|
||||||
|
@ -464,7 +435,7 @@ void initServer()
|
||||||
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) {
|
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||||
if (captivePortal(request)) return;
|
if (captivePortal(request)) return;
|
||||||
if (!showWelcomePage || request->hasArg(F("sliders"))) {
|
if (!showWelcomePage || request->hasArg(F("sliders"))) {
|
||||||
handleStaticContent(request, F("/index.htm"), 200, FPSTR(s_html), PAGE_index, PAGE_index_L);
|
handleStaticContent(request, F("/index.htm"), 200, FPSTR(CONTENT_TYPE_HTML), PAGE_index, PAGE_index_L);
|
||||||
} else {
|
} else {
|
||||||
serveSettings(request);
|
serveSettings(request);
|
||||||
}
|
}
|
||||||
|
@ -473,20 +444,20 @@ void initServer()
|
||||||
#ifdef WLED_ENABLE_PIXART
|
#ifdef WLED_ENABLE_PIXART
|
||||||
static const char _pixart_htm[] PROGMEM = "/pixart.htm";
|
static const char _pixart_htm[] PROGMEM = "/pixart.htm";
|
||||||
server.on(_pixart_htm, HTTP_GET, [](AsyncWebServerRequest *request) {
|
server.on(_pixart_htm, HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||||
handleStaticContent(request, FPSTR(_pixart_htm), 200, FPSTR(s_html), PAGE_pixart, PAGE_pixart_L);
|
handleStaticContent(request, FPSTR(_pixart_htm), 200, FPSTR(CONTENT_TYPE_HTML), PAGE_pixart, PAGE_pixart_L);
|
||||||
});
|
});
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef WLED_DISABLE_PXMAGIC
|
#ifndef WLED_DISABLE_PXMAGIC
|
||||||
static const char _pxmagic_htm[] PROGMEM = "/pxmagic.htm";
|
static const char _pxmagic_htm[] PROGMEM = "/pxmagic.htm";
|
||||||
server.on(_pxmagic_htm, HTTP_GET, [](AsyncWebServerRequest *request) {
|
server.on(_pxmagic_htm, HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||||
handleStaticContent(request, FPSTR(_pxmagic_htm), 200, FPSTR(s_html), PAGE_pxmagic, PAGE_pxmagic_L);
|
handleStaticContent(request, FPSTR(_pxmagic_htm), 200, FPSTR(CONTENT_TYPE_HTML), PAGE_pxmagic, PAGE_pxmagic_L);
|
||||||
});
|
});
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const char _cpal_htm[] PROGMEM = "/cpal.htm";
|
static const char _cpal_htm[] PROGMEM = "/cpal.htm";
|
||||||
server.on(_cpal_htm, HTTP_GET, [](AsyncWebServerRequest *request) {
|
server.on(_cpal_htm, HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||||
handleStaticContent(request, FPSTR(_cpal_htm), 200, FPSTR(s_html), PAGE_cpal, PAGE_cpal_L);
|
handleStaticContent(request, FPSTR(_cpal_htm), 200, FPSTR(CONTENT_TYPE_HTML), PAGE_cpal, PAGE_cpal_L);
|
||||||
});
|
});
|
||||||
|
|
||||||
#ifdef WLED_ENABLE_WEBSOCKETS
|
#ifdef WLED_ENABLE_WEBSOCKETS
|
||||||
|
@ -511,7 +482,7 @@ void initServer()
|
||||||
#ifndef WLED_DISABLE_ALEXA
|
#ifndef WLED_DISABLE_ALEXA
|
||||||
if(espalexa.handleAlexaApiCall(request)) return;
|
if(espalexa.handleAlexaApiCall(request)) return;
|
||||||
#endif
|
#endif
|
||||||
handleStaticContent(request, request->url(), 404, FPSTR(s_html), PAGE_404, PAGE_404_length);
|
handleStaticContent(request, request->url(), 404, FPSTR(CONTENT_TYPE_HTML), PAGE_404, PAGE_404_length);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -522,7 +493,7 @@ void serveMessage(AsyncWebServerRequest* request, uint16_t code, const String& h
|
||||||
messageSub = subl;
|
messageSub = subl;
|
||||||
optionType = optionT;
|
optionType = optionT;
|
||||||
|
|
||||||
request->send_P(code, FPSTR(s_html), PAGE_msg, msgProcessor);
|
request->send_P(code, FPSTR(CONTENT_TYPE_HTML), PAGE_msg, msgProcessor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -530,7 +501,7 @@ void serveJsonError(AsyncWebServerRequest* request, uint16_t code, uint16_t erro
|
||||||
{
|
{
|
||||||
AsyncJsonResponse *response = new AsyncJsonResponse(64);
|
AsyncJsonResponse *response = new AsyncJsonResponse(64);
|
||||||
if (error < ERR_NOT_IMPL) response->addHeader(F("Retry-After"), F("1"));
|
if (error < ERR_NOT_IMPL) response->addHeader(F("Retry-After"), F("1"));
|
||||||
response->setContentType(s_json);
|
response->setContentType(CONTENT_TYPE_JSON);
|
||||||
response->setCode(code);
|
response->setCode(code);
|
||||||
JsonObject obj = response->getRoot();
|
JsonObject obj = response->getRoot();
|
||||||
obj[F("error")] = error;
|
obj[F("error")] = error;
|
||||||
|
@ -546,12 +517,12 @@ void serveSettingsJS(AsyncWebServerRequest* request)
|
||||||
byte subPage = request->arg(F("p")).toInt();
|
byte subPage = request->arg(F("p")).toInt();
|
||||||
if (subPage > 10) {
|
if (subPage > 10) {
|
||||||
strcpy_P(buf, PSTR("alert('Settings for this request are not implemented.');"));
|
strcpy_P(buf, PSTR("alert('Settings for this request are not implemented.');"));
|
||||||
request->send(501, FPSTR(s_javascript), buf);
|
request->send(501, FPSTR(CONTENT_TYPE_JAVASCRIPT), buf);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (subPage > 0 && !correctPIN && strlen(settingsPIN)>0) {
|
if (subPage > 0 && !correctPIN && strlen(settingsPIN)>0) {
|
||||||
strcpy_P(buf, PSTR("alert('PIN incorrect.');"));
|
strcpy_P(buf, PSTR("alert('PIN incorrect.');"));
|
||||||
request->send(401, FPSTR(s_javascript), buf);
|
request->send(401, FPSTR(CONTENT_TYPE_JAVASCRIPT), buf);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
strcat_P(buf,PSTR("function GetV(){var d=document;"));
|
strcat_P(buf,PSTR("function GetV(){var d=document;"));
|
||||||
|
@ -559,7 +530,7 @@ void serveSettingsJS(AsyncWebServerRequest* request)
|
||||||
strcat_P(buf,PSTR("}"));
|
strcat_P(buf,PSTR("}"));
|
||||||
|
|
||||||
AsyncWebServerResponse *response;
|
AsyncWebServerResponse *response;
|
||||||
response = request->beginResponse(200, FPSTR(s_javascript), buf);
|
response = request->beginResponse(200, FPSTR(CONTENT_TYPE_JAVASCRIPT), buf);
|
||||||
response->addHeader(F("Cache-Control"), F("no-store"));
|
response->addHeader(F("Cache-Control"), F("no-store"));
|
||||||
response->addHeader(F("Expires"), F("0"));
|
response->addHeader(F("Expires"), F("0"));
|
||||||
request->send(response);
|
request->send(response);
|
||||||
|
@ -640,7 +611,7 @@ void serveSettings(AsyncWebServerRequest* request, bool post) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int code = 200;
|
int code = 200;
|
||||||
String contentType = FPSTR(s_html);
|
String contentType = FPSTR(CONTENT_TYPE_HTML);
|
||||||
const uint8_t* content;
|
const uint8_t* content;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
|
@ -666,7 +637,7 @@ void serveSettings(AsyncWebServerRequest* request, bool post) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case SUBPAGE_PINREQ : content = PAGE_settings_pin; len = PAGE_settings_pin_length; code = 401; break;
|
case SUBPAGE_PINREQ : content = PAGE_settings_pin; len = PAGE_settings_pin_length; code = 401; break;
|
||||||
case SUBPAGE_CSS : content = PAGE_settingsCss; len = PAGE_settingsCss_length; contentType = FPSTR(s_css); break;
|
case SUBPAGE_CSS : content = PAGE_settingsCss; len = PAGE_settingsCss_length; contentType = FPSTR(CONTENT_TYPE_CSS); break;
|
||||||
case SUBPAGE_JS : serveSettingsJS(request); return;
|
case SUBPAGE_JS : serveSettingsJS(request); return;
|
||||||
case SUBPAGE_WELCOME : content = PAGE_welcome; len = PAGE_welcome_length; break;
|
case SUBPAGE_WELCOME : content = PAGE_welcome; len = PAGE_welcome_length; break;
|
||||||
default: content = PAGE_settings; len = PAGE_settings_length; break;
|
default: content = PAGE_settings; len = PAGE_settings_length; break;
|
||||||
|
|
|
@ -55,7 +55,7 @@ void wsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventTyp
|
||||||
} else {
|
} else {
|
||||||
verboseResponse = deserializeState(root);
|
verboseResponse = deserializeState(root);
|
||||||
}
|
}
|
||||||
releaseJSONBufferLock(); // will clean fileDoc
|
releaseJSONBufferLock();
|
||||||
|
|
||||||
if (!interfaceUpdateCallMode) { // individual client response only needed if no WS broadcast soon
|
if (!interfaceUpdateCallMode) { // individual client response only needed if no WS broadcast soon
|
||||||
if (verboseResponse) {
|
if (verboseResponse) {
|
||||||
|
@ -102,7 +102,6 @@ void wsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventTyp
|
||||||
void sendDataWs(AsyncWebSocketClient * client)
|
void sendDataWs(AsyncWebSocketClient * client)
|
||||||
{
|
{
|
||||||
if (!ws.count()) return;
|
if (!ws.count()) return;
|
||||||
AsyncWebSocketMessageBuffer * buffer;
|
|
||||||
|
|
||||||
if (!requestJSONBufferLock(12)) {
|
if (!requestJSONBufferLock(12)) {
|
||||||
if (client) {
|
if (client) {
|
||||||
|
@ -129,7 +128,7 @@ void sendDataWs(AsyncWebSocketClient * client)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
buffer = ws.makeBuffer(len); // will not allocate correct memory sometimes on ESP8266
|
AsyncWebSocketBuffer buffer(len);
|
||||||
#ifdef ESP8266
|
#ifdef ESP8266
|
||||||
size_t heap2 = ESP.getFreeHeap();
|
size_t heap2 = ESP.getFreeHeap();
|
||||||
DEBUG_PRINT(F("heap ")); DEBUG_PRINTLN(ESP.getFreeHeap());
|
DEBUG_PRINT(F("heap ")); DEBUG_PRINTLN(ESP.getFreeHeap());
|
||||||
|
@ -141,23 +140,18 @@ void sendDataWs(AsyncWebSocketClient * client)
|
||||||
DEBUG_PRINTLN(F("WS buffer allocation failed."));
|
DEBUG_PRINTLN(F("WS buffer allocation failed."));
|
||||||
ws.closeAll(1013); //code 1013 = temporary overload, try again later
|
ws.closeAll(1013); //code 1013 = temporary overload, try again later
|
||||||
ws.cleanupClients(0); //disconnect all clients to release memory
|
ws.cleanupClients(0); //disconnect all clients to release memory
|
||||||
ws._cleanBuffers();
|
|
||||||
return; //out of memory
|
return; //out of memory
|
||||||
}
|
}
|
||||||
|
serializeJson(*pDoc, (char *)buffer.data(), len);
|
||||||
buffer->lock();
|
|
||||||
serializeJson(*pDoc, (char *)buffer->get(), len);
|
|
||||||
|
|
||||||
DEBUG_PRINT(F("Sending WS data "));
|
DEBUG_PRINT(F("Sending WS data "));
|
||||||
if (client) {
|
if (client) {
|
||||||
client->text(buffer);
|
client->text(std::move(buffer));
|
||||||
DEBUG_PRINTLN(F("to a single client."));
|
DEBUG_PRINTLN(F("to a single client."));
|
||||||
} else {
|
} else {
|
||||||
ws.textAll(buffer);
|
ws.textAll(std::move(buffer));
|
||||||
DEBUG_PRINTLN(F("to multiple clients."));
|
DEBUG_PRINTLN(F("to multiple clients."));
|
||||||
}
|
}
|
||||||
buffer->unlock();
|
|
||||||
ws._cleanBuffers();
|
|
||||||
|
|
||||||
releaseJSONBufferLock();
|
releaseJSONBufferLock();
|
||||||
}
|
}
|
||||||
|
@ -187,11 +181,10 @@ bool sendLiveLedsWs(uint32_t wsClient)
|
||||||
#endif
|
#endif
|
||||||
size_t bufSize = pos + (used/n)*3;
|
size_t bufSize = pos + (used/n)*3;
|
||||||
|
|
||||||
AsyncWebSocketMessageBuffer * wsBuf = ws.makeBuffer(bufSize);
|
AsyncWebSocketBuffer wsBuf(bufSize);
|
||||||
if (!wsBuf) return false; //out of memory
|
if (!wsBuf) return false; //out of memory
|
||||||
uint8_t* buffer = wsBuf->get();
|
uint8_t* buffer = reinterpret_cast<uint8_t*>(wsBuf.data());
|
||||||
if (!buffer) return false; //out of memory
|
if (!buffer) return false; //out of memory
|
||||||
wsBuf->lock(); // protect buffer from being cleaned by another WS instance
|
|
||||||
buffer[0] = 'L';
|
buffer[0] = 'L';
|
||||||
buffer[1] = 1; //version
|
buffer[1] = 1; //version
|
||||||
|
|
||||||
|
@ -218,9 +211,7 @@ bool sendLiveLedsWs(uint32_t wsClient)
|
||||||
buffer[pos++] = scale8(qadd8(w, b), strip.getBrightness()); //B
|
buffer[pos++] = scale8(qadd8(w, b), strip.getBrightness()); //B
|
||||||
}
|
}
|
||||||
|
|
||||||
wsc->binary(wsBuf);
|
wsc->binary(std::move(wsBuf));
|
||||||
wsBuf->unlock(); // un-protect buffer
|
|
||||||
ws._cleanBuffers();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -145,10 +145,13 @@ void appendGPIOinfo() {
|
||||||
oappend(SET_F("d.rsvd=[22,23,24,25,26,27,28,29,30,31,32"));
|
oappend(SET_F("d.rsvd=[22,23,24,25,26,27,28,29,30,31,32"));
|
||||||
#elif defined(CONFIG_IDF_TARGET_ESP32S3)
|
#elif defined(CONFIG_IDF_TARGET_ESP32S3)
|
||||||
oappend(SET_F("d.rsvd=[19,20,22,23,24,25,26,27,28,29,30,31,32")); // includes 19+20 for USB OTG (JTAG)
|
oappend(SET_F("d.rsvd=[19,20,22,23,24,25,26,27,28,29,30,31,32")); // includes 19+20 for USB OTG (JTAG)
|
||||||
|
if (psramFound()) oappend(SET_F(",33,34,35,36,37")); // in use for "octal" PSRAM or "octal" FLASH -seems that octal PSRAM is very common on S3.
|
||||||
#elif defined(CONFIG_IDF_TARGET_ESP32C3)
|
#elif defined(CONFIG_IDF_TARGET_ESP32C3)
|
||||||
oappend(SET_F("d.rsvd=[11,12,13,14,15,16,17"));
|
oappend(SET_F("d.rsvd=[11,12,13,14,15,16,17"));
|
||||||
#elif defined(ESP32)
|
#elif defined(ESP32)
|
||||||
oappend(SET_F("d.rsvd=[6,7,8,9,10,11,24,28,29,30,31,37,38"));
|
oappend(SET_F("d.rsvd=[6,7,8,9,10,11,24,28,29,30,31,37,38"));
|
||||||
|
if (!pinManager.isPinOk(16,false)) oappend(SET_F(",16")); // covers PICO & WROVER
|
||||||
|
if (!pinManager.isPinOk(17,false)) oappend(SET_F(",17")); // covers PICO & WROVER
|
||||||
#else
|
#else
|
||||||
oappend(SET_F("d.rsvd=[6,7,8,9,10,11"));
|
oappend(SET_F("d.rsvd=[6,7,8,9,10,11"));
|
||||||
#endif
|
#endif
|
||||||
|
@ -163,14 +166,6 @@ void appendGPIOinfo() {
|
||||||
|
|
||||||
//Note: Using pin 3 (RX) disables Adalight / Serial JSON
|
//Note: Using pin 3 (RX) disables Adalight / Serial JSON
|
||||||
|
|
||||||
#if defined(ARDUINO_ARCH_ESP32) && defined(BOARD_HAS_PSRAM)
|
|
||||||
#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32S3) && !defined(CONFIG_IDF_TARGET_ESP32C3)
|
|
||||||
if (psramFound()) oappend(SET_F(",16,17")); // GPIO16 & GPIO17 reserved for SPI RAM on ESP32 (not on S2, S3 or C3)
|
|
||||||
#elif defined(CONFIG_IDF_TARGET_ESP32S3)
|
|
||||||
if (psramFound()) oappend(SET_F(",33,34,35,36,37")); // in use for "octal" PSRAM or "octal" FLASH -seems that octal PSRAM is very common on S3.
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef WLED_USE_ETHERNET
|
#ifdef WLED_USE_ETHERNET
|
||||||
if (ethernetType != WLED_ETH_NONE && ethernetType < WLED_NUM_ETH_TYPES) {
|
if (ethernetType != WLED_ETH_NONE && ethernetType < WLED_NUM_ETH_TYPES) {
|
||||||
for (uint8_t p=0; p<WLED_ETH_RSVD_PINS_COUNT; p++) { oappend(","); oappend(itoa(esp32_nonconfigurable_ethernet_pins[p].pin,nS,10)); }
|
for (uint8_t p=0; p<WLED_ETH_RSVD_PINS_COUNT; p++) { oappend(","); oappend(itoa(esp32_nonconfigurable_ethernet_pins[p].pin,nS,10)); }
|
||||||
|
@ -360,6 +355,7 @@ void getSettingsJS(byte subPage, char* dest)
|
||||||
|
|
||||||
sappend('c',SET_F("MS"),autoSegments);
|
sappend('c',SET_F("MS"),autoSegments);
|
||||||
sappend('c',SET_F("CCT"),correctWB);
|
sappend('c',SET_F("CCT"),correctWB);
|
||||||
|
sappend('c',SET_F("IC"),cctICused);
|
||||||
sappend('c',SET_F("CR"),cctFromRgb);
|
sappend('c',SET_F("CR"),cctFromRgb);
|
||||||
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());
|
||||||
|
|
Ładowanie…
Reference in New Issue