From 32dc661836122f175654df42961ed76e01fb0244 Mon Sep 17 00:00:00 2001 From: Thrillfiishing <124837308+scattervideo@users.noreply.github.com> Date: Mon, 17 Feb 2025 15:40:03 -0500 Subject: [PATCH 1/2] Added Chase Race Effect to WLED --- wled00/FX.cpp | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++ wled00/FX.h | 4 +-- 2 files changed, 80 insertions(+), 2 deletions(-) diff --git a/wled00/FX.cpp b/wled00/FX.cpp index 8d3e71b94d..2b91e0438e 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -925,6 +925,75 @@ static uint16_t chase(uint32_t color1, uint32_t color2, uint32_t color3, bool do return FRAMETIME; } +/** + * Chase_Race function to allow 3 colored bands to race along the LEDs with black between the colors. + * color1, color2, and color3 = colors of the three leaders in the race + */ +uint16_t chase_race(uint32_t color1, uint32_t color2, uint32_t color3, bool do_palette) +{ + uint16_t counter = strip.now * ((SEGMENT.speed >> 2) + 1); + uint16_t a = (counter * SEGLEN) >> 16; + // Use intensity setting to vary chase up to 1/2 string length + unsigned size = 1 + ((SEGMENT.intensity * SEGLEN) >> 10); + unsigned gap = size / 8; // Smaller black band size as a fraction of color size + uint16_t b = a + size; // "trail" of chase, filled with color1 + if (b > SEGLEN) + b -= SEGLEN; + uint16_t c = b + size + gap; // Add black gap after color1 + if (c > SEGLEN) + c -= SEGLEN; + uint16_t d = c + size; // "trail" of color2 + if (d > SEGLEN) + d -= SEGLEN; + uint16_t e = d + size + gap; // Add black gap after color2 + if (e > SEGLEN) + e -= SEGLEN; + uint16_t f = e + size; // "trail" of color3 + if (f > SEGLEN) + f -= SEGLEN; + // Background + SEGMENT.fill(0); // Set the entire strip to black + // Fill between points a and b with color1 + if (a < b) + { + for (unsigned i = a; i < b; i++) + SEGMENT.setPixelColor(i, color1); + } + else + { + for (unsigned i = a; i < SEGLEN; i++) + SEGMENT.setPixelColor(i, color1); + for (unsigned i = 0; i < b; i++) + SEGMENT.setPixelColor(i, color1); + } + // Fill between points c and d with color2 + if (c < d) + { + for (unsigned i = c; i < d; i++) + SEGMENT.setPixelColor(i, color2); + } + else + { + for (unsigned i = c; i < SEGLEN; i++) + SEGMENT.setPixelColor(i, color2); + for (unsigned i = 0; i < d; i++) + SEGMENT.setPixelColor(i, color2); + } + // Fill between points e and f with color3 + if (e < f) + { + for (unsigned i = e; i < f; i++) + SEGMENT.setPixelColor(i, color3); + } + else + { + for (unsigned i = e; i < SEGLEN; i++) + SEGMENT.setPixelColor(i, color3); + for (unsigned i = 0; i < f; i++) + SEGMENT.setPixelColor(i, color3); + } + return FRAMETIME; +} /* * Bicolor chase, more primary color. @@ -934,6 +1003,14 @@ uint16_t mode_chase_color(void) { } static const char _data_FX_MODE_CHASE_COLOR[] PROGMEM = "Chase@!,Width;!,!,!;!"; +/* +* Chace Race with 3 color strips +*/ +uint16_t mode_chase_race() +{ + return chase_race(SEGCOLOR(0), SEGCOLOR(1), SEGCOLOR(2), false); +} +static const char _data_FX_MODE_CHASE_RACE[] PROGMEM = "Chase Race@!,Width;!,!,!;!"; /* * Primary running followed by random color. @@ -10192,6 +10269,7 @@ void WS2812FX::setupEffectData() { addEffect(FX_MODE_BLINK_RAINBOW, &mode_blink_rainbow, _data_FX_MODE_BLINK_RAINBOW); addEffect(FX_MODE_ANDROID, &mode_android, _data_FX_MODE_ANDROID); addEffect(FX_MODE_CHASE_COLOR, &mode_chase_color, _data_FX_MODE_CHASE_COLOR); + addEffect(FX_MODE_CHASE_RACE, &mode_chase_race, _data_FX_MODE_CHASE_RACE); addEffect(FX_MODE_CHASE_RANDOM, &mode_chase_random, _data_FX_MODE_CHASE_RANDOM); addEffect(FX_MODE_CHASE_RAINBOW, &mode_chase_rainbow, _data_FX_MODE_CHASE_RAINBOW); addEffect(FX_MODE_CHASE_FLASH, &mode_chase_flash, _data_FX_MODE_CHASE_FLASH); diff --git a/wled00/FX.h b/wled00/FX.h index 3544e1fa7f..1c1e4a8de6 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -351,8 +351,8 @@ extern byte realtimeMode; // used in getMappedPixelIndex() #define FX_MODE_PS1DGEQ 212 #define FX_MODE_PSFIRE1D 213 #define FX_MODE_PS1DSONICSTREAM 214 -#define MODE_COUNT 215 - +#define FX_MODE_CHASE_RACE 215 +#define MODE_COUNT 216 #define BLEND_STYLE_FADE 0x00 // universal #define BLEND_STYLE_FAIRY_DUST 0x01 // universal From 6fc249532180f59cc531791cb55f06af7e730d9c Mon Sep 17 00:00:00 2001 From: Thrillfiishing <124837308+scattervideo@users.noreply.github.com> Date: Tue, 18 Feb 2025 10:31:28 -0500 Subject: [PATCH 2/2] Updated based upon feedback from DedeHai and fixed typo. --- package-lock.json | 4 +-- platformio.ini | 4 +-- wled00/FX.cpp | 92 +++++++++++++++++------------------------------ 3 files changed, 37 insertions(+), 63 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0afeeaafd8..c81072cfc6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "wled", - "version": "0.16.0-dev", + "version": "0.16.0-alpha", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "wled", - "version": "0.16.0-dev", + "version": "0.16.0-alpha", "license": "ISC", "dependencies": { "clean-css": "^5.3.3", diff --git a/platformio.ini b/platformio.ini index 5b1b212656..0b37c5056b 100644 --- a/platformio.ini +++ b/platformio.ini @@ -10,8 +10,8 @@ # ------------------------------------------------------------------------------ # CI/release binaries -default_envs = nodemcuv2, esp8266_2m, esp01_1m_full, nodemcuv2_160, esp8266_2m_160, esp01_1m_full_160, nodemcuv2_compat, esp8266_2m_compat, esp01_1m_full_compat, esp32dev, esp32dev_V4, esp32_eth, lolin_s2_mini, esp32c3dev, esp32s3dev_16MB_opi, esp32s3dev_8MB_opi, esp32s3_4M_qspi, esp32_wrover - +#default_envs = nodemcuv2, esp8266_2m, esp01_1m_full, nodemcuv2_160, esp8266_2m_160, esp01_1m_full_160, nodemcuv2_compat, esp8266_2m_compat, esp01_1m_full_compat, esp32dev, esp32dev_V4, esp32_eth, lolin_s2_mini, esp32c3dev, esp32s3dev_16MB_opi, esp32s3dev_8MB_opi, esp32s3_4M_qspi, esp32_wrover +default_envs = esp32dev src_dir = ./wled00 data_dir = ./wled00/data build_cache_dir = ~/.buildcache diff --git a/wled00/FX.cpp b/wled00/FX.cpp index 2b91e0438e..f5b1f7b53f 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -929,69 +929,43 @@ static uint16_t chase(uint32_t color1, uint32_t color2, uint32_t color3, bool do * Chase_Race function to allow 3 colored bands to race along the LEDs with black between the colors. * color1, color2, and color3 = colors of the three leaders in the race */ -uint16_t chase_race(uint32_t color1, uint32_t color2, uint32_t color3, bool do_palette) + +uint16_t chase_race(uint32_t color1, uint32_t color2, uint32_t color3) { uint16_t counter = strip.now * ((SEGMENT.speed >> 2) + 1); uint16_t a = (counter * SEGLEN) >> 16; + // Use intensity setting to vary chase up to 1/2 string length unsigned size = 1 + ((SEGMENT.intensity * SEGLEN) >> 10); - unsigned gap = size / 8; // Smaller black band size as a fraction of color size - uint16_t b = a + size; // "trail" of chase, filled with color1 - if (b > SEGLEN) - b -= SEGLEN; - uint16_t c = b + size + gap; // Add black gap after color1 - if (c > SEGLEN) - c -= SEGLEN; - uint16_t d = c + size; // "trail" of color2 - if (d > SEGLEN) - d -= SEGLEN; - uint16_t e = d + size + gap; // Add black gap after color2 - if (e > SEGLEN) - e -= SEGLEN; - uint16_t f = e + size; // "trail" of color3 - if (f > SEGLEN) - f -= SEGLEN; - // Background - SEGMENT.fill(0); // Set the entire strip to black - // Fill between points a and b with color1 - if (a < b) - { - for (unsigned i = a; i < b; i++) - SEGMENT.setPixelColor(i, color1); - } - else - { - for (unsigned i = a; i < SEGLEN; i++) - SEGMENT.setPixelColor(i, color1); - for (unsigned i = 0; i < b; i++) - SEGMENT.setPixelColor(i, color1); - } - // Fill between points c and d with color2 - if (c < d) - { - for (unsigned i = c; i < d; i++) - SEGMENT.setPixelColor(i, color2); - } - else - { - for (unsigned i = c; i < SEGLEN; i++) - SEGMENT.setPixelColor(i, color2); - for (unsigned i = 0; i < d; i++) - SEGMENT.setPixelColor(i, color2); - } - // Fill between points e and f with color3 - if (e < f) - { - for (unsigned i = e; i < f; i++) - SEGMENT.setPixelColor(i, color3); - } - else + unsigned gap = 1 + size / 4; // Smaller black band size as a fraction of color size + + // Calculate positions for each color band + uint16_t positions[] = { + a, // Start of color1 + (a + size) % SEGLEN, // End of color1 + (a + size + gap) % SEGLEN, // Start of color2 + (a + size * 2 + gap) % SEGLEN, // End of color2 + (a + size * 2 + gap * 2) % SEGLEN, // Start of color3 + (a + size * 3 + gap * 2) % SEGLEN // End of color3 + }; + + // Define compact lambda for filling LED segments using modulo + auto fillSegment = [](uint16_t start, uint16_t end, uint32_t color) { - for (unsigned i = e; i < SEGLEN; i++) - SEGMENT.setPixelColor(i, color3); - for (unsigned i = 0; i < f; i++) - SEGMENT.setPixelColor(i, color3); - } + for (unsigned count = 0; count < SEGLEN && count < end - start + (end < start ? SEGLEN : 0); count++) + { + SEGMENT.setPixelColor((start + count) % SEGLEN, color); + } + }; + + // Set background to black + SEGMENT.fill(0); + + // Fill the three color segments + fillSegment(positions[0], positions[1], color1); + fillSegment(positions[2], positions[3], color2); + fillSegment(positions[4], positions[5], color3); + return FRAMETIME; } @@ -1004,11 +978,11 @@ uint16_t mode_chase_color(void) { static const char _data_FX_MODE_CHASE_COLOR[] PROGMEM = "Chase@!,Width;!,!,!;!"; /* -* Chace Race with 3 color strips +* Chase Race with 3 color strips */ uint16_t mode_chase_race() { - return chase_race(SEGCOLOR(0), SEGCOLOR(1), SEGCOLOR(2), false); + return chase_race(SEGCOLOR(0), SEGCOLOR(1), SEGCOLOR(2)); } static const char _data_FX_MODE_CHASE_RACE[] PROGMEM = "Chase Race@!,Width;!,!,!;!";