From 422e4e37a7d6bc0b0fd1c911ed6c59015846628e Mon Sep 17 00:00:00 2001 From: Henry Gabryjelski Date: Wed, 17 Nov 2021 10:49:13 -0800 Subject: [PATCH 01/16] Separate board name using two underscores --- platformio.ini | 41 ++++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/platformio.ini b/platformio.ini index c31fd239..66800fa8 100644 --- a/platformio.ini +++ b/platformio.ini @@ -17,16 +17,16 @@ [platformio] extra_configs = platformio_override.ini ; so users can easily override settings -default_envs = fastled_webserver, fib512_d1_mini, fib256_d1_mini, fib128_d1_mini, fib64_full_d1_mini, fib64_mini_d1_mini, fib32_d1_mini +default_envs = fastled_webserver__d1_mini, fib512__d1_mini, fib256__d1_mini, fib128__d1_mini, fib64_full__d1_mini, fib64_mini__d1_mini, fib32__d1_mini ; default_envs = fastled_webserver -; default_envs = fib512_d1_mini -; default_envs = fib256_d1_mini -; default_envs = fib128_d1_mini -; default_envs = fib64_full_d1_mini -; default_envs = fib64_mini_d1_mini -; default_envs = fib64_micro_d1_mini -; default_envs = fib64_nano_d1_mini -; default_envs = fib32_d1_mini +; default_envs = fib512__d1_mini +; default_envs = fib256__d1_mini +; default_envs = fib128__d1_mini +; default_envs = fib64_full__d1_mini +; default_envs = fib64_mini__d1_mini +; default_envs = fib64_micro__d1_mini +; default_envs = fib64_nano__d1_mini +; default_envs = fib32__d1_mini src_dir = ./esp8266-fastled-webserver/ data_dir = ./esp8266-fastled-webserver/data build_cache_dir = ~/.buildcache @@ -86,14 +86,13 @@ board_build.flash_mode = dout board_build.filesystem = littlefs monitor_speed = 115200 upload_speed = 921600 +extra_scripts = ${scripts_defaults.extra_scripts} lib_compat_mode = strict lib_deps = fastled/FastLED @ 3.4.0 https://github.com/arduino-libraries/NTPClient.git @ 3.2.0 https://github.com/tzapu/WiFiManager.git @ ^2.0.4-beta -extra_scripts = ${scripts_defaults.extra_scripts} - [esp8266] build_flags = -D ESP8266 @@ -113,7 +112,7 @@ build_flags = lib_deps = ${env.lib_deps} -[env:fastled_webserver] +[env:fastled_webserver__d1_mini] board = d1_mini platform = ${common.platform_fibonacci_default} platform_packages = ${common.platform_packages} @@ -123,7 +122,7 @@ build_flags = ${common.build_flags_esp8266} -D PRODUCT_DEFAULT -[env:fib512_d1_mini] +[env:fib512__d1_mini] board = d1_mini platform = ${common.platform_fibonacci_default} platform_packages = ${common.platform_packages} @@ -133,7 +132,7 @@ build_flags = ${common.build_flags_esp8266} -D PRODUCT_FIBONACCI512 -[env:fib256_d1_mini] +[env:fib256__d1_mini] board = d1_mini platform = ${common.platform_fibonacci_default} platform_packages = ${common.platform_packages} @@ -143,7 +142,7 @@ build_flags = ${common.build_flags_esp8266} -D PRODUCT_FIBONACCI256 -[env:fib128_d1_mini] +[env:fib128__d1_mini] board = d1_mini platform = ${common.platform_fibonacci_default} platform_packages = ${common.platform_packages} @@ -153,7 +152,7 @@ build_flags = ${common.build_flags_esp8266} -D PRODUCT_FIBONACCI128 -[env:fib64_full_d1_mini] +[env:fib64_full__d1_mini] board = d1_mini platform = ${common.platform_fibonacci_default} platform_packages = ${common.platform_packages} @@ -164,7 +163,7 @@ build_flags = -D PRODUCT_FIBONACCI64_FULL -[env:fib64_mini_d1_mini] +[env:fib64_mini__d1_mini] board = d1_mini platform = ${common.platform_fibonacci_default} platform_packages = ${common.platform_packages} @@ -182,7 +181,7 @@ build_flags = ; 256KB Flash and 32 KB RAM ; Support *is* possible, but would require ; factoring out all the WiFi functionality (at least). -[env:fib64_micro_d1_mini] +[env:fib64_micro__d1_mini] board = d1_mini platform = ${common.platform_fibonacci_default} platform_packages = ${common.platform_packages} @@ -199,7 +198,7 @@ build_flags = ; 256KB Flash and 32 KB RAM ; Support *is* possible, but would require ; factoring out all the WiFi functionality (at least). -[env:fib64_nano_d1_mini] +[env:fib64_nano__d1_mini] board = d1_mini platform = ${common.platform_fibonacci_default} platform_packages = ${common.platform_packages} @@ -209,7 +208,7 @@ build_flags = ${common.build_flags_esp8266} -D PRODUCT_FIBONACCI64_NANO -[env:fib32_d1_mini] +[env:fib32__d1_mini] board = d1_mini platform = ${common.platform_fibonacci_default} platform_packages = ${common.platform_packages} @@ -221,7 +220,7 @@ build_flags = ; NOT YET SUPPORTED ; ESP32 is a work-in-progress -[env:fib256_d1_mini32] +[env:fib256__d1_mini32] board = wemos_d1_mini32 platform = espressif32@2.0 platform_packages = ${common.platform_packages} From 68f7350acb6405eb34bfecaa8b63825d3d281097 Mon Sep 17 00:00:00 2001 From: Henry Gabryjelski Date: Sat, 20 Nov 2021 11:54:52 -0800 Subject: [PATCH 02/16] Simplify environment sections --- platformio.ini | 73 +++++++++++++++++--------------------------------- 1 file changed, 25 insertions(+), 48 deletions(-) diff --git a/platformio.ini b/platformio.ini index 66800fa8..53ac463e 100644 --- a/platformio.ini +++ b/platformio.ini @@ -70,7 +70,7 @@ arduino_core_develop = https://github.com/platformio/platform-espressif8266#deve arduino_core_git = https://github.com/platformio/platform-espressif8266#feature/stage ; Define the version to use based on the Arduino Core version... -platform_fibonacci_default = ${common.arduino_core_2_7_4} +platform_default = ${common.arduino_core_2_7_4} platform_packages = tasmota/framework-arduinoespressif8266 @ 3.20704.7 platformio/toolchain-xtensa @ ~2.40802.200502 platformio/tool-esptool @ ~1.413.0 @@ -112,63 +112,56 @@ build_flags = lib_deps = ${env.lib_deps} -[env:fastled_webserver__d1_mini] +[common__d1_mini] +platform = ${common.platform_default} +platform_packages = ${common.platform_packages} +lib_deps = ${esp8266.lib_deps} board = d1_mini -platform = ${common.platform_fibonacci_default} +board_build.ldscript = ${common.ldscript_4m1m} +build_unflags = ${common.build_unflags} + +[common__d1_mini32] +platform = espressif32@2.0 platform_packages = ${common.platform_packages} +lib_deps = ${esp32.lib_deps} +board = wemos_d1_mini32 board_build.ldscript = ${common.ldscript_4m1m} build_unflags = ${common.build_unflags} + + +[env:fastled_webserver__d1_mini] +extends = common__d1_mini build_flags = ${common.build_flags_esp8266} -D PRODUCT_DEFAULT [env:fib512__d1_mini] -board = d1_mini -platform = ${common.platform_fibonacci_default} -platform_packages = ${common.platform_packages} -board_build.ldscript = ${common.ldscript_4m1m} -build_unflags = ${common.build_unflags} +extends = common__d1_mini build_flags = ${common.build_flags_esp8266} -D PRODUCT_FIBONACCI512 [env:fib256__d1_mini] -board = d1_mini -platform = ${common.platform_fibonacci_default} -platform_packages = ${common.platform_packages} -board_build.ldscript = ${common.ldscript_4m1m} -build_unflags = ${common.build_unflags} +extends = common__d1_mini build_flags = ${common.build_flags_esp8266} -D PRODUCT_FIBONACCI256 [env:fib128__d1_mini] -board = d1_mini -platform = ${common.platform_fibonacci_default} -platform_packages = ${common.platform_packages} -board_build.ldscript = ${common.ldscript_4m1m} -build_unflags = ${common.build_unflags} +extends = common__d1_mini build_flags = ${common.build_flags_esp8266} -D PRODUCT_FIBONACCI128 [env:fib64_full__d1_mini] -board = d1_mini -platform = ${common.platform_fibonacci_default} -platform_packages = ${common.platform_packages} -board_build.ldscript = ${common.ldscript_4m1m} -build_unflags = ${common.build_unflags} +extends = common__d1_mini build_flags = ${common.build_flags_esp8266} -D PRODUCT_FIBONACCI64_FULL [env:fib64_mini__d1_mini] -board = d1_mini -platform = ${common.platform_fibonacci_default} -platform_packages = ${common.platform_packages} -board_build.ldscript = ${common.ldscript_4m1m} -build_unflags = ${common.build_unflags} +extends = common__d1_mini build_flags = ${common.build_flags_esp8266} -D PRODUCT_FIBONACCI64_MINI @@ -182,11 +175,7 @@ build_flags = ; Support *is* possible, but would require ; factoring out all the WiFi functionality (at least). [env:fib64_micro__d1_mini] -board = d1_mini -platform = ${common.platform_fibonacci_default} -platform_packages = ${common.platform_packages} -board_build.ldscript = ${common.ldscript_4m1m} -build_unflags = ${common.build_unflags} +extends = common__d1_mini build_flags = ${common.build_flags_esp8266} -D PRODUCT_FIBONACCI64_MICRO @@ -199,21 +188,13 @@ build_flags = ; Support *is* possible, but would require ; factoring out all the WiFi functionality (at least). [env:fib64_nano__d1_mini] -board = d1_mini -platform = ${common.platform_fibonacci_default} -platform_packages = ${common.platform_packages} -board_build.ldscript = ${common.ldscript_4m1m} -build_unflags = ${common.build_unflags} +extends = common__d1_mini build_flags = ${common.build_flags_esp8266} -D PRODUCT_FIBONACCI64_NANO [env:fib32__d1_mini] -board = d1_mini -platform = ${common.platform_fibonacci_default} -platform_packages = ${common.platform_packages} -board_build.ldscript = ${common.ldscript_4m1m} -build_unflags = ${common.build_unflags} +extends = common__d1_mini build_flags = ${common.build_flags_esp8266} -D PRODUCT_FIBONACCI32 @@ -221,11 +202,7 @@ build_flags = ; NOT YET SUPPORTED ; ESP32 is a work-in-progress [env:fib256__d1_mini32] -board = wemos_d1_mini32 -platform = espressif32@2.0 -platform_packages = ${common.platform_packages} -board_build.ldscript = ${common.ldscript_4m1m} -build_unflags = ${common.build_unflags} +extends = common__d1_mini32 build_flags = ${common.build_flags_esp32} -D PRODUCT_FIBONACCI256 From 939936e00d1df85ca2c22577b9444213cbb05e8b Mon Sep 17 00:00:00 2001 From: Henry Gabryjelski Date: Sat, 20 Nov 2021 11:56:26 -0800 Subject: [PATCH 03/16] FIX: ESP32 doesn't like `auto` references --- esp8266-fastled-webserver/Map.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/esp8266-fastled-webserver/Map.cpp b/esp8266-fastled-webserver/Map.cpp index da95218b..1a233371 100644 --- a/esp8266-fastled-webserver/Map.cpp +++ b/esp8266-fastled-webserver/Map.cpp @@ -59,7 +59,7 @@ const uint8_t coordsX[NUM_PIXELS] { 170, 178, 185, 191, 196, 199, 202, 202, 202, 200, 196, 191, 184, 175, 161, 132, 148, 166, 176, 183, 188, 190, 192, 191, 190, 186, 182, 176, 170, 162, 153, 125, 136, 145, 154, 161, 168, 173, 177, 180, 181, 181, 178, 174, 167, 155, 139, 157, 164, 169, 170, 170, 168, 165, 160, 154, 147, 139, 129, 119, 109, 82, 93, 104, 114, 124, 132, 140, 147, 152, 157, 159, 160, 159, 155, 145, 145, 150, 150, 149, 146, 141, 135, 127, 119, 110, 100, 90, 79, 68, 57, 45, 56, 66, 77, 87, 97, 107, 115, 123, 130, 135, 139, 142, 141, 136, 134, 134, 131, 126, 120, 113, 105, 96, 86, 76, 66, 56, 45, 35, 25, 18, 27, 37, 47, 57, 67, 77, 86, 95, 104, 112, 119, 124, 128, 129, 125, 120, 113, 105, 97, 88, 78, 69, 59, 50, 40, 31, 22, 14, 6, 0, 6, 12, 19, 27, 35, 44, 54, 63, 73, 82, 91, 101, 109, 118, 121, 108, 98, 88, 78, 69, 59, 50, 41, 33, 25, 18, 12, 7, 3, 6, 8, 11, 15, 20, 26, 33, 40, 48, 57, 67, 77, 87, 98, 111, 102, 89, 77, 67, 58, 49, 41, 34, 28, 23, 19, 16, 15, 14, 15, 26, 24, 23, 24, 26, 28, 33, 38, 44, 51, 60, 69, 80, 93, 111, 100, 85, 73, 64, 55, 49, 43, 39, 36, 34, 33, 34, 36, 39, 43, 58, 53, 49, 45, 44, 43, 44, 46, 50, 55, 61, 69, 79, 93, 116, 104, 87, 76, 68, 62, 58, 55, 54, 54, 55, 58, 62, 68, 74, 82, 108, 99, 90, 83, 77, 72, 68, 65, 64, 65, 67, 70, 76, 85, 97, 112, 94, 85, 80, 76, 75, 75, 77, 81, 85, 91, 98, 106, 115, 125, 153, 142, 131, 122, 113, 105, 99, 93, 89, 87, 85, 86, 89, 95, 106, 123, 105, 99, 96, 96, 98, 101, 106, 112, 119, 128, 137, 147, 157, 168, 180, 193, 182, 171, 161, 151, 141, 133, 125, 118, 113, 108, 106, 106, 108, 115, 116, 114, 115, 118, 123, 129, 137, 145, 154, 164, 174, 184, 195, 206, 216, 226, 216, 205, 195, 185, 175, 165, 156, 147, 139, 133, 127, 123, 121, 124, 127, 129, 134, 141, 148, 156, 165, 174, 184, 194, 204, 214, 224, 233, 242, 253, 246, 238, 229, 221, 211, 202, 192, 182, 173, 164, 155, 147, 140, 133, 134, 142, 151, 160, 169, 179, 188, 198, 207, 216, 225, 233, 241, 247, 253, 255, 251, 247, 241, 234, 227, 219, 210, 201, 192, 182, 173, 163, 153, 142, 134, 151, 163, 174, 184, 194, 203, 212, 220, 227, 233, 239, 243, 247, 249, 242, 242, 241, 238, 235, 230, 225, 218, 211, 203, 194, 184, 173, 161, 146, 155, 170, 182, 192, 201, 208, 215, 221, 226, 229, 231, 232, 232, 231, 228, 215, 219, 221, 223, 223, 221, 219, 215, 210, 204, 197, 188, 177, 164, 144, 154, 170, 182, 191, 198, 204, 208, 211, 212, 213, 212, 209, 205, 200, 194 }; const uint8_t coordsY[NUM_PIXELS] { 6, 14, 22, 31, 41, 50, 60, 70, 80, 89, 98, 106, 114, 120, 125, 128, 124, 116, 109, 101, 92, 82, 73, 63, 54, 44, 35, 27, 18, 11, 4, 0, 5, 10, 17, 24, 32, 40, 49, 59, 68, 78, 87, 97, 106, 116, 121, 106, 95, 85, 75, 65, 56, 47, 38, 31, 24, 17, 12, 7, 4, 10, 10, 13, 16, 20, 25, 31, 39, 46, 55, 64, 74, 85, 96, 111, 101, 87, 76, 65, 56, 48, 41, 34, 29, 25, 21, 20, 19, 19, 21, 33, 30, 29, 28, 29, 31, 34, 39, 45, 51, 59, 69, 79, 92, 111, 101, 85, 73, 64, 56, 50, 45, 41, 39, 38, 38, 40, 43, 47, 52, 68, 62, 56, 53, 50, 49, 49, 50, 53, 57, 63, 70, 80, 94, 119, 106, 89, 78, 70, 65, 61, 59, 59, 60, 62, 66, 71, 77, 84, 92, 119, 109, 100, 92, 85, 80, 75, 72, 70, 70, 71, 74, 79, 87, 99, 114, 97, 88, 83, 81, 80, 81, 84, 88, 94, 100, 108, 116, 126, 136, 163, 152, 142, 132, 123, 114, 107, 101, 96, 93, 91, 91, 93, 98, 108, 108, 102, 101, 101, 104, 108, 114, 120, 128, 137, 146, 157, 167, 178, 190, 203, 192, 181, 170, 160, 150, 141, 133, 126, 119, 115, 111, 110, 111, 118, 119, 118, 120, 124, 130, 136, 144, 153, 162, 172, 182, 193, 203, 214, 224, 232, 223, 213, 202, 192, 182, 172, 163, 154, 146, 139, 132, 128, 125, 126, 129, 133, 139, 146, 154, 162, 172, 181, 191, 201, 210, 220, 229, 238, 246, 255, 249, 242, 234, 225, 216, 207, 197, 188, 178, 169, 160, 151, 143, 136, 135, 145, 155, 164, 174, 183, 193, 202, 211, 220, 228, 236, 243, 249, 254, 253, 250, 246, 242, 236, 229, 222, 213, 205, 196, 186, 176, 166, 155, 143, 133, 153, 166, 177, 187, 196, 205, 214, 221, 228, 234, 238, 242, 245, 246, 246, 236, 237, 237, 236, 233, 229, 225, 219, 212, 204, 195, 186, 175, 162, 146, 156, 171, 182, 192, 201, 208, 214, 220, 223, 226, 228, 228, 227, 224, 221, 207, 211, 215, 217, 218, 218, 216, 213, 209, 203, 196, 187, 177, 164, 142, 153, 170, 181, 190, 196, 201, 205, 207, 208, 207, 205, 202, 197, 191, 184, 159, 168, 176, 182, 188, 192, 195, 197, 197, 196, 193, 189, 182, 173, 160, 146, 164, 173, 180, 184, 186, 186, 185, 183, 179, 174, 167, 160, 151, 142, 114, 125, 135, 144, 152, 159, 165, 170, 173, 175, 176, 174, 171, 164, 153, 136, 154, 161, 164, 165, 164, 162, 157, 152, 145, 138, 129, 119, 109, 98, 72, 83, 94, 105, 114, 124, 132, 139, 145, 150, 153, 155, 155, 152, 143, 142, 146, 146, 143, 139, 134, 127, 119, 110, 101, 91, 81, 70, 59, 48, 37, 48, 58, 69, 79, 89, 99, 108, 116, 123, 129, 134, 137, 138, 134, 132, 130, 126, 121, 114, 106, 98, 88, 79, 69, 59, 48, 38, 29, 19 }; const uint8_t angles[NUM_PIXELS] { 205, 208, 211, 215, 218, 221, 225, 228, 231, 235, 238, 242, 245, 248, 252, 255, 246, 243, 239, 236, 233, 229, 226, 223, 219, 216, 213, 209, 206, 203, 199, 190, 194, 197, 200, 204, 207, 211, 214, 217, 221, 224, 227, 231, 234, 237, 232, 229, 225, 222, 219, 215, 212, 208, 205, 202, 198, 195, 192, 188, 185, 176, 180, 183, 186, 190, 193, 196, 200, 203, 206, 210, 213, 216, 220, 223, 214, 211, 208, 204, 201, 198, 194, 191, 188, 184, 181, 177, 174, 171, 167, 162, 165, 169, 172, 175, 179, 182, 185, 189, 192, 196, 199, 202, 206, 209, 200, 197, 193, 190, 187, 183, 180, 177, 173, 170, 167, 163, 160, 157, 153, 148, 151, 154, 158, 161, 165, 168, 171, 175, 178, 181, 185, 188, 191, 195, 186, 183, 179, 176, 173, 169, 166, 162, 159, 156, 152, 149, 146, 142, 139, 130, 133, 137, 140, 144, 147, 150, 154, 157, 160, 164, 167, 170, 174, 177, 172, 168, 165, 162, 158, 155, 152, 148, 145, 141, 138, 135, 131, 128, 125, 116, 119, 123, 126, 129, 133, 136, 139, 143, 146, 149, 153, 156, 160, 163, 154, 151, 147, 144, 141, 137, 134, 131, 127, 124, 121, 117, 114, 110, 107, 102, 105, 108, 112, 115, 118, 122, 125, 129, 132, 135, 139, 142, 145, 149, 140, 137, 133, 130, 126, 123, 120, 116, 113, 110, 106, 103, 100, 96, 93, 87, 91, 94, 98, 101, 104, 108, 111, 114, 118, 121, 124, 128, 131, 134, 126, 122, 119, 116, 112, 109, 106, 102, 99, 95, 92, 89, 85, 82, 79, 70, 73, 77, 80, 83, 87, 90, 93, 97, 100, 103, 107, 110, 114, 117, 111, 108, 105, 101, 98, 95, 91, 88, 85, 81, 78, 74, 71, 68, 64, 56, 59, 62, 66, 69, 72, 76, 79, 82, 86, 89, 93, 96, 99, 103, 97, 94, 90, 87, 84, 80, 77, 74, 70, 67, 64, 60, 57, 54, 50, 47, 41, 45, 48, 51, 55, 58, 62, 65, 68, 72, 75, 78, 82, 85, 88, 80, 76, 73, 70, 66, 63, 59, 56, 53, 49, 46, 43, 39, 36, 33, 27, 31, 34, 37, 41, 44, 47, 51, 54, 57, 61, 64, 67, 71, 74, 65, 62, 59, 55, 52, 49, 45, 42, 39, 35, 32, 28, 25, 22, 18, 10, 13, 16, 20, 23, 26, 30, 33, 36, 40, 43, 47, 50, 53, 57, 51, 48, 44, 41, 38, 34, 31, 28, 24, 21, 18, 14, 11, 8, 4, 251, 254, 2, 5, 9, 12, 16, 19, 22, 26, 29, 32, 36, 39, 42, 37, 34, 30, 27, 24, 20, 17, 13, 10, 7, 3, 0, 252, 249, 245, 236, 240, 243, 247, 250, 253, 1, 5, 8, 11, 15, 18, 21, 25, 28, 19, 16, 13, 9, 6, 3, 255, 251, 248, 244, 241, 238, 234, 231, 228, 222, 226, 229, 232, 236, 239, 242, 246, 249, 252, 0, 4, 7, 11, 14, 5, 2, 254, 250, 247, 244, 240, 237, 234, 230, 227, 223, 220, 217, 213 }; - static const auto (&radiusProxy)[NUM_PIXELS] = physicalToFibonacci; + static const uint16_t (&radiusProxy)[NUM_PIXELS] = physicalToFibonacci; static const uint8_t RADII_SCALE_DIVISOR { 2 }; static const uint8_t RADII_SCALE_MULTIPLIER { 1 }; #elif defined(PRODUCT_FIBONACCI256) @@ -68,7 +68,7 @@ const uint8_t coordsX[NUM_PIXELS] { 133, 156, 165, 168, 165, 158, 147, 132, 114, 95, 76, 57, 41, 28, 19, 15, 17, 24, 37, 56, 123, 96, 73, 53, 38, 28, 24, 25, 31, 41, 55, 71, 89, 106, 122, 136, 146, 152, 152, 143, 138, 136, 128, 115, 101, 85, 70, 56, 44, 37, 33, 34, 41, 53, 69, 90, 114, 140, 167, 226, 204, 180, 154, 129, 106, 85, 67, 54, 46, 43, 44, 50, 60, 72, 86, 100, 113, 123, 128, 117, 104, 90, 78, 67, 59, 54, 54, 59, 68, 82, 100, 121, 143, 167, 191, 212, 231, 246, 255, 251, 251, 245, 233, 218, 199, 178, 156, 134, 114, 96, 82, 73, 67, 66, 70, 78, 89, 103, 111, 94, 84, 80, 81, 86, 96, 109, 126, 145, 165, 185, 204, 220, 233, 241, 244, 241, 232, 217, 179, 201, 217, 229, 235, 235, 230, 220, 207, 190, 172, 154, 136, 121, 108, 99, 95, 96, 104, 120, 110, 111, 118, 130, 144, 160, 176, 192, 206, 217, 224, 227, 224, 216, 202, 184, 162, 137, 110, 44, 68, 94, 120, 145, 168, 187, 202, 212, 216, 216, 212, 203, 191, 177, 162, 148, 135, 126, 122, 136, 147, 161, 174, 186, 197, 204, 206, 205, 198, 187, 172, 152, 130, 106, 81, 58, 36, 17, 0, 5, 15, 30, 49, 71, 93, 116, 138, 157, 173, 185, 192, 195, 193, 187, 178, 166, 152, 137, 149, 164, 175, 180, 182, 179, 171, 159, 143, 125, 105, 83, 63, 44, 28, 16, 9, 7, 12, 23 }; const uint8_t coordsY[NUM_PIXELS] { 126, 120, 109, 96, 82, 69, 57, 49, 45, 45, 50, 59, 74, 92, 114, 138, 163, 188, 211, 231, 255, 248, 235, 218, 198, 175, 152, 129, 107, 89, 74, 63, 57, 56, 59, 66, 76, 88, 102, 116, 103, 88, 77, 71, 68, 70, 77, 88, 103, 121, 141, 163, 184, 205, 222, 236, 245, 249, 247, 208, 224, 235, 241, 240, 234, 223, 209, 191, 172, 152, 132, 115, 101, 90, 84, 82, 86, 95, 114, 107, 98, 98, 103, 112, 126, 142, 159, 177, 195, 210, 222, 230, 233, 230, 223, 209, 191, 168, 142, 98, 125, 151, 174, 194, 209, 219, 223, 223, 218, 208, 195, 180, 164, 148, 134, 122, 114, 112, 123, 128, 138, 151, 165, 180, 193, 203, 211, 214, 212, 206, 194, 178, 158, 134, 109, 83, 58, 35, 11, 28, 48, 71, 95, 120, 142, 163, 179, 192, 200, 203, 202, 196, 187, 175, 162, 148, 136, 133, 152, 166, 177, 186, 190, 191, 187, 178, 165, 148, 128, 107, 84, 62, 41, 24, 11, 2, 0, 28, 16, 9, 8, 13, 23, 37, 55, 75, 96, 116, 135, 151, 164, 173, 177, 177, 172, 162, 146, 153, 161, 163, 160, 152, 139, 124, 106, 87, 69, 51, 36, 25, 18, 16, 20, 29, 44, 64, 133, 106, 81, 60, 44, 32, 26, 25, 29, 38, 50, 65, 82, 99, 115, 129, 140, 147, 148, 138, 134, 131, 122, 110, 95, 80, 65, 52, 42, 36, 34, 37, 45, 59, 77, 98, 123, 149, 176, 202 }; const uint8_t angles[NUM_PIXELS] { 0, 247, 238, 229, 220, 211, 203, 194, 185, 176, 167, 159, 150, 141, 132, 123, 115, 106, 97, 88, 65, 74, 83, 92, 100, 109, 118, 127, 136, 144, 153, 162, 171, 180, 188, 197, 206, 215, 224, 232, 209, 201, 192, 183, 174, 165, 157, 148, 139, 130, 121, 113, 104, 95, 86, 77, 69, 60, 51, 28, 37, 46, 54, 63, 72, 81, 90, 98, 107, 116, 125, 134, 142, 151, 160, 169, 178, 186, 195, 172, 163, 155, 146, 137, 128, 119, 111, 102, 93, 84, 75, 67, 58, 49, 40, 31, 23, 14, 5, 246, 255, 8, 17, 26, 35, 44, 52, 61, 70, 79, 88, 96, 105, 114, 123, 132, 140, 149, 135, 126, 117, 108, 100, 91, 82, 73, 64, 56, 47, 38, 29, 20, 12, 3, 250, 241, 232, 223, 209, 218, 227, 235, 244, 253, 6, 15, 24, 33, 41, 50, 59, 68, 77, 85, 94, 103, 112, 98, 89, 80, 71, 62, 54, 45, 36, 27, 18, 10, 1, 247, 239, 230, 221, 212, 203, 195, 186, 163, 172, 180, 189, 198, 207, 216, 224, 233, 242, 251, 4, 13, 22, 31, 39, 48, 57, 66, 75, 52, 43, 34, 25, 16, 8, 254, 245, 237, 228, 219, 210, 201, 193, 184, 175, 166, 157, 149, 126, 134, 143, 152, 161, 170, 178, 187, 196, 205, 214, 222, 231, 240, 249, 2, 11, 20, 28, 37, 14, 5, 252, 243, 235, 226, 217, 208, 199, 191, 182, 173, 164, 155, 147, 138, 129, 120, 111, 103 }; - static const auto (&radiusProxy)[NUM_PIXELS] = physicalToFibonacci; + static const uint8_t (&radiusProxy)[NUM_PIXELS] = physicalToFibonacci; static const uint8_t RADII_SCALE_DIVISOR { 1 }; static const uint8_t RADII_SCALE_MULTIPLIER { 1 }; #elif defined(PRODUCT_FIBONACCI128) @@ -77,7 +77,7 @@ const uint8_t coordsX[NUM_PIXELS] { 137, 170, 182, 186, 182, 172, 156, 135, 110, 83, 26, 49, 74, 99, 121, 141, 155, 164, 164, 151, 145, 141, 129, 112, 91, 69, 47, 27, 11, 0, 9, 11, 19, 33, 50, 70, 90, 108, 123, 130, 114, 96, 77, 58, 43, 32, 25, 25, 32, 45, 85, 65, 51, 43, 42, 47, 58, 74, 94, 105, 81, 68, 62, 63, 70, 84, 103, 127, 154, 218, 193, 167, 142, 119, 101, 89, 83, 84, 96, 118, 104, 106, 116, 132, 152, 175, 198, 221, 241, 255, 248, 236, 219, 199, 178, 158, 140, 126, 121, 140, 157, 176, 195, 213, 227, 237, 241, 239, 193, 210, 221, 225, 222, 214, 201, 184, 164, 142, 160, 181, 196, 204, 206, 202, 191, 174, 152, 125 }; const uint8_t coordsY[NUM_PIXELS] { 130, 121, 105, 86, 66, 47, 31, 19, 13, 13, 55, 39, 30, 28, 33, 43, 57, 75, 95, 115, 96, 75, 60, 50, 46, 49, 59, 74, 96, 122, 166, 139, 114, 93, 78, 69, 67, 72, 85, 112, 102, 90, 89, 96, 110, 129, 152, 177, 203, 227, 247, 228, 207, 184, 161, 140, 123, 112, 109, 126, 132, 146, 165, 185, 206, 225, 240, 251, 255, 224, 235, 240, 237, 229, 216, 199, 181, 161, 143, 139, 166, 186, 202, 215, 221, 222, 216, 204, 185, 115, 142, 166, 184, 197, 203, 202, 195, 181, 158, 167, 180, 182, 178, 166, 148, 126, 101, 74, 21, 42, 66, 91, 114, 134, 150, 159, 160, 147, 141, 137, 124, 106, 85, 63, 42, 24, 9, 0 }; const uint8_t angles[NUM_PIXELS] { 0, 247, 239, 230, 221, 212, 203, 194, 186, 177, 154, 163, 171, 180, 189, 198, 207, 216, 224, 233, 210, 201, 192, 184, 175, 166, 157, 148, 139, 131, 116, 125, 134, 143, 152, 160, 169, 178, 187, 196, 173, 164, 155, 146, 137, 129, 120, 111, 102, 93, 79, 88, 97, 105, 114, 123, 132, 141, 150, 135, 126, 118, 109, 100, 91, 82, 73, 65, 56, 33, 42, 50, 59, 68, 77, 86, 95, 103, 112, 98, 89, 80, 71, 63, 54, 45, 36, 27, 18, 252, 4, 13, 22, 31, 39, 48, 57, 66, 75, 52, 43, 34, 25, 16, 8, 255, 246, 237, 214, 223, 232, 241, 250, 2, 11, 20, 29, 37, 14, 5, 253, 244, 235, 226, 218, 209, 200, 191 }; - static const auto (&radiusProxy)[NUM_PIXELS] = physicalToFibonacci; + static const uint8_t (&radiusProxy)[NUM_PIXELS] = physicalToFibonacci; static const uint8_t RADII_SCALE_DIVISOR { 1 }; static const uint8_t RADII_SCALE_MULTIPLIER { 2 }; #elif defined(PRODUCT_FIBONACCI64_FULL) || defined(PRODUCT_FIBONACCI64_MINI) @@ -86,7 +86,7 @@ const uint8_t coordsX[NUM_PIXELS] { 140, 189, 208, 214, 208, 146, 168, 180, 180, 162, 152, 146, 129, 103, 72, 40, 70, 97, 120, 131, 107, 79, 50, 23, 0, 7, 23, 46, 76, 93, 57, 37, 28, 29, 87, 68, 59, 62, 80, 113, 91, 94, 109, 133, 202, 172, 145, 125, 117, 145, 170, 198, 227, 253, 255, 235, 210, 181, 148, 175, 207, 228, 240, 244 }; const uint8_t coordsY[NUM_PIXELS] { 128, 114, 91, 63, 34, 0, 21, 48, 76, 106, 78, 47, 25, 11, 5, 38, 35, 42, 61, 101, 87, 69, 68, 78, 98, 143, 118, 102, 98, 122, 131, 152, 179, 209, 255, 230, 202, 174, 148, 142, 181, 210, 235, 252, 235, 234, 224, 203, 170, 183, 201, 205, 198, 181, 134, 157, 171, 173, 153, 145, 138, 120, 93, 63 }; const uint8_t angles[NUM_PIXELS] { 0, 249, 241, 232, 223, 200, 208, 217, 226, 235, 212, 203, 194, 185, 176, 162, 171, 180, 188, 197, 174, 165, 156, 147, 139, 124, 133, 142, 151, 136, 128, 119, 110, 101, 78, 86, 95, 104, 113, 99, 90, 81, 72, 63, 40, 49, 58, 67, 75, 52, 43, 34, 25, 17, 2, 11, 20, 29, 38, 14, 6, 255, 246, 237 }; - static const auto (&radiusProxy)[NUM_PIXELS] = physicalToFibonacci; + static const uint8_t (&radiusProxy)[NUM_PIXELS] = physicalToFibonacci; static const uint8_t RADII_SCALE_DIVISOR { 1 }; static const uint8_t RADII_SCALE_MULTIPLIER { 4 }; #elif defined(PRODUCT_FIBONACCI32) @@ -95,7 +95,7 @@ const uint8_t coordsX[NUM_PIXELS] { 152, 224, 252, 210, 211, 184, 169, 161, 89, 121, 138, 102, 61, 19, 13, 57, 82, 29, 0, 36, 63, 111, 79, 83, 158, 129, 118, 160, 196, 255, 212, 163, 203, 250 }; const uint8_t coordsY[NUM_PIXELS] { 120, 101, 69, 7, 48, 90, 50, 7, 0, 27, 83, 62, 37, 35, 84, 78, 112, 125, 154, 185, 149, 140, 195, 236, 255, 226, 179, 198, 223, 181, 183, 156, 144, 135 }; const uint8_t angles[NUM_PIXELS] { 255, 246, 237, 214, 223, 232, 208, 199, 176, 185, 193, 170, 161, 152, 138, 147, 132, 123, 114, 100, 108, 94, 85, 76, 53, 62, 70, 47, 38, 15, 23, 32, 9, 0 }; - static const auto (&radiusProxy)[NUM_PIXELS] = physicalToFibonacci; + static const uint8_t (&radiusProxy)[NUM_PIXELS] = physicalToFibonacci; static const uint8_t RADII_SCALE_DIVISOR { 1 }; static const uint8_t RADII_SCALE_MULTIPLIER { 8 }; #elif defined(PRODUCT_KRAKEN64) @@ -104,7 +104,7 @@ const uint8_t angles[NUM_PIXELS] { 0, 249, 241, 232, 223, 200, 208, 217, 226, 235, 212, 203, 194, 185, 176, 162, 171, 180, 188, 197, 174, 165, 156, 147, 139, 124, 133, 142, 151, 136, 128, 119, 110, 101, 78, 86, 95, 104, 113, 99, 90, 81, 72, 63, 40, 49, 58, 67, 75, 52, 43, 34, 25, 17, 2, 11, 20, 29, 38, 14, 6, 255, 246, 237 }; const uint8_t body[NUM_PIXELS] { 0, 16, 32, 48, 64, 80, 96, 112, 128, 143, 159, 175, 191, 207, 223, 239, 255, 143, 159, 175, 191, 207, 223, 239, 255, 143, 159, 175, 191, 207, 223, 239, 255, 143, 159, 175, 191, 207, 223, 239, 143, 159, 175, 191, 207, 223, 239, 255, 143, 159, 175, 191, 207, 223, 239, 255, 143, 159, 175, 191, 207, 223, 239, 255 }; static_assert(NUM_PIXELS == ARRAY_SIZE2(body), ""); - static const auto (&radiusProxy)[NUM_PIXELS] = body; + static const uint8_t (&radiusProxy)[NUM_PIXELS] = body; static const uint8_t RADII_SCALE_DIVISOR { 1 }; // body[] values are already in range [0..255] static const uint8_t RADII_SCALE_MULTIPLIER { 1 }; // body[] values are already in range [0..255] // For reference purposes... @@ -139,7 +139,7 @@ 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }; - static const auto (&radiusProxy)[NUM_PIXELS] = radii; + static const uint8_t (&radiusProxy)[NUM_PIXELS] = radii; static const uint8_t RADII_SCALE_DIVISOR { 1 }; // radii[] values are already in range [0..255] static const uint8_t RADII_SCALE_MULTIPLIER { 1 }; // radii[] values are already in range [0..255] From 21520742d64becb999cbe5fd3b6d8f6e0d42b8fe Mon Sep 17 00:00:00 2001 From: Henry Gabryjelski Date: Sat, 20 Nov 2021 11:56:50 -0800 Subject: [PATCH 04/16] formatting change only --- .../include/configs/controller/controller_esp32.h | 10 +++++----- .../include/configs/controller/controller_esp8266.h | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/esp8266-fastled-webserver/include/configs/controller/controller_esp32.h b/esp8266-fastled-webserver/include/configs/controller/controller_esp32.h index 246ee964..b93b67bc 100644 --- a/esp8266-fastled-webserver/include/configs/controller/controller_esp32.h +++ b/esp8266-fastled-webserver/include/configs/controller/controller_esp32.h @@ -21,7 +21,9 @@ #define ESP8266_FASTLED_WEBSERVER_CONTROLLER_ESP32_H -static_assert(PARALLEL_OUTPUT_CHANNELS <= 4, "ESP32 only has support for four parallel outputs defined, can be updated to support 16 outputs"); +// Would need to define (and use) the additional DATA_PIN_x symbols, +// and update the corresponding code using those symbols. +static_assert(PARALLEL_OUTPUT_CHANNELS <= 4, "While ESP32 supporst 16 parallel outputs, currently only support four parallel outputs"); // TODO: consider using I2S (instead of RMT) on the ESP32: // @@ -29,13 +31,11 @@ static_assert(PARALLEL_OUTPUT_CHANNELS <= 4, "ESP32 only has support for four pa // // See https://github.com/FastLED/FastLED/issues/1220#issuecomment-822677011 -#define DATA_PIN - #if !defined(DATA_PIN) #if PARALLEL_OUTPUT_CHANNELS == 1 - #define DATA_PIN 18 // d1 mini32 (same physical location as D5 on the d1 mini) + #define DATA_PIN 18 // d1 mini32 (same physical location as D5 on the d1 mini) #else - #define DATA_PIN 23 // d1 mini32 (same physical location as D7 on the d1 mini) + #define DATA_PIN 23 // d1 mini32 (same physical location as D7 on the d1 mini) #endif #endif diff --git a/esp8266-fastled-webserver/include/configs/controller/controller_esp8266.h b/esp8266-fastled-webserver/include/configs/controller/controller_esp8266.h index 9ac16079..e8c62b0c 100644 --- a/esp8266-fastled-webserver/include/configs/controller/controller_esp8266.h +++ b/esp8266-fastled-webserver/include/configs/controller/controller_esp8266.h @@ -24,9 +24,9 @@ static_assert(PARALLEL_OUTPUT_CHANNELS <= 6, "ESP8266 only supports six parallel #if !defined(DATA_PIN) #if PARALLEL_OUTPUT_CHANNELS == 1 - #define DATA_PIN D5 // d1 mini + #define DATA_PIN D5 // d1 mini #else - #define DATA_PIN D7 // Fib512 uses different default for primary output pin + #define DATA_PIN D7 // Fib512 uses different default for primary output pin #endif #endif From a0824803f47d98d666785665bcc53c59eba2f4e0 Mon Sep 17 00:00:00 2001 From: Henry Gabryjelski Date: Sun, 21 Nov 2021 16:54:03 -0800 Subject: [PATCH 05/16] Use ArduinoJSON to reduce heap fragmentation Use a pre-allocated DynamicJsonDocument to more easily create the JSON structure. As a nice side effect, it also performs only two allocations: One for the DynamicJsonDocument, One for `result.reserve()` call. The old function had 28 lines of the form: `(String)json += "foo" + (String)bar() + ","` Each line creates three temporary String objects: (e.g., "foo", result from bar()), ","). It then appends "foo" + "bar" (often another allocation), then appends the trailing close-quote and comma (unlikely, but potentially another allocation). Finally, the first temporary variable (now "foo : bar,") is appended to the current final result string (28 allocations). --- README.md | 3 + esp8266-fastled-webserver/Info.cpp | 134 ++++++++++++++++++++++------- esp8266-fastled-webserver/common.h | 4 + platformio.ini | 8 +- 4 files changed, 115 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index 2864800d..0d864575 100644 --- a/README.md +++ b/README.md @@ -65,6 +65,9 @@ The app depends on the following libraries. They must either be downloaded from * [FastLED](https://github.com/FastLED/FastLED) * [IRremoteESP8266](https://github.com/sebastienwarin/IRremoteESP8266) * [Arduino WebSockets](https://github.com/Links2004/arduinoWebSockets) +* [Arduino JSON](https://arduinojson.org) +* [lolrol LittleFS](https://github.com/lorol/LITTLEFS) -- (integrated into ESP32 core v2, which is not used here yet) + Download the app code from GitHub using the green Clone or Download button from [the GitHub project main page](https://github.com/jasoncoon/esp8266-fastled-webserver) and click Download ZIP. Decompress the ZIP file in your Arduino sketch folder. diff --git a/esp8266-fastled-webserver/Info.cpp b/esp8266-fastled-webserver/Info.cpp index badab026..5d11991f 100644 --- a/esp8266-fastled-webserver/Info.cpp +++ b/esp8266-fastled-webserver/Info.cpp @@ -12,38 +12,110 @@ String WiFi_SSID(bool persistent) { return String(reinterpret_cast(tmp)); } +#if 1 // This is documentation, useful to calculate minimum JsonDocument buffer size for "info" +// +// Note the use of a raw string literals below. This makes it easier to copy/paste into: +// https://arduinojson.org/v6/assistant/ +// +// uint32 max: 4294967295 ... but assistant requires ARDUINOJSON_USE_LONG_LONG +// if any value is >= 2,000,000,000 (which is odd, as that is +// not related to any power-of-two value...) +// uint32 mux: 1999999999 ... maximum value assistant allows w/o ARDUINOJSON_USE_LONG_LONG +// uint16 max: 65535 +// uint8 max: 255 +// boolean: "false" +// SSID: "0123456789ABCDEF0123456789ABCDEF" (spec limit 32 octets) +// macAddress: "00:11:22:33:44:55" +// IPv4: "255.255.255.255" +// IPv6: "0011:2233:4455:6677:8899:AABB:CCDD:EEFF" +// hostname: spec limit 65 octets ... (67 chars) [65+2 for string quotes] +// +// +// Any decent compiler will throw away this unreferenced data during optimization. +// +// This pretty-printed version takes 1031 characters, minified version takes 890 characters. +static const char MaximumLengthJson[] { R"RAW_STRING( +{ + "millis" : 4294967295, + "vcc" : 65535, + "wiFiChipId" : "FF22CC44", + "flashChipId" : "FF22CC44", + "flashChipSize" : 4294967295, + "flashChipRealSize" : 4294967295, + "sdkVersion" : "2.2.2-SOME_RANDOM_STRING_LENGTH", + "coreVersion" : "2.3.4-SOME_RANDOM_STRING", + "bootVersion" : 255, + "cpuFreqMHz" : 255, + "freeHeap" : 4294967295, + "sketchSize" : 4294967295, + "freeSketchSpace" : 4294967295, + "resetReason" : "Software/System restart", + "isConnected" : false, + "wiFiSsidDefault" : "0123456789ABCDEF0123456789ABCDEF", + "wiFiSSID" : "0123456789ABCDEF0123456789ABCDEF", + "localIP" : "255.255.255.255", + "gatewayIP" : "255.255.255.255", + "subnetMask" : "255.255.255.255", + "dnsIP" : "255.255.255.255", + "hostname" : "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF", + "macAddress" : "00:11:22:33:44:55", + "autoConnect" : false, + "softAPSSID" : "0123456789ABCDEF0123456789ABCDEF", + "softAPIP" : "255.255.255.255", + "BSSID" : "00:11:22:33:44:55", + "softAPMacAddress" : "00:11:22:33:44:55" +} +)RAW_STRING" }; +static const char MinifiedMaximumLengthJson[] { R"RAW_STRING( +{"millis":2147483640,"vcc":65535,"wiFiChipId":"FF22CC44","flashChipId":"FF22CC44","flashChipSize":1073741823,"flashChipRealSize":1073741823,"sdkVersion":"2.2.2-SOME_RANDOM_STRING_LENGTH","coreVersion":"2.3.4-SOME_RANDOM_STRING","bootVersion":255,"cpuFreqMHz":255,"freeHeap":1073741823,"sketchSize":1073741823,"freeSketchSpace":1073741823,"resetReason":"Software/System restart","isConnected":false,"wiFiSsidDefault":"0123456789ABCDEF0123456789ABCDEF","wiFiSSID":"0123456789ABCDEF0123456789ABCDEF","localIP":"255.255.255.255","gatewayIP":"255.255.255.255","subnetMask":"255.255.255.255","dnsIP":"255.255.255.255","hostname":"0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF","macAddress":"00:11:22:33:44:55","autoConnect":false,"softAPSSID":"0123456789ABCDEF0123456789ABCDEF","softAPIP":"255.255.255.255","BSSID":"00:11:22:33:44:55","softAPMacAddress":"00:11:22:33:44:55"} +)RAW_STRING" }; +#endif +static const size_t infoJsonDocumentAllocationSize = 1024; + String getInfoJson() { - String json = "{"; - json += "\"millis\":" + (String)millis() + ","; - json += "\"vcc\":" + (String)ESP.getVcc() + ","; - json += "\"wiFiChipId\":\"" + String(WIFI_getChipId(), HEX) + "\","; - json += "\"flashChipId\":\"" + String(ESP.getFlashChipId(), HEX) + "\","; - json += "\"flashChipSize\":" + (String)ESP.getFlashChipSize() + ","; - json += "\"flashChipRealSize\":" + (String)ESP.getFlashChipRealSize() + ","; - json += "\"sdkVersion\":\"" + (String)system_get_sdk_version() + "\","; - json += "\"coreVersion\":\"" + (String)ESP.getCoreVersion() + "\","; - json += "\"bootVersion\":" + (String)system_get_boot_version() + ","; - json += "\"cpuFreqMHz\":" + (String)ESP.getCpuFreqMHz() + ","; - json += "\"freeHeap\":" + (String)ESP.getFreeHeap() + ","; - json += "\"sketchSize\":" + (String)ESP.getSketchSize() + ","; - json += "\"freeSketchSpace\":" + (String)ESP.getFreeSketchSpace() + ","; - json += "\"resetReason\":\"" + (String)ESP.getResetReason() + "\","; - json += "\"isConnected\":" + (WiFi.isConnected() ? String("true") : String("false")) + ","; - json += "\"wiFiSsidDefault\":\"" + (String)WiFi_SSID(true) + "\","; - json += "\"wiFiSSID\":\"" + (String)WiFi_SSID(false) + "\","; - json += "\"localIP\":\"" + WiFi.localIP().toString() + "\","; - json += "\"gatewayIP\":\"" + WiFi.gatewayIP().toString() + "\","; - json += "\"subnetMask\":\"" + WiFi.subnetMask().toString() + "\","; - json += "\"dnsIP\":\"" + WiFi.dnsIP().toString() + "\","; - json += "\"hostname\":\"" + WiFi.hostname() + "\","; - json += "\"macAddress\":\"" + WiFi.macAddress() + "\","; - json += "\"autoConnect\":" + (WiFi.getAutoConnect() ? String("true") : String("false")) + ","; - json += "\"softAPSSID\":\"" + WiFi.softAPSSID() + "\","; - json += "\"softAPIP\":\"" + WiFi.softAPIP().toString() + "\","; - json += "\"BSSID\":\"" + (String)WiFi.BSSIDstr() + "\","; - json += "\"softAPmacAddress\":\"" + (String)WiFi.softAPmacAddress() + "\""; - json += "}"; + DynamicJsonDocument jsonDoc(infoJsonDocumentAllocationSize); + jsonDoc[F("millis")] = millis(); // uint32_t (unsigned long) + jsonDoc[F("vcc")] = ESP.getVcc(); // uint16_t + jsonDoc[F("wiFiChipId")] = String(WIFI_getChipId(), HEX); // HEX(uint32_t) + jsonDoc[F("flashChipId")] = String(ESP.getFlashChipId(), HEX); // HEX(uint32_t) + jsonDoc[F("flashChipSize")] = ESP.getFlashChipSize(); // uint32_t + jsonDoc[F("flashChipRealSize")] = ESP.getFlashChipRealSize(); // uint32_t + jsonDoc[F("sdkVersion")] = system_get_sdk_version(); // String; example: "2.2.2-" + jsonDoc[F("coreVersion")] = ESP.getCoreVersion(); // String; example: "" + jsonDoc[F("bootVersion")] = system_get_boot_version(); // uint8_t + jsonDoc[F("cpuFreqMHz")] = ESP.getCpuFreqMHz(); // uint8_t + jsonDoc[F("freeHeap")] = ESP.getFreeHeap(); // uint32_t + jsonDoc[F("sketchSize")] = ESP.getSketchSize(); // uint32_t + jsonDoc[F("freeSketchSpace")] = ESP.getFreeSketchSpace(); // uint32_t + jsonDoc[F("resetReason")] = ESP.getResetReason(); // longest: "Software/System restart" + jsonDoc[F("isConnected")] = WiFi.isConnected(); // boolean + jsonDoc[F("wiFiSsidDefault")] = WiFi_SSID(true); // SSID + jsonDoc[F("wiFiSSID")] = WiFi_SSID(false); // SSID + jsonDoc[F("localIP")] = WiFi.localIP().toString(); // IPAddress (IPv4 only currently) + jsonDoc[F("gatewayIP")] = WiFi.gatewayIP().toString(); // IPAddress (IPv4 only currently) + jsonDoc[F("subnetMask")] = WiFi.subnetMask().toString(); // IPAddress (IPv4 only currently) + jsonDoc[F("dnsIP")] = WiFi.dnsIP().toString(); // IPAddress (IPv4 only currently) + jsonDoc[F("hostname")] = WiFi.hostname(); // hostname + jsonDoc[F("macAddress")] = WiFi.macAddress(); // macAddress + jsonDoc[F("autoConnect")] = WiFi.getAutoConnect(); // boolean + jsonDoc[F("softAPSSID")] = WiFi.softAPSSID(); // SSID + jsonDoc[F("softAPIP")] = WiFi.softAPIP().toString(); // IPv4 + jsonDoc[F("BSSID")] = WiFi.BSSIDstr(); // macAddress + jsonDoc[F("softAPMacAddress")] = WiFi.softAPmacAddress(); // macAddress + + // what to do if overflow the ArduinoJSON buffer? + if (jsonDoc.overflowed()) { + // NOTE: this should *NEVER* occur if the maximum string lengths were calculated properly + return String(F("{}")); + }; - return json; + // convert to String + String result; + // avoid heap fragmentation by pre-allocating 1023 bytes for result string. + // As of 2021-11-21, maximum 890 chars needed for minified result. + // As of 2021-11-21, maximum 1031 characters needed for prettified result. + result.reserve(1023); + serializeJson(jsonDoc, result); + return result; } diff --git a/esp8266-fastled-webserver/common.h b/esp8266-fastled-webserver/common.h index 0b0a3e1a..0fa0ff27 100644 --- a/esp8266-fastled-webserver/common.h +++ b/esp8266-fastled-webserver/common.h @@ -27,6 +27,10 @@ #include "config.h" #if 1 // external libraries + #define ARDUINOJSON_DECODE_UNICODE 0 // don't need to decode Unicode to UTF-8 + #define ARDUINOJSON_USE_LONG_LONG 1 // storing uint32_t requires this flag + #include "ArduinoJson.h" + #define FASTLED_INTERNAL // no other way to suppress build warnings #include FASTLED_USING_NAMESPACE diff --git a/platformio.ini b/platformio.ini index 53ac463e..3023c388 100644 --- a/platformio.ini +++ b/platformio.ini @@ -89,9 +89,11 @@ upload_speed = 921600 extra_scripts = ${scripts_defaults.extra_scripts} lib_compat_mode = strict lib_deps = - fastled/FastLED @ 3.4.0 - https://github.com/arduino-libraries/NTPClient.git @ 3.2.0 - https://github.com/tzapu/WiFiManager.git @ ^2.0.4-beta + fastled/FastLED @ 3.4.0 + bblanchon/ArduinoJson @ ^6.18.5 + lorol/LITTLEFS_esp32 @ ^1.0.6 + https://github.com/arduino-libraries/NTPClient.git @ 3.2.0 + https://github.com/tzapu/WiFiManager.git @ ^2.0.4-beta [esp8266] build_flags = From 64d66a1e0f439ea1a5dd6bd7d2c2dfe5dad31c0f Mon Sep 17 00:00:00 2001 From: Henry Gabryjelski Date: Wed, 24 Nov 2021 16:46:34 -0800 Subject: [PATCH 06/16] namespace and enum for field type The anonymous/unnamed namespace ensures no unintended pollution of the global namespace, and makes clear what the external API for this file contains. This makes it much easier to change the underlying implementation, as it's guaranteed that changes internal to the namespace won't break other source files. Use of a scoped enum for field type enables compiler warnings. Specifically, use of a `switch` statement with no `default` case will generate a compiler warning/error if missing any values. Tested to generate 100% identical JSON on Fib256. --- esp8266-fastled-webserver/Fields.cpp | 211 ++++++++++++++++----------- 1 file changed, 122 insertions(+), 89 deletions(-) diff --git a/esp8266-fastled-webserver/Fields.cpp b/esp8266-fastled-webserver/Fields.cpp index f20af72a..63cd4c95 100644 --- a/esp8266-fastled-webserver/Fields.cpp +++ b/esp8266-fastled-webserver/Fields.cpp @@ -17,18 +17,42 @@ */ #include "common.h" -const String NumberFieldType = "Number"; -const String BooleanFieldType = "Boolean"; -const String SelectFieldType = "Select"; -const String ColorFieldType = "Color"; -const String SectionFieldType = "Section"; -const String StringFieldType = "String"; -const String LabelFieldType = "Label"; - -uint8_t power = 1; -uint8_t brightness = brightnessMap[brightnessIndex]; +// only items outside the anonymous namespace can be exported. +// this keeps the global namespace cleaner, with no runtime/RAM costs. +inline namespace InternalFieldsDetails { + enum struct Field_t : uint8_t { + Number, + Boolean, + Select, + Color, + Section, + String, + Label, + }; + constexpr bool IsValid(const Field_t& t) { + return ( + (t == Field_t::String ) || + (t == Field_t::Label ) || + (t == Field_t::Color ) || + (t == Field_t::Boolean ) || + (t == Field_t::Number ) || + (t == Field_t::Section ) || + (t == Field_t::Select ) ); + } + const String ToString(const Field_t& t) { + return + (t == Field_t::String) ? F("String") : + (t == Field_t::Label) ? F("Label") : + (t == Field_t::Color) ? F("Color") : + (t == Field_t::Boolean) ? F("Boolean") : + (t == Field_t::Number) ? F("Number") : + (t == Field_t::Section) ? F("Section") : + (t == Field_t::Select) ? F("Select") : + F("Invalid") ; + } + inline namespace LegacyStringGettersAndSetters { // This just helps folding / hiding these functions //String setPower(String value) { // power = value.toInt(); @@ -106,20 +130,6 @@ String getClockBackgroundFade() { return String(clockBackgroundFade); } -void setShowClock(uint8_t value) -{ - showClock = value == 0 ? 0 : 1; - writeAndCommitSettings(); - broadcastInt("showClock", showClock); -} - -void setClockBackgroundFade(uint8_t value) -{ - clockBackgroundFade = value; - writeAndCommitSettings(); - broadcastInt("clockBackgroundFade", clockBackgroundFade); -} - String getSolidColor() { return String(solidColor.r) + "," + String(solidColor.g) + "," + String(solidColor.b); } @@ -299,19 +309,21 @@ String setSHueMax(String value) { return value; } + } -typedef String (*FieldSetter)(String); -typedef String (*FieldGetter)(); -struct Field { - String name; - String label; - String type; - uint8_t min; - uint8_t max; - FieldGetter getValue; - FieldGetter getOptions; - FieldSetter setValue; -}; + typedef String (*FieldSetter)(String); + typedef String (*FieldGetter)(); + typedef String (*FieldOptions)(); + struct Field { + const String name; + const String label; + Field_t type; + uint8_t min; + uint8_t max; + FieldGetter getValue; + FieldOptions getOptions; + FieldSetter setValue; + }; // passing array reference works fine, but need to make the function a template // to capture the array size... on the positive side, no need to pass `count` parameter @@ -341,6 +353,7 @@ String setFieldValue(String name, String value, const Field (&fields)[N]) { } return String(); } + template String getFieldsJson(const Field (&fields)[N]) { String json = "["; @@ -348,10 +361,13 @@ String getFieldsJson(const Field (&fields)[N]) { for (uint8_t i = 0; i < N; i++) { Field field = fields[i]; - json += "{\"name\":\"" + field.name + "\",\"label\":\"" + field.label + "\",\"type\":\"" + field.type + "\""; + json += "{\"name\":\"" + field.name + + "\",\"label\":\"" + field.label + + "\",\"type\":\"" + ToString(field.type) + + "\""; if(field.getValue) { - if (field.type == ColorFieldType || field.type == StringFieldType || field.type == LabelFieldType) { + if (field.type == Field_t::Color || field.type == Field_t::String || field.type == Field_t::Label) { json += ",\"value\":\"" + field.getValue() + "\""; } else { @@ -359,7 +375,7 @@ String getFieldsJson(const Field (&fields)[N]) { } } - if (field.type == NumberFieldType) { + if (field.type == Field_t::Number) { json += ",\"min\":" + String(field.min); json += ",\"max\":" + String(field.max); } @@ -385,81 +401,98 @@ String getFieldsJson(const Field (&fields)[N]) { // only items that use the 'getOptions': patterns and palettes // only items that support 'setValue': options used for pridePlayground const Field fields[] = { - {"name", "Name", LabelFieldType, 0, 0, getName, nullptr, nullptr}, - - {"power", "Power", BooleanFieldType, 0, 1, getPower, nullptr, nullptr}, - {"brightness", "Brightness", NumberFieldType, 1, 255, getBrightness, nullptr, nullptr}, - {"pattern", "Pattern", SelectFieldType, 0, patternCount, getPattern, getPatterns, nullptr}, - {"palette", "Palette", SelectFieldType, 0, paletteCount, getPalette, getPalettes, nullptr}, - {"speed", "Speed", NumberFieldType, 1, 255, getSpeed, nullptr, nullptr}, + {"name", "Name", Field_t::Label, 0, 0, getName, nullptr, nullptr}, + {"power", "Power", Field_t::Boolean, 0, 1, getPower, nullptr, nullptr}, + {"brightness", "Brightness", Field_t::Number, 1, 255, getBrightness, nullptr, nullptr}, + {"pattern", "Pattern", Field_t::Select, 0, patternCount, getPattern, getPatterns, nullptr}, + {"palette", "Palette", Field_t::Select, 0, paletteCount, getPalette, getPalettes, nullptr}, + {"speed", "Speed", Field_t::Number, 1, 255, getSpeed, nullptr, nullptr}, //-------------------------------------------------------------------------------------------------------- - {"autoplaySection", "Autoplay", SectionFieldType, 0, 0, nullptr, nullptr, nullptr}, - {"autoplay", "Autoplay", BooleanFieldType, 0, 1, getAutoplay, nullptr, nullptr}, - {"autoplayDuration", "Autoplay Duration", NumberFieldType, 0, 255, getAutoplayDuration, nullptr, nullptr}, + {"autoplaySection", "Autoplay", Field_t::Section, 0, 0, nullptr, nullptr, nullptr}, + {"autoplay", "Autoplay", Field_t::Boolean, 0, 1, getAutoplay, nullptr, nullptr}, + {"autoplayDuration", "Autoplay Duration", Field_t::Number, 0, 255, getAutoplayDuration, nullptr, nullptr}, //-------------------------------------------------------------------------------------------------------- - {"clock", "Clock", SectionFieldType, 0, 0, nullptr, nullptr, nullptr}, - {"showClock", "Show Clock", BooleanFieldType, 0, 1, getShowClock, nullptr, nullptr}, - {"clockBackgroundFade", "Background Fade", NumberFieldType, 0, 255, getClockBackgroundFade, nullptr, nullptr}, + {"clock", "Clock", Field_t::Section, 0, 0, nullptr, nullptr, nullptr}, + {"showClock", "Show Clock", Field_t::Boolean, 0, 1, getShowClock, nullptr, nullptr}, + {"clockBackgroundFade", "Background Fade", Field_t::Number, 0, 255, getClockBackgroundFade, nullptr, nullptr}, //-------------------------------------------------------------------------------------------------------- - {"solidColorSection", "Solid Color", SectionFieldType, 0, 0, nullptr, nullptr, nullptr}, - {"solidColor", "Color", ColorFieldType, 0, 255, getSolidColor, nullptr, nullptr}, + {"solidColorSection", "Solid Color", Field_t::Section, 0, 0, nullptr, nullptr, nullptr}, + {"solidColor", "Color", Field_t::Color, 0, 255, getSolidColor, nullptr, nullptr}, //-------------------------------------------------------------------------------------------------------- - {"fireSection", "Fire & Water", SectionFieldType, 0, 0, nullptr, nullptr, nullptr}, - {"cooling", "Cooling", NumberFieldType, 0, 255, getCooling, nullptr, nullptr}, - {"sparking", "Sparking", NumberFieldType, 0, 255, getSparking, nullptr, nullptr}, + {"fireSection", "Fire & Water", Field_t::Section, 0, 0, nullptr, nullptr, nullptr}, + {"cooling", "Cooling", Field_t::Number, 0, 255, getCooling, nullptr, nullptr}, + {"sparking", "Sparking", Field_t::Number, 0, 255, getSparking, nullptr, nullptr}, //-------------------------------------------------------------------------------------------------------- - {"twinklesSection", "Twinkles", SectionFieldType, 0, 0, nullptr, nullptr, nullptr}, - {"twinkleSpeed", "Twinkle Speed", NumberFieldType, 0, 8, getTwinkleSpeed, nullptr, nullptr}, - {"twinkleDensity", "Twinkle Density", NumberFieldType, 0, 8, getTwinkleDensity, nullptr, nullptr}, - {"coolLikeIncandescent", "Incandescent Cool", BooleanFieldType, 0, 1, getCoolLikeIncandescent, nullptr, nullptr}, - + {"twinklesSection", "Twinkles", Field_t::Section, 0, 0, nullptr, nullptr, nullptr}, + {"twinkleSpeed", "Twinkle Speed", Field_t::Number, 0, 8, getTwinkleSpeed, nullptr, nullptr}, + {"twinkleDensity", "Twinkle Density", Field_t::Number, 0, 8, getTwinkleDensity, nullptr, nullptr}, + {"coolLikeIncandescent", "Incandescent Cool", Field_t::Boolean, 0, 1, getCoolLikeIncandescent, nullptr, nullptr}, //-------------------------------------------------------------------------------------------------------- - {"prideSection", "Pride Playground", SectionFieldType, 0, 0, nullptr, nullptr, nullptr}, + {"prideSection", "Pride Playground", Field_t::Section, 0, 0, nullptr, nullptr, nullptr }, + {"saturationBpm", "Saturation BPM", Field_t::Number, 0, 255, getSaturationBpm, nullptr, setSaturationBpm }, + {"saturationMin", "Saturation Min", Field_t::Number, 0, 255, getSaturationMin, nullptr, setSaturationMin }, + {"saturationMax", "Saturation Max", Field_t::Number, 0, 255, getSaturationMax, nullptr, setSaturationMax }, + {"brightDepthBpm", "Brightness Depth BPM", Field_t::Number, 0, 255, getBrightDepthBpm, nullptr, setBrightDepthBpm }, + {"brightDepthMin", "Brightness Depth Min", Field_t::Number, 0, 255, getBrightDepthMin, nullptr, setBrightDepthMin }, + {"brightDepthMax", "Brightness Depth Max", Field_t::Number, 0, 255, getBrightDepthMax, nullptr, setBrightDepthMax }, + {"brightThetaIncBpm", "Bright Theta Inc BPM", Field_t::Number, 0, 255, getBrightThetaIncBpm, nullptr, setBrightThetaIncBpm}, + {"brightThetaIncMin", "Bright Theta Inc Min", Field_t::Number, 0, 255, getBrightThetaIncMin, nullptr, setBrightThetaIncMin}, + {"brightThetaIncMax", "Bright Theta Inc Max", Field_t::Number, 0, 255, getBrightThetaIncMax, nullptr, setBrightThetaIncMax}, + {"msMultiplierBpm", "Time Multiplier BPM", Field_t::Number, 0, 255, getMsMultiplierBpm, nullptr, setMsMultiplierBpm }, + {"msMultiplierMin", "Time Multiplier Min", Field_t::Number, 0, 255, getMsMultiplierMin, nullptr, setMsMultiplierMin }, + {"msMultiplierMax", "Time Multiplier Max", Field_t::Number, 0, 255, getMsMultiplierMax, nullptr, setMsMultiplierMax }, + {"hueIncBpm", "Hue Inc BPM", Field_t::Number, 0, 255, getHueIncBpm, nullptr, setHueIncBpm }, + {"hueIncMin", "Hue Inc Min", Field_t::Number, 0, 255, getHueIncMin, nullptr, setHueIncMin }, + {"hueIncMax", "Hue Inc Max", Field_t::Number, 0, 255, getHueIncMax, nullptr, setHueIncMax }, + {"sHueBpm", "S Hue BPM", Field_t::Number, 0, 255, getSHueBpm, nullptr, setSHueBpm }, + {"sHueMin", "S Hue Min", Field_t::Number, 0, 255, getSHueMin, nullptr, setSHueMin }, + {"sHueMax", "S Hue Max", Field_t::Number, 0, 255, getSHueMax, nullptr, setSHueMax }, +}; - {"saturationBpm", "Saturation BPM", NumberFieldType, 0, 255, getSaturationBpm, nullptr, setSaturationBpm}, - {"saturationMin", "Saturation Min", NumberFieldType, 0, 255, getSaturationMin, nullptr, setSaturationMin}, - {"saturationMax", "Saturation Max", NumberFieldType, 0, 255, getSaturationMax, nullptr, setSaturationMax}, +Field getField(String name) { + return getField(name, fields); +} - {"brightDepthBpm", "Brightness Depth BPM", NumberFieldType, 0, 255, getBrightDepthBpm, nullptr, setBrightDepthBpm}, - {"brightDepthMin", "Brightness Depth Min", NumberFieldType, 0, 255, getBrightDepthMin, nullptr, setBrightDepthMin}, - {"brightDepthMax", "Brightness Depth Max", NumberFieldType, 0, 255, getBrightDepthMax, nullptr, setBrightDepthMax}, +} // end inline anonymous namespace - {"brightThetaIncBpm", "Bright Theta Inc BPM", NumberFieldType, 0, 255, getBrightThetaIncBpm, nullptr, setBrightThetaIncBpm}, - {"brightThetaIncMin", "Bright Theta Inc Min", NumberFieldType, 0, 255, getBrightThetaIncMin, nullptr, setBrightThetaIncMin}, - {"brightThetaIncMax", "Bright Theta Inc Max", NumberFieldType, 0, 255, getBrightThetaIncMax, nullptr, setBrightThetaIncMax}, +// Everything else is exported from this file.... - {"msMultiplierBpm", "Time Multiplier BPM", NumberFieldType, 0, 255, getMsMultiplierBpm, nullptr, setMsMultiplierBpm}, - {"msMultiplierMin", "Time Multiplier Min", NumberFieldType, 0, 255, getMsMultiplierMin, nullptr, setMsMultiplierMin}, - {"msMultiplierMax", "Time Multiplier Max", NumberFieldType, 0, 255, getMsMultiplierMax, nullptr, setMsMultiplierMax}, +void setShowClock(uint8_t value) +{ + showClock = value == 0 ? 0 : 1; + writeAndCommitSettings(); + broadcastInt("showClock", showClock); +} +void setClockBackgroundFade(uint8_t value) +{ + clockBackgroundFade = value; + writeAndCommitSettings(); + broadcastInt("clockBackgroundFade", clockBackgroundFade); +} - {"hueIncBpm", "Hue Inc BPM", NumberFieldType, 0, 255, getHueIncBpm, nullptr, setHueIncBpm}, - {"hueIncMin", "Hue Inc Min", NumberFieldType, 0, 255, getHueIncMin, nullptr, setHueIncMin}, - {"hueIncMax", "Hue Inc Max", NumberFieldType, 0, 255, getHueIncMax, nullptr, setHueIncMax}, - {"sHueBpm", "S Hue BPM", NumberFieldType, 0, 255, getSHueBpm, nullptr, setSHueBpm}, - {"sHueMin", "S Hue Min", NumberFieldType, 0, 255, getSHueMin, nullptr, setSHueMin}, - {"sHueMax", "S Hue Max", NumberFieldType, 0, 255, getSHueMax, nullptr, setSHueMax}, -}; -const uint8_t fieldCount = ARRAY_SIZE2(fields); -// TODO: consider using ArduinoJSON ... pre-allocated buffer, simpler usage, tested code +// The following simplify getting JSON to allow dynamic interaction via webpage scripts +uint8_t power = 1; +uint8_t brightness = brightnessMap[brightnessIndex]; -Field getField(String name) { - return getField(name, fields); +// getFieldsJson() lists all the options that the user can set, and is used by (at least) +// the built-in webserver to generate UI to adjust these options. +String getFieldsJson() { + return getFieldsJson(fields); } + +// getFieldValue() is used to get a current value for the String getFieldValue(String name) { return getFieldValue(name, fields); } String setFieldValue(String name, String value) { return setFieldValue(name, value, fields); } -String getFieldsJson() { - return getFieldsJson(fields); -} From fc7cd56c357708c89db023690c372e45d96aae8f Mon Sep 17 00:00:00 2001 From: Henry Gabryjelski Date: Wed, 24 Nov 2021 16:56:37 -0800 Subject: [PATCH 07/16] Add and use JSON converter function for `Field` Confirmed identical JSON output for at least Fib256. --- esp8266-fastled-webserver/Fields.cpp | 96 +++++++++++++++++----------- 1 file changed, 58 insertions(+), 38 deletions(-) diff --git a/esp8266-fastled-webserver/Fields.cpp b/esp8266-fastled-webserver/Fields.cpp index 63cd4c95..eee8c3e0 100644 --- a/esp8266-fastled-webserver/Fields.cpp +++ b/esp8266-fastled-webserver/Fields.cpp @@ -325,6 +325,50 @@ String setSHueMax(String value) { FieldSetter setValue; }; + void convertToJson(const Field& field, JsonVariant dst) { + if (field.name.length() == 0) { + return; + } + if (!IsValid(field.type)) { + return; + } + + dst[F("name")] = field.name; + dst[F("label")] = field.label; + + dst[F("type")] = ToString(field.type); + // obj[F("readonly")] = (field.setValue == nullptr); + if (field.getValue != nullptr) { + switch (field.type) { + case Field_t::Color: // legacy ... sad but true ... + case Field_t::String: + case Field_t::Label: + dst[F("value")] = field.getValue(); + break; + + case Field_t::Boolean: + case Field_t::Number: + case Field_t::Section: + case Field_t::Select: + dst[F("value")] = field.getValue().toInt(); // TODO: fix double-conversion + break; + + // intentionally no default ... causes compilation warning if new enum types added w/o updating here + } + } + if (field.type == Field_t::Number) { + dst[F("min")] = field.min; + dst[F("max")] = field.max; + } + if (field.getOptions != nullptr) { + // TODO -- Update getOptions() functions (only two) to use ArduinoJSON directly + String tmp = field.getOptions(); + String options = "[" + tmp + "]"; + dst[F("options")] = serialized(options); + } + return; + } + // passing array reference works fine, but need to make the function a template // to capture the array size... on the positive side, no need to pass `count` parameter template @@ -356,45 +400,21 @@ String setFieldValue(String name, String value, const Field (&fields)[N]) { template String getFieldsJson(const Field (&fields)[N]) { - String json = "["; - - for (uint8_t i = 0; i < N; i++) { - Field field = fields[i]; - - json += "{\"name\":\"" + field.name - + "\",\"label\":\"" + field.label - + "\",\"type\":\"" + ToString(field.type) - + "\""; - - if(field.getValue) { - if (field.type == Field_t::Color || field.type == Field_t::String || field.type == Field_t::Label) { - json += ",\"value\":\"" + field.getValue() + "\""; - } - else { - json += ",\"value\":" + field.getValue(); - } - } - - if (field.type == Field_t::Number) { - json += ",\"min\":" + String(field.min); - json += ",\"max\":" + String(field.max); - } - - if (field.getOptions) { - json += ",\"options\":["; - json += field.getOptions(); - json += "]"; - } - - json += "}"; - - if (i < N - 1) - json += ","; + // As of 2021-11-23, https://arduinojson.org/v6/assistant/ reports minimum 8041 bytes required (for Fib256). + // This depends upon three things: + // 1. the number of fields + // 2. the number of palettes (and their names) + // 3. the number of patterns (and their names) + DynamicJsonDocument jsonDoc(8192); + JsonArray array = jsonDoc.to(); // document is an array of fields + for (const Field& field : fields) { + array.add(field); } - - json += "]"; - - return json; + // that's all ... just serialize the result to String (or anything else...) + String result; + result.reserve(6*1024); // ~4939 for Fib256 ... pre-allocation is a performance optimization + serializeJson(jsonDoc, result); + return result; } // name, label, type, min, max, getValue, getOptions, setValue From a5c21e2ed662e9bb5c54ef4d71ba98d3cc9bb14e Mon Sep 17 00:00:00 2001 From: Henry Gabryjelski Date: Wed, 24 Nov 2021 17:11:58 -0800 Subject: [PATCH 08/16] arduinoJson used for palettes and patterns Verified identical JSON output on at least Fib256. --- esp8266-fastled-webserver/Fields.cpp | 46 ++++++++++------------------ 1 file changed, 17 insertions(+), 29 deletions(-) diff --git a/esp8266-fastled-webserver/Fields.cpp b/esp8266-fastled-webserver/Fields.cpp index eee8c3e0..dc0e8c1e 100644 --- a/esp8266-fastled-webserver/Fields.cpp +++ b/esp8266-fastled-webserver/Fields.cpp @@ -86,34 +86,10 @@ String getPattern() { return String(currentPatternIndex); } -String getPatterns() { - String json = ""; - - for (uint8_t i = 0; i < patternCount; i++) { - json += "\"" + patterns[i].name + "\""; - if (i < patternCount - 1) - json += ","; - } - - return json; -} - String getPalette() { return String(currentPaletteIndex); } -String getPalettes() { - String json = ""; - - for (uint8_t i = 0; i < paletteCount; i++) { - json += "\"" + paletteNames[i] + "\""; - if (i < paletteCount - 1) - json += ","; - } - - return json; -} - String getAutoplay() { return String(autoplay); } @@ -311,9 +287,23 @@ String setSHueMax(String value) { } + inline namespace Options { + void getPatterns(JsonVariant dst) { + for (uint8_t i = 0; i < patternCount; i++) { + dst.add(patterns[i].name); + } + } + + void getPalettes(JsonVariant dst) { + for (uint8_t i = 0; i < paletteCount; i++) { + dst.add(paletteNames[i]); + } + } + } + typedef String (*FieldSetter)(String); typedef String (*FieldGetter)(); - typedef String (*FieldOptions)(); + typedef void (*FieldOptions)(JsonVariant); struct Field { const String name; const String label; @@ -361,10 +351,8 @@ String setSHueMax(String value) { dst[F("max")] = field.max; } if (field.getOptions != nullptr) { - // TODO -- Update getOptions() functions (only two) to use ArduinoJSON directly - String tmp = field.getOptions(); - String options = "[" + tmp + "]"; - dst[F("options")] = serialized(options); + JsonArray options = dst.createNestedArray(F("options")); + field.getOptions(options); } return; } From ca2a3073e540c2a1ca850cb221f2fdf2d4749e49 Mon Sep 17 00:00:00 2001 From: Henry Gabryjelski Date: Thu, 25 Nov 2021 13:52:24 -0800 Subject: [PATCH 09/16] Indentation only. --- esp8266-fastled-webserver/Fields.cpp | 408 +++++++++++++-------------- 1 file changed, 204 insertions(+), 204 deletions(-) diff --git a/esp8266-fastled-webserver/Fields.cpp b/esp8266-fastled-webserver/Fields.cpp index 36af4280..2e02ea3f 100644 --- a/esp8266-fastled-webserver/Fields.cpp +++ b/esp8266-fastled-webserver/Fields.cpp @@ -58,246 +58,246 @@ inline namespace InternalFieldsDetails { inline namespace LegacyStringGettersAndSetters { // This just helps folding / hiding these functions -//String setPower(String value) { -// power = value.toInt(); -// if(power < 0) power = 0; -// else if (power > 1) power = 1; -// return String(power); -//} - -String getPower() { - return String(power); -} + //String setPower(String value) { + // power = value.toInt(); + // if(power < 0) power = 0; + // else if (power > 1) power = 1; + // return String(power); + //} + + String getPower() { + return String(power); + } -//String setBrightness(String value) { -// brightness = value.toInt(); -// if(brightness < 0) brightness = 0; -// else if (brightness > 255) brightness = 255; -// return String(brightness); -//} - -// TODO: wrapper class for EEPROM settings, to help ensure clear understanding -// of all locations that can cause settings committed / EEPROM write. -// Also simplifies reading prior value before writing new value (extend EEPROM life) -// Also simplifies later extending CRC, transactional updates, bypassing "dead" -// areas of EEPROM, etc. - -String getBrightness() { - return String(brightness); -} + //String setBrightness(String value) { + // brightness = value.toInt(); + // if(brightness < 0) brightness = 0; + // else if (brightness > 255) brightness = 255; + // return String(brightness); + //} + + // TODO: wrapper class for EEPROM settings, to help ensure clear understanding + // of all locations that can cause settings committed / EEPROM write. + // Also simplifies reading prior value before writing new value (extend EEPROM life) + // Also simplifies later extending CRC, transactional updates, bypassing "dead" + // areas of EEPROM, etc. + + String getBrightness() { + return String(brightness); + } -String getPattern() { - return String(currentPatternIndex); -} + String getPattern() { + return String(currentPatternIndex); + } -String getPalette() { - return String(currentPaletteIndex); -} + String getPalette() { + return String(currentPaletteIndex); + } -String getAutoplay() { - return String(autoplay); -} + String getAutoplay() { + return String(autoplay); + } -String getAutoplayDuration() { - return String(autoplayDuration); -} + String getAutoplayDuration() { + return String(autoplayDuration); + } -String getShowClock() { - return String(showClock); -} + String getShowClock() { + return String(showClock); + } -String getClockBackgroundFade() { - return String(clockBackgroundFade); -} + String getClockBackgroundFade() { + return String(clockBackgroundFade); + } -String getSolidColor() { - return String(solidColor.r) + "," + String(solidColor.g) + "," + String(solidColor.b); -} + String getSolidColor() { + return String(solidColor.r) + "," + String(solidColor.g) + "," + String(solidColor.b); + } -String getCooling() { - return String(cooling); -} + String getCooling() { + return String(cooling); + } -String getSparking() { - return String(sparking); -} + String getSparking() { + return String(sparking); + } -String getSpeed() { - return String(speed); -} + String getSpeed() { + return String(speed); + } -String getTwinkleSpeed() { - return String(twinkleSpeed); -} + String getTwinkleSpeed() { + return String(twinkleSpeed); + } -String getTwinkleDensity() { - return String(twinkleDensity); -} + String getTwinkleDensity() { + return String(twinkleDensity); + } -String getCoolLikeIncandescent() { - return String(coolLikeIncandescent); -} + String getCoolLikeIncandescent() { + return String(coolLikeIncandescent); + } -String getName() { - return nameString; -} + String getName() { + return nameString; + } -String getUtcOffsetIndex() { - return String(utcOffsetIndex); -} + String getUtcOffsetIndex() { + return String(utcOffsetIndex); + } -String setUtcOffsetIndexString(String value) -{ - auto tmp = setUtcOffsetIndex(value.toInt()); - return String(tmp); -} + String setUtcOffsetIndexString(String value) + { + auto tmp = setUtcOffsetIndex(value.toInt()); + return String(tmp); + } -// Pride Playground fields + // Pride Playground fields -String getSaturationBpm() { - return String(saturationBpm); -} -String setSaturationBpm(String value) -{ - saturationBpm = value.toInt(); - return value; -} + String getSaturationBpm() { + return String(saturationBpm); + } + String setSaturationBpm(String value) + { + saturationBpm = value.toInt(); + return value; + } -String getSaturationMin() { - return String(saturationMin); -} -String setSaturationMin(String value) { - saturationMin = value.toInt(); - return value; -} + String getSaturationMin() { + return String(saturationMin); + } + String setSaturationMin(String value) { + saturationMin = value.toInt(); + return value; + } -String getSaturationMax() { - return String(saturationMax); -} -String setSaturationMax(String value) { - saturationMax = value.toInt(); - return value; -} + String getSaturationMax() { + return String(saturationMax); + } + String setSaturationMax(String value) { + saturationMax = value.toInt(); + return value; + } -String getBrightDepthBpm() { - return String(brightDepthBpm); -} -String setBrightDepthBpm(String value) { - brightDepthBpm = value.toInt(); - return value; -} + String getBrightDepthBpm() { + return String(brightDepthBpm); + } + String setBrightDepthBpm(String value) { + brightDepthBpm = value.toInt(); + return value; + } -String getBrightDepthMin() { - return String(brightDepthMin); -} -String setBrightDepthMin(String value) { - brightDepthMin = value.toInt(); - return value; -} + String getBrightDepthMin() { + return String(brightDepthMin); + } + String setBrightDepthMin(String value) { + brightDepthMin = value.toInt(); + return value; + } -String getBrightDepthMax() { - return String(brightDepthMax); -} -String setBrightDepthMax(String value) { - brightDepthMax = value.toInt(); - return value; -} + String getBrightDepthMax() { + return String(brightDepthMax); + } + String setBrightDepthMax(String value) { + brightDepthMax = value.toInt(); + return value; + } -String getBrightThetaIncBpm() { - return String(brightThetaIncBpm); -} -String setBrightThetaIncBpm(String value) { - brightThetaIncBpm = value.toInt(); - return value; -} + String getBrightThetaIncBpm() { + return String(brightThetaIncBpm); + } + String setBrightThetaIncBpm(String value) { + brightThetaIncBpm = value.toInt(); + return value; + } -String getBrightThetaIncMin() { - return String(brightThetaIncMin); -} -String setBrightThetaIncMin(String value) { - brightThetaIncMin = value.toInt(); - return value; -} + String getBrightThetaIncMin() { + return String(brightThetaIncMin); + } + String setBrightThetaIncMin(String value) { + brightThetaIncMin = value.toInt(); + return value; + } -String getBrightThetaIncMax() { - return String(brightThetaIncMax); -} -String setBrightThetaIncMax(String value) { - brightThetaIncMax = value.toInt(); - return value; -} + String getBrightThetaIncMax() { + return String(brightThetaIncMax); + } + String setBrightThetaIncMax(String value) { + brightThetaIncMax = value.toInt(); + return value; + } -String getMsMultiplierBpm() { - return String(msMultiplierBpm); -} -String setMsMultiplierBpm(String value) { - msMultiplierBpm = value.toInt(); - return value; -} + String getMsMultiplierBpm() { + return String(msMultiplierBpm); + } + String setMsMultiplierBpm(String value) { + msMultiplierBpm = value.toInt(); + return value; + } -String getMsMultiplierMin() { - return String(msMultiplierMin); -} -String setMsMultiplierMin(String value) { - msMultiplierMin = value.toInt(); - return value; -} + String getMsMultiplierMin() { + return String(msMultiplierMin); + } + String setMsMultiplierMin(String value) { + msMultiplierMin = value.toInt(); + return value; + } -String getMsMultiplierMax() { - return String(msMultiplierMax); -} -String setMsMultiplierMax(String value) { - msMultiplierMax = value.toInt(); - return value; -} + String getMsMultiplierMax() { + return String(msMultiplierMax); + } + String setMsMultiplierMax(String value) { + msMultiplierMax = value.toInt(); + return value; + } -String getHueIncBpm() { - return String(hueIncBpm); -} -String setHueIncBpm(String value) { - hueIncBpm = value.toInt(); - return value; -} + String getHueIncBpm() { + return String(hueIncBpm); + } + String setHueIncBpm(String value) { + hueIncBpm = value.toInt(); + return value; + } -String getHueIncMin() { - return String(hueIncMin); -} -String setHueIncMin(String value) { - hueIncMin = value.toInt(); - return value; -} + String getHueIncMin() { + return String(hueIncMin); + } + String setHueIncMin(String value) { + hueIncMin = value.toInt(); + return value; + } -String getHueIncMax() { - return String(hueIncMax); -} -String setHueIncMax(String value) { - hueIncMax = value.toInt(); - return value; -} + String getHueIncMax() { + return String(hueIncMax); + } + String setHueIncMax(String value) { + hueIncMax = value.toInt(); + return value; + } -String getSHueBpm() { - return String(sHueBpm); -} -String setSHueBpm(String value) { - sHueBpm = value.toInt(); - return value; -} + String getSHueBpm() { + return String(sHueBpm); + } + String setSHueBpm(String value) { + sHueBpm = value.toInt(); + return value; + } -String getSHueMin() { - return String(sHueMin); -} -String setSHueMin(String value) { - sHueMin = value.toInt(); - return value; -} + String getSHueMin() { + return String(sHueMin); + } + String setSHueMin(String value) { + sHueMin = value.toInt(); + return value; + } -String getSHueMax() { - return String(sHueMax); -} -String setSHueMax(String value) { - sHueMax = value.toInt(); - return value; -} + String getSHueMax() { + return String(sHueMax); + } + String setSHueMax(String value) { + sHueMax = value.toInt(); + return value; + } } From a18e9504ff487e5e311f5cf5c429b5ae7b85cf1a Mon Sep 17 00:00:00 2001 From: Henry Gabryjelski Date: Thu, 25 Nov 2021 13:53:06 -0800 Subject: [PATCH 10/16] More indentation --- esp8266-fastled-webserver/Fields.cpp | 206 +++++++++++++-------------- 1 file changed, 103 insertions(+), 103 deletions(-) diff --git a/esp8266-fastled-webserver/Fields.cpp b/esp8266-fastled-webserver/Fields.cpp index 2e02ea3f..c5e19893 100644 --- a/esp8266-fastled-webserver/Fields.cpp +++ b/esp8266-fastled-webserver/Fields.cpp @@ -372,116 +372,116 @@ inline namespace InternalFieldsDetails { return; } -// passing array reference works fine, but need to make the function a template -// to capture the array size... on the positive side, no need to pass `count` parameter -template -Field getField(String name, const Field (&fields)[N]) { - for (uint8_t i = 0; i < N; i++) { - Field field = fields[i]; - if (field.name == name) { - return field; + // passing array reference works fine, but need to make the function a template + // to capture the array size... on the positive side, no need to pass `count` parameter + template + Field getField(String name, const Field (&fields)[N]) { + for (uint8_t i = 0; i < N; i++) { + Field field = fields[i]; + if (field.name == name) { + return field; + } } + return Field(); } - return Field(); -} -template -String getFieldValue(String name, const Field (&fields)[N]) { - Field field = getField(name, fields); - if (field.getValue) { - return field.getValue(); + template + String getFieldValue(String name, const Field (&fields)[N]) { + Field field = getField(name, fields); + if (field.getValue) { + return field.getValue(); + } + return String(); } - return String(); -} -template -String setFieldValue(String name, String value, const Field (&fields)[N]) { - Field field = getField(name, fields); - if (field.setValue) { - return field.setValue(value); + template + String setFieldValue(String name, String value, const Field (&fields)[N]) { + Field field = getField(name, fields); + if (field.setValue) { + return field.setValue(value); + } + return String(); } - return String(); -} -template -String getFieldsJson(const Field (&fields)[N]) { - // As of 2021-11-23, https://arduinojson.org/v6/assistant/ reports minimum 8041 bytes required (for Fib256). - // This depends upon three things: - // 1. the number of fields - // 2. the number of palettes (and their names) - // 3. the number of patterns (and their names) - DynamicJsonDocument jsonDoc(8192); - JsonArray array = jsonDoc.to(); // document is an array of fields - for (const Field& field : fields) { - array.add(field); + template + String getFieldsJson(const Field (&fields)[N]) { + // As of 2021-11-23, https://arduinojson.org/v6/assistant/ reports minimum 8041 bytes required (for Fib256). + // This depends upon three things: + // 1. the number of fields + // 2. the number of palettes (and their names) + // 3. the number of patterns (and their names) + DynamicJsonDocument jsonDoc(8192); + JsonArray array = jsonDoc.to(); // document is an array of fields + for (const Field& field : fields) { + array.add(field); + } + // that's all ... just serialize the result to String (or anything else...) + String result; + result.reserve(6*1024); // ~4939 for Fib256 ... pre-allocation is a performance optimization + serializeJson(jsonDoc, result); + return result; } - // that's all ... just serialize the result to String (or anything else...) - String result; - result.reserve(6*1024); // ~4939 for Fib256 ... pre-allocation is a performance optimization - serializeJson(jsonDoc, result); - return result; -} -// name, label, type, min, max, getValue, getOptions, setValue -// only items that use the 'getOptions': patterns and palettes -// only items that support 'setValue': options used for pridePlayground -const Field fields[] = { - {"name", "Name", Field_t::Label, 0, 0, getName, nullptr, nullptr}, - {"power", "Power", Field_t::Boolean, 0, 1, getPower, nullptr, nullptr}, - {"brightness", "Brightness", Field_t::Number, 1, 255, getBrightness, nullptr, nullptr}, - {"pattern", "Pattern", Field_t::Select, 0, patternCount, getPattern, getPatterns, nullptr}, - {"palette", "Palette", Field_t::Select, 0, paletteCount, getPalette, getPalettes, nullptr}, - {"speed", "Speed", Field_t::Number, 1, 255, getSpeed, nullptr, nullptr}, - - //-------------------------------------------------------------------------------------------------------- - {"autoplaySection", "Autoplay", Field_t::Section, 0, 0, nullptr, nullptr, nullptr}, - {"autoplay", "Autoplay", Field_t::Boolean, 0, 1, getAutoplay, nullptr, nullptr}, - {"autoplayDuration", "Autoplay Duration", Field_t::Number, 0, 255, getAutoplayDuration, nullptr, nullptr}, - - //-------------------------------------------------------------------------------------------------------- - {"clock", "Clock", Field_t::Section, 0, 0, nullptr, nullptr, nullptr}, - {"showClock", "Show Clock", Field_t::Boolean, 0, 1, getShowClock, nullptr, nullptr}, - {"clockBackgroundFade", "Background Fade", Field_t::Number, 0, 255, getClockBackgroundFade, nullptr, nullptr}, - {"utcOffsetIndex", "UTC Offset", Field_t::UtcOffset, 0, 104, getUtcOffsetIndex, nullptr, setUtcOffsetIndexString}, - - //-------------------------------------------------------------------------------------------------------- - {"solidColorSection", "Solid Color", Field_t::Section, 0, 0, nullptr, nullptr, nullptr}, - {"solidColor", "Color", Field_t::Color, 0, 255, getSolidColor, nullptr, nullptr}, - - //-------------------------------------------------------------------------------------------------------- - {"fireSection", "Fire & Water", Field_t::Section, 0, 0, nullptr, nullptr, nullptr}, - {"cooling", "Cooling", Field_t::Number, 0, 255, getCooling, nullptr, nullptr}, - {"sparking", "Sparking", Field_t::Number, 0, 255, getSparking, nullptr, nullptr}, - - //-------------------------------------------------------------------------------------------------------- - {"twinklesSection", "Twinkles", Field_t::Section, 0, 0, nullptr, nullptr, nullptr}, - {"twinkleSpeed", "Twinkle Speed", Field_t::Number, 0, 8, getTwinkleSpeed, nullptr, nullptr}, - {"twinkleDensity", "Twinkle Density", Field_t::Number, 0, 8, getTwinkleDensity, nullptr, nullptr}, - {"coolLikeIncandescent", "Incandescent Cool", Field_t::Boolean, 0, 1, getCoolLikeIncandescent, nullptr, nullptr}, - - //-------------------------------------------------------------------------------------------------------- - {"prideSection", "Pride Playground", Field_t::Section, 0, 0, nullptr, nullptr, nullptr }, - {"saturationBpm", "Saturation BPM", Field_t::Number, 0, 255, getSaturationBpm, nullptr, setSaturationBpm }, - {"saturationMin", "Saturation Min", Field_t::Number, 0, 255, getSaturationMin, nullptr, setSaturationMin }, - {"saturationMax", "Saturation Max", Field_t::Number, 0, 255, getSaturationMax, nullptr, setSaturationMax }, - {"brightDepthBpm", "Brightness Depth BPM", Field_t::Number, 0, 255, getBrightDepthBpm, nullptr, setBrightDepthBpm }, - {"brightDepthMin", "Brightness Depth Min", Field_t::Number, 0, 255, getBrightDepthMin, nullptr, setBrightDepthMin }, - {"brightDepthMax", "Brightness Depth Max", Field_t::Number, 0, 255, getBrightDepthMax, nullptr, setBrightDepthMax }, - {"brightThetaIncBpm", "Bright Theta Inc BPM", Field_t::Number, 0, 255, getBrightThetaIncBpm, nullptr, setBrightThetaIncBpm}, - {"brightThetaIncMin", "Bright Theta Inc Min", Field_t::Number, 0, 255, getBrightThetaIncMin, nullptr, setBrightThetaIncMin}, - {"brightThetaIncMax", "Bright Theta Inc Max", Field_t::Number, 0, 255, getBrightThetaIncMax, nullptr, setBrightThetaIncMax}, - {"msMultiplierBpm", "Time Multiplier BPM", Field_t::Number, 0, 255, getMsMultiplierBpm, nullptr, setMsMultiplierBpm }, - {"msMultiplierMin", "Time Multiplier Min", Field_t::Number, 0, 255, getMsMultiplierMin, nullptr, setMsMultiplierMin }, - {"msMultiplierMax", "Time Multiplier Max", Field_t::Number, 0, 255, getMsMultiplierMax, nullptr, setMsMultiplierMax }, - {"hueIncBpm", "Hue Inc BPM", Field_t::Number, 0, 255, getHueIncBpm, nullptr, setHueIncBpm }, - {"hueIncMin", "Hue Inc Min", Field_t::Number, 0, 255, getHueIncMin, nullptr, setHueIncMin }, - {"hueIncMax", "Hue Inc Max", Field_t::Number, 0, 255, getHueIncMax, nullptr, setHueIncMax }, - {"sHueBpm", "S Hue BPM", Field_t::Number, 0, 255, getSHueBpm, nullptr, setSHueBpm }, - {"sHueMin", "S Hue Min", Field_t::Number, 0, 255, getSHueMin, nullptr, setSHueMin }, - {"sHueMax", "S Hue Max", Field_t::Number, 0, 255, getSHueMax, nullptr, setSHueMax }, -}; - -Field getField(String name) { - return getField(name, fields); -} + // name, label, type, min, max, getValue, getOptions, setValue + // only items that use the 'getOptions': patterns and palettes + // only items that support 'setValue': options used for pridePlayground + const Field fields[] = { + {"name", "Name", Field_t::Label, 0, 0, getName, nullptr, nullptr}, + {"power", "Power", Field_t::Boolean, 0, 1, getPower, nullptr, nullptr}, + {"brightness", "Brightness", Field_t::Number, 1, 255, getBrightness, nullptr, nullptr}, + {"pattern", "Pattern", Field_t::Select, 0, patternCount, getPattern, getPatterns, nullptr}, + {"palette", "Palette", Field_t::Select, 0, paletteCount, getPalette, getPalettes, nullptr}, + {"speed", "Speed", Field_t::Number, 1, 255, getSpeed, nullptr, nullptr}, + + //-------------------------------------------------------------------------------------------------------- + {"autoplaySection", "Autoplay", Field_t::Section, 0, 0, nullptr, nullptr, nullptr}, + {"autoplay", "Autoplay", Field_t::Boolean, 0, 1, getAutoplay, nullptr, nullptr}, + {"autoplayDuration", "Autoplay Duration", Field_t::Number, 0, 255, getAutoplayDuration, nullptr, nullptr}, + + //-------------------------------------------------------------------------------------------------------- + {"clock", "Clock", Field_t::Section, 0, 0, nullptr, nullptr, nullptr}, + {"showClock", "Show Clock", Field_t::Boolean, 0, 1, getShowClock, nullptr, nullptr}, + {"clockBackgroundFade", "Background Fade", Field_t::Number, 0, 255, getClockBackgroundFade, nullptr, nullptr}, + {"utcOffsetIndex", "UTC Offset", Field_t::UtcOffset, 0, 104, getUtcOffsetIndex, nullptr, setUtcOffsetIndexString}, + + //-------------------------------------------------------------------------------------------------------- + {"solidColorSection", "Solid Color", Field_t::Section, 0, 0, nullptr, nullptr, nullptr}, + {"solidColor", "Color", Field_t::Color, 0, 255, getSolidColor, nullptr, nullptr}, + + //-------------------------------------------------------------------------------------------------------- + {"fireSection", "Fire & Water", Field_t::Section, 0, 0, nullptr, nullptr, nullptr}, + {"cooling", "Cooling", Field_t::Number, 0, 255, getCooling, nullptr, nullptr}, + {"sparking", "Sparking", Field_t::Number, 0, 255, getSparking, nullptr, nullptr}, + + //-------------------------------------------------------------------------------------------------------- + {"twinklesSection", "Twinkles", Field_t::Section, 0, 0, nullptr, nullptr, nullptr}, + {"twinkleSpeed", "Twinkle Speed", Field_t::Number, 0, 8, getTwinkleSpeed, nullptr, nullptr}, + {"twinkleDensity", "Twinkle Density", Field_t::Number, 0, 8, getTwinkleDensity, nullptr, nullptr}, + {"coolLikeIncandescent", "Incandescent Cool", Field_t::Boolean, 0, 1, getCoolLikeIncandescent, nullptr, nullptr}, + + //-------------------------------------------------------------------------------------------------------- + {"prideSection", "Pride Playground", Field_t::Section, 0, 0, nullptr, nullptr, nullptr }, + {"saturationBpm", "Saturation BPM", Field_t::Number, 0, 255, getSaturationBpm, nullptr, setSaturationBpm }, + {"saturationMin", "Saturation Min", Field_t::Number, 0, 255, getSaturationMin, nullptr, setSaturationMin }, + {"saturationMax", "Saturation Max", Field_t::Number, 0, 255, getSaturationMax, nullptr, setSaturationMax }, + {"brightDepthBpm", "Brightness Depth BPM", Field_t::Number, 0, 255, getBrightDepthBpm, nullptr, setBrightDepthBpm }, + {"brightDepthMin", "Brightness Depth Min", Field_t::Number, 0, 255, getBrightDepthMin, nullptr, setBrightDepthMin }, + {"brightDepthMax", "Brightness Depth Max", Field_t::Number, 0, 255, getBrightDepthMax, nullptr, setBrightDepthMax }, + {"brightThetaIncBpm", "Bright Theta Inc BPM", Field_t::Number, 0, 255, getBrightThetaIncBpm, nullptr, setBrightThetaIncBpm}, + {"brightThetaIncMin", "Bright Theta Inc Min", Field_t::Number, 0, 255, getBrightThetaIncMin, nullptr, setBrightThetaIncMin}, + {"brightThetaIncMax", "Bright Theta Inc Max", Field_t::Number, 0, 255, getBrightThetaIncMax, nullptr, setBrightThetaIncMax}, + {"msMultiplierBpm", "Time Multiplier BPM", Field_t::Number, 0, 255, getMsMultiplierBpm, nullptr, setMsMultiplierBpm }, + {"msMultiplierMin", "Time Multiplier Min", Field_t::Number, 0, 255, getMsMultiplierMin, nullptr, setMsMultiplierMin }, + {"msMultiplierMax", "Time Multiplier Max", Field_t::Number, 0, 255, getMsMultiplierMax, nullptr, setMsMultiplierMax }, + {"hueIncBpm", "Hue Inc BPM", Field_t::Number, 0, 255, getHueIncBpm, nullptr, setHueIncBpm }, + {"hueIncMin", "Hue Inc Min", Field_t::Number, 0, 255, getHueIncMin, nullptr, setHueIncMin }, + {"hueIncMax", "Hue Inc Max", Field_t::Number, 0, 255, getHueIncMax, nullptr, setHueIncMax }, + {"sHueBpm", "S Hue BPM", Field_t::Number, 0, 255, getSHueBpm, nullptr, setSHueBpm }, + {"sHueMin", "S Hue Min", Field_t::Number, 0, 255, getSHueMin, nullptr, setSHueMin }, + {"sHueMax", "S Hue Max", Field_t::Number, 0, 255, getSHueMax, nullptr, setSHueMax }, + }; + + Field getField(String name) { + return getField(name, fields); + } } // end inline anonymous namespace From c147d83ff27dbb11ea2334391b6c3f97539144e6 Mon Sep 17 00:00:00 2001 From: Henry Gabryjelski Date: Thu, 25 Nov 2021 16:40:39 -0800 Subject: [PATCH 11/16] Make namespace anonymous --- esp8266-fastled-webserver/Fields.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/esp8266-fastled-webserver/Fields.cpp b/esp8266-fastled-webserver/Fields.cpp index c5e19893..7fc1176a 100644 --- a/esp8266-fastled-webserver/Fields.cpp +++ b/esp8266-fastled-webserver/Fields.cpp @@ -19,7 +19,7 @@ // only items outside the anonymous namespace can be exported. // this keeps the global namespace cleaner, with no runtime/RAM costs. -inline namespace InternalFieldsDetails { +inline namespace { enum struct Field_t : uint8_t { Number, Boolean, From 942a8a6f88706ec488797b1345505bd087b7497b Mon Sep 17 00:00:00 2001 From: Henry Gabryjelski Date: Fri, 26 Nov 2021 14:33:25 -0800 Subject: [PATCH 12/16] re-order IsValid() for clarity --- esp8266-fastled-webserver/Fields.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/esp8266-fastled-webserver/Fields.cpp b/esp8266-fastled-webserver/Fields.cpp index 7fc1176a..9c34b807 100644 --- a/esp8266-fastled-webserver/Fields.cpp +++ b/esp8266-fastled-webserver/Fields.cpp @@ -32,13 +32,13 @@ inline namespace { }; constexpr bool IsValid(const Field_t& t) { return ( - (t == Field_t::String ) || - (t == Field_t::Label ) || - (t == Field_t::Color ) || - (t == Field_t::Boolean ) || (t == Field_t::Number ) || - (t == Field_t::Section ) || + (t == Field_t::Boolean ) || (t == Field_t::Select ) || + (t == Field_t::Color ) || + (t == Field_t::Section ) || + (t == Field_t::String ) || + (t == Field_t::Label ) || (t == Field_t::UtcOffset) ); } From ba9c743c37b883e814eae4f6650f837438914c94 Mon Sep 17 00:00:00 2001 From: Henry Gabryjelski Date: Fri, 26 Nov 2021 16:53:51 -0800 Subject: [PATCH 13/16] Fix #218 - add missing build environments --- platformio.ini | 29 ++++++++++++++++++++++++++++- platformio_override_example.ini | 23 +++++++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 platformio_override_example.ini diff --git a/platformio.ini b/platformio.ini index 3023c388..09d9d966 100644 --- a/platformio.ini +++ b/platformio.ini @@ -17,7 +17,7 @@ [platformio] extra_configs = platformio_override.ini ; so users can easily override settings -default_envs = fastled_webserver__d1_mini, fib512__d1_mini, fib256__d1_mini, fib128__d1_mini, fib64_full__d1_mini, fib64_mini__d1_mini, fib32__d1_mini +default_envs = fastled_webserver__d1_mini, fib512__d1_mini, fib256__d1_mini, fib128__d1_mini, fib64_full__d1_mini, fib64_mini__d1_mini, fib32__d1_mini, esp_thing__d1_mini, kraken64__d1_mini, esp_thing__d1_mini, 1628_rings__d1_mini ; default_envs = fastled_webserver ; default_envs = fib512__d1_mini ; default_envs = fib256__d1_mini @@ -27,6 +27,15 @@ default_envs = fastled_webserver__d1_mini, fib512__d1_mini, fib256__d1_mini, fib ; default_envs = fib64_micro__d1_mini ; default_envs = fib64_nano__d1_mini ; default_envs = fib32__d1_mini +; default_envs = esp_thing__d1_mini +; default_envs = kraken64__d1_mini +; default_envs = esp_thing__d1_mini +; default_envs = 1628_rings__d1_mini + + + + + src_dir = ./esp8266-fastled-webserver/ data_dir = ./esp8266-fastled-webserver/data build_cache_dir = ~/.buildcache @@ -208,3 +217,21 @@ extends = common__d1_mini32 build_flags = ${common.build_flags_esp32} -D PRODUCT_FIBONACCI256 + +[env:kraken64__d1_mini] +extends = common__d1_mini +build_flags = + ${common.build_flags_esp8266} + -D PRODUCT_KRAKEN64 + +[env:esp_thing__d1_mini] +extends = common__d1_mini +build_flags = + ${common.build_flags_esp8266} + -D PRODUCT_ESP8266_THING + +[env:1628_rings__d1_mini] +extends = common__d1_mini +build_flags = + ${common.build_flags_esp8266} + -D PRODUCT_1628_RINGS diff --git a/platformio_override_example.ini b/platformio_override_example.ini new file mode 100644 index 00000000..03c74df6 --- /dev/null +++ b/platformio_override_example.ini @@ -0,0 +1,23 @@ + +; The following is an example build environment. +; It can be used to build a custom binary for the +; "ESP Thing" board, where there are a different +; number of LEDs attached to each data pin. + +[env:custom_esp_thing_older] +platform = ${common.platform_default} +platform_packages = ${common.platform_packages} +lib_deps = ${esp8266.lib_deps} +board = d1_mini +board_build.ldscript = ${common.ldscript_4m1m} +build_unflags = ${common.build_unflags} +build_flags = + ${common.build_flags_esp8266} + -D PRODUCT_ESP8266_THING + -D NUM_PIXELS=72 + -D PIXELS_ON_DATA_PIN_1=5 + -D PIXELS_ON_DATA_PIN_2=7 + -D PIXELS_ON_DATA_PIN_3=11 + -D PIXELS_ON_DATA_PIN_4=13 + -D PIXELS_ON_DATA_PIN_5=17 + -D PIXELS_ON_DATA_PIN_6=19 From 7f61d0f985b542a94356c2aa06ae6593cc9c0143 Mon Sep 17 00:00:00 2001 From: Henry Gabryjelski Date: Fri, 26 Nov 2021 16:56:34 -0800 Subject: [PATCH 14/16] update example platformio_override.ini --- platformio_override_example.ini | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/platformio_override_example.ini b/platformio_override_example.ini index 03c74df6..8876284c 100644 --- a/platformio_override_example.ini +++ b/platformio_override_example.ini @@ -4,13 +4,9 @@ ; "ESP Thing" board, where there are a different ; number of LEDs attached to each data pin. -[env:custom_esp_thing_older] -platform = ${common.platform_default} -platform_packages = ${common.platform_packages} -lib_deps = ${esp8266.lib_deps} -board = d1_mini -board_build.ldscript = ${common.ldscript_4m1m} -build_unflags = ${common.build_unflags} + +[env:custom_esp_thing] +extends = common__d1_mini build_flags = ${common.build_flags_esp8266} -D PRODUCT_ESP8266_THING @@ -21,3 +17,4 @@ build_flags = -D PIXELS_ON_DATA_PIN_4=13 -D PIXELS_ON_DATA_PIN_5=17 -D PIXELS_ON_DATA_PIN_6=19 + From 540693d2014e55f6daa42c507274f19faf87f9c1 Mon Sep 17 00:00:00 2001 From: Henry Gabryjelski Date: Fri, 26 Nov 2021 17:58:41 -0800 Subject: [PATCH 15/16] Minor adjustments to pattern #ifdef's --- esp8266-fastled-webserver/common.h | 1 - .../esp8266-fastled-webserver.ino | 43 ++++++------------- 2 files changed, 14 insertions(+), 30 deletions(-) diff --git a/esp8266-fastled-webserver/common.h b/esp8266-fastled-webserver/common.h index 2b23c076..af545caf 100644 --- a/esp8266-fastled-webserver/common.h +++ b/esp8266-fastled-webserver/common.h @@ -132,7 +132,6 @@ void broadcastString(String name, String value); // Structures typedef void (*Pattern)(); -typedef Pattern PatternList[]; typedef struct { Pattern pattern; String name; diff --git a/esp8266-fastled-webserver/esp8266-fastled-webserver.ino b/esp8266-fastled-webserver/esp8266-fastled-webserver.ino index 5748cff7..379ac44b 100644 --- a/esp8266-fastled-webserver/esp8266-fastled-webserver.ino +++ b/esp8266-fastled-webserver/esp8266-fastled-webserver.ino @@ -90,45 +90,30 @@ void dimAll(byte value) // List of patterns to cycle through. Each is defined as a separate function below. // NOTE: HAS_POLAR_COORDS implies HAS_COORDINATE_MAP -// IS_FIBONACCI implies HAS_COORDINATE_MAP - -// TODO: Consider patterns listing name and all variants: -// [] original variant -// [] fibonacci variant (or nullptr) -// [] concentric ring variant (or nullptr) -// [] coordinates variant (or nullptr) -// WHY #1: Easier to manage defining the patterns via a macro, -// which discards arguments that do not apply for a given -// board, than this #if/#endif spaghetti mess. -// WHY #2: Easier for users to see correlations between the patterns, -// when switching between them. -// WHY #3: May eventually be able to change mapping for standard -// effects (emulating led array, but using custom mapping), -// which could further reduce code duplication. +// IS_FIBONACCI implies HAS_COORDINATE_MAP const PatternAndName patterns[] = { - { pride, "Pride" }, + { pride, "Pride" }, #if IS_FIBONACCI - { prideFibonacci, "Pride Fibonacci" }, + { prideFibonacci, "Pride Fibonacci" }, #endif - { colorWaves, "Color Waves" }, + { colorWaves, "Color Waves" }, #if IS_FIBONACCI { colorWavesFibonacci, "Color Waves Fibonacci" }, #endif -#if IS_FIBONACCI { pridePlayground, "Pride Playground" }, +#if IS_FIBONACCI { pridePlaygroundFibonacci, "Pride Playground Fibonacci" }, +#endif { colorWavesPlayground, "Color Waves Playground" }, +#if IS_FIBONACCI { colorWavesPlaygroundFibonacci, "Color Waves Playground Fibonacci" }, #endif - { wheel, "Wheel" }, -#if (PARALLEL_OUTPUT_CHANNELS > 1) - { multi_test, "Multi Test" }, -#endif + { wheel, "Wheel" }, #if IS_FIBONACCI { swirlFibonacci, "Swirl Fibonacci"}, @@ -141,7 +126,7 @@ const PatternAndName patterns[] = { #endif #if HAS_COORDINATE_MAP // really a wrong name... and likely doing way more computation than necessary - { radarSweepPalette, "Radar Sweep Palette" }, + { radarSweepPalette, "Radar Sweep Palette" }, #endif #if HAS_COORDINATE_MAP @@ -205,13 +190,10 @@ const PatternAndName patterns[] = { { drawSpiralAnalogClock34_21_and_13, "Spiral Analog Clock 34, 21 & 13"}, #endif - { pridePlayground, "Pride Playground" }, - { colorWavesPlayground, "Color Waves Playground" }, - #if defined(PRODUCT_KRAKEN64) // Kraken patterns ... these use body[], which is also used as a proxy for radius... - { radiusPalette, "Kraken Palette" }, - { radiusGradientPalette, "Kraken Gradient Palette" }, + { radiusPalette, "Kraken Palette" }, + { radiusGradientPalette, "Kraken Gradient Palette" }, #endif // twinkle patterns @@ -247,6 +229,9 @@ const PatternAndName patterns[] = { { water, "Water" }, { strandTest, "Strand Test" }, +#if (PARALLEL_OUTPUT_CHANNELS > 1) + { multi_test, "Multi Test" }, +#endif { showSolidColor, "Solid Color" } // This *must* be the last pattern }; From f50d34ed95cf337adc009164935ee9da66236b59 Mon Sep 17 00:00:00 2001 From: Henry Gabryjelski Date: Fri, 26 Nov 2021 18:15:18 -0800 Subject: [PATCH 16/16] comment updates (no code change) --- esp8266-fastled-webserver/Noise.cpp | 3 ++- esp8266-fastled-webserver/esp8266-fastled-webserver.ino | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/esp8266-fastled-webserver/Noise.cpp b/esp8266-fastled-webserver/Noise.cpp index 69d03772..7b29452b 100644 --- a/esp8266-fastled-webserver/Noise.cpp +++ b/esp8266-fastled-webserver/Noise.cpp @@ -146,7 +146,8 @@ void drawNoise(CRGBPalette16 palette, uint8_t hueReduce = 0) } #if HAS_POLAR_COORDS // change to "HAS_CONCENTRIC_RINGS" ? -// drawPolarNoise() uses angles[] and rings[][] (may move to using radii[]) + +// drawPolarNoise() uses angles[] and radii[] void drawPolarNoise(CRGBPalette16 palette, uint8_t hueReduce = 0) { for (uint16_t i = 0; i < NUM_PIXELS; i++) { diff --git a/esp8266-fastled-webserver/esp8266-fastled-webserver.ino b/esp8266-fastled-webserver/esp8266-fastled-webserver.ino index 379ac44b..2cf4e6f4 100644 --- a/esp8266-fastled-webserver/esp8266-fastled-webserver.ino +++ b/esp8266-fastled-webserver/esp8266-fastled-webserver.ino @@ -144,7 +144,7 @@ const PatternAndName patterns[] = { { xyGradientPalette, "XY Axis Gradient Palette" }, #endif -#if HAS_POLAR_COORDS // really a wrong name... and likely doing way more computation than necessary +#if HAS_POLAR_COORDS // noise patterns (Polar variations) { gradientPalettePolarNoise, "Gradient Palette Polar Noise" }, { palettePolarNoise, "Palette Polar Noise" },