diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index 9cdd54f..36c1520 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -54,6 +54,7 @@ set(headers displays/menus/graphsmenu.h displays/menus/invertmenu.h displays/menus/larsmmodesettingsmenu.h + displays/menus/ledstripmenu.h displays/menus/modessettingsmenu.h displays/menus/mosfetsmenu.h displays/menus/motorstatedebugmenu.h diff --git a/main/accessors/settingsaccessors.h b/main/accessors/settingsaccessors.h index 16e3544..2d1d088 100644 --- a/main/accessors/settingsaccessors.h +++ b/main/accessors/settingsaccessors.h @@ -18,11 +18,11 @@ struct RefAccessorSaveSettings : public virtual RefAccessor #ifdef FEATURE_BMS struct AutoConnectBmsAccessor : public RefAccessorSaveSettings { bool &getRef() const override { return settings.autoConnectBms; } }; #endif -struct ReverseBeepAccessor : public RefAccessorSaveSettings { bool &getRef() const override { return settings.reverseBeep; } }; -struct ReverseBeepFreq0Accessor : public RefAccessorSaveSettings { uint8_t &getRef() const override { return settings.reverseBeepFreq0; } }; -struct ReverseBeepFreq1Accessor : public RefAccessorSaveSettings { uint8_t &getRef() const override { return settings.reverseBeepFreq1; } }; -struct ReverseBeepDuration0Accessor : public RefAccessorSaveSettings { int16_t &getRef() const override { return settings.reverseBeepDuration0; } }; -struct ReverseBeepDuration1Accessor : public RefAccessorSaveSettings { int16_t &getRef() const override { return settings.reverseBeepDuration1; } }; +struct ReverseBeepAccessor : public RefAccessorSaveSettings { bool &getRef() const override { return settings.buzzer.reverseBeep; } }; +struct ReverseBeepFreq0Accessor : public RefAccessorSaveSettings { uint8_t &getRef() const override { return settings.buzzer.reverseBeepFreq0; } }; +struct ReverseBeepFreq1Accessor : public RefAccessorSaveSettings { uint8_t &getRef() const override { return settings.buzzer.reverseBeepFreq1; } }; +struct ReverseBeepDuration0Accessor : public RefAccessorSaveSettings { int16_t &getRef() const override { return settings.buzzer.reverseBeepDuration0; } }; +struct ReverseBeepDuration1Accessor : public RefAccessorSaveSettings { int16_t &getRef() const override { return settings.buzzer.reverseBeepDuration1; } }; struct IMotMaxAccessor : public RefAccessorSaveSettings { int16_t &getRef() const override { return settings.limits.iMotMax; } }; struct IDcMaxAccessor : public RefAccessorSaveSettings { int16_t &getRef() const override { return settings.limits.iDcMax; } }; @@ -142,4 +142,8 @@ struct TempomatModeModelModeAccessor : public RefAccessorSaveSettings { UnifiedModelMode &getRef() const override { return settings.larsmMode.modelMode; } }; struct LarsmModeModeAccessor : public RefAccessorSaveSettings { LarsmModeMode &getRef() const override { return settings.larsmMode.mode; } }; struct LarsmModeIterationsAccessor : public RefAccessorSaveSettings { uint8_t &getRef() const override { return settings.larsmMode.iterations; } }; + +#ifdef FEATURE_LEDSTRIP +struct EnableBrakeLightsAccessor : public RefAccessorSaveSettings { bool &getRef() const override { return settings.ledstrip.enableBrakeLights; } }; +#endif } diff --git a/main/displays/menus/ledstripmenu.h b/main/displays/menus/ledstripmenu.h new file mode 100644 index 0000000..84620b4 --- /dev/null +++ b/main/displays/menus/ledstripmenu.h @@ -0,0 +1,42 @@ +#pragma once + +// local includes +#include "menudisplay.h" +#include "menuitem.h" +#include "actions/toggleboolaction.h" +#include "actions/switchscreenaction.h" +#include "texts.h" +#include "icons/back.h" +#include "checkboxicon.h" +#include "globals.h" +#include "accessors/settingsaccessors.h" +#ifdef FEATURE_LEDSTRIP +#include "ledstrip.h" +#endif + +// forward declares +namespace { +class MainWindow; +} // namespace + +using namespace espgui; + +namespace { +#ifdef FEATURE_LEDSTRIP +struct EnableLedAnimationAccessor : public RefAccessor { bool &getRef() const override { return enableLedAnimation; } }; + +class LedstripMenu : + public MenuDisplay, + public StaticText, + public BackActionInterface> +{ +public: + LedstripMenu() + { + constructMenuItem, ToggleBoolAction, CheckboxIcon, EnableLedAnimationAccessor>>(); + constructMenuItem, ToggleBoolAction, CheckboxIcon, EnableBrakeLightsAccessor>>(); + constructMenuItem, SwitchScreenAction, StaticMenuItemIcon<&espgui::icons::back>>>(); + } +}; +#endif +} // namespace diff --git a/main/displays/menus/mainmenu.h b/main/displays/menus/mainmenu.h index cd70f1b..223afb8 100644 --- a/main/displays/menus/mainmenu.h +++ b/main/displays/menus/mainmenu.h @@ -27,6 +27,7 @@ namespace { class StatusDisplay; class SelectModeMenu; +class LedstripMenu; class ProfilesMenu; class PresetsMenu; class GraphsMenu; @@ -55,6 +56,9 @@ public: { constructMenuItem, SwitchScreenAction, StaticMenuItemIcon<&espgui::icons::back>>>(); constructMenuItem, SwitchScreenAction, StaticMenuItemIcon<&icons::modes>>>(); +#ifdef FEATURE_LEDSTRIP + constructMenuItem, SwitchScreenAction>>(); +#endif constructMenuItem, ModeSettingsAction>>(); constructMenuItem, SwitchScreenAction, StaticMenuItemIcon<&icons::presets>>>(); constructMenuItem, SwitchScreenAction>>(); diff --git a/main/ledstrip.h b/main/ledstrip.h index fefc9d1..a83d8f5 100644 --- a/main/ledstrip.h +++ b/main/ledstrip.h @@ -8,9 +8,13 @@ #include "globals.h" namespace { +bool enableLedAnimation{false}; + std::array leds; uint8_t gHue = 0; +void showDefaultLedstrip(); + void initLedStrip() { FastLED.addLeds(std::begin(leds), leds.size()) @@ -21,28 +25,45 @@ void updateLedStrip() { EVERY_N_MILLISECONDS( 20 ) { gHue++; } - float avgPwm{}; - for (const Controller &controller : controllers) + if (settings.ledstrip.enableBrakeLights) { - avgPwm += - controller.command.left.pwm * (controller.invertLeft ? -1 : 1) + - controller.command.right.pwm * (controller.invertRight ? -1 : 1); - } - avgPwm /= 4; + float avgPwm{}; + for (const Controller &controller : controllers) + { + avgPwm += + controller.command.left.pwm * (controller.invertLeft ? -1 : 1) + + controller.command.right.pwm * (controller.invertRight ? -1 : 1); + } + avgPwm /= 4; - if (avgPwm < -50.f) - { - auto color = avgSpeedKmh < -0.1f ? CRGB{255, 255, 255} : CRGB{255, 0, 0}; - constexpr auto kleinerOffset = 4; - constexpr auto grosserOffset = 10; + if (avgPwm < -1.f) + { + auto color = avgSpeedKmh < -0.1f ? CRGB{255, 255, 255} : CRGB{255, 0, 0}; + constexpr auto kleinerOffset = 4; + constexpr auto grosserOffset = 10; - const auto center = std::begin(leds) + (leds.size() / 2) + 1; + const auto center = std::begin(leds) + (leds.size() / 2) + 1; - std::fill(std::begin(leds), std::end(leds), CRGB{0, 0, 0}); - std::fill(center - grosserOffset, center - kleinerOffset, color); - std::fill(center + kleinerOffset, center + grosserOffset, color); + std::fill(std::begin(leds), std::end(leds), CRGB{0, 0, 0}); + std::fill(center - grosserOffset, center - kleinerOffset, color); + std::fill(center + kleinerOffset, center + grosserOffset, color); + } + else + { + showDefaultLedstrip(); + } } else + { + showDefaultLedstrip(); + } + + FastLED.show(); +} + +void showDefaultLedstrip() +{ + if (enableLedAnimation) { fadeToBlackBy(std::begin(leds), leds.size(), 20); @@ -53,8 +74,8 @@ void updateLedStrip() dothue += 32; } } - - FastLED.show(); + else + std::fill(std::begin(leds), std::end(leds), CRGB{0, 0, 0}); } } // namespace #endif diff --git a/main/main.cpp b/main/main.cpp index 2868f92..40f4c51 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -52,6 +52,9 @@ using namespace std::chrono_literals; #include "displays/menus/controllerhardwaresettingsmenu.h" #include "displays/menus/invertmenu.h" #include "displays/menus/larsmmodesettingsmenu.h" +#ifdef FEATURE_LEDSTRIP +#include "displays/menus/ledstripmenu.h" +#endif #include "displays/menus/limitssettingsmenu.h" #include "displays/menus/mainmenu.h" #include "displays/menus/tempomatmodesettingsmenu.h" diff --git a/main/presets.h b/main/presets.h index 200fa80..addf9a4 100644 --- a/main/presets.h +++ b/main/presets.h @@ -24,6 +24,14 @@ constexpr Settings::Limits defaultLimits { .phaseAdvMax = DEFAULT_FIELDADVMAX }; +constexpr Settings::Buzzer defaultBuzzer { + .reverseBeep = false, + .reverseBeepFreq0 = 3, + .reverseBeepFreq1 = 0, + .reverseBeepDuration0 = 500, + .reverseBeepDuration1 = 500, +}; + constexpr Settings::Limits kidsLimits { .iMotMax = 5, .iDcMax = 7, @@ -205,15 +213,17 @@ constexpr Settings::LarsmMode defaultLarsmMode { .iterations = 100 }; +#ifdef FEATURE_LEDSTRIP +constexpr Settings::Ledstrip defaultLedstrip { + .enableBrakeLights = true +}; +#endif + constexpr Settings defaultSettings { #ifdef FEATURE_BMS .autoConnectBms = false, #endif - .reverseBeep = false, - .reverseBeepFreq0 = 3, - .reverseBeepFreq1 = 0, - .reverseBeepDuration0 = 500, - .reverseBeepDuration1 = 500, + .buzzer = defaultBuzzer, .limits = defaultLimits, .wifiSettings = defaultWifiSettings, #ifdef FEATURE_BLUETOOTH @@ -230,7 +240,10 @@ constexpr Settings defaultSettings { #endif .defaultMode = defaultDefaultMode, .tempomatMode = defaultTempomatMode, - .larsmMode = defaultLarsmMode + .larsmMode = defaultLarsmMode, +#ifdef FEATURE_LEDSTRIP + .ledstrip = defaultLedstrip, +#endif }; StringSettings makeDefaultStringSettings() diff --git a/main/settings.h b/main/settings.h index 5ea7163..ad52d39 100644 --- a/main/settings.h +++ b/main/settings.h @@ -30,11 +30,13 @@ struct Settings bool autoConnectBms; #endif - bool reverseBeep; - uint8_t reverseBeepFreq0; - uint8_t reverseBeepFreq1; - int16_t reverseBeepDuration0; - int16_t reverseBeepDuration1; + struct Buzzer { + bool reverseBeep; + uint8_t reverseBeepFreq0; + uint8_t reverseBeepFreq1; + int16_t reverseBeepDuration0; + int16_t reverseBeepDuration1; + } buzzer; struct Limits { int16_t iMotMax; // [A] Maximum motor current limit @@ -145,6 +147,11 @@ struct Settings uint8_t iterations; } larsmMode; +#ifdef FEATURE_LEDSTRIP + struct Ledstrip { + bool enableBrakeLights; + } ledstrip; +#endif template void executeForEveryCommonSetting(T &&callable); @@ -160,6 +167,12 @@ void Settings::executeForEveryCommonSetting(T &&callable) callable("autoConnectBms", autoConnectBms); #endif + callable("reverseBeep", buzzer.reverseBeep); + callable("revBeepFreq0", buzzer.reverseBeepFreq0); + callable("revBeepFreq1", buzzer.reverseBeepFreq1); + callable("revBeepDur0", buzzer.reverseBeepDuration0); + callable("revBeepDur1", buzzer.reverseBeepDuration1); + callable("wifiEnabled", wifiSettings.wifiEnabled); #ifdef FEATURE_BLUETOOTH @@ -221,17 +234,15 @@ void Settings::executeForEveryCommonSetting(T &&callable) callable("cloudEnabled", cloudSettings.cloudEnabled); callable("clodTransmTmout", cloudSettings.cloudTransmitTimeout); #endif + +#ifdef FEATURE_LEDSTRIP + callable("enableBrakeLigh", ledstrip.enableBrakeLights); +#endif } template void Settings::executeForEveryProfileSetting(T &&callable) { - callable("reverseBeep", reverseBeep); - callable("revBeepFreq0", reverseBeepFreq0); - callable("revBeepFreq1", reverseBeepFreq1); - callable("revBeepDur0", reverseBeepDuration0); - callable("revBeepDur1", reverseBeepDuration1); - callable("iMotMax", limits.iMotMax); callable("iDcMax", limits.iDcMax); callable("nMotMax", limits.nMotMax); diff --git a/main/texts.h b/main/texts.h index 7c6e9c8..6c25c40 100644 --- a/main/texts.h +++ b/main/texts.h @@ -232,6 +232,12 @@ constexpr char TEXT_SETMODE[] = "Set mode"; constexpr char TEXT_SETITERATIONS[] = "Set iterations"; //constexpr char TEXT_BACK[] = "Back"; +//LedstripMenu +constexpr char TEXT_LEDSTRIP[] = "Ledstrip"; +constexpr char TEXT_LEDANIMATION[] = "LED Animation"; +constexpr char TEXT_BRAKELIGHTS[] = "Brake Lights"; +//constexpr char TEXT_BACK[] = "Back"; + //ModesSettingsMenu //constexpr char TEXT_MODESSETTINGS[] = "Modes settings"; constexpr char TEXT_DEFAULTMODESETTIGNS[] = "Default mode settings"; diff --git a/main/utils.h b/main/utils.h index 2bd3bd5..da17079 100644 --- a/main/utils.h +++ b/main/utils.h @@ -138,7 +138,7 @@ void fixCommonParams() motor.phaseAdvMax = settings.limits.phaseAdvMax; } - if (settings.reverseBeep) + if (settings.buzzer.reverseBeep) { const auto x = motors(); const auto shouldBeep = std::all_of(std::begin(x), std::end(x), [](const bobbycar::protocol::serial::MotorState &motor){ return motor.pwm < 0; }); @@ -150,7 +150,7 @@ void fixCommonParams() reverseBeepToggle = true; lastReverseBeepToggle = espchrono::millis_clock::now(); for (auto &controller : controllers) - controller.command.buzzer = {.freq=settings.reverseBeepFreq0, .pattern=0}; + controller.command.buzzer = {.freq=settings.buzzer.reverseBeepFreq0, .pattern=0}; } else for (auto &controller : controllers) @@ -158,12 +158,12 @@ void fixCommonParams() currentlyReverseBeeping = shouldBeep; } - else if (shouldBeep && espchrono::millis_clock::now() - lastReverseBeepToggle >= std::chrono::milliseconds{reverseBeepToggle?settings.reverseBeepDuration0:settings.reverseBeepDuration1}) + else if (shouldBeep && espchrono::millis_clock::now() - lastReverseBeepToggle >= std::chrono::milliseconds{reverseBeepToggle?settings.buzzer.reverseBeepDuration0:settings.buzzer.reverseBeepDuration1}) { reverseBeepToggle = !reverseBeepToggle; for (auto &controller : controllers) - controller.command.buzzer = {.freq=uint8_t(reverseBeepToggle?settings.reverseBeepFreq0:settings.reverseBeepFreq1), .pattern=0}; + controller.command.buzzer = {.freq=uint8_t(reverseBeepToggle?settings.buzzer.reverseBeepFreq0:settings.buzzer.reverseBeepFreq1), .pattern=0}; lastReverseBeepToggle = espchrono::millis_clock::now(); }