Again refactorings more

This commit is contained in:
2021-11-02 22:47:46 +01:00
parent 86a7ef66ee
commit d70a3aa73f
18 changed files with 795 additions and 787 deletions

View File

@ -0,0 +1,240 @@
#include "ledstripcolorsdisplay.h"
// esp-idf includes
#include <esp_log.h>
// 3rdparty lib includes
#include <TFT_eSPI.h>
#include <cpputils.h>
#include <menuitem.h>
#include <actions/switchscreenaction.h>
#include <actioninterface.h>
#include <tftinstance.h>
#include <screenmanager.h>
// local includes
#include "menudisplay.h"
#include "utils.h"
#include "icons/back.h"
#include "icons/bobbycar.h"
#include "texts.h"
#include "actions/dummyaction.h"
#include "globals.h"
#include "displays/menus/ledstripmenu.h"
int8_t selected_side = 7;
int8_t selected_color;
bool state_select_color{false};
bool last_state = {false};
const std::array<CRGB, 8> Colors = {
CRGB{0,0,0},
CRGB{255,255,255},
CRGB{255,0,0},
CRGB{255,255,0},
CRGB{0,255,0},
CRGB{0,255,255},
CRGB{0,0,255},
CRGB{255,0,255}
};
const std::array<uint16_t, 8> tft_colors = {
TFT_BLACK,
TFT_WHITE,
TFT_RED,
TFT_YELLOW,
TFT_GREEN,
TFT_CYAN,
TFT_BLUE,
TFT_MAGENTA
};
std::string LedstripColorsDisplay::text() const
{
return TEXT_LEDSTRIPCOLORMENU;
}
void LedstripColorsDisplay::back()
{
if(!state_select_color)
{
espgui::switchScreen<LedstripMenu>();
}
else
{
state_select_color = false;
espgui::tft.fillRect(0, 228, espgui::tft.width(), ((espgui::tft.width() - 40) / 8) + 4, TFT_BLACK);
}
}
void LedstripColorsDisplay::initScreen()
{
Base::initScreen();
espgui::tft.setSwapBytes(true);
espgui::tft.pushImage(70, 60, bobbyicons::bobbycar.WIDTH, bobbyicons::bobbycar.HEIGHT, bobbyicons::bobbycar.buffer);
espgui::tft.setSwapBytes(false);
}
void LedstripColorsDisplay::redraw()
{
Base::redraw();
auto y_pos = ((espgui::tft.width() - 40) / 8 + 4) + 240;
if (last_state != state_select_color)
{
espgui::tft.fillRect(0,y_pos - 1, espgui::tft.width(), 20, TFT_BLACK);
last_state = state_select_color;
}
espgui::tft.setTextFont(2);
espgui::tft.setTextColor(TFT_WHITE);
espgui::tft.drawString(state_select_color ?
"Please select a color!" :
"Please select a side!", 50, y_pos);
if (!already_drew_circle)
{
drawSide(static_cast<Bobbycar_Side>(selected_side), TFT_GOLD);
already_drew_circle = true;
}
}
void LedstripColorsDisplay::rotate(int offset)
{
if (offset < 0)
{
if (state_select_color)
{
selected_color++;
if (selected_color > 7)
{
selected_color = 0;
}
}
else
{
selected_side++;
if (selected_side > 7)
{
selected_side = 0;
}
}
}
else if (offset > 0)
{
if (state_select_color)
{
selected_color--;
if (selected_color < 0)
{
selected_color = 7;
}
}
else
{
selected_side--;
if (selected_side < 0)
{
selected_side = 7;
}
}
}
if (state_select_color)
{
drawColors();
}
else
{
espgui::tft.fillRect(0, 228, espgui::tft.width(), ((espgui::tft.width() - 40) / 8) + 4, TFT_BLACK);
clearSides();
drawSide(static_cast<Bobbycar_Side>(selected_side), TFT_GOLD);
}
}
void LedstripColorsDisplay::confirm()
{
if(!state_select_color)
{
state_select_color = true;
drawColors();
}
else
{
ledstrip_custom_colors[selected_side] = Colors[selected_color];
// Uncomment to close select color menu on color select
/*
state_select_color = false;
espgui::tft.fillRect(0, 228, espgui::tft.width(), ((espgui::tft.width() - 40) / 8) + 4, TFT_BLACK);
*/
}
}
void LedstripColorsDisplay::drawColors()
{
uint16_t width = (espgui::tft.width() - 40);
auto cube_width = width / 8;
espgui::tft.fillRect(0, 228, espgui::tft.width(), cube_width + 4, TFT_BLACK);
espgui::tft.fillRect(21, 231, width - 1, cube_width - 1, TFT_WHITE);
espgui::tft.fillRect(20 + (selected_color * cube_width - 1), 228, cube_width + 4, cube_width + 4, TFT_YELLOW);
for (int index = 0; index < 8; index++)
{
auto offset = index * (cube_width);
espgui::tft.fillRect(22 + offset, 232, cube_width - 4, cube_width - 4, tft_colors[index]);
}
}
void LedstripColorsDisplay::clearSides()
{
for(int index = 0; index < 8; index++)
{
drawSide(static_cast<Bobbycar_Side>(index), TFT_BLACK);
}
}
void LedstripColorsDisplay::drawSide(Bobbycar_Side side, unsigned int color)
{
const auto middle = espgui::tft.width() / 2;
const auto width = bobbyicons::bobbycar.WIDTH;
const auto height = bobbyicons::bobbycar.HEIGHT;
const auto left = middle - (width / 2);
const auto right = middle + (width / 2);
const auto above = 50;
const auto bellow = above + 10 + bobbyicons::bobbycar.HEIGHT;
switch (side) {
case Bobbycar_Side::FRONT:
espgui::tft.fillRect(left, above, width, 5, color);
break;
case Bobbycar_Side::FRONT_LEFT:
espgui::tft.fillRect(left - 10, above + 10, 5, height / 2, color);
espgui::tft.fillRect(left, above, width / 2, 5, color);
break;
case Bobbycar_Side::LEFT:
espgui::tft.fillRect(left - 10, above + 10, 5, height, color);
break;
case Bobbycar_Side::BACK_LEFT:
espgui::tft.fillRect(left - 10, above + 10 + (height / 2), 5, height / 2, color);
espgui::tft.fillRect(left, bellow + 5, width / 2, 5, color);
break;
case Bobbycar_Side::BACK:
espgui::tft.fillRect(left, bellow + 5, width, 5, color);
break;
case Bobbycar_Side::BACK_RIGHT:
espgui::tft.fillRect(right + 5, above + 10 + (height / 2), 5, height / 2, color);
espgui::tft.fillRect(middle, bellow + 5, width / 2, 5, color);
break;
case Bobbycar_Side::RIGHT:
espgui::tft.fillRect(right + 5, above + 10, 5, height, color);
break;
case Bobbycar_Side::FRONT_RIGHT:
espgui::tft.fillRect(right + 5, above + 10, 5, height / 2, color);
espgui::tft.fillRect(middle, above, width / 2, 5, color);
break;
}
// espgui::tft.fillCircle(espgui::tft.width() / 2, 140, 100, TFT_BLACK);
}

View File

@ -1,57 +1,23 @@
#pragma once
// esp-idf includes
#include <esp_log.h>
// system includes
#include <array>
// 3rdparty lib includes
#include <TFT_eSPI.h>
#include <displaywithtitle.h>
#include <FastLED.h>
#include <cpputils.h>
#include <menuitem.h>
#include <actions/switchscreenaction.h>
#include <actioninterface.h>
// local includes
#include "menudisplay.h"
#include "utils.h"
#include "ledstrip.h"
#include "icons/back.h"
#include "icons/bobbycar.h"
#include "texts.h"
#include "actions/dummyaction.h"
#include "globals.h"
namespace {
class LedstripMenu;
}
extern int8_t selected_side;
extern int8_t selected_color;
extern bool state_select_color;
extern bool last_state;
namespace {
static int8_t selected_side = 7;
static int8_t selected_color;
bool state_select_color{false};
bool last_state = {false};
extern const std::array<CRGB, 8> Colors;
const std::array<CRGB, 8> Colors = {
CRGB{0,0,0},
CRGB{255,255,255},
CRGB{255,0,0},
CRGB{255,255,0},
CRGB{0,255,0},
CRGB{0,255,255},
CRGB{0,0,255},
CRGB{255,0,255}
};
const std::array<uint16_t, 8> tft_colors = {
TFT_BLACK,
TFT_WHITE,
TFT_RED,
TFT_YELLOW,
TFT_GREEN,
TFT_CYAN,
TFT_BLUE,
TFT_MAGENTA
};
extern const std::array<uint16_t, 8> tft_colors;
class LedstripColorsDisplay : public espgui::DisplayWithTitle
{
@ -72,195 +38,3 @@ public:
private:
bool already_drew_circle{false};
};
std::string LedstripColorsDisplay::text() const
{
return TEXT_LEDSTRIPCOLORMENU;
}
void LedstripColorsDisplay::back()
{
if(!state_select_color)
{
switchScreen<LedstripMenu>();
}
else
{
state_select_color = false;
tft.fillRect(0, 228, tft.width(), ((tft.width() - 40) / 8) + 4, TFT_BLACK);
}
}
void LedstripColorsDisplay::initScreen()
{
Base::initScreen();
tft.setSwapBytes(true);
tft.pushImage(70, 60, bobbyicons::bobbycar.WIDTH, bobbyicons::bobbycar.HEIGHT, bobbyicons::bobbycar.buffer);
tft.setSwapBytes(false);
}
void LedstripColorsDisplay::redraw()
{
Base::redraw();
auto y_pos = ((tft.width() - 40) / 8 + 4) + 240;
if (last_state != state_select_color)
{
tft.fillRect(0,y_pos - 1, tft.width(), 20, TFT_BLACK);
last_state = state_select_color;
}
tft.setTextFont(2);
tft.setTextColor(TFT_WHITE);
tft.drawString(state_select_color ?
"Please select a color!" :
"Please select a side!", 50, y_pos);
if (!already_drew_circle)
{
drawSide(static_cast<Bobbycar_Side>(selected_side), TFT_GOLD);
already_drew_circle = true;
}
}
void LedstripColorsDisplay::rotate(int offset)
{
if (offset < 0)
{
if (state_select_color)
{
selected_color++;
if (selected_color > 7)
{
selected_color = 0;
}
}
else
{
selected_side++;
if (selected_side > 7)
{
selected_side = 0;
}
}
}
else if (offset > 0)
{
if (state_select_color)
{
selected_color--;
if (selected_color < 0)
{
selected_color = 7;
}
}
else
{
selected_side--;
if (selected_side < 0)
{
selected_side = 7;
}
}
}
if (state_select_color)
{
drawColors();
}
else
{
tft.fillRect(0, 228, tft.width(), ((tft.width() - 40) / 8) + 4, TFT_BLACK);
clearSides();
drawSide(static_cast<Bobbycar_Side>(selected_side), TFT_GOLD);
}
}
void LedstripColorsDisplay::confirm()
{
if(!state_select_color)
{
state_select_color = true;
drawColors();
}
else
{
ledstrip_custom_colors[selected_side] = Colors[selected_color];
// Uncomment to close select color menu on color select
/*
state_select_color = false;
tft.fillRect(0, 228, tft.width(), ((tft.width() - 40) / 8) + 4, TFT_BLACK);
*/
}
}
void LedstripColorsDisplay::drawColors()
{
uint16_t width = (tft.width() - 40);
auto cube_width = width / 8;
tft.fillRect(0, 228, tft.width(), cube_width + 4, TFT_BLACK);
tft.fillRect(21, 231, width - 1, cube_width - 1, TFT_WHITE);
tft.fillRect(20 + (selected_color * cube_width - 1), 228, cube_width + 4, cube_width + 4, TFT_YELLOW);
for (int index = 0; index < 8; index++)
{
auto offset = index * (cube_width);
tft.fillRect(22 + offset, 232, cube_width - 4, cube_width - 4, tft_colors[index]);
}
}
void LedstripColorsDisplay::clearSides()
{
for(int index = 0; index < 8; index++)
{
drawSide(static_cast<Bobbycar_Side>(index), TFT_BLACK);
}
}
void LedstripColorsDisplay::drawSide(Bobbycar_Side side, unsigned int color)
{
const auto middle = tft.width() / 2;
const auto width = bobbyicons::bobbycar.WIDTH;
const auto height = bobbyicons::bobbycar.HEIGHT;
const auto left = middle - (width / 2);
const auto right = middle + (width / 2);
const auto above = 50;
const auto bellow = above + 10 + bobbyicons::bobbycar.HEIGHT;
switch (side) {
case Bobbycar_Side::FRONT:
tft.fillRect(left, above, width, 5, color);
break;
case Bobbycar_Side::FRONT_LEFT:
tft.fillRect(left - 10, above + 10, 5, height / 2, color);
tft.fillRect(left, above, width / 2, 5, color);
break;
case Bobbycar_Side::LEFT:
tft.fillRect(left - 10, above + 10, 5, height, color);
break;
case Bobbycar_Side::BACK_LEFT:
tft.fillRect(left - 10, above + 10 + (height / 2), 5, height / 2, color);
tft.fillRect(left, bellow + 5, width / 2, 5, color);
break;
case Bobbycar_Side::BACK:
tft.fillRect(left, bellow + 5, width, 5, color);
break;
case Bobbycar_Side::BACK_RIGHT:
tft.fillRect(right + 5, above + 10 + (height / 2), 5, height / 2, color);
tft.fillRect(middle, bellow + 5, width / 2, 5, color);
break;
case Bobbycar_Side::RIGHT:
tft.fillRect(right + 5, above + 10, 5, height, color);
break;
case Bobbycar_Side::FRONT_RIGHT:
tft.fillRect(right + 5, above + 10, 5, height / 2, color);
tft.fillRect(middle, above, width / 2, 5, color);
break;
}
// tft.fillCircle(tft.width() / 2, 140, 100, TFT_BLACK);
}
} // Namespace

View File

@ -10,11 +10,6 @@
#include "texts.h"
#include "debugtexthelpers.h"
// forward declares
namespace {
class DebugMenu;
} // namespace
using namespace espgui;
namespace {

View File

@ -0,0 +1,59 @@
#include "debugmenu.h"
// 3rdparty lib includes
#include "menuitem.h"
#include "actions/switchscreenaction.h"
#include "actions/dummyaction.h"
#include "actions/toggleboolaction.h"
#include "checkboxicon.h"
#include "icons/back.h"
// local includes
#include "utils.h"
#include "actions/loadsettingsaction.h"
#include "actions/savesettingsaction.h"
#include "actions/erasenvsaction.h"
#include "icons/lock.h"
#include "debugcolorhelpers.h"
#include "esptexthelpers.h"
#include "displays/menus/commanddebugmenu.h"
#include "displays/menus/motorstatedebugmenu.h"
#include "displays/menus/feedbackdebugmenu.h"
#include "displays/menus/motorfeedbackdebugmenu.h"
#include "displays/menus/dynamicdebugmenu.h"
#include "displays/menus/mainmenu.h"
using namespace espgui;
DebugMenu::DebugMenu()
{
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_LOADSETTINGS>, LoadSettingsAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SAVESETTINGS>, SaveSettingsAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_ERASENVS>, EraseNvsAction>>();
constructMenuItem<makeComponent<MenuItem, EmptyText, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_FRONTCOMMAND>, SwitchScreenAction<FrontCommandDebugMenu>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACKCOMMAND>, SwitchScreenAction<BackCommandDebugMenu>>>();
constructMenuItem<makeComponent<MenuItem, EmptyText, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_FRONTLEFTCOMMAND>, SwitchScreenAction<FrontLeftMotorStateDebugMenu>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_FRONTRIGHTCOMMAND>, SwitchScreenAction<FrontRightMotorStateDebugMenu>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACKLEFTCOMMAND>, SwitchScreenAction<BackLeftMotorStateDebugMenu>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACKRIGHTCOMMAND>, SwitchScreenAction<BackRightMotorStateDebugMenu>>>();
constructMenuItem<makeComponent<MenuItem, EmptyText, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_FRONTFEEDBACK>, SwitchScreenAction<FrontFeedbackDebugMenu>, FrontFeedbackColor<TFT_WHITE>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACKFEEDBACK>, SwitchScreenAction<BackFeedbackDebugMenu>, BackFeedbackColor<TFT_WHITE>>>();
constructMenuItem<makeComponent<MenuItem, EmptyText, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, LastRebootReasonText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, EmptyText, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_FRONTLEFTFEEDBACK>, SwitchScreenAction<FrontLeftMotorFeedbackDebugMenu>, FrontFeedbackColor<TFT_WHITE>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_FRONTRIGHTFEEDBACK>, SwitchScreenAction<FrontRightMotorFeedbackDebugMenu>, FrontFeedbackColor<TFT_WHITE>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACKLEFTFEEDBACK>, SwitchScreenAction<BackLeftMotorFeedbackDebugMenu>, BackFeedbackColor<TFT_WHITE>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACKRIGHTFEEDBACK>, SwitchScreenAction<BackRightMotorFeedbackDebugMenu>, BackFeedbackColor<TFT_WHITE>>>();
constructMenuItem<makeComponent<MenuItem, EmptyText, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_DYNAMICMENU>, SwitchScreenAction<DynamicDebugMenu>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<MainMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
}
void DebugMenu::back()
{
switchScreen<MainMenu>();
}

View File

@ -1,56 +1,17 @@
#pragma once
// local includes
// 3rdparty lib includes
#include "menudisplay.h"
#include "utils.h"
#include "menuitem.h"
#include "actions/loadsettingsaction.h"
#include "actions/savesettingsaction.h"
#include "actions/erasenvsaction.h"
#include "actions/switchscreenaction.h"
#include "actions/dummyaction.h"
#include "actions/toggleboolaction.h"
#include "icons/lock.h"
#include "checkboxicon.h"
#include "icons/back.h"
// local includes
#include "texts.h"
#include "debugcolorhelpers.h"
using namespace espgui;
namespace {
class DebugMenu :
public MenuDisplay,
public StaticText<TEXT_DEBUG>,
public BackActionInterface<SwitchScreenAction<MainMenu>>
public espgui::MenuDisplay,
public espgui::StaticText<TEXT_DEBUG>
{
public:
DebugMenu()
{
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_LOADSETTINGS>, LoadSettingsAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SAVESETTINGS>, SaveSettingsAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_ERASENVS>, EraseNvsAction>>();
constructMenuItem<makeComponent<MenuItem, EmptyText, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_FRONTCOMMAND>, SwitchScreenAction<FrontCommandDebugMenu>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACKCOMMAND>, SwitchScreenAction<BackCommandDebugMenu>>>();
constructMenuItem<makeComponent<MenuItem, EmptyText, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_FRONTLEFTCOMMAND>, SwitchScreenAction<FrontLeftMotorStateDebugMenu>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_FRONTRIGHTCOMMAND>, SwitchScreenAction<FrontRightMotorStateDebugMenu>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACKLEFTCOMMAND>, SwitchScreenAction<BackLeftMotorStateDebugMenu>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACKRIGHTCOMMAND>, SwitchScreenAction<BackRightMotorStateDebugMenu>>>();
constructMenuItem<makeComponent<MenuItem, EmptyText, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_FRONTFEEDBACK>, SwitchScreenAction<FrontFeedbackDebugMenu>, FrontFeedbackColor<TFT_WHITE>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACKFEEDBACK>, SwitchScreenAction<BackFeedbackDebugMenu>, BackFeedbackColor<TFT_WHITE>>>();
constructMenuItem<makeComponent<MenuItem, EmptyText, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, LastRebootReasonText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, EmptyText, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_FRONTLEFTFEEDBACK>, SwitchScreenAction<FrontLeftMotorFeedbackDebugMenu>, FrontFeedbackColor<TFT_WHITE>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_FRONTRIGHTFEEDBACK>, SwitchScreenAction<FrontRightMotorFeedbackDebugMenu>, FrontFeedbackColor<TFT_WHITE>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACKLEFTFEEDBACK>, SwitchScreenAction<BackLeftMotorFeedbackDebugMenu>, BackFeedbackColor<TFT_WHITE>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACKRIGHTFEEDBACK>, SwitchScreenAction<BackRightMotorFeedbackDebugMenu>, BackFeedbackColor<TFT_WHITE>>>();
constructMenuItem<makeComponent<MenuItem, EmptyText, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_DYNAMICMENU>, SwitchScreenAction<DynamicDebugMenu>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<MainMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
}
DebugMenu();
void back() override;
};
} // namespace

View File

@ -22,11 +22,6 @@
#include "icons/back.h"
#include "texts.h"
// forward declares
namespace {
class DebugMenu;
} // namespace
using namespace espgui;
namespace {

View File

@ -11,11 +11,6 @@
#include "debugtexthelpers.h"
#include "debugcolorhelpers.h"
// forward declares
namespace {
class DebugMenu;
} // namespace
using namespace espgui;
namespace {

View File

@ -0,0 +1,143 @@
#include "ledstripmenu.h"
// 3rdparty lib includes
#include <FastLED.h>
#include "menuitem.h"
#include "actions/toggleboolaction.h"
#include "actions/switchscreenaction.h"
#include "icons/back.h"
#include "checkboxicon.h"
#include "changevaluedisplay.h"
#include "actioninterface.h"
// local includes
#include "ledstripselectanimationmenu.h"
#include "ledstripselectblinkmenu.h"
#include "globals.h"
#include "accessors/settingsaccessors.h"
#ifdef FEATURE_LEDSTRIP
#include "ledstrip.h"
#endif
#include "displays/ledstripcolorsdisplay.h"
#include "displays/menus/mainmenu.h"
#ifdef FEATURE_LEDSTRIP
namespace {
using LedsCountChangeScreen = makeComponent<
ChangeValueDisplay<int16_t>,
StaticText<TEXT_LEDSCOUNT>,
LedsCountAccessor,
BackActionInterface<SwitchScreenAction<LedstripMenu>>,
SwitchScreenAction<LedstripMenu>
>;
using CenterOffsetChangeScreen = makeComponent<
ChangeValueDisplay<int16_t>,
StaticText<TEXT_CENTEROFFSET>,
CenterOffsetAccessor,
BackActionInterface<SwitchScreenAction<LedstripMenu>>,
SwitchScreenAction<LedstripMenu>
>;
using SmallOffsetChangeScreen = makeComponent<
ChangeValueDisplay<int16_t>,
StaticText<TEXT_SMALLOFFSET>,
SmallOffsetAccessor,
BackActionInterface<SwitchScreenAction<LedstripMenu>>,
SwitchScreenAction<LedstripMenu>
>;
using BigOffsetChangeScreen = makeComponent<
ChangeValueDisplay<int16_t>,
StaticText<TEXT_BIGOFFSET>,
BigOffsetAccessor,
BackActionInterface<SwitchScreenAction<LedstripMenu>>,
SwitchScreenAction<LedstripMenu>
>;
using DeziampereChangeScreen = makeComponent<
ChangeValueDisplay<int16_t>,
StaticText<TEXT_LEDSTRIP_MILLIAMP>,
DeziampereAccessor,
BackActionInterface<SwitchScreenAction<LedstripMenu>>,
SwitchScreenAction<LedstripMenu>
>;
using StVOOffsetChangeScreen = makeComponent<
ChangeValueDisplay<int16_t>,
StaticText<TEXT_STVO_FRONTOFFSET>,
LedsStVOFrontOffsetAccessor,
BackActionInterface<SwitchScreenAction<LedstripMenu>>,
SwitchScreenAction<LedstripMenu>
>;
using StVOLengthChangeScreen = makeComponent<
ChangeValueDisplay<int16_t>,
StaticText<TEXT_STVO_FRONTLENGTH>,
LedsStVOFrontLengthAccessor,
BackActionInterface<SwitchScreenAction<LedstripMenu>>,
SwitchScreenAction<LedstripMenu>
>;
using animationMultiplierChangeScreen = makeComponent<
ChangeValueDisplay<int16_t>,
StaticText<TEXT_ANIMATION_MULTIPLIER>,
AnimationMultiplierAccessor,
BackActionInterface<SwitchScreenAction<LedstripMenu>>,
SwitchScreenAction<LedstripMenu>
>;
using ledstripBrightnessChangeScreen = makeComponent<
ChangeValueDisplay<uint8_t>,
StaticText<TEXT_LEDSTRIP_BRIGHTNESS>,
LedstripBrightnessAccessor,
BackActionInterface<SwitchScreenAction<LedstripMenu>>,
SwitchScreenAction<LedstripMenu>
>;
class AllCustomLedsOffAction : public virtual ActionInterface
{
public:
void triggered() override
{
for(int index = 0; index < 8; index++)
{
ledstrip_custom_colors[index] = CRGB{0,0,0};
}
}
};
} // namespace
using namespace espgui;
LedstripMenu::LedstripMenu()
{
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_LEDSTRIPCOLORMENU>, SwitchScreenAction<LedstripColorsDisplay>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_LEDANIMATION>, ToggleBoolAction, CheckboxIcon, EnableLedAnimationAccessor>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BRAKELIGHTS>, ToggleBoolAction, CheckboxIcon, EnableBrakeLightsAccessor>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BLINKBEEP>, ToggleBoolAction, CheckboxIcon, EnableBeepWhenBlinkAccessor>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_FULLBLINK>, ToggleBoolAction, CheckboxIcon, EnableFullBlinkAccessor>>();
if (!simplified) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_LEDSTRIP_STVO>, ToggleBoolAction, CheckboxIcon, EnableLedstripStVOAccessor>>(); }
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_STVO_ENABLEFRONTLIGHT>, ToggleBoolAction, CheckboxIcon, EnableLedstripStVOFrontlight>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_LEDSTRIP_ALLCUSTOMOFF>, AllCustomLedsOffAction>>();
if (!simplified) { constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_STVO_FRONTOFFSET, LedsStVOFrontOffsetAccessor>, SwitchScreenAction<StVOOffsetChangeScreen>>>(); }
if (!simplified) { constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_STVO_FRONTLENGTH, LedsStVOFrontLengthAccessor>, SwitchScreenAction<StVOLengthChangeScreen>>>(); }
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SELECTANIMATION>, SwitchScreenAction<LedstripSelectAnimationMenu>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BLINKANIMATION>, SwitchScreenAction<LedstripSelectBlinkMenu>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_ANIMATION_MULTIPLIER>, SwitchScreenAction<animationMultiplierChangeScreen>>>();
if (!simplified) { constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_LEDSCOUNT, LedsCountAccessor>, SwitchScreenAction<LedsCountChangeScreen>>>(); }
if (!simplified) { constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_CENTEROFFSET, CenterOffsetAccessor>, SwitchScreenAction<CenterOffsetChangeScreen>>>(); }
if (!simplified) { constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_SMALLOFFSET, SmallOffsetAccessor>, SwitchScreenAction<SmallOffsetChangeScreen>>>(); }
if (!simplified) { constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_BIGOFFSET, BigOffsetAccessor>, SwitchScreenAction<BigOffsetChangeScreen>>>(); }
if (!simplified) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_LEDSTRIP_BRIGHTNESS>, SwitchScreenAction<ledstripBrightnessChangeScreen>>>(); }
if (!simplified) { constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_LEDSTRIP_MILLIAMP, DeziampereAccessor>, SwitchScreenAction<DeziampereChangeScreen>>>(); }
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<MainMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
}
void LedstripMenu::back()
{
switchScreen<MainMenu>();
}
#endif

View File

@ -1,152 +1,19 @@
#pragma once
#include <FastLED.h>
// 3rdparty lib includes
#include "menudisplay.h"
// local includes
#include "menudisplay.h"
#include "menuitem.h"
#include "actions/toggleboolaction.h"
#include "actions/switchscreenaction.h"
#include "ledstripselectanimationmenu.h"
#include "ledstripselectblinkmenu.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
#include "changevaluedisplay.h"
#include "actioninterface.h"
// forward declares
namespace {
class MainWindow;
class LedstripColorsDisplay;
} // namespace
using namespace espgui;
namespace {
#ifdef FEATURE_LEDSTRIP
class LedstripMenu;
class LedstripSelectAnimationMenu;
using LedsCountChangeScreen = makeComponent<
ChangeValueDisplay<int16_t>,
StaticText<TEXT_LEDSCOUNT>,
LedsCountAccessor,
BackActionInterface<SwitchScreenAction<LedstripMenu>>,
SwitchScreenAction<LedstripMenu>
>;
using CenterOffsetChangeScreen = makeComponent<
ChangeValueDisplay<int16_t>,
StaticText<TEXT_CENTEROFFSET>,
CenterOffsetAccessor,
BackActionInterface<SwitchScreenAction<LedstripMenu>>,
SwitchScreenAction<LedstripMenu>
>;
using SmallOffsetChangeScreen = makeComponent<
ChangeValueDisplay<int16_t>,
StaticText<TEXT_SMALLOFFSET>,
SmallOffsetAccessor,
BackActionInterface<SwitchScreenAction<LedstripMenu>>,
SwitchScreenAction<LedstripMenu>
>;
using BigOffsetChangeScreen = makeComponent<
ChangeValueDisplay<int16_t>,
StaticText<TEXT_BIGOFFSET>,
BigOffsetAccessor,
BackActionInterface<SwitchScreenAction<LedstripMenu>>,
SwitchScreenAction<LedstripMenu>
>;
using DeziampereChangeScreen = makeComponent<
ChangeValueDisplay<int16_t>,
StaticText<TEXT_LEDSTRIP_MILLIAMP>,
DeziampereAccessor,
BackActionInterface<SwitchScreenAction<LedstripMenu>>,
SwitchScreenAction<LedstripMenu>
>;
using StVOOffsetChangeScreen = makeComponent<
ChangeValueDisplay<int16_t>,
StaticText<TEXT_STVO_FRONTOFFSET>,
LedsStVOFrontOffsetAccessor,
BackActionInterface<SwitchScreenAction<LedstripMenu>>,
SwitchScreenAction<LedstripMenu>
>;
using StVOLengthChangeScreen = makeComponent<
ChangeValueDisplay<int16_t>,
StaticText<TEXT_STVO_FRONTLENGTH>,
LedsStVOFrontLengthAccessor,
BackActionInterface<SwitchScreenAction<LedstripMenu>>,
SwitchScreenAction<LedstripMenu>
>;
using animationMultiplierChangeScreen = makeComponent<
ChangeValueDisplay<int16_t>,
StaticText<TEXT_ANIMATION_MULTIPLIER>,
AnimationMultiplierAccessor,
BackActionInterface<SwitchScreenAction<LedstripMenu>>,
SwitchScreenAction<LedstripMenu>
>;
using ledstripBrightnessChangeScreen = makeComponent<
ChangeValueDisplay<uint8_t>,
StaticText<TEXT_LEDSTRIP_BRIGHTNESS>,
LedstripBrightnessAccessor,
BackActionInterface<SwitchScreenAction<LedstripMenu>>,
SwitchScreenAction<LedstripMenu>
>;
class AllCustomLedsOffAction : public virtual ActionInterface
{
public:
void triggered() {
for(int index = 0; index < 8; index++)
{
ledstrip_custom_colors[index] = CRGB{0,0,0};
}
}
};
class LedstripMenu :
public MenuDisplay,
public StaticText<TEXT_LEDSTRIP>,
public BackActionInterface<SwitchScreenAction<MainMenu>>
public espgui::MenuDisplay,
public espgui::StaticText<TEXT_LEDSTRIP>
{
public:
LedstripMenu()
{
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_LEDSTRIPCOLORMENU>, SwitchScreenAction<LedstripColorsDisplay>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_LEDANIMATION>, ToggleBoolAction, CheckboxIcon, EnableLedAnimationAccessor>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BRAKELIGHTS>, ToggleBoolAction, CheckboxIcon, EnableBrakeLightsAccessor>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BLINKBEEP>, ToggleBoolAction, CheckboxIcon, EnableBeepWhenBlinkAccessor>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_FULLBLINK>, ToggleBoolAction, CheckboxIcon, EnableFullBlinkAccessor>>();
LedstripMenu();
if (!simplified) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_LEDSTRIP_STVO>, ToggleBoolAction, CheckboxIcon, EnableLedstripStVOAccessor>>(); }
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_STVO_ENABLEFRONTLIGHT>, ToggleBoolAction, CheckboxIcon, EnableLedstripStVOFrontlight>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_LEDSTRIP_ALLCUSTOMOFF>, AllCustomLedsOffAction>>();
if (!simplified) { constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_STVO_FRONTOFFSET, LedsStVOFrontOffsetAccessor>, SwitchScreenAction<StVOOffsetChangeScreen>>>(); }
if (!simplified) { constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_STVO_FRONTLENGTH, LedsStVOFrontLengthAccessor>, SwitchScreenAction<StVOLengthChangeScreen>>>(); }
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SELECTANIMATION>, SwitchScreenAction<LedstripSelectAnimationMenu>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BLINKANIMATION>, SwitchScreenAction<LedstripSelectBlinkMenu>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_ANIMATION_MULTIPLIER>, SwitchScreenAction<animationMultiplierChangeScreen>>>();
if (!simplified) { constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_LEDSCOUNT, LedsCountAccessor>, SwitchScreenAction<LedsCountChangeScreen>>>(); }
if (!simplified) { constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_CENTEROFFSET, CenterOffsetAccessor>, SwitchScreenAction<CenterOffsetChangeScreen>>>(); }
if (!simplified) { constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_SMALLOFFSET, SmallOffsetAccessor>, SwitchScreenAction<SmallOffsetChangeScreen>>>(); }
if (!simplified) { constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_BIGOFFSET, BigOffsetAccessor>, SwitchScreenAction<BigOffsetChangeScreen>>>(); }
if (!simplified) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_LEDSTRIP_BRIGHTNESS>, SwitchScreenAction<ledstripBrightnessChangeScreen>>>(); }
if (!simplified) { constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_LEDSTRIP_MILLIAMP, DeziampereAccessor>, SwitchScreenAction<DeziampereChangeScreen>>>(); }
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<MainMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
}
void back() override;
};
#endif
} // namespace

View File

@ -32,10 +32,6 @@ class currentSelectedAnimationText : public virtual TextInterface { public: std:
using namespace espgui;
namespace {
class LedstripMenu;
}
namespace {
class LedstripSelectAnimationMenu :
public MenuDisplay,

View File

@ -37,11 +37,7 @@ class currentSelectedBlinkAnimationText : public virtual TextInterface { public:
using namespace espgui;
namespace {
class LedstripMenu;
}
namespace {
namespace {
class LedstripSelectBlinkMenu :
public MenuDisplay,
public StaticText<TEXT_BLINKANIMATION>,

View File

@ -11,11 +11,6 @@
#include "debugtexthelpers.h"
#include "debugcolorhelpers.h"
// forward declares
namespace {
class DebugMenu;
} // namespace
using namespace espgui;
namespace {

View File

@ -10,11 +10,6 @@
#include "texts.h"
#include "debugtexthelpers.h"
// forward declares
namespace {
class DebugMenu;
} // namespace
using namespace espgui;
namespace {

View File

@ -0,0 +1,46 @@
#include "powersupplydisplay.h"
// 3rdparty lib includes
#include <tftinstance.h>
#include <screenmanager.h>
#include "actions/switchscreenaction.h"
// local includes
#include "globals.h"
#include "displays/menus/mainmenu.h"
#if defined(FEATURE_CAN) && defined(FEATURE_POWERSUPPLY)
void PowerSupplyDisplay::initScreen()
{
espgui::tft.fillScreen(TFT_BLACK);
espgui::tft.setTextColor(TFT_WHITE, TFT_BLACK);
espgui::tft.setTextFont(4);
espgui::tft.drawString("Voltage:", 0, m_voltageLabel.y());
m_voltageLabel.start();
espgui::tft.drawString("Current:", 0, m_currentLabel.y());
m_currentLabel.start();
}
void PowerSupplyDisplay::redraw()
{
m_voltageLabel.redraw(std::to_string(50.4) + 'V');
m_currentLabel.redraw(std::to_string(15.1) + 'A');
}
void PowerSupplyDisplay::confirm()
{
// TODO
}
void PowerSupplyDisplay::back()
{
espgui::switchScreen<MainMenu>();
}
void PowerSupplyDisplay::rotate(int offset)
{
// TODO
}
#endif

View File

@ -1,56 +1,24 @@
#pragma once
// Arduino includes
#include <Arduino.h>
// local includes
// 3rdparty lib includes
#include "display.h"
#include "actions/switchscreenaction.h"
#include "globals.h"
#include "widgets/label.h"
namespace {
#if defined(FEATURE_CAN) && defined(FEATURE_POWERSUPPLY)
class PowerSupplyDisplay : public Display, public DummyConfirm, public BackActionInterface<SwitchScreenAction<MainMenu>>
class PowerSupplyDisplay : public espgui::Display
{
using Base = espgui::Display;
public:
void initScreen() override;
void redraw() override;
void confirm() override;
void back() override;
void rotate(int offset) override;
Label m_voltageLabel{120, 50};
Label m_currentLabel{120, 75};
espgui::Label m_voltageLabel{120, 50};
espgui::Label m_currentLabel{120, 75};
};
void PowerSupplyDisplay::initScreen()
{
tft.fillScreen(TFT_BLACK);
tft.setTextColor(TFT_WHITE, TFT_BLACK);
tft.setTextFont(4);
tft.drawString("Voltage:", 0, m_voltageLabel.y());
m_voltageLabel.start();
tft.drawString("Current:", 0, m_currentLabel.y());
m_currentLabel.start();
}
void PowerSupplyDisplay::redraw()
{
m_voltageLabel.redraw(std::to_string(50.4) + 'V');
m_currentLabel.redraw(std::to_string(15.1) + 'A');
}
void PowerSupplyDisplay::confirm()
{
// TODO
}
void PowerSupplyDisplay::rotate(int offset)
{
// TODO
}
#endif
}

View File

@ -5,6 +5,7 @@
// 3rdparty lib includes
#include <fmt/core.h>
#include <espstrutils.h>
// local includes
#include "textinterface.h"
@ -37,46 +38,7 @@ class HeapLargest32Text : public virtual espgui::TextInterface { public: std::st
return fmt::format("HeapLargest32: {}", heap_caps_get_largest_free_block(MALLOC_CAP_INTERNAL|MALLOC_CAP_32BIT)); }};
class LastRebootReasonText : public virtual espgui::TextInterface { public: std::string text() const override {
std::string reset_reason_string;
switch (esp_reset_reason()) {
case 0:
reset_reason_string = "Unkown";
break;
case 1:
reset_reason_string = "Power on";
break;
case 2:
reset_reason_string = "External Pin";
break;
case 3:
reset_reason_string = "esp_restart";
break;
case 4:
reset_reason_string = "Exception/panic";
break;
case 5:
reset_reason_string = "Interrupt wd";
break;
case 6:
reset_reason_string = "Task wd";
break;
case 7:
reset_reason_string = "Other wd";
break;
case 8:
reset_reason_string = "Deepsleep";
break;
case 9:
reset_reason_string = "Brownout";
break;
case 10:
reset_reason_string = "SDIO";
break;
default:
return fmt::format("Last Reboot Reason: {}", esp_reset_reason());
}
return fmt::format("Last Reboot Reason: {}", reset_reason_string); }};
return fmt::format("Last Reboot Reason: {}", espcpputils::toString(esp_reset_reason())); }};
constexpr char TEXT_ESPCHIPREVISION[] = "Chip revision: ";
using EspChipRevisionText = espgui::StaticText<TEXT_ESPCHIPREVISION>; //EspStatusTextHelper<TEXT_ESPCHIPREVISION, uint8_t, &EspClass::getChipRevision>;

View File

@ -0,0 +1,259 @@
#include "ledstrip.h"
// 3rdparty lib includes
// local includes
#include "globals.h"
#include "cpputils.h"
#include "espchrono.h"
#include "ledstripdefines.h"
using namespace std::chrono_literals;
#ifdef FEATURE_LEDSTRIP
std::vector<CRGB> leds;
uint8_t gHue = 0;
int16_t blinkAnimation = LEDSTRIP_OVERWRITE_NONE;
int16_t animation_type = LEDSTRIP_ANIMATION_TYPE_DEFAULTRAINBOW;
void initLedStrip()
{
animation_type = settings.ledstrip.animationType;
leds.resize(settings.ledstrip.ledsCount);
FastLED.addLeds<NEOPIXEL, PINS_LEDSTRIP>(&*std::begin(leds), leds.size())
.setCorrection(TypicalSMD5050);
}
void updateLedStrip()
{
EVERY_N_MILLISECONDS( 20 ) { gHue++; }
static bool have_disabled_beeper = false;
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)
{
if (settings.ledstrip.enableBeepWhenBlink)
{
for (Controller &controller : controllers)
controller.command.buzzer.freq = 3;
}
auto color = CRGB{255, 255, 0};
const auto center = (std::begin(leds) + (leds.size() / 2) + settings.ledstrip.centerOffset);
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)
{
for (Controller &controller : controllers)
controller.command.buzzer.freq = 0;
}
}
}
else
{
if (settings.ledstrip.enableBrakeLights)
{
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 < -1.f)
{
auto color = avgSpeedKmh < -0.1f ? CRGB{255, 255, 255} : CRGB{255, 0, 0};
const auto center = (std::begin(leds) + (leds.size() / 2) + settings.ledstrip.centerOffset);
std::fill(std::begin(leds), std::end(leds), CRGB{0, 0, 0});
if (settings.ledstrip.enableFullBlink)
{
std::fill(std::begin(leds), std::end(leds), color);
}
else
{
std::fill(center - settings.ledstrip.bigOffset, center - settings.ledstrip.smallOffset, color);
std::fill(center + settings.ledstrip.smallOffset, center + settings.ledstrip.bigOffset, color);
}
}
else
{
showAnimation();
}
}
else
{
showAnimation();
}
}
if (have_disabled_beeper == false && (!(cpputils::is_in(blinkAnimation, LEDSTRIP_OVERWRITE_BLINKLEFT, LEDSTRIP_OVERWRITE_BLINKRIGHT, LEDSTRIP_OVERWRITE_BLINKBOTH)) || !settings.ledstrip.enableBeepWhenBlink))
{
for (Controller &controller : controllers)
controller.command.buzzer.freq = 0;
have_disabled_beeper = true;
}
else if ((cpputils::is_in(blinkAnimation, LEDSTRIP_OVERWRITE_BLINKLEFT, LEDSTRIP_OVERWRITE_BLINKRIGHT, LEDSTRIP_OVERWRITE_BLINKBOTH)) && settings.ledstrip.enableBeepWhenBlink) have_disabled_beeper = false;
if (simplified || settings.ledstrip.enableStVO)
{
const auto center = (std::begin(leds) + (leds.size() / 2) + settings.ledstrip.centerOffset);
if (!(blinkAnimation == LEDSTRIP_OVERWRITE_BLINKLEFT || blinkAnimation == LEDSTRIP_OVERWRITE_BLINKBOTH) || !(espchrono::millis_clock::now().time_since_epoch() % 750ms < 375ms) || settings.ledstrip.enableFullBlink) // Condition for right
{
std::fill(center - settings.ledstrip.bigOffset, center - settings.ledstrip.smallOffset, CRGB{0, 0, 0});
std::fill(center - settings.ledstrip.bigOffset - 1U, center - settings.ledstrip.smallOffset - 1U, CRGB{255, 0, 0}); // Right
}
if (!(blinkAnimation == LEDSTRIP_OVERWRITE_BLINKRIGHT || blinkAnimation == LEDSTRIP_OVERWRITE_BLINKBOTH) || !(espchrono::millis_clock::now().time_since_epoch() % 750ms < 375ms) || settings.ledstrip.enableFullBlink) // Condition for left
{
std::fill(center + settings.ledstrip.smallOffset, center + settings.ledstrip.bigOffset, CRGB{0, 0, 0});
std::fill(center + settings.ledstrip.smallOffset + 1U, center + settings.ledstrip.bigOffset + 1U, CRGB{255, 0, 0}); // Left
}
if (settings.ledstrip.stvoFrontEnable)
{
std::fill(std::begin(leds) + settings.ledstrip.stvoFrontOffset, std::begin(leds) + settings.ledstrip.stvoFrontOffset + settings.ledstrip.stvoFrontLength, CRGB{255, 255, 255});
std::fill(std::end(leds) - settings.ledstrip.stvoFrontOffset - settings.ledstrip.stvoFrontLength, std::end(leds) - settings.ledstrip.stvoFrontOffset, CRGB{255, 255, 255});
}
}
FastLED.setMaxPowerInVoltsAndMilliamps(5,settings.ledstrip.deziampere * 100);
FastLED.setBrightness(settings.ledstrip.brightness);
FastLED.show();
}
void showAnimation()
{
if (settings.ledstrip.enableLedAnimation && !simplified)
{
if (animation_type == LEDSTRIP_ANIMATION_TYPE_DEFAULTRAINBOW) showDefaultLedstrip();
else if (animation_type == LEDSTRIP_ANIMATION_TYPE_BETTERRAINBOW) showBetterRainbow();
else if (animation_type == LEDSTRIP_ANIMATION_TYPE_SPEEDSYNCANIMATION) showSpeedSyncAnimation();
else if (animation_type == LEDSTRIP_ANIMATION_TYPE_CUSTOMCOLOR) showCustomColor();
else showDefaultLedstrip();
}
else
{
std::fill(std::begin(leds), std::end(leds), CRGB{0, 0, 0});
}
}
void showBetterRainbow()
{
fill_rainbow(&*std::begin(leds), leds.size(), gHue);
}
void fill_rainbow_invert_at( struct CRGB * pFirstLED, int numToFill, int invertAtLed,
uint8_t initialhue,
float deltahue )
{
float huecalc = initialhue;
CHSV hsv;
hsv.hue = initialhue;
hsv.val = 255;
hsv.sat = 240;
for( int i = 0; i < numToFill; i++) {
hsv.hue = huecalc;
pFirstLED[i] = hsv;
if(i>invertAtLed){
huecalc -= deltahue;
}else{
huecalc += deltahue;
}
}
}
void showSpeedSyncAnimation()
{
#ifdef LEDS_PER_METER
const float leds_per_meter = LEDS_PER_METER;
#else
const float leds_per_meter = 144;
#endif
static auto last_interval = espchrono::millis_clock::now();
auto difference_ms = espchrono::ago(last_interval).count();
static float hue_result = 0;
const float hue_per_led = 1. / std::max(uint8_t(1), uint8_t(settings.ledstrip.animationMultiplier));
const float meter_per_second = avgSpeedKmh / 3.6;
const float leds_per_second = meter_per_second * leds_per_meter;
const float hue_per_second = leds_per_second * hue_per_led;
hue_result += hue_per_second * difference_ms / 1000.f;
fill_rainbow_invert_at(&*std::begin(leds), leds.size(),leds.size()/2, hue_result,-hue_per_led);
last_interval = espchrono::millis_clock::now();
}
void showDefaultLedstrip()
{
fadeToBlackBy(&*std::begin(leds), leds.size(), 20);
uint8_t dothue = 0;
for (int i = 0; i < 8; i++)
{
leds[beatsin16(i + 7, 0, leds.size())] |= CHSV(dothue, 200, 255);
dothue += 32;
}
}
void showCustomColor()
{
const auto eighth_length = leds.size() / 8;
const auto center = (std::begin(leds) + (leds.size() / 2) + settings.ledstrip.centerOffset);
std::fill(std::begin(leds), std::end(leds), ledstrip_custom_colors[int(Bobbycar_Side::FRONT)]); // Front
std::fill(center - (eighth_length / 2), center + (eighth_length / 2), ledstrip_custom_colors[int(Bobbycar_Side::BACK)]); // Back
#ifdef LEDSTRIP_WRONG_DIRECTION
std::fill(center + (eighth_length / 2), center + (eighth_length / 2) + eighth_length, ledstrip_custom_colors[int(Bobbycar_Side::BACK_LEFT)]); // Back Left
std::fill(center - (eighth_length / 2) - eighth_length, center - (eighth_length / 2), ledstrip_custom_colors[int(Bobbycar_Side::BACK_RIGHT)]); // Back Right
#else
std::fill(center + (eighth_length / 2), center + (eighth_length / 2) + eighth_length, ledstrip_custom_colors[int(Bobbycar_Side::BACK_RIGHT)]); // Back Right
std::fill(center - (eighth_length / 2) - eighth_length, center - (eighth_length / 2), ledstrip_custom_colors[int(Bobbycar_Side::BACK_LEFT)]); // Back Left
#endif
#ifdef LEDSTRIP_WRONG_DIRECTION
std::fill(center + (eighth_length / 2) + eighth_length, center + (eighth_length / 2) + eighth_length + eighth_length, ledstrip_custom_colors[int(Bobbycar_Side::LEFT)]); // Left
std::fill(center - (eighth_length / 2) - eighth_length - eighth_length, center - (eighth_length / 2) - eighth_length, ledstrip_custom_colors[int(Bobbycar_Side::RIGHT)]); // Right
#else
std::fill(center + (eighth_length / 2) + eighth_length, center + (eighth_length / 2) + eighth_length + eighth_length, ledstrip_custom_colors[int(Bobbycar_Side::RIGHT)]); // Right
std::fill(center - (eighth_length / 2) - eighth_length - eighth_length, center - (eighth_length / 2) - eighth_length, ledstrip_custom_colors[int(Bobbycar_Side::LEFT)]); // Left
#endif
#ifdef LEDSTRIP_WRONG_DIRECTION
std::fill(center + (eighth_length / 2) + eighth_length + eighth_length, center + (eighth_length / 2) + eighth_length + eighth_length + eighth_length, ledstrip_custom_colors[int(Bobbycar_Side::FRONT_LEFT)]); // Front Left
std::fill(center - (eighth_length / 2) - eighth_length - eighth_length - eighth_length, center - (eighth_length / 2) - eighth_length - eighth_length, ledstrip_custom_colors[int(Bobbycar_Side::FRONT_RIGHT)]); // Front Right
#else
std::fill(center + (eighth_length / 2) + eighth_length + eighth_length, center + (eighth_length / 2) + eighth_length + eighth_length + eighth_length, ledstrip_custom_colors[int(Bobbycar_Side::FRONT_RIGHT)]); // Front Right
std::fill(center - (eighth_length / 2) - eighth_length - eighth_length - eighth_length, center - (eighth_length / 2) - eighth_length - eighth_length, ledstrip_custom_colors[int(Bobbycar_Side::FRONT_LEFT)]); // Front Left
#endif
}
#endif

View File

@ -1,19 +1,14 @@
#pragma once
#ifdef FEATURE_LEDSTRIP
// system includes
#include <vector>
// 3rdparty lib includes
#include <FastLED.h>
// local includes
#include "globals.h"
#include "cpputils.h"
#include "espchrono.h"
#include "ledstripdefines.h"
using namespace std::chrono_literals;
namespace {
enum Bobbycar_Side {
#ifdef FEATURE_LEDSTRIP
enum Bobbycar_Side
{
FRONT_RIGHT,
RIGHT,
BACK_RIGHT,
@ -24,11 +19,11 @@ enum Bobbycar_Side {
FRONT
};
std::vector<CRGB> leds;
uint8_t gHue = 0;
extern std::vector<CRGB> leds;
extern uint8_t gHue;
int16_t blinkAnimation = LEDSTRIP_OVERWRITE_NONE;
int16_t animation_type = LEDSTRIP_ANIMATION_TYPE_DEFAULTRAINBOW;
extern int16_t blinkAnimation;
extern int16_t animation_type;
void showDefaultLedstrip();
void showAnimation();
@ -36,240 +31,7 @@ void showBetterRainbow();
void showSpeedSyncAnimation();
void showCustomColor();
void initLedStrip()
{
animation_type = settings.ledstrip.animationType;
leds.resize(settings.ledstrip.ledsCount);
FastLED.addLeds<NEOPIXEL, PINS_LEDSTRIP>(&*std::begin(leds), leds.size())
.setCorrection(TypicalSMD5050);
}
void initLedStrip();
void updateLedStrip()
{
EVERY_N_MILLISECONDS( 20 ) { gHue++; }
static bool have_disabled_beeper = false;
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)
{
if (settings.ledstrip.enableBeepWhenBlink)
{
for (Controller &controller : controllers)
controller.command.buzzer.freq = 3;
}
auto color = CRGB{255, 255, 0};
const auto center = (std::begin(leds) + (leds.size() / 2) + settings.ledstrip.centerOffset);
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)
{
for (Controller &controller : controllers)
controller.command.buzzer.freq = 0;
}
}
}
else
{
if (settings.ledstrip.enableBrakeLights)
{
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 < -1.f)
{
auto color = avgSpeedKmh < -0.1f ? CRGB{255, 255, 255} : CRGB{255, 0, 0};
const auto center = (std::begin(leds) + (leds.size() / 2) + settings.ledstrip.centerOffset);
std::fill(std::begin(leds), std::end(leds), CRGB{0, 0, 0});
if (settings.ledstrip.enableFullBlink)
{
std::fill(std::begin(leds), std::end(leds), color);
}
else
{
std::fill(center - settings.ledstrip.bigOffset, center - settings.ledstrip.smallOffset, color);
std::fill(center + settings.ledstrip.smallOffset, center + settings.ledstrip.bigOffset, color);
}
}
else
{
showAnimation();
}
}
else
{
showAnimation();
}
}
if (have_disabled_beeper == false && (!(cpputils::is_in(blinkAnimation, LEDSTRIP_OVERWRITE_BLINKLEFT, LEDSTRIP_OVERWRITE_BLINKRIGHT, LEDSTRIP_OVERWRITE_BLINKBOTH)) || !settings.ledstrip.enableBeepWhenBlink))
{
for (Controller &controller : controllers)
controller.command.buzzer.freq = 0;
have_disabled_beeper = true;
}
else if ((cpputils::is_in(blinkAnimation, LEDSTRIP_OVERWRITE_BLINKLEFT, LEDSTRIP_OVERWRITE_BLINKRIGHT, LEDSTRIP_OVERWRITE_BLINKBOTH)) && settings.ledstrip.enableBeepWhenBlink) have_disabled_beeper = false;
if (simplified || settings.ledstrip.enableStVO)
{
const auto center = (std::begin(leds) + (leds.size() / 2) + settings.ledstrip.centerOffset);
if (!(blinkAnimation == LEDSTRIP_OVERWRITE_BLINKLEFT || blinkAnimation == LEDSTRIP_OVERWRITE_BLINKBOTH) || !(espchrono::millis_clock::now().time_since_epoch() % 750ms < 375ms) || settings.ledstrip.enableFullBlink) // Condition for right
{
std::fill(center - settings.ledstrip.bigOffset, center - settings.ledstrip.smallOffset, CRGB{0, 0, 0});
std::fill(center - settings.ledstrip.bigOffset - 1U, center - settings.ledstrip.smallOffset - 1U, CRGB{255, 0, 0}); // Right
}
if (!(blinkAnimation == LEDSTRIP_OVERWRITE_BLINKRIGHT || blinkAnimation == LEDSTRIP_OVERWRITE_BLINKBOTH) || !(espchrono::millis_clock::now().time_since_epoch() % 750ms < 375ms) || settings.ledstrip.enableFullBlink) // Condition for left
{
std::fill(center + settings.ledstrip.smallOffset, center + settings.ledstrip.bigOffset, CRGB{0, 0, 0});
std::fill(center + settings.ledstrip.smallOffset + 1U, center + settings.ledstrip.bigOffset + 1U, CRGB{255, 0, 0}); // Left
}
if (settings.ledstrip.stvoFrontEnable)
{
std::fill(std::begin(leds) + settings.ledstrip.stvoFrontOffset, std::begin(leds) + settings.ledstrip.stvoFrontOffset + settings.ledstrip.stvoFrontLength, CRGB{255, 255, 255});
std::fill(std::end(leds) - settings.ledstrip.stvoFrontOffset - settings.ledstrip.stvoFrontLength, std::end(leds) - settings.ledstrip.stvoFrontOffset, CRGB{255, 255, 255});
}
}
FastLED.setMaxPowerInVoltsAndMilliamps(5,settings.ledstrip.deziampere * 100);
FastLED.setBrightness(settings.ledstrip.brightness);
FastLED.show();
}
void showAnimation() {
if (settings.ledstrip.enableLedAnimation && !simplified)
{
if (animation_type == LEDSTRIP_ANIMATION_TYPE_DEFAULTRAINBOW) showDefaultLedstrip();
else if (animation_type == LEDSTRIP_ANIMATION_TYPE_BETTERRAINBOW) showBetterRainbow();
else if (animation_type == LEDSTRIP_ANIMATION_TYPE_SPEEDSYNCANIMATION) showSpeedSyncAnimation();
else if (animation_type == LEDSTRIP_ANIMATION_TYPE_CUSTOMCOLOR) showCustomColor();
else showDefaultLedstrip();
}
else
{
std::fill(std::begin(leds), std::end(leds), CRGB{0, 0, 0});
}
}
void showBetterRainbow() {
fill_rainbow(&*std::begin(leds), leds.size(), gHue);
}
void fill_rainbow_invert_at( struct CRGB * pFirstLED, int numToFill, int invertAtLed,
uint8_t initialhue,
float deltahue )
{
float huecalc = initialhue;
CHSV hsv;
hsv.hue = initialhue;
hsv.val = 255;
hsv.sat = 240;
for( int i = 0; i < numToFill; i++) {
hsv.hue = huecalc;
pFirstLED[i] = hsv;
if(i>invertAtLed){
huecalc -= deltahue;
}else{
huecalc += deltahue;
}
}
}
void showSpeedSyncAnimation() {
#ifdef LEDS_PER_METER
const float leds_per_meter = LEDS_PER_METER;
#else
const float leds_per_meter = 144;
#endif
static auto last_interval = espchrono::millis_clock::now();
auto difference_ms = espchrono::ago(last_interval).count();
static float hue_result = 0;
const float hue_per_led = 1. / std::max(uint8_t(1), uint8_t(settings.ledstrip.animationMultiplier));
const float meter_per_second = avgSpeedKmh / 3.6;
const float leds_per_second = meter_per_second * leds_per_meter;
const float hue_per_second = leds_per_second * hue_per_led;
hue_result += hue_per_second * difference_ms / 1000.f;
fill_rainbow_invert_at(&*std::begin(leds), leds.size(),leds.size()/2, hue_result,-hue_per_led);
last_interval = espchrono::millis_clock::now();
}
void showDefaultLedstrip()
{
fadeToBlackBy(&*std::begin(leds), leds.size(), 20);
uint8_t dothue = 0;
for (int i = 0; i < 8; i++)
{
leds[beatsin16(i + 7, 0, leds.size())] |= CHSV(dothue, 200, 255);
dothue += 32;
}
}
void showCustomColor()
{
const auto eighth_length = leds.size() / 8;
const auto center = (std::begin(leds) + (leds.size() / 2) + settings.ledstrip.centerOffset);
std::fill(std::begin(leds), std::end(leds), ledstrip_custom_colors[int(Bobbycar_Side::FRONT)]); // Front
std::fill(center - (eighth_length / 2), center + (eighth_length / 2), ledstrip_custom_colors[int(Bobbycar_Side::BACK)]); // Back
#ifdef LEDSTRIP_WRONG_DIRECTION
std::fill(center + (eighth_length / 2), center + (eighth_length / 2) + eighth_length, ledstrip_custom_colors[int(Bobbycar_Side::BACK_LEFT)]); // Back Left
std::fill(center - (eighth_length / 2) - eighth_length, center - (eighth_length / 2), ledstrip_custom_colors[int(Bobbycar_Side::BACK_RIGHT)]); // Back Right
#else
std::fill(center + (eighth_length / 2), center + (eighth_length / 2) + eighth_length, ledstrip_custom_colors[int(Bobbycar_Side::BACK_RIGHT)]); // Back Right
std::fill(center - (eighth_length / 2) - eighth_length, center - (eighth_length / 2), ledstrip_custom_colors[int(Bobbycar_Side::BACK_LEFT)]); // Back Left
#endif
#ifdef LEDSTRIP_WRONG_DIRECTION
std::fill(center + (eighth_length / 2) + eighth_length, center + (eighth_length / 2) + eighth_length + eighth_length, ledstrip_custom_colors[int(Bobbycar_Side::LEFT)]); // Left
std::fill(center - (eighth_length / 2) - eighth_length - eighth_length, center - (eighth_length / 2) - eighth_length, ledstrip_custom_colors[int(Bobbycar_Side::RIGHT)]); // Right
#else
std::fill(center + (eighth_length / 2) + eighth_length, center + (eighth_length / 2) + eighth_length + eighth_length, ledstrip_custom_colors[int(Bobbycar_Side::RIGHT)]); // Right
std::fill(center - (eighth_length / 2) - eighth_length - eighth_length, center - (eighth_length / 2) - eighth_length, ledstrip_custom_colors[int(Bobbycar_Side::LEFT)]); // Left
#endif
#ifdef LEDSTRIP_WRONG_DIRECTION
std::fill(center + (eighth_length / 2) + eighth_length + eighth_length, center + (eighth_length / 2) + eighth_length + eighth_length + eighth_length, ledstrip_custom_colors[int(Bobbycar_Side::FRONT_LEFT)]); // Front Left
std::fill(center - (eighth_length / 2) - eighth_length - eighth_length - eighth_length, center - (eighth_length / 2) - eighth_length - eighth_length, ledstrip_custom_colors[int(Bobbycar_Side::FRONT_RIGHT)]); // Front Right
#else
std::fill(center + (eighth_length / 2) + eighth_length + eighth_length, center + (eighth_length / 2) + eighth_length + eighth_length + eighth_length, ledstrip_custom_colors[int(Bobbycar_Side::FRONT_RIGHT)]); // Front Right
std::fill(center - (eighth_length / 2) - eighth_length - eighth_length - eighth_length, center - (eighth_length / 2) - eighth_length - eighth_length, ledstrip_custom_colors[int(Bobbycar_Side::FRONT_LEFT)]); // Front Left
#endif
}
} // namespace
void updateLedStrip();
#endif