From 12127ccdacb46bf30167785070732c347694fb8a Mon Sep 17 00:00:00 2001 From: David Madison Date: Mon, 9 Aug 2021 16:26:24 -0400 Subject: Add fill_rainbow_endless util functions For filling a rainbow pattern that's continuous in hue between the end of the strip and the beginning. Useful for out-of-the-box rainbow animations on looped strips and LED rings. --- keywords.txt | 1 + src/colorutils.cpp | 39 +++++++++++++++++++++++++++++++++++++++ src/colorutils.h | 15 +++++++++++++++ 3 files changed, 55 insertions(+) diff --git a/keywords.txt b/keywords.txt index 75df500c..91e7b3b1 100644 --- a/keywords.txt +++ b/keywords.txt @@ -131,6 +131,7 @@ fill_gradient KEYWORD2 fill_gradient_RGB KEYWORD2 fill_palette KEYWORD2 fill_rainbow KEYWORD2 +fill_rainbow_endless KEYWORD2 fill_solid KEYWORD2 map_data_into_colors_through_palette KEYWORD2 nblend KEYWORD2 diff --git a/src/colorutils.cpp b/src/colorutils.cpp index a1acaa5a..d1f45bd9 100644 --- a/src/colorutils.cpp +++ b/src/colorutils.cpp @@ -62,6 +62,45 @@ void fill_rainbow( struct CHSV * targetArray, int numToFill, } +void fill_rainbow_endless(struct CRGB* targetArray, int numToFill, uint8_t initialhue) +{ + if (numToFill == 0) return; // avoiding div/0 + + CHSV hsv; + hsv.hue = initialhue; + hsv.val = 255; + hsv.sat = 240; + + const uint16_t hueChange = 65536 / (uint16_t)numToFill; // hue change for each LED, * 256 for precision + uint16_t hueOffset = 0; // offset for hue value, with precision (*256) + + for (int i = 0; i < numToFill; ++i) { + targetArray[i] = hsv; + hueOffset += hueChange; // increase precise offset + hsv.hue = initialhue + (uint8_t)(hueOffset >> 8); // assign new hue with precise offset (as 8-bit) + } +} + +void fill_rainbow_endless(struct CHSV* targetArray, int numToFill, uint8_t initialhue) +{ + if (numToFill == 0) return; // avoiding div/0 + + CHSV hsv; + hsv.hue = initialhue; + hsv.val = 255; + hsv.sat = 240; + + const uint16_t hueChange = 65536 / (uint16_t)numToFill; // hue change for each LED, * 256 for precision + uint16_t hueOffset = 0; // offset for hue value, with precision (*256) + + for (int i = 0; i < numToFill; ++i) { + targetArray[i] = hsv; + hueOffset += hueChange; // increase precise offset + hsv.hue = initialhue + (uint8_t)(hueOffset >> 8); // assign new hue with precise offset (as 8-bit) + } +} + + void fill_gradient_RGB( CRGB* leds, uint16_t startpos, CRGB startcolor, uint16_t endpos, CRGB endcolor ) diff --git a/src/colorutils.h b/src/colorutils.h index f09d525f..237e9400 100644 --- a/src/colorutils.h +++ b/src/colorutils.h @@ -37,6 +37,21 @@ void fill_rainbow( struct CHSV * targetArray, int numToFill, uint8_t deltahue = 5); +/// fill_rainbow_endless - fill a range of LEDs with a rainbow of colors, at +/// full saturation and full value (brightness), +/// so that the hues are continuous between the end +/// of the strip and the beginning +void fill_rainbow_endless(struct CRGB* targetArray, int numToFill, + uint8_t initialhue); + +/// fill_rainbow_endless - fill a range of LEDs with a rainbow of colors, at +/// full saturation and full value (brightness), +/// so that the hues are continuous between the end +/// of the strip and the beginning +void fill_rainbow_endless(struct CHSV* targetArray, int numToFill, + uint8_t initialhue); + + // fill_gradient - fill an array of colors with a smooth HSV gradient // between two specified HSV colors. // Since 'hue' is a value around a color wheel, -- cgit v1.2.3 From fd06f2c97fc16034ba020eb2c2c2c8d643dbac6e Mon Sep 17 00:00:00 2001 From: David Madison Date: Sun, 2 Jan 2022 15:19:01 -0500 Subject: Refactor fill "endless" as fill "circular" --- src/colorutils.cpp | 4 ++-- src/colorutils.h | 20 ++++++++++---------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/colorutils.cpp b/src/colorutils.cpp index d1f45bd9..18aa9ed8 100644 --- a/src/colorutils.cpp +++ b/src/colorutils.cpp @@ -62,7 +62,7 @@ void fill_rainbow( struct CHSV * targetArray, int numToFill, } -void fill_rainbow_endless(struct CRGB* targetArray, int numToFill, uint8_t initialhue) +void fill_rainbow_circular(struct CRGB* targetArray, int numToFill, uint8_t initialhue) { if (numToFill == 0) return; // avoiding div/0 @@ -81,7 +81,7 @@ void fill_rainbow_endless(struct CRGB* targetArray, int numToFill, uint8_t initi } } -void fill_rainbow_endless(struct CHSV* targetArray, int numToFill, uint8_t initialhue) +void fill_rainbow_circular(struct CHSV* targetArray, int numToFill, uint8_t initialhue) { if (numToFill == 0) return; // avoiding div/0 diff --git a/src/colorutils.h b/src/colorutils.h index 237e9400..d33ce55e 100644 --- a/src/colorutils.h +++ b/src/colorutils.h @@ -37,18 +37,18 @@ void fill_rainbow( struct CHSV * targetArray, int numToFill, uint8_t deltahue = 5); -/// fill_rainbow_endless - fill a range of LEDs with a rainbow of colors, at -/// full saturation and full value (brightness), -/// so that the hues are continuous between the end -/// of the strip and the beginning -void fill_rainbow_endless(struct CRGB* targetArray, int numToFill, +/// fill_rainbow_circular - fill a range of LEDs with a rainbow of colors, at +/// full saturation and full value (brightness), +/// so that the hues are continuous between the end +/// of the strip and the beginning +void fill_rainbow_circular(struct CRGB* targetArray, int numToFill, uint8_t initialhue); -/// fill_rainbow_endless - fill a range of LEDs with a rainbow of colors, at -/// full saturation and full value (brightness), -/// so that the hues are continuous between the end -/// of the strip and the beginning -void fill_rainbow_endless(struct CHSV* targetArray, int numToFill, +/// fill_rainbow_circular - fill a range of LEDs with a rainbow of colors, at +/// full saturation and full value (brightness), +/// so that the hues are continuous between the end +/// of the strip and the beginning +void fill_rainbow_circular(struct CHSV* targetArray, int numToFill, uint8_t initialhue); -- cgit v1.2.3 From 5cc52a289a405fcc580aac6621cc240a1ca8fce6 Mon Sep 17 00:00:00 2001 From: David Madison Date: Sun, 2 Jan 2022 15:38:35 -0500 Subject: Create fill_palette_circular function --- src/colorutils.h | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/colorutils.h b/src/colorutils.h index d33ce55e..16534ef6 100644 --- a/src/colorutils.h +++ b/src/colorutils.h @@ -1566,7 +1566,7 @@ CHSV ColorFromPalette( const CHSVPalette32& pal, TBlendType blendType=LINEARBLEND); -// Fill a range of LEDs with a sequece of entryies from a palette +// Fill a range of LEDs with a sequence of entries from a palette template void fill_palette(CRGB* L, uint16_t N, uint8_t startIndex, uint8_t incIndex, const PALETTE& pal, uint8_t brightness, TBlendType blendType) @@ -1578,6 +1578,23 @@ void fill_palette(CRGB* L, uint16_t N, uint8_t startIndex, uint8_t incIndex, } } +// Fill a range of LEDs with a sequence of entries from a palette, so that +// the entire palette smoothly covers the range of LEDs +template +void fill_palette_circular(CRGB* L, uint16_t N, uint8_t startIndex, + const PALETTE& pal, uint8_t brightness, TBlendType blendType) +{ + if (N == 0) return; // avoiding div/0 + + const uint16_t colorChange = 65536 / N; // color change for each LED, * 256 for precision + uint16_t colorIndex = ((uint16_t) startIndex) << 8; // offset for color index, with precision (*256) + + for (uint16_t i = 0; i < N; ++i) { + L[i] = ColorFromPalette(pal, (colorIndex >> 8), brightness, blendType); + colorIndex += colorChange; + } +} + template void map_data_into_colors_through_palette( uint8_t *dataArray, uint16_t dataCount, -- cgit v1.2.3 From 3ebf7bf483c6066faec907855ab1f5882dc58d9a Mon Sep 17 00:00:00 2001 From: David Madison Date: Sun, 2 Jan 2022 15:56:53 -0500 Subject: Add brightness and blend defaults to fill_palette --- src/colorutils.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/colorutils.h b/src/colorutils.h index 16534ef6..4ea7962d 100644 --- a/src/colorutils.h +++ b/src/colorutils.h @@ -1569,7 +1569,7 @@ CHSV ColorFromPalette( const CHSVPalette32& pal, // Fill a range of LEDs with a sequence of entries from a palette template void fill_palette(CRGB* L, uint16_t N, uint8_t startIndex, uint8_t incIndex, - const PALETTE& pal, uint8_t brightness, TBlendType blendType) + const PALETTE& pal, uint8_t brightness=255, TBlendType blendType=LINEARBLEND) { uint8_t colorIndex = startIndex; for( uint16_t i = 0; i < N; ++i) { @@ -1582,7 +1582,7 @@ void fill_palette(CRGB* L, uint16_t N, uint8_t startIndex, uint8_t incIndex, // the entire palette smoothly covers the range of LEDs template void fill_palette_circular(CRGB* L, uint16_t N, uint8_t startIndex, - const PALETTE& pal, uint8_t brightness, TBlendType blendType) + const PALETTE& pal, uint8_t brightness=255, TBlendType blendType=LINEARBLEND) { if (N == 0) return; // avoiding div/0 -- cgit v1.2.3 From f2da89411b1180398e204ca8c8522845706954f1 Mon Sep 17 00:00:00 2001 From: David Madison Date: Sun, 2 Jan 2022 16:07:11 -0500 Subject: Reduce circular precision constants by 1 256 * 256 - 1, to fit into a uint16_t (2^16) --- src/colorutils.cpp | 4 ++-- src/colorutils.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/colorutils.cpp b/src/colorutils.cpp index 18aa9ed8..16cf855d 100644 --- a/src/colorutils.cpp +++ b/src/colorutils.cpp @@ -71,7 +71,7 @@ void fill_rainbow_circular(struct CRGB* targetArray, int numToFill, uint8_t init hsv.val = 255; hsv.sat = 240; - const uint16_t hueChange = 65536 / (uint16_t)numToFill; // hue change for each LED, * 256 for precision + const uint16_t hueChange = 65535 / (uint16_t)numToFill; // hue change for each LED, * 256 for precision (256 * 256 - 1) uint16_t hueOffset = 0; // offset for hue value, with precision (*256) for (int i = 0; i < numToFill; ++i) { @@ -90,7 +90,7 @@ void fill_rainbow_circular(struct CHSV* targetArray, int numToFill, uint8_t init hsv.val = 255; hsv.sat = 240; - const uint16_t hueChange = 65536 / (uint16_t)numToFill; // hue change for each LED, * 256 for precision + const uint16_t hueChange = 65535 / (uint16_t) numToFill; // hue change for each LED, * 256 for precision (256 * 256 - 1) uint16_t hueOffset = 0; // offset for hue value, with precision (*256) for (int i = 0; i < numToFill; ++i) { diff --git a/src/colorutils.h b/src/colorutils.h index 4ea7962d..8b9f98af 100644 --- a/src/colorutils.h +++ b/src/colorutils.h @@ -1586,7 +1586,7 @@ void fill_palette_circular(CRGB* L, uint16_t N, uint8_t startIndex, { if (N == 0) return; // avoiding div/0 - const uint16_t colorChange = 65536 / N; // color change for each LED, * 256 for precision + const uint16_t colorChange = 65535 / N; // color change for each LED, * 256 for precision uint16_t colorIndex = ((uint16_t) startIndex) << 8; // offset for color index, with precision (*256) for (uint16_t i = 0; i < N; ++i) { -- cgit v1.2.3 From dd30fd9143ca2eefaf68d29e5c72e8849e2a7c43 Mon Sep 17 00:00:00 2001 From: David Madison Date: Sun, 2 Jan 2022 16:25:43 -0500 Subject: Add reversing option to fill_circular functions --- src/colorutils.cpp | 10 ++++++---- src/colorutils.h | 10 ++++++---- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/colorutils.cpp b/src/colorutils.cpp index 16cf855d..941f4686 100644 --- a/src/colorutils.cpp +++ b/src/colorutils.cpp @@ -62,7 +62,7 @@ void fill_rainbow( struct CHSV * targetArray, int numToFill, } -void fill_rainbow_circular(struct CRGB* targetArray, int numToFill, uint8_t initialhue) +void fill_rainbow_circular(struct CRGB* targetArray, int numToFill, uint8_t initialhue, bool reversed) { if (numToFill == 0) return; // avoiding div/0 @@ -76,12 +76,13 @@ void fill_rainbow_circular(struct CRGB* targetArray, int numToFill, uint8_t init for (int i = 0; i < numToFill; ++i) { targetArray[i] = hsv; - hueOffset += hueChange; // increase precise offset + if (reversed) hueOffset -= hueChange; + else hueOffset += hueChange; hsv.hue = initialhue + (uint8_t)(hueOffset >> 8); // assign new hue with precise offset (as 8-bit) } } -void fill_rainbow_circular(struct CHSV* targetArray, int numToFill, uint8_t initialhue) +void fill_rainbow_circular(struct CHSV* targetArray, int numToFill, uint8_t initialhue, bool reversed) { if (numToFill == 0) return; // avoiding div/0 @@ -95,7 +96,8 @@ void fill_rainbow_circular(struct CHSV* targetArray, int numToFill, uint8_t init for (int i = 0; i < numToFill; ++i) { targetArray[i] = hsv; - hueOffset += hueChange; // increase precise offset + if (reversed) hueOffset -= hueChange; + else hueOffset += hueChange; hsv.hue = initialhue + (uint8_t)(hueOffset >> 8); // assign new hue with precise offset (as 8-bit) } } diff --git a/src/colorutils.h b/src/colorutils.h index 8b9f98af..43c9c0ad 100644 --- a/src/colorutils.h +++ b/src/colorutils.h @@ -42,14 +42,14 @@ void fill_rainbow( struct CHSV * targetArray, int numToFill, /// so that the hues are continuous between the end /// of the strip and the beginning void fill_rainbow_circular(struct CRGB* targetArray, int numToFill, - uint8_t initialhue); + uint8_t initialhue, bool reversed=false); /// fill_rainbow_circular - fill a range of LEDs with a rainbow of colors, at /// full saturation and full value (brightness), /// so that the hues are continuous between the end /// of the strip and the beginning void fill_rainbow_circular(struct CHSV* targetArray, int numToFill, - uint8_t initialhue); + uint8_t initialhue, bool reversed=false); // fill_gradient - fill an array of colors with a smooth HSV gradient @@ -1582,7 +1582,8 @@ void fill_palette(CRGB* L, uint16_t N, uint8_t startIndex, uint8_t incIndex, // the entire palette smoothly covers the range of LEDs template void fill_palette_circular(CRGB* L, uint16_t N, uint8_t startIndex, - const PALETTE& pal, uint8_t brightness=255, TBlendType blendType=LINEARBLEND) + const PALETTE& pal, uint8_t brightness=255, TBlendType blendType=LINEARBLEND, + bool reversed=false) { if (N == 0) return; // avoiding div/0 @@ -1591,7 +1592,8 @@ void fill_palette_circular(CRGB* L, uint16_t N, uint8_t startIndex, for (uint16_t i = 0; i < N; ++i) { L[i] = ColorFromPalette(pal, (colorIndex >> 8), brightness, blendType); - colorIndex += colorChange; + if (reversed) colorIndex -= colorChange; + else colorIndex += colorChange; } } -- cgit v1.2.3 From bbce974dc7111e7c11559812f5b6c2d8f7519cc8 Mon Sep 17 00:00:00 2001 From: David Madison Date: Sun, 2 Jan 2022 17:07:06 -0500 Subject: Add fill_circular keywords --- keywords.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/keywords.txt b/keywords.txt index 91e7b3b1..4fb29ab2 100644 --- a/keywords.txt +++ b/keywords.txt @@ -130,8 +130,9 @@ fade_video KEYWORD2 fill_gradient KEYWORD2 fill_gradient_RGB KEYWORD2 fill_palette KEYWORD2 +fill_palette_circular KEYWORD2 fill_rainbow KEYWORD2 -fill_rainbow_endless KEYWORD2 +fill_rainbow_circular KEYWORD2 fill_solid KEYWORD2 map_data_into_colors_through_palette KEYWORD2 nblend KEYWORD2 -- cgit v1.2.3