From be05e423037158d4cdb42dfc55e6fd0ba492aa21 Mon Sep 17 00:00:00 2001 From: CommanderRedYT Date: Mon, 15 Nov 2021 20:38:54 +0100 Subject: [PATCH] Added blink animation (Resolves #106) --- main/accessors/settingsaccessors.h | 1 + main/displays/menus/ledstripselectblinkmenu.h | 5 + main/ledstrip.cpp | 103 ++++++++++++++---- main/ledstrip.h | 1 + main/ledstripdefines.h | 3 + main/presets.h | 3 +- main/settings.h | 2 + main/texts.h | 1 + main/utils.cpp | 27 ++++- main/utils.h | 1 + 10 files changed, 126 insertions(+), 21 deletions(-) diff --git a/main/accessors/settingsaccessors.h b/main/accessors/settingsaccessors.h index 7280cbe..6ae137a 100644 --- a/main/accessors/settingsaccessors.h +++ b/main/accessors/settingsaccessors.h @@ -171,6 +171,7 @@ struct LedsStVOFrontLengthAccessor : public RefAccessorSaveSettings { i struct EnableLedstripStVOFrontlight : public RefAccessorSaveSettings { bool &getRef() const override { return settings.ledstrip.stvoFrontEnable; } }; struct AnimationMultiplierAccessor : public RefAccessorSaveSettings { int16_t &getRef() const override { return settings.ledstrip.animationMultiplier; } }; struct LedstripBrightnessAccessor : public RefAccessorSaveSettings { uint8_t &getRef() const override { return settings.ledstrip.brightness; } }; +struct LedstripEnableBlinkAnimation : public RefAccessorSaveSettings { bool &getRef() const override { return settings.ledstrip.enableAnimBlink; } }; #endif // Battery diff --git a/main/displays/menus/ledstripselectblinkmenu.h b/main/displays/menus/ledstripselectblinkmenu.h index e565bf2..3f284e9 100644 --- a/main/displays/menus/ledstripselectblinkmenu.h +++ b/main/displays/menus/ledstripselectblinkmenu.h @@ -11,7 +11,11 @@ #include "actions/dummyaction.h" #include "actions/ledstripblinkactions.h" #include "actions/switchscreenaction.h" +#include "actions/toggleboolaction.h" +#include "checkboxicon.h" #include "ledstripdefines.h" +#include "accessors/settingsaccessors.h" +#include "ledstripmenu.h" #ifdef FEATURE_LEDSTRIP class currentSelectedBlinkAnimationText : public virtual TextInterface { public: std::string text() const override { @@ -53,6 +57,7 @@ namespace { constructMenuItem, LedstripAnimationBlinkLeftAction>>(); constructMenuItem, LedstripAnimationBlinkRightAction>>(); constructMenuItem, LedstripAnimationBlinkBothAction>>(); + constructMenuItem, ToggleBoolAction, CheckboxIcon, LedstripEnableBlinkAnimation>>(); constructMenuItem, SwitchScreenAction, StaticMenuItemIcon<&espgui::icons::back>>>(); } }; diff --git a/main/ledstrip.cpp b/main/ledstrip.cpp index 3264dba..c94bf3a 100644 --- a/main/ledstrip.cpp +++ b/main/ledstrip.cpp @@ -7,6 +7,7 @@ #include "cpputils.h" #include "espchrono.h" #include "ledstripdefines.h" +#include "utils.h" using namespace std::chrono_literals; @@ -34,33 +35,97 @@ void updateLedStrip() if (cpputils::is_in(blinkAnimation, LEDSTRIP_OVERWRITE_BLINKLEFT, LEDSTRIP_OVERWRITE_BLINKRIGHT, LEDSTRIP_OVERWRITE_BLINKBOTH)) { std::fill(std::begin(leds), std::end(leds), CRGB{0, 0, 0}); - if (espchrono::millis_clock::now().time_since_epoch() % 750ms < 375ms) + const bool enAnim = settings.ledstrip.enableAnimBlink; + if (espchrono::millis_clock::now().time_since_epoch() % 750ms < 375ms || enAnim) { + const auto anim_to_fill = time_to_percent(750ms, 500ms, 100ms, settings.ledstrip.enableFullBlink ? (leds.size() / 2) : settings.ledstrip.bigOffset - settings.ledstrip.smallOffset, settings.ledstrip.enableFullBlink); if (settings.ledstrip.enableBeepWhenBlink) { - for (Controller &controller : controllers) - controller.command.buzzer.freq = 3; + if (espchrono::millis_clock::now().time_since_epoch() % 750ms < 375ms) + for (Controller &controller : controllers) + controller.command.buzzer.freq = 3; + else + for (Controller &controller : controllers) + controller.command.buzzer.freq = 0; } - auto color = CRGB{255, 255, 0}; + auto color = CRGB{255, 200, 0}; const auto center = (std::begin(leds) + (leds.size() / 2) + settings.ledstrip.centerOffset); - if (blinkAnimation != LEDSTRIP_OVERWRITE_BLINKRIGHT && !settings.ledstrip.enableFullBlink) + if (settings.ledstrip.enableFullBlink) { - std::fill(center - settings.ledstrip.bigOffset, center - settings.ledstrip.smallOffset, color); + // Full + if (BLINK_LEFT_EXPR) + { + // Blink left + if (!enAnim) + { + std::fill(std::begin(leds), center, color); + } + else + { + std::fill(std::begin(leds)+anim_to_fill, center, color); + } + } + if (BLINK_RIGHT_EXPR) + { + // Blink right + if (!enAnim) + { + std::fill(center, std::end(leds), color); + } + else + { + std::fill(center, std::end(leds) - anim_to_fill, color); + } + } } - else if(blinkAnimation != LEDSTRIP_OVERWRITE_BLINKRIGHT && settings.ledstrip.enableFullBlink) + else { - std::fill(std::begin(leds), center, color); - } - if (blinkAnimation != LEDSTRIP_OVERWRITE_BLINKLEFT && !settings.ledstrip.enableFullBlink) - { - std::fill(center + settings.ledstrip.smallOffset, center + settings.ledstrip.bigOffset, color); - } - else if(blinkAnimation != LEDSTRIP_OVERWRITE_BLINKLEFT && settings.ledstrip.enableFullBlink) - { - std::fill(center, std::end(leds), color); + // Only in the back + if (BLINK_LEFT_EXPR) + { + // Blink left + if (!enAnim) + { + std::fill(center - settings.ledstrip.bigOffset, center - settings.ledstrip.smallOffset, color); + } + else + { + std::fill(center - settings.ledstrip.smallOffset - anim_to_fill, center - settings.ledstrip.smallOffset, color); + } + } + if (BLINK_RIGHT_EXPR) + { + // Blink right + if (!enAnim) + { + std::fill(center + settings.ledstrip.smallOffset, center + settings.ledstrip.bigOffset, color); + } + else + { + std::fill(center + settings.ledstrip.smallOffset, center + settings.ledstrip.smallOffset + anim_to_fill, color); + } + } } +// Old way to blink +// if (blinkAnimation != LEDSTRIP_OVERWRITE_BLINKRIGHT && !settings.ledstrip.enableFullBlink) +// { +// std::fill(center - settings.ledstrip.bigOffset, center - settings.ledstrip.smallOffset, color); +// } +// else if(blinkAnimation != LEDSTRIP_OVERWRITE_BLINKRIGHT && settings.ledstrip.enableFullBlink) +// { +// std::fill(std::begin(leds), center, color); +// } +// if (blinkAnimation != LEDSTRIP_OVERWRITE_BLINKLEFT && !settings.ledstrip.enableFullBlink) +// { +// std::fill(center + settings.ledstrip.smallOffset, center + settings.ledstrip.bigOffset, color); +// } +// else if(blinkAnimation != LEDSTRIP_OVERWRITE_BLINKLEFT && settings.ledstrip.enableFullBlink) +// { +// std::fill(center, std::end(leds), color); +// } + } else { if (settings.ledstrip.enableBeepWhenBlink) { @@ -93,10 +158,10 @@ void updateLedStrip() { std::fill(std::begin(leds), std::end(leds), color); } - else + else if(!settings.ledstrip.enableAnimBlink) { - std::fill(center - settings.ledstrip.bigOffset, center - settings.ledstrip.smallOffset, color); - std::fill(center + settings.ledstrip.smallOffset, center + settings.ledstrip.bigOffset, color); + std::fill(center - settings.ledstrip.bigOffset - 2, center - settings.ledstrip.smallOffset + 2, color); + std::fill(center + settings.ledstrip.smallOffset - 2, center + settings.ledstrip.bigOffset + 2, color); } } else diff --git a/main/ledstrip.h b/main/ledstrip.h index 76fcc34..ab7e6d5 100644 --- a/main/ledstrip.h +++ b/main/ledstrip.h @@ -7,6 +7,7 @@ #include #ifdef FEATURE_LEDSTRIP +#define crgb_iterator __gnu_cxx::__normal_iterator> enum Bobbycar_Side { FRONT_RIGHT, diff --git a/main/ledstripdefines.h b/main/ledstripdefines.h index efbdde8..283f1e3 100644 --- a/main/ledstripdefines.h +++ b/main/ledstripdefines.h @@ -18,3 +18,6 @@ #define LEDSTRIP_ANIMATION_TYPE_BETTERRAINBOW 1 #define LEDSTRIP_ANIMATION_TYPE_SPEEDSYNCANIMATION 2 #define LEDSTRIP_ANIMATION_TYPE_CUSTOMCOLOR 3 + +#define BLINK_LEFT_EXPR blinkAnimation != LEDSTRIP_OVERWRITE_BLINKRIGHT +#define BLINK_RIGHT_EXPR blinkAnimation != LEDSTRIP_OVERWRITE_BLINKLEFT diff --git a/main/presets.h b/main/presets.h index 99d81f8..98d766e 100644 --- a/main/presets.h +++ b/main/presets.h @@ -245,7 +245,8 @@ constexpr Settings::Ledstrip defaultLedstrip { .stvoFrontLength = 10, .stvoFrontEnable = false, .animationMultiplier = 10, - .brightness = 255 + .brightness = 255, + .enableAnimBlink = false }; #endif diff --git a/main/settings.h b/main/settings.h index d0b092a..483b787 100644 --- a/main/settings.h +++ b/main/settings.h @@ -170,6 +170,7 @@ struct Settings bool stvoFrontEnable; int16_t animationMultiplier; uint8_t brightness; + bool enableAnimBlink; } ledstrip; #endif @@ -302,6 +303,7 @@ void Settings::executeForEveryCommonSetting(T &&callable) callable("ledstvoen", ledstrip.stvoFrontEnable); callable("ledAnimMul", ledstrip.animationMultiplier); callable("ledbrightness", ledstrip.brightness); + callable("enAnimBlink", ledstrip.enableAnimBlink); #endif callable("batteryCS", battery.cellsSeries); diff --git a/main/texts.h b/main/texts.h index 9fec446..c939f79 100644 --- a/main/texts.h +++ b/main/texts.h @@ -293,6 +293,7 @@ constexpr char TEXT_STVO_ENABLEFRONTLIGHT[] = "StVO Front Enable"; constexpr char TEXT_ANIMATION_MULTIPLIER[] = "Animation Multiplier"; constexpr char TEXT_LEDSTRIP_BRIGHTNESS[] = "Ledstrip Brightness"; constexpr char TEXT_LEDSTRIP_ALLCUSTOMOFF[] = "All custom off"; +constexpr char TEXT_LEDSTRIP_EN_BLINK_ANIM[] = "Animated Blink"; //constexpr char TEXT_BACK[] = "Back"; //LedstripSelectAnimationMenu diff --git a/main/utils.cpp b/main/utils.cpp index 95e4cd0..0711c16 100644 --- a/main/utils.cpp +++ b/main/utils.cpp @@ -339,7 +339,8 @@ void secondsToHMS( const float seconds, uint16_t &h, uint16_t &m, uint16_t &s ) h = t; } -std::string get_current_driving_time_string() { +std::string get_current_driving_time_string() +{ uint16_t hour{}; uint16_t minute{}; uint16_t second{}; @@ -347,3 +348,27 @@ std::string get_current_driving_time_string() { std::string out = fmt::format("Drive: {:02d}:{:02d}:{:02d}", hour, minute, second); return out; } + +uint8_t time_to_percent(std::chrono::duration> repeat, std::chrono::duration> riseTime, std::chrono::duration> fullTime, size_t numLeds, bool invert) +{ + const auto now = espchrono::millis_clock::now().time_since_epoch() % repeat; + int activated = invert ? numLeds : 0; + if (now <= riseTime) + { + if (invert) + { + activated = numLeds - ((now*numLeds) / riseTime); + } + else + { + activated = (now*numLeds) / riseTime; + } + } + else if (now < riseTime + fullTime) + { + activated = invert ? 0 : numLeds; + } + else + activated = invert ? numLeds : 0; + return activated; +} diff --git a/main/utils.h b/main/utils.h index f91f709..b88a65c 100644 --- a/main/utils.h +++ b/main/utils.h @@ -61,3 +61,4 @@ float wattToMotorCurrent(float watt); std::string get_current_uptime_string(); std::string get_current_driving_time_string(); void secondsToHMS( const float seconds, uint16_t &h, uint8_t &m, uint8_t &s ); +uint8_t time_to_percent(std::chrono::duration> repeat, std::chrono::duration> riseTime, std::chrono::duration> fullTime, size_t numLeds, bool invert);