From acfead4229534c2d7e98d07ec93d7d2dc15770bc Mon Sep 17 00:00:00 2001 From: DmitryBlinov Date: Tue, 30 Mar 2021 16:36:59 +0300 Subject: [PATCH] garland: add waves animation (#2430) * Add anim_waves * Minor fixes Co-authored-by: Dmitry Blinov --- code/espurna/garland.cpp | 2 +- code/espurna/garland/anim.h | 6 +-- code/espurna/garland/animations/anim_glow.h | 2 +- code/espurna/garland/animations/anim_waves.h | 55 ++++++++++++++++++++ code/espurna/garland/color.h | 27 +++++++++- code/espurna/garland/scene.h | 1 + 6 files changed, 86 insertions(+), 7 deletions(-) create mode 100644 code/espurna/garland/animations/anim_waves.h diff --git a/code/espurna/garland.cpp b/code/espurna/garland.cpp index 68932c18..1e9b87b5 100644 --- a/code/espurna/garland.cpp +++ b/code/espurna/garland.cpp @@ -139,7 +139,7 @@ Adafruit_NeoPixel pixels = Adafruit_NeoPixel(GARLAND_LEDS, GARLAND_D_PIN, NEO_GR Scene scene(&pixels); Anim* anims[] = {new AnimGlow(), new AnimStart(), new AnimPixieDust(), new AnimSparkr(), new AnimRun(), new AnimStars(), new AnimSpread(), - new AnimRandCyc(), new AnimFly(), new AnimComets(), new AnimAssemble(), new AnimDolphins(), new AnimSalut(), new AnimFountain()}; + new AnimRandCyc(), new AnimFly(), new AnimComets(), new AnimAssemble(), new AnimDolphins(), new AnimSalut(), new AnimFountain(), new AnimWaves()}; constexpr size_t animsSize() { return sizeof(anims)/sizeof(anims[0]); } diff --git a/code/espurna/garland/anim.h b/code/espurna/garland/anim.h index 4fffcbc1..fa69b197 100644 --- a/code/espurna/garland/anim.h +++ b/code/espurna/garland/anim.h @@ -37,11 +37,11 @@ protected: int inc; //brigthness animation (BrA) current initial phase - byte braPhase; + byte braPhase = 0; //braPhase change speed - byte braPhaseSpd = 5; + byte braPhaseSpd = 8; //BrA frequency (spatial) - byte braFreq = 150; + byte braFreq = 40; Color curColor = Color(0); Color prevColor = Color(0); diff --git a/code/espurna/garland/animations/anim_glow.h b/code/espurna/garland/animations/anim_glow.h index 96b4de99..bb3d91e6 100644 --- a/code/espurna/garland/animations/anim_glow.h +++ b/code/espurna/garland/animations/anim_glow.h @@ -22,7 +22,7 @@ class AnimGlow : public Anim { glowForEachLed(i); } } else { - for (int i = 0; i < numLeds; ++i) { + for (int i = numLeds - 1 ; i >= 0; --i) { leds[i] = curColor; glowForEachLed(i); } diff --git a/code/espurna/garland/animations/anim_waves.h b/code/espurna/garland/animations/anim_waves.h new file mode 100644 index 00000000..810e2529 --- /dev/null +++ b/code/espurna/garland/animations/anim_waves.h @@ -0,0 +1,55 @@ +#if GARLAND_SUPPORT + +#include "../anim.h" +#include "../palette.h" + +//------------------------------------------------------------------------------ +class AnimWaves : public Anim { + private: + int bra_phase; + int bra_phase_speed; + byte bra_speed; + byte bra_min; + int sign; + + public: + AnimWaves() : Anim("Waves") { + } + + void SetupImpl() override { + curColor = palette->getRndInterpColor().max_bright(); + glowSetUp(); + sign = braPhaseSpd > 128 ? -1 : 1; + bra_phase = secureRandom(255); + bra_phase_speed = secureRandom(2, 5); + bra_speed = secureRandom(4, 12); + bra_min = secureRandom(20, 30); + } + + void Run() override { + int bra = bra_phase; + int8_t bra_inc = -sign * bra_speed; + + for (int i = 0; i < numLeds; ++i) { + leds[i] = curColor; + glowForEachLed(i); + leds[i] = leds[i].brightness((byte)bra); + bra += bra_inc; + if (bra > 255 || bra < bra_min) { + bra_inc = -bra_inc; + bra = bra > 255 ? 255 : bra_min; + } + } + + glowRun(); + + bra_phase += bra_phase_speed; + if (bra_phase > 255 || bra_phase < bra_min) { + bra_phase_speed = -bra_phase_speed; + sign = -sign; + bra_phase = bra_phase > 255 ? 255 : bra_min; + } + } +}; + +#endif // GARLAND_SUPPORT diff --git a/code/espurna/garland/color.h b/code/espurna/garland/color.h index f86d4ee6..208874df 100644 --- a/code/espurna/garland/color.h +++ b/code/espurna/garland/color.h @@ -10,6 +10,7 @@ Inspired by https://github.com/Vasil-Pahomov/ArWs2812 (currently https://github. #if GARLAND_SUPPORT #include +#include struct Color { @@ -47,19 +48,35 @@ struct Color } //fades (decreases all RGB channels brightness) this color by k - void fade(byte k) { + Color& fade(byte k) { if (r>=k) { r=r-k; } else { r=0; } if (g>=k) { g=g-k; } else { g=0; } if (b>=k) { b=b-k; } else { b=0; } + return *this; } //fades color separately for each channel - void fade3(byte dr, byte dg, byte db) { + Color& fade3(byte dr, byte dg, byte db) { if (r>=dr) { r=r-dr; } else { r=0; } if (g>=dg) { g=g-dg; } else { g=0; } if (b>=db) { b=b-db; } else { b=0; } + return *this; } + Color max_bright() { + if (r==255 || g==255 || b==255) + return Color(r, g, b); + double kr = 255.0/r; + double kg = 255.0/g; + double kb = 255.0/b; + double k1 = kr < kg ? kr : kg; + double k2 = k1 < kb ? k1 : kb; + int r0 = r * k2; + int g0 = g * k2; + int b0 = b * k2; + return Color(r0, g0, b0); + } + //checks whether this color is visually close to given one bool isCloseTo(Color c) const { int diff = abs(r - c.r) + abs(g - c.g) + abs(b - c.b); @@ -81,6 +98,12 @@ struct Color Serial.print(("b="));Serial.println(b); } + String to_str() { + char buf[20]; + sprintf(buf, "r=%hhu, g=%hhu, b=%hhu", r, g, b); + return buf; + } + friend bool operator== (const Color &c1, const Color &c2); }; diff --git a/code/espurna/garland/scene.h b/code/espurna/garland/scene.h index 5a66b9e5..761cef26 100644 --- a/code/espurna/garland/scene.h +++ b/code/espurna/garland/scene.h @@ -27,6 +27,7 @@ Inspired by https://github.com/Vasil-Pahomov/ArWs2812 (currently https://github. #include "animations/anim_spread.h" #include "animations/anim_stars.h" #include "animations/anim_start.h" +#include "animations/anim_waves.h" class Adafruit_NeoPixel; class Palette;