This commit is contained in:
2021-11-02 01:43:58 +01:00
parent 8c2ce911ba
commit 1de44c630b
57 changed files with 1789 additions and 1816 deletions

View File

@ -317,6 +317,7 @@ set(sources
displays/menus/presetsmenu.cpp
displays/menus/profilesmenu.cpp
displays/menus/selectbatterytypemenu.cpp
displays/menus/selectbuildservermenu.cpp
displays/menus/selectmodemenu.cpp
displays/menus/settingsmenu.cpp
displays/menus/stationwifisettingsmenu.cpp

View File

@ -0,0 +1,15 @@
#include "bluetoothbeginaction.h"
// local includes
#include "globals.h"
#ifdef FEATURE_BLUETOOTH
void BluetoothBeginAction::triggered()
{
if (!bluetoothSerial.begin(deviceName))
{
//Serial.println("Could not begin bluetooth");
// TODO: better error handling
}
}
#endif

View File

@ -1,23 +1,12 @@
#pragma once
#include "actioninterface.h"
#include "globals.h"
// 3rdparty lib includes
#include <actioninterface.h>
using namespace espgui;
namespace {
#ifdef FEATURE_BLUETOOTH
class BluetoothBeginAction : public virtual ActionInterface
class BluetoothBeginAction : public virtual espgui::ActionInterface
{
public:
void triggered() override
{
if (!bluetoothSerial.begin(deviceName))
{
//Serial.println("Could not begin bluetooth");
// TODO: better error handling
}
}
void triggered() override;
};
#endif
}

View File

@ -0,0 +1 @@
#include "battery.h"

View File

@ -3,10 +3,10 @@
// 3rdparty lib includes
#include <fmt/core.h>
#include <cpptypesafeenum.h>
#include <cpputils.h>
// local includes
#include "globals.h"
#include "cpputils.h"
#define BatteryCellTypeValues(x) \
x(_22P) \
@ -16,91 +16,94 @@
DECLARE_TYPESAFE_ENUM(BatteryCellType, : uint8_t, BatteryCellTypeValues)
namespace {
float mapFloat(float x, float in_min, float in_max, float out_min, float out_max) {
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
#define CURVE(higherVoltage,lowerVoltage,fromAh,toAh) if(cellVoltage >= lowerVoltage && cellVoltage <= higherVoltage) return 100 * (expected_ah - mapFloat(cellVoltage, higherVoltage, lowerVoltage, fromAh, toAh)) / expected_ah;
#define CURVE(higherVoltage,lowerVoltage,fromAh,toAh) \
if (cellVoltage >= lowerVoltage && cellVoltage <= higherVoltage) \
return 100 * (expected_ah - cpputils::mapValue<float>(cellVoltage, higherVoltage, lowerVoltage, fromAh, toAh)) / expected_ah;
float getBatteryPercentage(float batVoltage, BatteryCellType cellType)
{
const float cellVoltage = batVoltage / settings.battery.cellsSeries;
switch (cellType) {
case BatteryCellType::_22P: {
const float expected_ah = 2.2;
if(cellVoltage > 4.15){
return 100;
}
CURVE(4.15, 4.04, 0, 0.25)
CURVE(4.04, 3.95, 0.25, 0.5)
CURVE(3.95, 3.86, 0.5, 0.75)
CURVE(3.86, 3.74, 0.75, 1.0)
CURVE(3.74, 3.64, 1.0, 1.25)
CURVE(3.64, 3.59, 1.25, 1.5)
CURVE(3.59, 3.54, 1.5, 1.75)
CURVE(3.54, 3.43, 1.75, 2.0)
CURVE(3.43, 3.35, 2.0, 2.1)
CURVE(3.35, 2.50, 2.1, 2.2)
break;
}
case BatteryCellType::MH1: {
const float expected_ah = 3.2;
if(cellVoltage > 4.15){
return 100;
}
CURVE(4.15, 4.09, 0, 0.25)
CURVE(4.09, 4.04, 0.25, 0.5)
CURVE(4.04, 3.95, 0.5, 0.75)
CURVE(3.95, 3.88, 0.75, 1.0)
CURVE(3.88, 3.79, 1.0, 1.25)
CURVE(3.79, 3.70, 1.25, 1.5)
CURVE(3.70, 3.65, 1.5, 1.75)
CURVE(3.65, 3.60, 1.75, 2.0)
CURVE(3.60, 3.56, 2.0, 2.25)
CURVE(3.56, 3.50, 2.25, 2.5)
CURVE(3.50, 3.40, 2.5, 2.75)
CURVE(3.40, 3.30, 2.75, 3.0)
CURVE(3.30, 2.5, 3.0, 3.2)
break;
}
case BatteryCellType::HG2: {
const float expected_ah = 3.0;
if(cellVoltage > 4.15){
return 100;
}
CURVE(4.15, 4.08, 0, 0.25)
CURVE(4.08, 4.01, 0.25, 0.5)
CURVE(4.01, 3.92, 0.5, 0.75)
CURVE(3.92, 3.84, 0.75, 1.0)
CURVE(3.84, 3.75, 1.0, 1.25)
CURVE(3.75, 3.67, 1.25, 1.5)
CURVE(3.67, 3.62, 1.5, 1.75)
CURVE(3.62, 3.55, 1.75, 2.0)
CURVE(3.55, 3.44, 2.0, 2.25)
CURVE(3.44, 3.30, 2.25, 2.5)
CURVE(3.30, 3.05, 2.5, 2.75)
CURVE(3.05, 2.50, 2.75, 3.0)
break;
}
case BatteryCellType::VTC5: {
const float expected_ah = 2.6;
if(cellVoltage > 4.15){
return 100;
}
CURVE(4.15, 4.08, 0, 0.25)
CURVE(4.08, 3.98, 0.25, 0.5)
CURVE(3.98, 3.89, 0.5, 0.75)
CURVE(3.89, 3.79, 0.75, 1.0)
CURVE(3.79, 3.71, 1.0, 1.25)
CURVE(3.71, 3.64, 1.25, 1.5)
CURVE(3.64, 3.53, 1.5, 1.75)
CURVE(3.53, 3.44, 1.75, 2.0)
CURVE(3.44, 3.20, 2.0, 2.25)
CURVE(3.20, 2.80, 2.25, 2.5)
CURVE(2.80, 2.50, 2.5, 2.60)
break;
}
switch (cellType)
{
case BatteryCellType::_22P:
{
const float expected_ah = 2.2;
if (cellVoltage > 4.15)
return 100;
CURVE(4.15, 4.04, 0, 0.25)
CURVE(4.04, 3.95, 0.25, 0.5)
CURVE(3.95, 3.86, 0.5, 0.75)
CURVE(3.86, 3.74, 0.75, 1.0)
CURVE(3.74, 3.64, 1.0, 1.25)
CURVE(3.64, 3.59, 1.25, 1.5)
CURVE(3.59, 3.54, 1.5, 1.75)
CURVE(3.54, 3.43, 1.75, 2.0)
CURVE(3.43, 3.35, 2.0, 2.1)
CURVE(3.35, 2.50, 2.1, 2.2)
break;
}
case BatteryCellType::MH1:
{
const float expected_ah = 3.2;
if (cellVoltage > 4.15)
return 100;
CURVE(4.15, 4.09, 0, 0.25)
CURVE(4.09, 4.04, 0.25, 0.5)
CURVE(4.04, 3.95, 0.5, 0.75)
CURVE(3.95, 3.88, 0.75, 1.0)
CURVE(3.88, 3.79, 1.0, 1.25)
CURVE(3.79, 3.70, 1.25, 1.5)
CURVE(3.70, 3.65, 1.5, 1.75)
CURVE(3.65, 3.60, 1.75, 2.0)
CURVE(3.60, 3.56, 2.0, 2.25)
CURVE(3.56, 3.50, 2.25, 2.5)
CURVE(3.50, 3.40, 2.5, 2.75)
CURVE(3.40, 3.30, 2.75, 3.0)
CURVE(3.30, 2.5, 3.0, 3.2)
break;
}
case BatteryCellType::HG2:
{
const float expected_ah = 3.0;
if (cellVoltage > 4.15)
return 100;
CURVE(4.15, 4.08, 0, 0.25)
CURVE(4.08, 4.01, 0.25, 0.5)
CURVE(4.01, 3.92, 0.5, 0.75)
CURVE(3.92, 3.84, 0.75, 1.0)
CURVE(3.84, 3.75, 1.0, 1.25)
CURVE(3.75, 3.67, 1.25, 1.5)
CURVE(3.67, 3.62, 1.5, 1.75)
CURVE(3.62, 3.55, 1.75, 2.0)
CURVE(3.55, 3.44, 2.0, 2.25)
CURVE(3.44, 3.30, 2.25, 2.5)
CURVE(3.30, 3.05, 2.5, 2.75)
CURVE(3.05, 2.50, 2.75, 3.0)
break;
}
case BatteryCellType::VTC5:
{
const float expected_ah = 2.6;
if (cellVoltage > 4.15)
return 100;
CURVE(4.15, 4.08, 0, 0.25)
CURVE(4.08, 3.98, 0.25, 0.5)
CURVE(3.98, 3.89, 0.5, 0.75)
CURVE(3.89, 3.79, 0.75, 1.0)
CURVE(3.79, 3.71, 1.0, 1.25)
CURVE(3.71, 3.64, 1.25, 1.5)
CURVE(3.64, 3.53, 1.5, 1.75)
CURVE(3.53, 3.44, 1.75, 2.0)
CURVE(3.44, 3.20, 2.0, 2.25)
CURVE(3.20, 2.80, 2.25, 2.5)
CURVE(2.80, 2.50, 2.5, 2.60)
break;
}
}
return 0.f;
}
@ -116,7 +119,7 @@ float getRemainingWattHours()
float avgVoltage = 0;
for (auto &controller : controllers)
{
avgVoltage += controller.getCalibratedVoltage(settings.battery.applyCalibration);
avgVoltage += controller.getCalibratedVoltage();
}
avgVoltage = avgVoltage / controllers.size();
@ -128,7 +131,7 @@ std::string getBatteryPercentageString()
float avgVoltage = 0;
for (auto &controller : controllers)
{
avgVoltage += controller.getCalibratedVoltage(settings.battery.applyCalibration);
avgVoltage += controller.getCalibratedVoltage();
}
avgVoltage = avgVoltage / controllers.size();

View File

@ -81,11 +81,11 @@ void handleBle()
{
auto arr = doc.createNestedArray("v");
if (controllers.front.feedbackValid)
arr.add(controllers.front.getCalibratedVoltage(settings.battery.applyCalibration));
arr.add(controllers.front.getCalibratedVoltage());
else
arr.add(nullptr);
if (controllers.back.feedbackValid)
arr.add(controllers.back.getCalibratedVoltage(settings.battery.applyCalibration));
arr.add(controllers.back.getCalibratedVoltage());
else
arr.add(nullptr);
}

View File

@ -110,7 +110,7 @@ void cloudCollect()
}
cloudBuffer += fmt::format(",[{:.02f},{:.02f}",
controller.getCalibratedVoltage(settings.battery.applyCalibration),
controller.getCalibratedVoltage(),
fixBoardTemp(controller.feedback.boardTemp));
constexpr const auto addMotor = [](const bobbycar::protocol::serial::MotorState &command,

View File

@ -1,5 +1,8 @@
#include "controller.h"
// local includes
#include "globals.h"
Controller::Controller(
#ifdef FEATURE_SERIAL
HardwareSerial &serial,
@ -15,10 +18,10 @@ Controller::Controller(
{
}
float Controller::getCalibratedVoltage(bool applyCalibration) const
float Controller::getCalibratedVoltage() const
{
float voltage = feedback.batVoltage;
if (applyCalibration)
if (settings.battery.applyCalibration)
{
voltage = ((voltage - float(voltageCalib30V)) * (20.f / (float(voltageCalib50V) - float(voltageCalib30V))) + 30.f);
}

View File

@ -53,5 +53,5 @@ struct Controller
FeedbackParser parser{serial, feedbackValid, feedback};
#endif
float getCalibratedVoltage(bool applyCalibration) const;
float getCalibratedVoltage() const;
};

View File

@ -48,7 +48,7 @@ public:
using RightCommand = CommandTexts<LeftCommandGetter>;
//struct BatVoltageText : public virtual TextInterface { public: std::string text() const override { std::string line{"batVoltage: "}; if (controller::get().feedbackValid) line += std::to_string(controller::get().feedback.batVoltage); return line; } };
struct BatVoltageFixedText : public virtual TextInterface { public: std::string text() const override { std::string line{"batVoltage: "}; if (controller::get().feedbackValid) line += fmt::format("{:.2f}V", controller::get().getCalibratedVoltage(settings.battery.applyCalibration)); return line; } };
struct BatVoltageFixedText : public virtual TextInterface { public: std::string text() const override { std::string line{"batVoltage: "}; if (controller::get().feedbackValid) line += fmt::format("{:.2f}V", controller::get().getCalibratedVoltage()); return line; } };
//struct BoardTempText : public virtual TextInterface { public: std::string text() const override { std::string line{"boardTemp: "}; if (controller::get().feedbackValid) line += std::to_string(controller::get().feedback.boardTemp); return line; } };
struct BoardTempFixedText : public virtual TextInterface { public: std::string text() const override { std::string line{"boardTemp: "}; if (controller::get().feedbackValid) line += fmt::format("{:.2f}C", fixBoardTemp(controller::get().feedback.boardTemp)); return line; } };
struct TimeoutCntSerialText : public virtual TextInterface { public: std::string text() const override { std::string line{"timeoutCntSerial: "}; if (controller::get().feedbackValid) line += std::to_string(controller::get().feedback.timeoutCntSerial); return line; } };

View File

@ -11,11 +11,6 @@
#include "widgets/label.h"
#include "screenmanager.h"
namespace {
class MainMenu;
class MetersDisplay;
class StatusDisplay;
}
namespace {
#if defined(FEATURE_BLUETOOTH) && defined(FEATURE_BMS)
class BmsDisplay : public Display, public ConfirmActionInterface<SwitchScreenAction<MainMenu>>, public DummyBack

View File

@ -0,0 +1,276 @@
#include "calibratedisplay.h"
// 3rdparty lib includes
#include <tftinstance.h>
#include <screenmanager.h>
// local includes
#include "displays/statusdisplay.h"
#include "displays/menus/boardcomputerhardwaresettingsmenu.h"
CalibrateDisplay::CalibrateDisplay(bool bootup) :
m_bootup{bootup}
{
}
std::string CalibrateDisplay::text() const
{
return TEXT_CALIBRATE;
}
void CalibrateDisplay::start()
{
Base::start();
m_oldMode = currentMode;
currentMode = &m_mode;
m_selectedButton = 0;
m_status = Status::Begin;
copyFromSettings();
m_gas = std::nullopt;
m_brems = std::nullopt;
}
void CalibrateDisplay::initScreen()
{
Base::initScreen();
espgui::tft.setTextFont(4);
espgui::tft.setTextColor(TFT_WHITE, TFT_BLACK);
espgui::tft.drawString("gas:", 25, 47);
espgui::tft.drawString("brems:", 25, 147);
for (auto &label : m_labels)
label.start();
for (auto &progressBar : m_progressBars)
progressBar.start();
m_renderedButton = -1;
}
void CalibrateDisplay::update()
{
Base::update();
if (raw_gas)
m_gas = cpputils::mapValueClamped<float>(*raw_gas, m_gasMin, m_gasMax, 0., 1000.);
else
m_gas = std::nullopt;
if (raw_brems)
m_brems = cpputils::mapValueClamped<float>(*raw_brems, m_bremsMin, m_bremsMax, 0., 1000.);
else
m_brems = std::nullopt;
}
void CalibrateDisplay::redraw()
{
Base::redraw();
m_labels[0].redraw(m_gas ? fmt::format("{:.02f}", *m_gas) : "?");
m_labels[1].redraw(raw_gas ? std::to_string(*raw_gas) : "?");
if (m_status == Status::GasMin)
espgui::tft.setTextColor(TFT_RED, TFT_BLACK);
m_labels[2].redraw(std::to_string(m_gasMin));
if (m_status == Status::GasMin)
espgui::tft.setTextColor(TFT_WHITE, TFT_BLACK);
if (m_status == Status::GasMax)
espgui::tft.setTextColor(TFT_RED, TFT_BLACK);
m_labels[3].redraw(std::to_string(m_gasMax));
if (m_status == Status::GasMax)
espgui::tft.setTextColor(TFT_WHITE, TFT_BLACK);
m_progressBars[0].redraw(m_gas ? *m_gas : 0);
m_labels[4].redraw(m_brems ? fmt::format("{:.02f}", *m_brems) : "?");
m_labels[5].redraw(raw_brems ? std::to_string(*raw_brems) : "?");
if (m_status == Status::BremsMin)
espgui::tft.setTextColor(TFT_RED, TFT_BLACK);
m_labels[6].redraw(std::to_string(m_bremsMin));
if (m_status == Status::BremsMin)
espgui::tft.setTextColor(TFT_WHITE, TFT_BLACK);
if (m_status == Status::BremsMax)
espgui::tft.setTextColor(TFT_RED, TFT_BLACK);
m_labels[7].redraw(std::to_string(m_bremsMax));
if (m_status == Status::BremsMax)
espgui::tft.setTextColor(TFT_WHITE, TFT_BLACK);
m_progressBars[1].redraw(m_brems ? *m_brems : 0);
m_labels[8].redraw([&](){
switch (m_status)
{
case Status::Begin: return "Start calibrating?";
case Status::GasMin: return "Release gas";
case Status::GasMax: return "Press gas";
case Status::BremsMin: return "Release brems";
case Status::BremsMax: return "Press brems";
case Status::Confirm: return "Verify";
}
__builtin_unreachable();
}());
{
const auto failed = !m_gas || !m_brems || (m_status == Status::Confirm && (*m_gas > 100 || *m_brems > 100));
const auto color = failed ? TFT_DARKGREY : TFT_WHITE;
espgui::tft.setTextColor(color, TFT_BLACK);
m_labels[9].redraw([&](){
switch (m_status)
{
case Status::Begin: return "Yes";
case Status::GasMin:
case Status::GasMax:
case Status::BremsMin:
case Status::BremsMax: return "Next";
case Status::Confirm: return "Save";
}
__builtin_unreachable();
}());
if (m_selectedButton != m_renderedButton && (m_selectedButton == 0 || m_renderedButton == 0))
espgui::tft.drawRect(3, 275, 100, 27, m_selectedButton == 0 ? color : TFT_BLACK);
}
espgui::tft.setTextColor(TFT_WHITE, TFT_BLACK);
m_labels[10].redraw([&](){
switch (m_status)
{
case Status::Begin: return "No";
case Status::GasMin:
case Status::GasMax:
case Status::BremsMin:
case Status::BremsMax:
case Status::Confirm: return "Abort";
}
__builtin_unreachable();
}());
if (m_selectedButton != m_renderedButton && (m_selectedButton == 1 || m_renderedButton == 1))
espgui::tft.drawRect(123, 275, 100, 27, m_selectedButton == 1 ? TFT_WHITE : TFT_BLACK);
m_renderedButton = m_selectedButton;
}
void CalibrateDisplay::stop()
{
Base::stop();
if (currentMode == &m_mode)
{
// to avoid crash after deconstruction
m_mode.stop();
lastMode = nullptr;
currentMode = m_oldMode;
}
}
void CalibrateDisplay::rotate(int offset)
{
Base::rotate(offset);
m_selectedButton += offset;
if (m_selectedButton < 0)
m_selectedButton = 1;
if (m_selectedButton > 1)
m_selectedButton = 0;
}
void CalibrateDisplay::back()
{
Base::back();
switch (m_status)
{
case Status::Begin:
if (m_bootup)
espgui::switchScreen<StatusDisplay>();
else
espgui::switchScreen<BoardcomputerHardwareSettingsMenu>();
break;
case Status::GasMin:
case Status::GasMax:
case Status::BremsMin:
case Status::BremsMax:
case Status::Confirm:
m_selectedButton = 0;
m_status = Status::Begin;
copyFromSettings();
}
}
void CalibrateDisplay::confirm()
{
Base::confirm();
switch (m_selectedButton)
{
case 0: // left button pressed
if (!raw_gas || !raw_brems || !m_gas || !m_brems)
return;
switch (m_status)
{
case Status::Begin:
m_status = Status::GasMin;
break;
case Status::GasMin:
m_gasMin = *raw_gas;
m_status = Status::GasMax;
break;
case Status::GasMax:
m_gasMax = *raw_gas;
m_status = Status::BremsMin;
{
const auto dead = (m_gasMax - m_gasMin)/20;
m_gasMin += dead;
m_gasMax -= dead;
}
break;
case Status::BremsMin:
m_bremsMin = *raw_brems;
m_status = Status::BremsMax;
break;
case Status::BremsMax:
m_bremsMax = *raw_brems;
m_status = Status::Confirm;
{
const auto dead = (m_bremsMax - m_bremsMin)/20;
m_bremsMin += dead;
m_bremsMax -= dead;
}
break;
case Status::Confirm:
if (*m_gas > 100 || *m_brems > 100)
return;
copyToSettings();
saveSettings();
if (m_bootup)
espgui::switchScreen<StatusDisplay>();
else
espgui::switchScreen<BoardcomputerHardwareSettingsMenu>();
}
break;
case 1: // right button pressed
back();
}
}
void CalibrateDisplay::copyFromSettings()
{
m_gasMin = settings.boardcomputerHardware.gasMin;
m_gasMax = settings.boardcomputerHardware.gasMax;
m_bremsMin = settings.boardcomputerHardware.bremsMin;
m_bremsMax = settings.boardcomputerHardware.bremsMax;
}
void CalibrateDisplay::copyToSettings()
{
settings.boardcomputerHardware.gasMin = m_gasMin;
settings.boardcomputerHardware.gasMax = m_gasMax;
settings.boardcomputerHardware.bremsMin = m_bremsMin;
settings.boardcomputerHardware.bremsMax = m_bremsMax;
}

View File

@ -7,29 +7,26 @@
// 3rdparty lib includes
#include <fmt/core.h>
#include <cpputils.h>
#include <displaywithtitle.h>
#include <actions/switchscreenaction.h>
#include <widgets/label.h>
#include <widgets/progressbar.h>
// local includes
#include "display.h"
#include "actions/switchscreenaction.h"
#include "globals.h"
#include "utils.h"
#include "texts.h"
#include "widgets/label.h"
#include "widgets/progressbar.h"
#include "modes/ignoreinputmode.h"
namespace {
class StatusDisplay;
class BoardcomputerHardwareSettingsMenu;
}
namespace {
class CalibrateDisplay : public Display
class CalibrateDisplay : public espgui::DisplayWithTitle
{
using Base = espgui::DisplayWithTitle;
public:
CalibrateDisplay() = default;
CalibrateDisplay(bool bootup);
std::string text() const override;
void start() override;
void initScreen() override;
void update() override;
@ -50,26 +47,26 @@ private:
ModeInterface *m_oldMode;
IgnoreInputMode m_mode{0, bobbycar::protocol::ControlType::FieldOrientedControl, bobbycar::protocol::ControlMode::Torque};
std::array<Label, 11> m_labels {{
Label{25, 72}, // 100, 23
Label{145, 72}, // 100, 23
Label{25, 97}, // 100, 23
Label{145, 97}, // 100, 23
std::array<espgui::Label, 11> m_labels {{
espgui::Label{25, 72}, // 100, 23
espgui::Label{145, 72}, // 100, 23
espgui::Label{25, 97}, // 100, 23
espgui::Label{145, 97}, // 100, 23
Label{25, 172}, // 100, 23
Label{145, 172}, // 100, 23
Label{25, 197}, // 100, 23
Label{145, 197}, // 100, 23
espgui::Label{25, 172}, // 100, 23
espgui::Label{145, 172}, // 100, 23
espgui::Label{25, 197}, // 100, 23
espgui::Label{145, 197}, // 100, 23
Label{25, 247}, // 190, 23
espgui::Label{25, 247}, // 190, 23
Label{25, 277}, // 100, 23
Label{145, 277}, // 100, 23
espgui::Label{25, 277}, // 100, 23
espgui::Label{145, 277}, // 100, 23
}};
std::array<ProgressBar, 2> m_progressBars {{
ProgressBar{20, 129, 200, 10, 0, 1000},
ProgressBar{20, 229, 200, 10, 0, 1000}
std::array<espgui::ProgressBar, 2> m_progressBars {{
espgui::ProgressBar{20, 129, 200, 10, 0, 1000},
espgui::ProgressBar{20, 229, 200, 10, 0, 1000}
}};
enum Status {
@ -87,257 +84,3 @@ private:
int16_t m_gasMin, m_gasMax, m_bremsMin, m_bremsMax;
std::optional<float> m_gas, m_brems;
};
CalibrateDisplay::CalibrateDisplay(bool bootup) :
m_bootup{bootup}
{
}
void CalibrateDisplay::start()
{
m_oldMode = currentMode;
currentMode = &m_mode;
m_selectedButton = 0;
m_status = Status::Begin;
copyFromSettings();
m_gas = std::nullopt;
m_brems = std::nullopt;
}
void CalibrateDisplay::initScreen()
{
tft.fillScreen(TFT_BLACK);
tft.setTextFont(4);
tft.setTextColor(TFT_YELLOW);
tft.drawString(TEXT_CALIBRATE, 5, 5, 4);
tft.fillRect(0, 34, tft.width(), 3, TFT_WHITE);
tft.setTextColor(TFT_WHITE, TFT_BLACK);
tft.drawString("gas:", 25, 47);
tft.drawString("brems:", 25, 147);
for (auto &label : m_labels)
label.start();
for (auto &progressBar : m_progressBars)
progressBar.start();
m_renderedButton = -1;
}
void CalibrateDisplay::update()
{
if (raw_gas)
m_gas = cpputils::mapValueClamped<float>(*raw_gas, m_gasMin, m_gasMax, 0., 1000.);
else
m_gas = std::nullopt;
if (raw_brems)
m_brems = cpputils::mapValueClamped<float>(*raw_brems, m_bremsMin, m_bremsMax, 0., 1000.);
else
m_brems = std::nullopt;
}
void CalibrateDisplay::redraw()
{
m_labels[0].redraw(m_gas ? fmt::format("{:.02f}", *m_gas) : "?");
m_labels[1].redraw(raw_gas ? std::to_string(*raw_gas) : "?");
if (m_status == Status::GasMin)
tft.setTextColor(TFT_RED, TFT_BLACK);
m_labels[2].redraw(std::to_string(m_gasMin));
if (m_status == Status::GasMin)
tft.setTextColor(TFT_WHITE, TFT_BLACK);
if (m_status == Status::GasMax)
tft.setTextColor(TFT_RED, TFT_BLACK);
m_labels[3].redraw(std::to_string(m_gasMax));
if (m_status == Status::GasMax)
tft.setTextColor(TFT_WHITE, TFT_BLACK);
m_progressBars[0].redraw(m_gas ? *m_gas : 0);
m_labels[4].redraw(m_brems ? fmt::format("{:.02f}", *m_brems) : "?");
m_labels[5].redraw(raw_brems ? std::to_string(*raw_brems) : "?");
if (m_status == Status::BremsMin)
tft.setTextColor(TFT_RED, TFT_BLACK);
m_labels[6].redraw(std::to_string(m_bremsMin));
if (m_status == Status::BremsMin)
tft.setTextColor(TFT_WHITE, TFT_BLACK);
if (m_status == Status::BremsMax)
tft.setTextColor(TFT_RED, TFT_BLACK);
m_labels[7].redraw(std::to_string(m_bremsMax));
if (m_status == Status::BremsMax)
tft.setTextColor(TFT_WHITE, TFT_BLACK);
m_progressBars[1].redraw(m_brems ? *m_brems : 0);
m_labels[8].redraw([&](){
switch (m_status)
{
case Status::Begin: return "Start calibrating?";
case Status::GasMin: return "Release gas";
case Status::GasMax: return "Press gas";
case Status::BremsMin: return "Release brems";
case Status::BremsMax: return "Press brems";
case Status::Confirm: return "Verify";
}
__builtin_unreachable();
}());
{
const auto failed = !m_gas || !m_brems || (m_status == Status::Confirm && (*m_gas > 100 || *m_brems > 100));
const auto color = failed ? TFT_DARKGREY : TFT_WHITE;
tft.setTextColor(color, TFT_BLACK);
m_labels[9].redraw([&](){
switch (m_status)
{
case Status::Begin: return "Yes";
case Status::GasMin:
case Status::GasMax:
case Status::BremsMin:
case Status::BremsMax: return "Next";
case Status::Confirm: return "Save";
}
__builtin_unreachable();
}());
if (m_selectedButton != m_renderedButton && (m_selectedButton == 0 || m_renderedButton == 0))
tft.drawRect(3, 275, 100, 27, m_selectedButton == 0 ? color : TFT_BLACK);
}
tft.setTextColor(TFT_WHITE, TFT_BLACK);
m_labels[10].redraw([&](){
switch (m_status)
{
case Status::Begin: return "No";
case Status::GasMin:
case Status::GasMax:
case Status::BremsMin:
case Status::BremsMax:
case Status::Confirm: return "Abort";
}
__builtin_unreachable();
}());
if (m_selectedButton != m_renderedButton && (m_selectedButton == 1 || m_renderedButton == 1))
tft.drawRect(123, 275, 100, 27, m_selectedButton == 1 ? TFT_WHITE : TFT_BLACK);
m_renderedButton = m_selectedButton;
}
void CalibrateDisplay::stop()
{
if (currentMode == &m_mode)
{
// to avoid crash after deconstruction
m_mode.stop();
lastMode = nullptr;
currentMode = m_oldMode;
}
}
void CalibrateDisplay::rotate(int offset)
{
m_selectedButton += offset;
if (m_selectedButton < 0)
m_selectedButton = 1;
if (m_selectedButton > 1)
m_selectedButton = 0;
}
void CalibrateDisplay::back()
{
switch (m_status)
{
case Status::Begin:
if (m_bootup)
switchScreen<StatusDisplay>();
else
switchScreen<BoardcomputerHardwareSettingsMenu>();
break;
case Status::GasMin:
case Status::GasMax:
case Status::BremsMin:
case Status::BremsMax:
case Status::Confirm:
m_selectedButton = 0;
m_status = Status::Begin;
copyFromSettings();
}
}
void CalibrateDisplay::confirm()
{
switch (m_selectedButton)
{
case 0: // left button pressed
if (!raw_gas || !raw_brems || !m_gas || !m_brems)
return;
switch (m_status)
{
case Status::Begin:
m_status = Status::GasMin;
break;
case Status::GasMin:
m_gasMin = *raw_gas;
m_status = Status::GasMax;
break;
case Status::GasMax:
m_gasMax = *raw_gas;
m_status = Status::BremsMin;
{
const auto dead = (m_gasMax - m_gasMin)/20;
m_gasMin += dead;
m_gasMax -= dead;
}
break;
case Status::BremsMin:
m_bremsMin = *raw_brems;
m_status = Status::BremsMax;
break;
case Status::BremsMax:
m_bremsMax = *raw_brems;
m_status = Status::Confirm;
{
const auto dead = (m_bremsMax - m_bremsMin)/20;
m_bremsMin += dead;
m_bremsMax -= dead;
}
break;
case Status::Confirm:
if (*m_gas > 100 || *m_brems > 100)
return;
copyToSettings();
saveSettings();
if (m_bootup)
switchScreen<StatusDisplay>();
else
switchScreen<BoardcomputerHardwareSettingsMenu>();
}
break;
case 1: // right button pressed
back();
}
}
void CalibrateDisplay::copyFromSettings()
{
m_gasMin = settings.boardcomputerHardware.gasMin;
m_gasMax = settings.boardcomputerHardware.gasMax;
m_bremsMin = settings.boardcomputerHardware.bremsMin;
m_bremsMax = settings.boardcomputerHardware.bremsMax;
}
void CalibrateDisplay::copyToSettings()
{
settings.boardcomputerHardware.gasMin = m_gasMin;
settings.boardcomputerHardware.gasMax = m_gasMax;
settings.boardcomputerHardware.bremsMin = m_bremsMin;
settings.boardcomputerHardware.bremsMax = m_bremsMax;
}
}

View File

@ -0,0 +1,82 @@
#include "calibratevoltagedisplay.h"
// 3rdparty lib includes
#include <fmt/core.h>
#include <actions/toggleboolaction.h>
#include <checkboxicon.h>
// local includes
#include "displays/menus/batterymenu.h"
#include "accessors/settingsaccessors.h"
namespace {
class Save30VCalibrationAction : public virtual espgui::ActionInterface
{
public:
void triggered() override
{
settings.battery.front30VoltCalibration = controllers.front.feedback.batVoltage;
settings.battery.back30VoltCalibration = controllers.back.feedback.batVoltage;
saveSettings();
}
};
class Save50VCalibrationAction : public virtual espgui::ActionInterface
{
public:
void triggered() override
{
settings.battery.front50VoltCalibration = controllers.front.feedback.batVoltage;
settings.battery.back50VoltCalibration = controllers.back.feedback.batVoltage;
saveSettings();
}
};
class ResetCalibrationAction : public virtual espgui::ActionInterface
{
public:
void triggered() override
{
settings.battery.front30VoltCalibration = 3000;
settings.battery.back30VoltCalibration = 3000;
settings.battery.front50VoltCalibration = 5000;
settings.battery.back50VoltCalibration = 5000;
saveSettings();
}
};
float convertToFloat(int16_t value)
{
return value/100.;
}
class BatteryVoltageCalibrationFront30VText : public virtual espgui::TextInterface { public: std::string text() const override { return fmt::format("30V Front: {}", convertToFloat(settings.battery.front30VoltCalibration)); } };
class BatteryVoltageCalibrationBack30VText : public virtual espgui::TextInterface { public: std::string text() const override { return fmt::format("30V Back: {}", convertToFloat(settings.battery.back30VoltCalibration)); } };
class BatteryVoltageCalibrationFront50VText : public virtual espgui::TextInterface { public: std::string text() const override { return fmt::format("50V Front: {}", convertToFloat(settings.battery.front50VoltCalibration)); } };
class BatteryVoltageCalibrationBack50VText : public virtual espgui::TextInterface { public: std::string text() const override { return fmt::format("50V Back: {}", convertToFloat(settings.battery.back50VoltCalibration)); } };
class BatteryVoltageCalibratedText : public virtual espgui::TextInterface { public: std::string text() const override { if (settings.battery.applyCalibration) return fmt::format("F{:.2f}V B{:.2f}", controllers.front.getCalibratedVoltage(), controllers.back.getCalibratedVoltage()); else return "Not activated"; } };
} // namespace
using namespace espgui;
CalibrateVoltageDisplay::CalibrateVoltageDisplay()
{
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_VOLTAGECALIBRATION_30V>, Save30VCalibrationAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_VOLTAGECALIBRATION_50V>, Save50VCalibrationAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BATTERY_APPLYCALIB>, ToggleBoolAction, CheckboxIcon, BatteryApplyCalibrationAccessor>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<BatteryMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
constructMenuItem<makeComponent<MenuItem, EmptyText, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, BatteryVoltageCalibrationFront30VText, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, BatteryVoltageCalibrationBack30VText, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, BatteryVoltageCalibrationFront50VText, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, BatteryVoltageCalibrationBack50VText, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, BatteryVoltageCalibratedText, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_VOLTAGECALIBRATION_RESET>, ResetCalibrationAction>>();
}
void CalibrateVoltageDisplay::back()
{
switchScreen<BatteryMenu>();
}

View File

@ -14,78 +14,12 @@
#include "widgets/label.h"
#include "globals.h"
using namespace espgui;
class CalibrateVoltageDisplay :
public espgui::MenuDisplay,
public espgui::StaticText<TEXT_BATTERY_CALIBRATE>
{
public:
CalibrateVoltageDisplay();
namespace {
class CalibrateVoltageDisplay;
class BatteryMenu;
class Save30VCalibrationAction : public virtual ActionInterface
{
public:
void triggered() override {
settings.battery.front30VoltCalibration = controllers.front.feedback.batVoltage;
settings.battery.back30VoltCalibration = controllers.back.feedback.batVoltage;
saveSettings();
}
};
class Save50VCalibrationAction : public virtual ActionInterface
{
public:
void triggered() override {
settings.battery.front50VoltCalibration = controllers.front.feedback.batVoltage;
settings.battery.back50VoltCalibration = controllers.back.feedback.batVoltage;
saveSettings();
}
};
class ResetCalibrationAction : public virtual ActionInterface
{
public:
void triggered() override {
settings.battery.front30VoltCalibration = 3000;
settings.battery.back30VoltCalibration = 3000;
settings.battery.front50VoltCalibration = 5000;
settings.battery.back50VoltCalibration = 5000;
saveSettings();
}
};
float convertToFloat(int16_t value)
{
return value/100.;
}
class BatteryVoltageCalibrationFront30VText : public virtual TextInterface { public: std::string text() const override { return fmt::format("30V Front: {}", convertToFloat(settings.battery.front30VoltCalibration)); } };
class BatteryVoltageCalibrationBack30VText : public virtual TextInterface { public: std::string text() const override { return fmt::format("30V Back: {}", convertToFloat(settings.battery.back30VoltCalibration)); } };
class BatteryVoltageCalibrationFront50VText : public virtual TextInterface { public: std::string text() const override { return fmt::format("50V Front: {}", convertToFloat(settings.battery.front50VoltCalibration)); } };
class BatteryVoltageCalibrationBack50VText : public virtual TextInterface { public: std::string text() const override { return fmt::format("50V Back: {}", convertToFloat(settings.battery.back50VoltCalibration)); } };
class BatteryVoltageCalibratedText : public virtual TextInterface { public: std::string text() const override { if (settings.battery.applyCalibration) return fmt::format("F{:.2f}V B{:.2f}", controllers.front.getCalibratedVoltage(settings.battery.applyCalibration), controllers.back.getCalibratedVoltage(settings.battery.applyCalibration)); else return "Not activated"; } };
}
namespace {
class CalibrateVoltageDisplay :
public MenuDisplay,
public StaticText<TEXT_BATTERY_CALIBRATE>,
public BackActionInterface<SwitchScreenAction<BatteryMenu>>
{
public:
CalibrateVoltageDisplay()
{
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_VOLTAGECALIBRATION_30V>, Save30VCalibrationAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_VOLTAGECALIBRATION_50V>, Save50VCalibrationAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BATTERY_APPLYCALIB>, ToggleBoolAction, CheckboxIcon, BatteryApplyCalibrationAccessor>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<BatteryMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
constructMenuItem<makeComponent<MenuItem, EmptyText, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, BatteryVoltageCalibrationFront30VText, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, BatteryVoltageCalibrationBack30VText, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, BatteryVoltageCalibrationFront50VText, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, BatteryVoltageCalibrationBack50VText, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, BatteryVoltageCalibratedText, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_VOLTAGECALIBRATION_RESET>, ResetCalibrationAction>>();
}
};
} // Namespace
void back() override;
};

View File

@ -11,11 +11,6 @@
#include "widgets/progressbar.h"
#include "modes/ignoreinputmode.h"
namespace {
class StatusDisplay;
class BoardcomputerHardwareSettingsMenu;
}
namespace {
#ifdef FEATURE_GAMETRAK
class GametrakCalibrateDisplay : public Display, public ConfirmActionInterface<SwitchScreenAction<BoardcomputerHardwareSettingsMenu>>, public BackActionInterface<SwitchScreenAction<BoardcomputerHardwareSettingsMenu>>

View File

@ -0,0 +1,46 @@
#include "aboutmenu.h"
// local includes
#include "utils.h"
#include "actions/dummyaction.h"
#include "actions/switchscreenaction.h"
#include "icons/back.h"
#include "esptexthelpers.h"
#ifdef FEATURE_OTA
#include <espasyncota.h>
#include <esp_ota_ops.h>
#include "fmt/core.h"
#endif
AboutMenu::AboutMenu()
{
constructMenuItem<makeComponent<MenuItem, currentVersionText, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, HeapTotal8Text, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, HeapFree8Text, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, HeapMinFree8Text, StaticFont<2>, DisabledColor, DummyAction>>();
#ifndef HEAP_LRGST_CRASH_TEXT_FIX
constructMenuItem<makeComponent<MenuItem, HeapLargest8Text, StaticFont<2>, DisabledColor, DummyAction>>();
#endif
constructMenuItem<makeComponent<MenuItem, HeapTotal32Text, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, HeapFree32Text, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, HeapMinFree32Text, StaticFont<2>, DisabledColor, DummyAction>>();
#ifndef HEAP_LRGST_CRASH_TEXT_FIX
constructMenuItem<makeComponent<MenuItem, HeapLargest32Text, StaticFont<2>, DisabledColor, DummyAction>>();
#endif
constructMenuItem<makeComponent<MenuItem, EspChipRevisionText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, EspCpuFreqMHzText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, EspCycleCountText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, EspSdkVersionText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, EspFlashChipSizeText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, EspFlashChipSpeedText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, EspFlashChipModeText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, EspSketchSizeText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, EspSketchMd5Text, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, EspFreeSketchSpaceText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<SettingsMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
}
void AboutMenu::back()
{
switchScreen<SettingsMenu>();
}

View File

@ -1,29 +1,15 @@
#pragma once
// local includes
#include "menudisplay.h"
#include "utils.h"
#include "actions/dummyaction.h"
#include "actions/switchscreenaction.h"
#include "icons/back.h"
#include "esptexthelpers.h"
#include "texts.h"
#ifdef FEATURE_OTA
#include <espasyncota.h>
#include <esp_ota_ops.h>
#include "fmt/core.h"
#endif
// 3rdparty lib includes
#include <menudisplay.h>
// forward declares
namespace {
class SettingsMenu;
} // namespace
// local includes
#include "texts.h"
using namespace espgui;
namespace {
class currentVersionText : public virtual TextInterface { public: std::string text() const override {
class CurrentVersionText : public virtual TextInterface { public: std::string text() const override {
#ifdef FEATURE_OTA
if (const esp_app_desc_t *app_desc = esp_ota_get_app_description())
{
@ -38,36 +24,11 @@ constexpr char TEXT_VERSION[] = "Version: 1.0";
class AboutMenu :
public MenuDisplay,
public StaticText<TEXT_ABOUT>,
public BackActionInterface<SwitchScreenAction<SettingsMenu>>
public StaticText<TEXT_ABOUT>
{
public:
AboutMenu()
{
constructMenuItem<makeComponent<MenuItem, currentVersionText, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, HeapTotal8Text, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, HeapFree8Text, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, HeapMinFree8Text, StaticFont<2>, DisabledColor, DummyAction>>();
#ifndef HEAP_LRGST_CRASH_TEXT_FIX
constructMenuItem<makeComponent<MenuItem, HeapLargest8Text, StaticFont<2>, DisabledColor, DummyAction>>();
#endif
constructMenuItem<makeComponent<MenuItem, HeapTotal32Text, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, HeapFree32Text, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, HeapMinFree32Text, StaticFont<2>, DisabledColor, DummyAction>>();
#ifndef HEAP_LRGST_CRASH_TEXT_FIX
constructMenuItem<makeComponent<MenuItem, HeapLargest32Text, StaticFont<2>, DisabledColor, DummyAction>>();
#endif
constructMenuItem<makeComponent<MenuItem, EspChipRevisionText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, EspCpuFreqMHzText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, EspCycleCountText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, EspSdkVersionText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, EspFlashChipSizeText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, EspFlashChipSpeedText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, EspFlashChipModeText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, EspSketchSizeText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, EspSketchMd5Text, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, EspFreeSketchSpaceText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<SettingsMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
}
AboutMenu();
void back() override;
};
} // namespace

View File

@ -0,0 +1,55 @@
#include "batterymenu.h"
// 3rdparty lib includes
#include <changevaluedisplay.h>
// local includes
#include "mainmenu.h"
#include "displays/calibratevoltagedisplay.h"
#include "accessors/settingsaccessors.h"
class CurrentBatteryStatusText : public virtual espgui::TextInterface { public: std::string text() const override { return getBatteryPercentageString(); } };
using BatteryCellSeriesChangeScreen = espgui::makeComponent<
espgui::ChangeValueDisplay<uint8_t>,
espgui::StaticText<TEXT_CELL_SERIES>,
BatterySeriesCellsAccessor,
espgui::BackActionInterface<espgui::SwitchScreenAction<BatteryMenu>>,
espgui::SwitchScreenAction<BatteryMenu>
>;
using BatteryCellParallelChangeScreen = espgui::makeComponent<
espgui::ChangeValueDisplay<uint8_t>,
espgui::StaticText<TEXT_CELL_PARALLEL>,
BatteryParallelCellsAccessor,
espgui::BackActionInterface<espgui::SwitchScreenAction<BatteryMenu>>,
espgui::SwitchScreenAction<BatteryMenu>
>;
using BatteryWHperKMChangeScreen = espgui::makeComponent<
espgui::ChangeValueDisplay<uint16_t>,
espgui::StaticText<TEXT_BATTERY_WHKM>,
BatteryWHperKMAccessor,
espgui::BackActionInterface<espgui::SwitchScreenAction<BatteryMenu>>,
espgui::SwitchScreenAction<BatteryMenu>
>;
using namespace espgui;
BatteryMenu::BatteryMenu()
{
constructMenuItem<makeComponent<MenuItem, CurrentBatteryStatusText, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, EmptyText, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_CELL_SERIES, BatterySeriesCellsAccessor>, SwitchScreenAction<BatteryCellSeriesChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_CELL_PARALLEL, BatteryParallelCellsAccessor>, SwitchScreenAction<BatteryCellParallelChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_BATTERY_WHKM, BatteryWHperKMAccessor>, SwitchScreenAction<BatteryWHperKMChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SELECT_CELL_TYPE>, SwitchScreenAction<BatteryTypeMenu>>>();
constructMenuItem<makeComponent<MenuItem, EmptyText, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BATTERY_CALIBRATE>, SwitchScreenAction<CalibrateVoltageDisplay>, StaticMenuItemIcon<&bobbyicons::settings>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<MainMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
}
void BatteryMenu::back()
{
switchScreen<MainMenu>();
}

View File

@ -1,71 +1,25 @@
#pragma once
// 3rdparty lib includes
#include <menudisplay.h>
#include <menuitem.h>
#include <icons/back.h>
#include <actions/dummyaction.h>
#include <actions/switchscreenaction.h>
// Local includes
#include "menudisplay.h"
#include "utils.h"
#include "menuitem.h"
#include "icons/back.h"
#include "icons/settings.h"
#include "texts.h"
#include "actions/dummyaction.h"
#include "actions/switchscreenaction.h"
#include "mainmenu.h"
#include "battery.h"
#include "selectbatterytypemenu.h"
#include "displays/calibratevoltagedisplay.h"
// Helper
class currentBatteryStatus : public virtual TextInterface { public: std::string text() const override { return getBatteryPercentageString(); } };
class BatteryMenu :
public espgui::MenuDisplay,
public espgui::StaticText<TEXT_BATTERY>
{
public:
BatteryMenu();
using namespace espgui;
namespace {
class BatteryMenu;
class CalibrateVoltageDisplay;
using BatteryCellSeriesChangeScreen = makeComponent<
ChangeValueDisplay<uint8_t>,
StaticText<TEXT_CELL_SERIES>,
BatterySeriesCellsAccessor,
BackActionInterface<SwitchScreenAction<BatteryMenu>>,
SwitchScreenAction<BatteryMenu>
>;
using BatteryCellParallelChangeScreen = makeComponent<
ChangeValueDisplay<uint8_t>,
StaticText<TEXT_CELL_PARALLEL>,
BatteryParallelCellsAccessor,
BackActionInterface<SwitchScreenAction<BatteryMenu>>,
SwitchScreenAction<BatteryMenu>
>;
using BatteryWHperKMChangeScreen = makeComponent<
ChangeValueDisplay<uint16_t>,
StaticText<TEXT_BATTERY_WHKM>,
BatteryWHperKMAccessor,
BackActionInterface<SwitchScreenAction<BatteryMenu>>,
SwitchScreenAction<BatteryMenu>
>;
}
namespace {
class BatteryMenu :
public MenuDisplay,
public StaticText<TEXT_BATTERY>,
public BackActionInterface<SwitchScreenAction<MainMenu>>
{
public:
BatteryMenu()
{
constructMenuItem<makeComponent<MenuItem, currentBatteryStatus, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, EmptyText, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_CELL_SERIES, BatterySeriesCellsAccessor>, SwitchScreenAction<BatteryCellSeriesChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_CELL_PARALLEL, BatteryParallelCellsAccessor>, SwitchScreenAction<BatteryCellParallelChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_BATTERY_WHKM, BatteryWHperKMAccessor>, SwitchScreenAction<BatteryWHperKMChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SELECT_CELL_TYPE>, SwitchScreenAction<BatteryTypeMenu>>>();
constructMenuItem<makeComponent<MenuItem, EmptyText, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BATTERY_CALIBRATE>, SwitchScreenAction<CalibrateVoltageDisplay>, StaticMenuItemIcon<&bobbyicons::settings>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<MainMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
}
};
} // Namespace
void back() override;
};

View File

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

View File

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

View File

@ -0,0 +1,183 @@
#include "boardcomputerhardwaresettingsmenu.h"
// 3rdparty lib includes
#include <fmt/core.h>
#include <changevaluedisplay.h>
#include <actions/dummyaction.h>
#include <actions/switchscreenaction.h>
#include <actions/toggleboolaction.h>
#include <icons/back.h>
#include <checkboxicon.h>
// local includes
#include "utils.h"
#include "icons/lock.h"
#include "accessors/settingsaccessors.h"
#include "displays/menus/lockscreensettingsmenu.h"
#include "displays/calibratedisplay.h"
namespace {
struct GasText : public virtual espgui::TextInterface {
public:
std::string text() const override
{
return fmt::format("{}: {}: {}",
"gas",
raw_gas ? std::to_string(*raw_gas) : "?",
gas ? fmt::format("{:.02f}", *gas) : "?");
}
};
struct BremsText : public virtual espgui::TextInterface {
public:
std::string text() const override
{
return fmt::format("{}: {}: {}",
"brems",
raw_brems ? std::to_string(*raw_brems) : "?",
brems ? fmt::format("{:.02f}", *brems) : "?");
}
};
using SampleCountChangeScreen = espgui::makeComponent<
espgui::ChangeValueDisplay<int16_t>,
espgui::StaticText<TEXT_SAMPLECOUNT>,
SampleCountAccessor,
espgui::BackActionInterface<espgui::SwitchScreenAction<BoardcomputerHardwareSettingsMenu>>,
espgui::SwitchScreenAction<BoardcomputerHardwareSettingsMenu>
>;
using GasMinChangeScreen = espgui::makeComponent<
espgui::ChangeValueDisplay<int16_t>,
espgui::StaticText<TEXT_GASMIN>,
GasMinAccessor,
espgui::BackActionInterface<espgui::SwitchScreenAction<BoardcomputerHardwareSettingsMenu>>,
espgui::SwitchScreenAction<BoardcomputerHardwareSettingsMenu>
>;
using GasMaxChangeScreen = espgui::makeComponent<
espgui::ChangeValueDisplay<int16_t>,
espgui::StaticText<TEXT_GASMAX>,
GasMaxAccessor,
espgui::BackActionInterface<espgui::SwitchScreenAction<BoardcomputerHardwareSettingsMenu>>,
espgui::SwitchScreenAction<BoardcomputerHardwareSettingsMenu>
>;
using BremsMinChangeScreen = espgui::makeComponent<
espgui::ChangeValueDisplay<int16_t>,
espgui::StaticText<TEXT_BREMSMIN>,
BremsMinAccessor,
espgui::BackActionInterface<espgui::SwitchScreenAction<BoardcomputerHardwareSettingsMenu>>,
espgui::SwitchScreenAction<BoardcomputerHardwareSettingsMenu>
>;
using BremsMaxChangeScreen = espgui::makeComponent<
espgui::ChangeValueDisplay<int16_t>,
espgui::StaticText<TEXT_BREMSMAX>,
BremsMaxAccessor,
espgui::BackActionInterface<espgui::SwitchScreenAction<BoardcomputerHardwareSettingsMenu>>,
espgui::SwitchScreenAction<BoardcomputerHardwareSettingsMenu>
>;
#if defined(FEATURE_DPAD) || defined(FEATURE_DPAD_3WIRESW) || defined(FEATURE_DPAD_5WIRESW) || defined(FEATURE_DPAD_5WIRESW_2OUT) || defined (FEATURE_DPAD_6WIRESW)
using DPadDebounceChangeScreen = espgui::makeComponent<
espgui::ChangeValueDisplay<uint8_t>,
espgui::StaticText<TEXT_DPADDEBOUNCE>,
DPadDebounceAccessor,
espgui::BackActionInterface<espgui::SwitchScreenAction<BoardcomputerHardwareSettingsMenu>>,
espgui::SwitchScreenAction<BoardcomputerHardwareSettingsMenu>
>;
#endif
#ifdef FEATURE_GAMETRAK
struct GametrakXText : public virtual TextInterface {
public:
std::string text() const override { return fmt::format("gametrakX: {}: {:.02f}", raw_gametrakX, gametrakX); }
};
struct GametrakYText : public virtual TextInterface {
public:
std::string text() const override { return fmt::format("gametrakY: {}: {:.02f}", raw_gametrakY, gametrakY); }
};
struct GametrakDistText : public virtual TextInterface {
public:
std::string text() const override { return fmt::format("gametrakDist: {}: {:.02f}", raw_gametrakDist, gametrakDist); }
};
using GametrakXMinChangeScreen = espgui::makeComponent<
espgui::ChangeValueDisplay<int16_t>,
espgui::StaticText<TEXT_SETGAMETRAKXMIN>,
GametrakXMinAccessor,
espgui::BackActionInterface<espgui::SwitchScreenAction<BoardcomputerHardwareSettingsMenu>>,
espgui::SwitchScreenAction<BoardcomputerHardwareSettingsMenu>
>;
using GametrakXMaxChangeScreen = espgui::makeComponent<
espgui::ChangeValueDisplay<int16_t>,
espgui::StaticText<TEXT_SETGAMETRAKXMAX>,
GametrakXMaxAccessor,
espgui::BackActionInterface<espgui::SwitchScreenAction<BoardcomputerHardwareSettingsMenu>>,
espgui::SwitchScreenAction<BoardcomputerHardwareSettingsMenu>
>;
using GametrakYMinChangeScreen = espgui::makeComponent<
espgui::ChangeValueDisplay<int16_t>,
espgui::StaticText<TEXT_SETGAMETRAKYMIN>,
GametrakYMinAccessor,
espgui::BackActionInterface<espgui::SwitchScreenAction<BoardcomputerHardwareSettingsMenu>>,
espgui::SwitchScreenAction<BoardcomputerHardwareSettingsMenu>
>;
using GametrakYMaxChangeScreen = espgui::makeComponent<
espgui::ChangeValueDisplay<int16_t>,
espgui::StaticText<TEXT_SETGAMETRAKYMAX>,
GametrakYMaxAccessor,
espgui::BackActionInterface<espgui::SwitchScreenAction<BoardcomputerHardwareSettingsMenu>>,
espgui::SwitchScreenAction<BoardcomputerHardwareSettingsMenu>
>;
using GametrakDistMinChangeScreen = espgui::makeComponent<
espgui::ChangeValueDisplay<int16_t>,
espgui::StaticText<TEXT_SETGAMETRAKDISTMIN>,
GametrakDistMinAccessor,
espgui::BackActionInterface<espgui::SwitchScreenAction<BoardcomputerHardwareSettingsMenu>>,
espgui::SwitchScreenAction<BoardcomputerHardwareSettingsMenu>
>;
using GametrakDistMaxChangeScreen = espgui::makeComponent<
espgui::ChangeValueDisplay<int16_t>,
espgui::StaticText<TEXT_SETGAMETRAKDISTMAX>,
GametrakDistMaxAccessor,
espgui::BackActionInterface<espgui::SwitchScreenAction<BoardcomputerHardwareSettingsMenu>>,
espgui::SwitchScreenAction<BoardcomputerHardwareSettingsMenu>
>;
#endif
} // namespace
using namespace espgui;
BoardcomputerHardwareSettingsMenu::BoardcomputerHardwareSettingsMenu()
{
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_LOCKSCREENSETTINGS>, SwitchScreenAction<LockscreenSettingsMenu>, StaticMenuItemIcon<&bobbyicons::lock>>>();
constructMenuItem<makeComponent<MenuItem, GasText, DisabledColor, StaticFont<2>, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, BremsText, DisabledColor, StaticFont<2>, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_CALIBRATE>, SwitchScreenAction<CalibrateDisplay>>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_SAMPLECOUNT, SampleCountAccessor>, SwitchScreenAction<SampleCountChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_GASMIN, GasMinAccessor>, SwitchScreenAction<GasMinChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_GASMAX, GasMaxAccessor>, SwitchScreenAction<GasMaxChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_BREMSMIN, BremsMinAccessor>, SwitchScreenAction<BremsMinChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_BREMSMAX, BremsMaxAccessor>, SwitchScreenAction<BremsMaxChangeScreen>>>();
#if defined(FEATURE_DPAD) || defined(FEATURE_DPAD_3WIRESW) || defined(FEATURE_DPAD_5WIRESW) || defined(FEATURE_DPAD_5WIRESW_2OUT) || defined (FEATURE_DPAD_6WIRESW)
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_DPADDEBOUNCE, DPadDebounceAccessor>, SwitchScreenAction<DPadDebounceChangeScreen>>>();
#endif
#ifdef FEATURE_GAMETRAK
constructMenuItem<makeComponent<MenuItem, EmptyText, DummyAction>,
constructMenuItem<makeComponent<MenuItem, GametrakXText, DisabledColor, StaticFont<2>, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, GametrakYText, DisabledColor, StaticFont<2>, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, GametrakDistText, DisabledColor, StaticFont<2>, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_GAMETRAKCALIBRATE>, SwitchScreenAction<GametrakCalibrateDisplay>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SETGAMETRAKXMIN>, SwitchScreenAction<GametrakXMinChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SETGAMETRAKXMAX>, SwitchScreenAction<GametrakXMaxChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SETGAMETRAKYMIN>, SwitchScreenAction<GametrakYMinChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SETGAMETRAKYMAX>, SwitchScreenAction<GametrakYMaxChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SETGAMETRAKDISTMIN>, SwitchScreenAction<GametrakDistMinChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SETGAMETRAKDISTMAX>, SwitchScreenAction<GametrakDistMaxChangeScreen>>>();
#endif
constructMenuItem<makeComponent<MenuItem, EmptyText, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_TIMERS>, SwitchScreenAction<TimersMenu>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<SettingsMenu>, StaticMenuItemIcon<&icons::back>>>();
}
void BoardcomputerHardwareSettingsMenu::back()
{
switchScreen<SettingsMenu>();
}

View File

@ -1,195 +1,15 @@
#pragma once
// 3rdparty lib includes
#include <fmt/core.h>
// local includes
#include "menudisplay.h"
#include "utils.h"
#include "changevaluedisplay.h"
#include "actions/dummyaction.h"
#include "actions/switchscreenaction.h"
#include "actions/toggleboolaction.h"
#include "icons/lock.h"
#include "icons/back.h"
#include "checkboxicon.h"
#include "texts.h"
#include "accessors/settingsaccessors.h"
// forward declares
namespace {
class BoardcomputerHardwareSettingsMenu;
class LockscreenSettingsMenu;
class CalibrateDisplay;
class GametrakCalibrateDisplay;
class TimersMenu;
class SettingsMenu;
} // namespace
using namespace espgui;
namespace {
struct GasText : public virtual TextInterface {
public:
std::string text() const override
{
return fmt::format("{}: {}: {}",
"gas",
raw_gas ? std::to_string(*raw_gas) : "?",
gas ? fmt::format("{:.02f}", *gas) : "?");
}
};
struct BremsText : public virtual TextInterface {
public:
std::string text() const override
{
return fmt::format("{}: {}: {}",
"brems",
raw_brems ? std::to_string(*raw_brems) : "?",
brems ? fmt::format("{:.02f}", *brems) : "?");
}
};
using SampleCountChangeScreen = makeComponent<
ChangeValueDisplay<int16_t>,
StaticText<TEXT_SAMPLECOUNT>,
SampleCountAccessor,
BackActionInterface<SwitchScreenAction<BoardcomputerHardwareSettingsMenu>>,
SwitchScreenAction<BoardcomputerHardwareSettingsMenu>
>;
using GasMinChangeScreen = makeComponent<
ChangeValueDisplay<int16_t>,
StaticText<TEXT_GASMIN>,
GasMinAccessor,
BackActionInterface<SwitchScreenAction<BoardcomputerHardwareSettingsMenu>>,
SwitchScreenAction<BoardcomputerHardwareSettingsMenu>
>;
using GasMaxChangeScreen = makeComponent<
ChangeValueDisplay<int16_t>,
StaticText<TEXT_GASMAX>,
GasMaxAccessor,
BackActionInterface<SwitchScreenAction<BoardcomputerHardwareSettingsMenu>>,
SwitchScreenAction<BoardcomputerHardwareSettingsMenu>
>;
using BremsMinChangeScreen = makeComponent<
ChangeValueDisplay<int16_t>,
StaticText<TEXT_BREMSMIN>,
BremsMinAccessor,
BackActionInterface<SwitchScreenAction<BoardcomputerHardwareSettingsMenu>>,
SwitchScreenAction<BoardcomputerHardwareSettingsMenu>
>;
using BremsMaxChangeScreen = makeComponent<
ChangeValueDisplay<int16_t>,
StaticText<TEXT_BREMSMAX>,
BremsMaxAccessor,
BackActionInterface<SwitchScreenAction<BoardcomputerHardwareSettingsMenu>>,
SwitchScreenAction<BoardcomputerHardwareSettingsMenu>
>;
#if defined(FEATURE_DPAD) || defined(FEATURE_DPAD_3WIRESW) || defined(FEATURE_DPAD_5WIRESW) || defined(FEATURE_DPAD_5WIRESW_2OUT) || defined (FEATURE_DPAD_6WIRESW)
using DPadDebounceChangeScreen = makeComponent<
ChangeValueDisplay<uint8_t>,
StaticText<TEXT_DPADDEBOUNCE>,
DPadDebounceAccessor,
BackActionInterface<SwitchScreenAction<BoardcomputerHardwareSettingsMenu>>,
SwitchScreenAction<BoardcomputerHardwareSettingsMenu>
>;
#endif
#ifdef FEATURE_GAMETRAK
struct GametrakXText : public virtual TextInterface {
public:
std::string text() const override { return fmt::format("gametrakX: {}: {:.02f}", raw_gametrakX, gametrakX); }
};
struct GametrakYText : public virtual TextInterface {
public:
std::string text() const override { return fmt::format("gametrakY: {}: {:.02f}", raw_gametrakY, gametrakY); }
};
struct GametrakDistText : public virtual TextInterface {
public:
std::string text() const override { return fmt::format("gametrakDist: {}: {:.02f}", raw_gametrakDist, gametrakDist); }
};
using GametrakXMinChangeScreen = makeComponent<
ChangeValueDisplay<int16_t>,
StaticText<TEXT_SETGAMETRAKXMIN>,
GametrakXMinAccessor,
BackActionInterface<SwitchScreenAction<BoardcomputerHardwareSettingsMenu>>,
SwitchScreenAction<BoardcomputerHardwareSettingsMenu>
>;
using GametrakXMaxChangeScreen = makeComponent<
ChangeValueDisplay<int16_t>,
StaticText<TEXT_SETGAMETRAKXMAX>,
GametrakXMaxAccessor,
BackActionInterface<SwitchScreenAction<BoardcomputerHardwareSettingsMenu>>,
SwitchScreenAction<BoardcomputerHardwareSettingsMenu>
>;
using GametrakYMinChangeScreen = makeComponent<
ChangeValueDisplay<int16_t>,
StaticText<TEXT_SETGAMETRAKYMIN>,
GametrakYMinAccessor,
BackActionInterface<SwitchScreenAction<BoardcomputerHardwareSettingsMenu>>,
SwitchScreenAction<BoardcomputerHardwareSettingsMenu>
>;
using GametrakYMaxChangeScreen = makeComponent<
ChangeValueDisplay<int16_t>,
StaticText<TEXT_SETGAMETRAKYMAX>,
GametrakYMaxAccessor,
BackActionInterface<SwitchScreenAction<BoardcomputerHardwareSettingsMenu>>,
SwitchScreenAction<BoardcomputerHardwareSettingsMenu>
>;
using GametrakDistMinChangeScreen = makeComponent<
ChangeValueDisplay<int16_t>,
StaticText<TEXT_SETGAMETRAKDISTMIN>,
GametrakDistMinAccessor,
BackActionInterface<SwitchScreenAction<BoardcomputerHardwareSettingsMenu>>,
SwitchScreenAction<BoardcomputerHardwareSettingsMenu>
>;
using GametrakDistMaxChangeScreen = makeComponent<
ChangeValueDisplay<int16_t>,
StaticText<TEXT_SETGAMETRAKDISTMAX>,
GametrakDistMaxAccessor,
BackActionInterface<SwitchScreenAction<BoardcomputerHardwareSettingsMenu>>,
SwitchScreenAction<BoardcomputerHardwareSettingsMenu>
>;
#endif
class BoardcomputerHardwareSettingsMenu :
public MenuDisplay,
public StaticText<TEXT_BOARDCOMPUTERHARDWARESETTINGS>,
public BackActionInterface<SwitchScreenAction<SettingsMenu>>
public espgui::MenuDisplay,
public espgui::StaticText<TEXT_BOARDCOMPUTERHARDWARESETTINGS>
{
public:
BoardcomputerHardwareSettingsMenu()
{
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_LOCKSCREENSETTINGS>, SwitchScreenAction<LockscreenSettingsMenu>, StaticMenuItemIcon<&bobbyicons::lock>>>();
constructMenuItem<makeComponent<MenuItem, GasText, DisabledColor, StaticFont<2>, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, BremsText, DisabledColor, StaticFont<2>, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_CALIBRATE>, SwitchScreenAction<CalibrateDisplay>>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_SAMPLECOUNT, SampleCountAccessor>, SwitchScreenAction<SampleCountChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_GASMIN, GasMinAccessor>, SwitchScreenAction<GasMinChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_GASMAX, GasMaxAccessor>, SwitchScreenAction<GasMaxChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_BREMSMIN, BremsMinAccessor>, SwitchScreenAction<BremsMinChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_BREMSMAX, BremsMaxAccessor>, SwitchScreenAction<BremsMaxChangeScreen>>>();
#if defined(FEATURE_DPAD) || defined(FEATURE_DPAD_3WIRESW) || defined(FEATURE_DPAD_5WIRESW) || defined(FEATURE_DPAD_5WIRESW_2OUT) || defined (FEATURE_DPAD_6WIRESW)
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_DPADDEBOUNCE, DPadDebounceAccessor>, SwitchScreenAction<DPadDebounceChangeScreen>>>();
#endif
#ifdef FEATURE_GAMETRAK
constructMenuItem<makeComponent<MenuItem, EmptyText, DummyAction>,
constructMenuItem<makeComponent<MenuItem, GametrakXText, DisabledColor, StaticFont<2>, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, GametrakYText, DisabledColor, StaticFont<2>, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, GametrakDistText, DisabledColor, StaticFont<2>, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_GAMETRAKCALIBRATE>, SwitchScreenAction<GametrakCalibrateDisplay>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SETGAMETRAKXMIN>, SwitchScreenAction<GametrakXMinChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SETGAMETRAKXMAX>, SwitchScreenAction<GametrakXMaxChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SETGAMETRAKYMIN>, SwitchScreenAction<GametrakYMinChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SETGAMETRAKYMAX>, SwitchScreenAction<GametrakYMaxChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SETGAMETRAKDISTMIN>, SwitchScreenAction<GametrakDistMinChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SETGAMETRAKDISTMAX>, SwitchScreenAction<GametrakDistMaxChangeScreen>>>();
#endif
constructMenuItem<makeComponent<MenuItem, EmptyText, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_TIMERS>, SwitchScreenAction<TimersMenu>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<SettingsMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
}
BoardcomputerHardwareSettingsMenu();
void back() override;
};
} // namespace

View File

@ -13,12 +13,6 @@
#include "globals.h"
#include "accessors/settingsaccessors.h"
// forward declares
namespace {
class BuzzerMenu;
class SettingsMenu;
} // namespace
using namespace espgui;
namespace {

View File

@ -17,12 +17,6 @@
#include "accessors/settingsaccessors.h"
#include "cloud.h"
// forward declares
namespace {
class CloudSettingsMenu;
class SettingsMenu;
} // namespace
namespace {
using CloudTransmitTimeoutChangeScreen = makeComponent<
ChangeValueDisplay<int16_t>,

View File

@ -14,15 +14,6 @@
#include "globals.h"
#include "accessors/settingsaccessors.h"
// forward declares
namespace {
class ControllerHardwareSettingsMenu;
class BoardcomputerHardwareSettingsMenu;
class EnableMenu;
class InvertMenu;
class SettingsMenu;
} // namespace
using namespace espgui;
namespace {

View File

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

View File

@ -10,12 +10,6 @@
#include "texts.h"
#include "accessors/settingsaccessors.h"
// forward declares
namespace {
class LimitsSettingsMenu;
class SettingsMenu;
} // namespace
using namespace espgui;
namespace {

View File

@ -12,12 +12,6 @@
#include "accessors/settingsaccessors.h"
#include "changevaluedisplay.h"
// forward declares
namespace {
class BoardcomputerHardwareSettingsMenu;
class LockscreenSettingsMenu;
} // namespace
using namespace espgui;
namespace {

View File

@ -0,0 +1,90 @@
#include "mainmenu.h"
// 3rdparty lib includes
#include "actions/switchscreenaction.h"
#include "icons/back.h"
// local includes
#include "displays/statusdisplay.h"
#include "displays/menus/selectmodemenu.h"
#include "displays/menus/selectmodemenu.h"
#include "displays/menus/ledstripmenu.h"
#include "actions/modesettingsaction.h"
#include "displays/menus/presetsmenu.h"
#include "displays/menus/profilesmenu.h"
#include "displays/menus/graphsmenu.h"
#include "displays/menus/batterymenu.h"
#include "displays/powersupplydisplay.h"
#include "displays/menus/bmsmenu.h"
#include "displays/menus/settingsmenu.h"
#include "displays/menus/mosfetsmenu.h"
#include "displays/menus/demosmenu.h"
#include "displays/lockscreen.h"
#include "displays/garagedisplay.h"
#include "displays/menus/otamenu.h"
#include "displays/poweroffdisplay.h"
#include "actions/rebootaction.h"
#include "displays/menus/debugmenu.h"
#include "icons/battery.h"
#include "icons/modes.h"
#include "icons/presets.h"
#include "icons/graph.h"
#ifdef FEATURE_BMS
#include "icons/bms.h"
#endif
#include "icons/settings.h"
#include "icons/lock.h"
#include "icons/demos.h"
#ifdef FEATURE_OTA
#include "icons/update.h"
#endif
#ifdef FEATURE_LEDSTRIP
#include "icons/neopixel.h"
#endif
#include "icons/poweroff.h"
#include "icons/reboot.h"
using namespace espgui;
MainMenu::MainMenu()
{
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_STATUS>, SwitchScreenAction<StatusDisplay>, StaticMenuItemIcon<&espgui::icons::back>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SELECTMODE>, SwitchScreenAction<SelectModeMenu>, StaticMenuItemIcon<&bobbyicons::modes>>>();
#ifdef FEATURE_LEDSTRIP
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_LEDSTRIP>, SwitchScreenAction<LedstripMenu>, StaticMenuItemIcon<&bobbyicons::neopixel>>>();
#endif
if (SHOWITEM) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_MODESETTINGS>, ModeSettingsAction>>(); }
if (SHOWITEM) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_PRESETS>, SwitchScreenAction<PresetsMenu>, StaticMenuItemIcon<&bobbyicons::presets>>>(); }
if (SHOWITEM) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_PROFILES>, SwitchScreenAction<ProfilesMenu>>>(); }
if (SHOWITEM) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_GRAPHS>, SwitchScreenAction<GraphsMenu>, StaticMenuItemIcon<&bobbyicons::graph>>>(); }
if (SHOWITEM) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BATTERY>, SwitchScreenAction<BatteryMenu>, StaticMenuItemIcon<&bobbyicons::battery>>>(); }
#if defined(FEATURE_CAN) && defined(FEATURE_POWERSUPPLY)
if (SHOWITEM) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_POWERSUPPLY>, SwitchScreenAction<PowerSupplyDisplay>>>(); }
#endif
#if defined(FEATURE_BLUETOOTH) && defined(FEATURE_BMS)
if (SHOWITEM) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BMS>, SwitchScreenAction<BmsMenu>, StaticMenuItemIcon<&bobbyicons::bms>>>(); }
#endif
if (SHOWITEM) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SETTINGS>, SwitchScreenAction<SettingsMenu>, StaticMenuItemIcon<&bobbyicons::settings>>>(); }
#ifdef FEATURE_MOSFETS
if (SHOWITEM) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_MOSFETS>, SwitchScreenAction<MosfetsMenu>>>(); }
#endif
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_DEMOS>, SwitchScreenAction<DemosMenu>, StaticMenuItemIcon<&bobbyicons::demos>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_LOCKVEHICLE>, SwitchScreenAction<Lockscreen>, StaticMenuItemIcon<&bobbyicons::lock>>>();
#ifdef FEATURE_GARAGE
if (SHOWITEM) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_GARAGE>, SwitchScreenAction<GarageDisplay>>>(); }
#endif
#ifdef FEATURE_OTA
if (SHOWITEM) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_UPDATE>, SwitchScreenAction<OtaMenu>, StaticMenuItemIcon<&bobbyicons::update>>>(); }
#endif
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_POWEROFF>, SwitchScreenAction<PoweroffDisplay>, StaticMenuItemIcon<&bobbyicons::poweroff>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_REBOOT>, RebootAction, StaticMenuItemIcon<&bobbyicons::reboot>>>();
if (SHOWITEM) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_DEBUG>, SwitchScreenAction<DebugMenu>>>(); }
#ifdef MAINMENU_PLUGIN
GMEN1
#endif
}
void MainMenu::back()
{
switchScreen<StatusDisplay>();
}

View File

@ -1,55 +1,16 @@
#pragma once
// local includes
// 3rdparty lib includes
#include "menudisplay.h"
#include "menuitem.h"
#include "batterymenu.h"
#include "actions/switchscreenaction.h"
#include "actions/modesettingsaction.h"
#include "actions/rebootaction.h"
// local includes
#include "texts.h"
#include "icons/back.h"
#include "icons/battery.h"
#include "icons/modes.h"
#include "icons/presets.h"
#include "icons/graph.h"
#ifdef FEATURE_BMS
#include "icons/bms.h"
#endif
#include "icons/settings.h"
#include "icons/lock.h"
#include "icons/demos.h"
#ifdef FEATURE_OTA
#include "icons/update.h"
#endif
#ifdef FEATURE_LEDSTRIP
#include "icons/neopixel.h"
#endif
#include "icons/poweroff.h"
#include "icons/reboot.h"
#ifdef MAINMENU_PLUGIN
#include MAINMENU_PLUGIN
#endif
// forward declares
namespace {
class StatusDisplay;
class SelectModeMenu;
class LedstripMenu;
class ProfilesMenu;
class PresetsMenu;
class GraphsMenu;
class PowerSupplyDisplay;
class BmsMenu;
class SettingsMenu;
class Lockscreen;
class MosfetsMenu;
class DemosMenu;
class GarageDisplay;
class OtaMenu;
class PoweroffDisplay;
class DebugMenu;
class BatteryMenu;
#ifdef MAINMENU_PLUGIN
GMEN2
#endif
@ -60,51 +21,12 @@ class BatteryMenu;
#endif
} // namespace
using namespace espgui;
namespace {
class MainMenu :
public MenuDisplay,
public StaticText<TEXT_MAINMENU>,
public BackActionInterface<SwitchScreenAction<StatusDisplay>>
public espgui::MenuDisplay,
public espgui::StaticText<TEXT_MAINMENU>
{
public:
MainMenu()
{
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_STATUS>, SwitchScreenAction<StatusDisplay>, StaticMenuItemIcon<&espgui::icons::back>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SELECTMODE>, SwitchScreenAction<SelectModeMenu>, StaticMenuItemIcon<&bobbyicons::modes>>>();
#ifdef FEATURE_LEDSTRIP
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_LEDSTRIP>, SwitchScreenAction<LedstripMenu>, StaticMenuItemIcon<&bobbyicons::neopixel>>>();
#endif
if (SHOWITEM) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_MODESETTINGS>, ModeSettingsAction>>(); }
if (SHOWITEM) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_PRESETS>, SwitchScreenAction<PresetsMenu>, StaticMenuItemIcon<&bobbyicons::presets>>>(); }
if (SHOWITEM) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_PROFILES>, SwitchScreenAction<ProfilesMenu>>>(); }
if (SHOWITEM) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_GRAPHS>, SwitchScreenAction<GraphsMenu>, StaticMenuItemIcon<&bobbyicons::graph>>>(); }
if (SHOWITEM) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BATTERY>, SwitchScreenAction<BatteryMenu>, StaticMenuItemIcon<&bobbyicons::battery>>>(); }
#if defined(FEATURE_CAN) && defined(FEATURE_POWERSUPPLY)
if (SHOWITEM) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_POWERSUPPLY>, SwitchScreenAction<PowerSupplyDisplay>>>(); }
#endif
#if defined(FEATURE_BLUETOOTH) && defined(FEATURE_BMS)
if (SHOWITEM) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BMS>, SwitchScreenAction<BmsMenu>, StaticMenuItemIcon<&bobbyicons::bms>>>(); }
#endif
if (SHOWITEM) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SETTINGS>, SwitchScreenAction<SettingsMenu>, StaticMenuItemIcon<&bobbyicons::settings>>>(); }
#ifdef FEATURE_MOSFETS
if (SHOWITEM) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_MOSFETS>, SwitchScreenAction<MosfetsMenu>>>(); }
#endif
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_DEMOS>, SwitchScreenAction<DemosMenu>, StaticMenuItemIcon<&bobbyicons::demos>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_LOCKVEHICLE>, SwitchScreenAction<Lockscreen>, StaticMenuItemIcon<&bobbyicons::lock>>>();
#ifdef FEATURE_GARAGE
if (SHOWITEM) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_GARAGE>, SwitchScreenAction<GarageDisplay>>>(); }
#endif
#ifdef FEATURE_OTA
if (SHOWITEM) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_UPDATE>, SwitchScreenAction<OtaMenu>, StaticMenuItemIcon<&bobbyicons::update>>>(); }
#endif
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_POWEROFF>, SwitchScreenAction<PoweroffDisplay>, StaticMenuItemIcon<&bobbyicons::poweroff>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_REBOOT>, RebootAction, StaticMenuItemIcon<&bobbyicons::reboot>>>();
if (SHOWITEM) { constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_DEBUG>, SwitchScreenAction<DebugMenu>>>(); }
#ifdef MAINMENU_PLUGIN
GMEN1
#endif
}
MainMenu();
void back() override;
};
} // namespace

View File

@ -7,15 +7,6 @@
#include "icons/back.h"
#include "texts.h"
// forward declares
namespace {
class DefaultModeSettingsMenu;
class TempomatModeSettingsMenu;
class LarsmModeSettingsMenu;
class GametrakModeSettingsMenu;
class SettingsMenu;
} // namespace
using namespace espgui;
namespace {

View File

@ -11,15 +11,6 @@
#include "texts.h"
#include "buildserver.h"
// forward declares
namespace {
class MainMenu;
class UpdateDisplay;
class SelectBuildMenu;
class SelectBuildServerMenu;
} // namespace
using namespace espgui;
namespace {

View File

@ -0,0 +1,35 @@
#include "selectbatterytypemenu.h"
// local includes
#include "battery.h"
#include "globals.h"
#include "utils.h"
#include "displays/menus/batterymenu.h"
namespace {
class CurrentBatteryTypeText : public virtual espgui::TextInterface { public: std::string text() const override { return getBatteryCellTypeString(); } };
template<BatteryCellType T>
class BatterySelectTypeAction : public virtual espgui::ActionInterface
{
public:
void triggered() override { settings.battery.cellType = uint8_t(T); saveSettings(); }
};
} // namespace
using namespace espgui;
BatteryTypeMenu::BatteryTypeMenu()
{
constructMenuItem<makeComponent<MenuItem, CurrentBatteryTypeText, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BATTERY_TYPE_22P>, BatterySelectTypeAction<BatteryCellType::_22P>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BATTERY_TYPE_HG2>, BatterySelectTypeAction<BatteryCellType::HG2>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BATTERY_TYPE_MH1>, BatterySelectTypeAction<BatteryCellType::MH1>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BATTERY_TYPE_VTC5>, BatterySelectTypeAction<BatteryCellType::VTC5>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<MainMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
}
void BatteryTypeMenu::back()
{
espgui::switchScreen<BatteryMenu>();
}

View File

@ -1,48 +1,23 @@
#pragma once
// 3rdparty lib includes
#include <menudisplay.h>
#include <menuitem.h>
#include <icons/back.h>
#include <actions/switchscreenaction.h>
#include <actioninterface.h>
// Local includes
#include "menudisplay.h"
#include "utils.h"
#include "menuitem.h"
#include "icons/back.h"
#include "texts.h"
#include "actions/switchscreenaction.h"
#include "batterymenu.h"
#include "battery.h"
#include "actioninterface.h"
#include "displays/menus/mainmenu.h"
// Helper
class currentBatteryType : public virtual TextInterface { public: std::string text() const override { return getBatteryCellTypeString(); } };
class BatteryTypeMenu :
public espgui::MenuDisplay,
public espgui::StaticText<TEXT_SELECT_CELL_TYPE>
{
public:
BatteryTypeMenu();
using namespace espgui;
namespace {
class BatteryTypeMenu;
class BatteryMenu;
template<BatteryCellType T>
class BatterySelectTypeAction : public virtual ActionInterface
{
public:
void triggered() override { settings.battery.cellType = uint8_t(T); saveSettings(); }
};
} // namespace
namespace {
class BatteryTypeMenu :
public MenuDisplay,
public StaticText<TEXT_SELECT_CELL_TYPE>,
public BackActionInterface<SwitchScreenAction<BatteryMenu>>
{
public:
BatteryTypeMenu()
{
constructMenuItem<makeComponent<MenuItem, currentBatteryType, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BATTERY_TYPE_22P>, BatterySelectTypeAction<BatteryCellType::_22P>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BATTERY_TYPE_HG2>, BatterySelectTypeAction<BatteryCellType::HG2>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BATTERY_TYPE_MH1>, BatterySelectTypeAction<BatteryCellType::MH1>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BATTERY_TYPE_VTC5>, BatterySelectTypeAction<BatteryCellType::VTC5>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<MainMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
}
};
} // Namespace
void back() override;
};

View File

@ -0,0 +1,71 @@
#include "selectbuildservermenu.h"
// esp-idf includes
#include <esp_log.h>
// 3rdparty lib includes
#include <fmt/core.h>
#include <actions/switchscreenaction.h>
// local includes
#include "displays/menus/settingsmenu.h"
namespace {
class BuildserverMenuItem : public espgui::MenuItem
{
public:
std::string text() const override { return m_buildserver_name; }
void setBuildserverName(std::string &&buildserver_name) { m_buildserver_name = std::move(buildserver_name); }
void setBuildserverName(const std::string &buildserver_name) { m_buildserver_name = buildserver_name; }
void setBuildserverUrl(std::string &&buildserver_url) { m_buildserver_url = std::move(buildserver_url); }
void setBuildserverUrl(const std::string &buildserver_url) { m_buildserver_url = buildserver_url; }
void triggered() override
{
stringSettings.otaServerUrl = m_buildserver_url;
if (m_buildserver_url.substr(m_buildserver_url.length() - 4) == ".bin")
{
stringSettings.otaUrl = m_buildserver_url;
}
saveSettings();
redownload = true;
url_for_latest.clear();
url_for_hashes.clear();
availableVersions = {};
}
private:
std::string m_buildserver_url;
std::string m_buildserver_name;
};
} // namespace
using namespace espgui;
SelectBuildServerMenu::SelectBuildServerMenu()
{
for (const auto &otaServer : stringSettings.otaServers)
{
std::string url = otaServer.url;
std::string name = (otaServer.name.empty()) ? url : otaServer.name;
if (!name.empty())
{
auto &menuitem = constructMenuItem<BuildserverMenuItem>();
menuitem.setBuildserverName(name);
menuitem.setBuildserverUrl(url);
}
}
if (menuItemCount() < 1)
{
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_NOBUILDSERVERCONFIGURED>, DefaultFont, StaticColor<TFT_RED>, DummyAction>>();
}
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<SettingsMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
}
void SelectBuildServerMenu::back()
{
espgui::switchScreen<SettingsMenu>();
}

View File

@ -1,87 +1,22 @@
#pragma once
// 3rdparty lib includes
#include <TFT_eSPI.h>
#include <menudisplay.h>
#include <actions/dummyaction.h>
#include <icons/back.h>
// local includes
#include "menudisplay.h"
#include "utils.h"
#include "actions/dummyaction.h"
#include "icons/back.h"
#include "texts.h"
#include "globals.h"
#include "buildserver.h"
// Debugging
#include "esp_log.h"
#include "fmt/core.h"
// forward declares
namespace {
class SettingsMenu;
} // namespace
using namespace espgui;
namespace {
class BuildserverMenuItem : public MenuItem
{
public:
std::string text() const override { return m_buildserver_name; }
void setBuildserverName(std::string &&buildserver_name) { m_buildserver_name = std::move(buildserver_name); }
void setBuildserverName(const std::string &buildserver_name) { m_buildserver_name = buildserver_name; }
void setBuildserverUrl(std::string &&buildserver_url) { m_buildserver_url = std::move(buildserver_url); }
void setBuildserverUrl(const std::string &buildserver_url) { m_buildserver_url = buildserver_url; }
void triggered() override
{
stringSettings.otaServerUrl = m_buildserver_url;
if (m_buildserver_url.substr(m_buildserver_url.length() - 4) == ".bin")
{
stringSettings.otaUrl = m_buildserver_url;
}
saveSettings();
redownload = true;
url_for_latest.clear();
url_for_hashes.clear();
availableVersions = {};
}
private:
std::string m_buildserver_url;
std::string m_buildserver_name;
};
class SelectBuildServerMenu :
public MenuDisplay,
public StaticText<TEXT_SELECTBUILDSERVERMENU>,
public BackActionInterface<SwitchScreenAction<SettingsMenu>>
public espgui::MenuDisplay,
public espgui::StaticText<TEXT_SELECTBUILDSERVERMENU>
{
public:
SelectBuildServerMenu() {
SelectBuildServerMenu();
for (const auto &otaServer : stringSettings.otaServers)
{
std::string url = otaServer.url;
std::string name = (otaServer.name.empty()) ? url : otaServer.name;
if (!name.empty()) {
auto &menuitem = constructMenuItem<BuildserverMenuItem>();
menuitem.setBuildserverName(name);
menuitem.setBuildserverUrl(url);
}
}
if (menuItemCount() < 1)
{
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_NOBUILDSERVERCONFIGURED>, DefaultFont, StaticColor<TFT_RED>, DummyAction>>();
}
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<SettingsMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
}
void back() override;
};
} // namespace

View File

@ -0,0 +1,94 @@
#include "settingsmenu.h"
// Arduino includes
#include <Arduino.h>
// 3rdparty lib includes
#include "actions/toggleboolaction.h"
#include "actions/switchscreenaction.h"
#include "checkboxicon.h"
#include "icons/back.h"
// local includes
#include "utils.h"
#include "icons/wifi.h"
#if defined(FEATURE_BLUETOOTH) || defined(FEATURE_BLE)
#include "icons/bluetooth.h"
#endif
#include "icons/time.h"
#include "icons/hardware.h"
#include "icons/buzzer.h"
#include "icons/info.h"
#include "icons/demos.h"
#include "icons/update.h"
#include "globals.h"
#include "accessors/settingsaccessors.h"
#include "displays/menus/limitssettingsmenu.h"
#include "displays/menus/wifisettingsmenu.h"
#include "displays/menus/bluetoothsettingsmenu.h"
#include "displays/menus/blesettingsmenu.h"
#include "displays/menus/cloudsettingsmenu.h"
#include "displays/menus/selectbuildservermenu.h"
#include "displays/menus/timesettingsmenu.h"
#include "displays/menus/modessettingsmenu.h"
#include "displays/menus/controllerhardwaresettingsmenu.h"
#include "displays/menus/boardcomputerhardwaresettingsmenu.h"
#include "displays/menus/buzzermenu.h"
#include "displays/menus/crashmenu.h"
#include "displays/menus/aboutmenu.h"
#include "displays/menus/mainmenu.h"
namespace {
#ifdef FEATURE_LEDBACKLIGHT
struct BacklightAccessor : public virtual espgui::AccessorInterface<bool>
{
bool getValue() const override { return digitalRead(PINS_LEDBACKLIGHT) != ledBacklightInverted; }
void setValue(bool value) override { digitalWrite(PINS_LEDBACKLIGHT, value != ledBacklightInverted); }
};
#endif
struct FrontLedAccessor : public espgui::RefAccessor<bool> { bool &getRef() const override { return controllers.front.command.led; } };
struct BackLedAccessor : public espgui::RefAccessor<bool> { bool &getRef() const override { return controllers.back.command.led; } };
} // namespace
using namespace espgui;
SettingsMenu::SettingsMenu()
{
#ifdef FEATURE_LEDBACKLIGHT
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACKLIGHT>, ToggleBoolAction, CheckboxIcon, BacklightAccessor>>();
#endif
if (!simplified)
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_LIMITSSETTINGS>, SwitchScreenAction<LimitsSettingsMenu>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_WIFISETTINGS>, SwitchScreenAction<WifiSettingsMenu>, StaticMenuItemIcon<&bobbyicons::wifi>>>();
#ifdef FEATURE_BLUETOOTH
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BLUETOOTHSETTINGS>, SwitchScreenAction<BluetoothSettingsMenu>, StaticMenuItemIcon<&bobbyicons::bluetooth>>>();
#endif
#ifdef FEATURE_BLE
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BLESETTINGS>, SwitchScreenAction<BleSettingsMenu>, StaticMenuItemIcon<&bobbyicons::bluetooth>>>();
#endif
#ifdef FEATURE_CLOUD
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_CLOUDSETTINGS>, SwitchScreenAction<CloudSettingsMenu>>>();
#endif
#ifdef FEATURE_OTA
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SELECTBUILDSERVERMENU>, SwitchScreenAction<SelectBuildServerMenu>, StaticMenuItemIcon<&bobbyicons::update>>>();
#endif
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_TIME>, SwitchScreenAction<TimeSettingsMenu>, StaticMenuItemIcon<&bobbyicons::time>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_MODESSETTINGS>, SwitchScreenAction<ModesSettingsMenu>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_CONTROLLERHARDWARESETTINGS>, SwitchScreenAction<ControllerHardwareSettingsMenu>, StaticMenuItemIcon<&bobbyicons::hardware>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BOARDCOMPUTERHARDWARESETTINGS>, SwitchScreenAction<BoardcomputerHardwareSettingsMenu>, StaticMenuItemIcon<&bobbyicons::hardware>>>();
#if defined(FEATURE_BLUETOOTH) && defined(FEATURE_BMS)
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_AUTOCONNECTBMS>, ToggleBoolAction, CheckboxIcon, AutoConnectBmsAccessor>>();
#endif
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BUZZER>, SwitchScreenAction<BuzzerMenu>, StaticMenuItemIcon<&bobbyicons::buzzer>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_FRONTLED>, ToggleBoolAction, CheckboxIcon, FrontLedAccessor>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACKLED>, ToggleBoolAction, CheckboxIcon, BackLedAccessor>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_CRASHMENU>, SwitchScreenAction<CrashMenu>, StaticMenuItemIcon<&bobbyicons::demos>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_ABOUT>, SwitchScreenAction<AboutMenu>, StaticMenuItemIcon<&bobbyicons::info>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<MainMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
}
void SettingsMenu::back()
{
switchScreen<MainMenu>();
}

View File

@ -1,98 +1,17 @@
#pragma once
// local includes
// 3rdparty lib includes
#include "menudisplay.h"
#include "utils.h"
#include "actions/toggleboolaction.h"
#include "actions/switchscreenaction.h"
#include "checkboxicon.h"
#include "icons/wifi.h"
#if defined(FEATURE_BLUETOOTH) || defined(FEATURE_BLE)
#include "icons/bluetooth.h"
#endif
#include "icons/time.h"
#include "icons/hardware.h"
#include "icons/buzzer.h"
#include "icons/info.h"
#include "icons/demos.h"
#include "icons/back.h"
#include "icons/update.h"
// local includes
#include "texts.h"
#include "globals.h"
#include "accessors/settingsaccessors.h"
// forward declares
namespace {
class LimitsSettingsMenu;
class WifiSettingsMenu;
class BluetoothSettingsMenu;
class BleSettingsMenu;
class CloudSettingsMenu;
class TimeSettingsMenu;
class ModesSettingsMenu;
class ControllerHardwareSettingsMenu;
class BoardcomputerHardwareSettingsMenu;
class BuzzerMenu;
class AboutMenu;
class MainMenu;
class CrashMenu;
class SelectBuildServerMenu;
}
using namespace espgui;
namespace {
#ifdef FEATURE_LEDBACKLIGHT
struct BacklightAccessor : public virtual AccessorInterface<bool>
{
bool getValue() const override { return digitalRead(PINS_LEDBACKLIGHT) != ledBacklightInverted; }
void setValue(bool value) override { digitalWrite(PINS_LEDBACKLIGHT, value != ledBacklightInverted); }
};
#endif
struct FrontLedAccessor : public RefAccessor<bool> { bool &getRef() const override { return controllers.front.command.led; } };
struct BackLedAccessor : public RefAccessor<bool> { bool &getRef() const override { return controllers.back.command.led; } };
class SettingsMenu :
public MenuDisplay,
public StaticText<TEXT_SETTINGS>,
public BackActionInterface<SwitchScreenAction<MainMenu>>
public espgui::MenuDisplay,
public espgui::StaticText<TEXT_SETTINGS>
{
public:
SettingsMenu()
{
#ifdef FEATURE_LEDBACKLIGHT
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACKLIGHT>, ToggleBoolAction, CheckboxIcon, BacklightAccessor>>();
#endif
if (!simplified)
{
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_LIMITSSETTINGS>, SwitchScreenAction<LimitsSettingsMenu>>>();
}
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_WIFISETTINGS>, SwitchScreenAction<WifiSettingsMenu>, StaticMenuItemIcon<&bobbyicons::wifi>>>();
#ifdef FEATURE_BLUETOOTH
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BLUETOOTHSETTINGS>, SwitchScreenAction<BluetoothSettingsMenu>, StaticMenuItemIcon<&bobbyicons::bluetooth>>>();
#endif
#ifdef FEATURE_BLE
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BLESETTINGS>, SwitchScreenAction<BleSettingsMenu>, StaticMenuItemIcon<&bobbyicons::bluetooth>>>();
#endif
#ifdef FEATURE_CLOUD
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_CLOUDSETTINGS>, SwitchScreenAction<CloudSettingsMenu>>>();
#endif
#ifdef FEATURE_OTA
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SELECTBUILDSERVERMENU>, SwitchScreenAction<SelectBuildServerMenu>, StaticMenuItemIcon<&bobbyicons::update>>>();
#endif
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_TIME>, SwitchScreenAction<TimeSettingsMenu>, StaticMenuItemIcon<&bobbyicons::time>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_MODESSETTINGS>, SwitchScreenAction<ModesSettingsMenu>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_CONTROLLERHARDWARESETTINGS>, SwitchScreenAction<ControllerHardwareSettingsMenu>, StaticMenuItemIcon<&bobbyicons::hardware>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BOARDCOMPUTERHARDWARESETTINGS>, SwitchScreenAction<BoardcomputerHardwareSettingsMenu>, StaticMenuItemIcon<&bobbyicons::hardware>>>();
#if defined(FEATURE_BLUETOOTH) && defined(FEATURE_BMS)
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_AUTOCONNECTBMS>, ToggleBoolAction, CheckboxIcon, AutoConnectBmsAccessor>>();
#endif
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BUZZER>, SwitchScreenAction<BuzzerMenu>, StaticMenuItemIcon<&bobbyicons::buzzer>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_FRONTLED>, ToggleBoolAction, CheckboxIcon, FrontLedAccessor>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACKLED>, ToggleBoolAction, CheckboxIcon, BackLedAccessor>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_CRASHMENU>, SwitchScreenAction<CrashMenu>, StaticMenuItemIcon<&bobbyicons::demos>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_ABOUT>, SwitchScreenAction<AboutMenu>, StaticMenuItemIcon<&bobbyicons::info>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<MainMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
}
SettingsMenu();
void back() override;
};
} // namespace

View File

@ -9,11 +9,6 @@
#include "texts.h"
#include "accessors/settingsaccessors.h"
// forward declares
namespace {
class BoardcomputerHardwareSettingsMenu;
} // namespace
using namespace espgui;
namespace {

View File

@ -18,12 +18,6 @@
#include "accessors/settingsaccessors.h"
#include "espstrutils.h"
// forward declares
namespace {
class SettingsMenu;
class TimeSettingsMenu;
} // namespace
using namespace espgui;
namespace {

View File

@ -7,14 +7,6 @@
#include "icons/back.h"
#include "texts.h"
// forward declares
namespace {
class GenericWifiSettingsMenu;
class StationWifiSettingsMenu;
class AccessPointWifiSettingsMenu;
class SettingsMenu;
} // namespace
using namespace espgui;
namespace {

View File

@ -0,0 +1,70 @@
#include "metersdisplay.h"
// 3rdparty lib includes
#include <tftinstance.h>
#include <fmt/core.h>
// local includes
#include "globals.h"
#include "utils.h"
#include "displays/menus/mainmenu.h"
#include "displays/statusdisplay.h"
#include "displays/bmsdisplay.h"
using namespace espgui;
void MetersDisplay::initScreen()
{
tft.fillScreen(TFT_BLACK);
m_vuMeter.start();
m_dischargingBar.start();
m_chargingBar.start();
m_sumCurrentLabel.start();
for (auto &meter : meters)
meter.start();
}
void MetersDisplay::redraw()
{
m_vuMeter.redraw(avgSpeedKmh);
m_dischargingBar.redraw(sumCurrent<0.f?(-sumCurrent):0.f);
m_chargingBar.redraw(sumCurrent>0.f?sumCurrent:0.f);
tft.setTextColor(TFT_WHITE, TFT_BLACK);
tft.setTextFont(2);
m_sumCurrentLabel.redraw(fmt::format("{:.02f}A", sumCurrent));
meters[0].redraw(controllers.front.getCalibratedVoltage(), 35, 50);
meters[1].redraw(controllers.back.getCalibratedVoltage(), 35, 50);
meters[2].redraw(fixCurrent(controllers.front.feedback.left.dcLink), -10, 10);
meters[3].redraw(fixCurrent(controllers.front.feedback.right.dcLink), -10, 10);
meters[4].redraw(fixCurrent(controllers.back.feedback.left.dcLink), -10, 10);
meters[5].redraw(fixCurrent(controllers.back.feedback.right.dcLink), -10, 10);
}
void MetersDisplay::confirm()
{
switchScreen<MainMenu>();
}
void MetersDisplay::back()
{
switchScreen<MainMenu>();
}
void MetersDisplay::rotate(int offset)
{
if (offset < 0)
switchScreen<StatusDisplay>();
else if (offset > 0)
#ifdef FEATURE_BMS
switchScreen<BmsDisplay>();
#else
switchScreen<StatusDisplay>();
#endif
}

View File

@ -1,96 +1,43 @@
#pragma once
// system includes
#include <array>
#include <Arduino.h>
// 3rdparty lib includes
#include <display.h>
#include <actions/switchscreenaction.h>
#include <widgets/label.h>
#include <widgets/reverseprogressbar.h>
#include <widgets/progressbar.h>
#include <widgets/verticalmeter.h>
#include <widgets/vumeter.h>
#include "display.h"
#include "actions/switchscreenaction.h"
#include "globals.h"
#include "utils.h"
#include "widgets/label.h"
#include "widgets/reverseprogressbar.h"
#include "widgets/progressbar.h"
#include "widgets/verticalmeter.h"
#include "widgets/vumeter.h"
namespace {
class MainMenu;
class StatusDisplay;
class BmsDisplay;
}
namespace {
class MetersDisplay : public Display, public ConfirmActionInterface<SwitchScreenAction<MainMenu>>, public BackActionInterface<SwitchScreenAction<MainMenu>>
class MetersDisplay :
public espgui::Display
{
public:
void initScreen() override;
void redraw() override;
void confirm() override;
void back() override;
void rotate(int offset) override;
private:
VuMeter m_vuMeter;
espgui::VuMeter m_vuMeter;
ReverseProgressBar m_dischargingBar{10, 135, 90, 15, 0, 40, TFT_GREEN};
ProgressBar m_chargingBar{100, 135, 90, 15, 0, 40, TFT_RED};
espgui::ReverseProgressBar m_dischargingBar{10, 135, 90, 15, 0, 40, TFT_GREEN};
espgui::ProgressBar m_chargingBar{100, 135, 90, 15, 0, 40, TFT_RED};
Label m_sumCurrentLabel{195,135};
espgui::Label m_sumCurrentLabel{195,135};
static constexpr auto x = 40;
std::array<VerticalMeter, 6> meters{{
VerticalMeter{"U f", "%.1f", 0*x, 160},
VerticalMeter{"U b", "%.1f", 1*x, 160},
VerticalMeter{"Ibl", "%.1f", 2*x, 160},
VerticalMeter{"Ibr", "%.1f", 3*x, 160},
VerticalMeter{"Ihl", "%.1f", 4*x, 160},
VerticalMeter{"Ihr", "%.1f", 5*x, 160}
std::array<espgui::VerticalMeter, 6> meters{{
espgui::VerticalMeter{"U f", "%.1f", 0*x, 160},
espgui::VerticalMeter{"U b", "%.1f", 1*x, 160},
espgui::VerticalMeter{"Ibl", "%.1f", 2*x, 160},
espgui::VerticalMeter{"Ibr", "%.1f", 3*x, 160},
espgui::VerticalMeter{"Ihl", "%.1f", 4*x, 160},
espgui::VerticalMeter{"Ihr", "%.1f", 5*x, 160}
}};
};
void MetersDisplay::initScreen()
{
tft.fillScreen(TFT_BLACK);
m_vuMeter.start();
m_dischargingBar.start();
m_chargingBar.start();
m_sumCurrentLabel.start();
for (auto &meter : meters)
meter.start();
}
void MetersDisplay::redraw()
{
m_vuMeter.redraw(avgSpeedKmh);
m_dischargingBar.redraw(sumCurrent<0.f?(-sumCurrent):0.f);
m_chargingBar.redraw(sumCurrent>0.f?sumCurrent:0.f);
tft.setTextColor(TFT_WHITE, TFT_BLACK);
tft.setTextFont(2);
m_sumCurrentLabel.redraw(std::to_string(sumCurrent) + 'A');
meters[0].redraw(controllers.front.getCalibratedVoltage(settings.battery.applyCalibration), 35, 50);
meters[1].redraw(controllers.back.getCalibratedVoltage(settings.battery.applyCalibration), 35, 50);
meters[2].redraw(fixCurrent(controllers.front.feedback.left.dcLink), -10, 10);
meters[3].redraw(fixCurrent(controllers.front.feedback.right.dcLink), -10, 10);
meters[4].redraw(fixCurrent(controllers.back.feedback.left.dcLink), -10, 10);
meters[5].redraw(fixCurrent(controllers.back.feedback.right.dcLink), -10, 10);
}
void MetersDisplay::rotate(int offset)
{
if (offset < 0)
switchScreen<StatusDisplay>();
else if (offset > 0)
#ifdef FEATURE_BMS
switchScreen<BmsDisplay>();
#else
switchScreen<StatusDisplay>();
#endif
}
}

View File

@ -9,11 +9,6 @@
#include "globals.h"
#include "widgets/label.h"
namespace {
class MainMenu;
class MetersDisplay;
class StatusDisplay;
}
namespace {
#if defined(FEATURE_CAN) && defined(FEATURE_POWERSUPPLY)
class PowerSupplyDisplay : public Display, public DummyConfirm, public BackActionInterface<SwitchScreenAction<MainMenu>>

View File

@ -0,0 +1,261 @@
#include "statusdisplay.h"
// 3rdparty lib includes
#include <fmt/core.h>
#include <espwifistack.h>
#include <tftinstance.h>
// local includes
#include "displays/menus/mainmenu.h"
#ifdef FEATURE_BMS
#include "displays/bmsdisplay.h"
#else
#include "displays/metersdisplay.h"
#endif
using namespace espgui;
void StatusDisplay::initScreen()
{
Base::initScreen();
tft.setTextFont(2);
tft.setTextColor(TFT_WHITE);
tft.drawString("gas", 0, 0);
m_labelRawGas.start();
m_labelGas.start();
m_progressBarGas.start();
tft.drawString("brems", 0, 15);
m_labelRawBrems.start();
m_labelBrems.start();
m_progressBarBrems.start();
m_batterypercent.start();
m_watthoursleft.start();
m_kilometersleft.start();
m_frontStatus.start();
m_backStatus.start();
tft.setTextFont(2);
tft.drawString("WiFi:", 0, bottomLines[0]);
m_labelWifiStatus.start();
tft.drawString("Lim0:", 173, bottomLines[0]);
m_labelLimit0.start();
tft.drawString("IP:", 0, bottomLines[1]);
m_labelIpAddress.start();
m_labelSignal.start();
tft.drawString("Lim1:", 173, bottomLines[1]);
m_labelLimit1.start();
tft.drawString("Perf:", 0, bottomLines[2]);
m_labelPerformance.start();
m_labelFreeMem.start();
tft.drawString("Mode:", 125, bottomLines[2]);
m_labelMode.start();
tft.drawString("Name:", 0, bottomLines[3]);
m_labelName.start();
m_labelProfile.start();
tft.setTextColor(TFT_WHITE, TFT_BLACK);
}
void StatusDisplay::redraw()
{
Base::redraw();
tft.setTextFont(2);
m_labelRawGas.redraw(raw_gas ? std::to_string(*raw_gas) : "?");
m_labelGas.redraw(gas ? fmt::format("{:.2f}", *gas) : "?");
m_progressBarGas.redraw(gas ? *gas : 0);
m_labelRawBrems.redraw(raw_brems ? std::to_string(*raw_brems) : "?");
m_labelBrems.redraw(brems ? fmt::format("{:.2f}", *brems) : "?");
m_progressBarBrems.redraw(brems ? *brems : 0);
m_batterypercent.redraw(getBatteryPercentageString());
m_watthoursleft.redraw(getBatteryRemainingWattHoursString());
m_kilometersleft.redraw(getRemainingRangeString());
m_frontStatus.redraw(controllers.front);
m_backStatus.redraw(controllers.back);
tft.setTextFont(2);
const auto staStatus = wifi_stack::get_sta_status();
if (staStatus == wifi_stack::WiFiStaStatus::CONNECTED)
{
if (const auto result = wifi_stack::get_sta_ap_info(); result)
{
m_labelWifiStatus.redraw(std::string_view{reinterpret_cast<const char*>(result->ssid)});
tft.setTextColor(result->rssi < -80 ? TFT_ORANGE : TFT_WHITE, TFT_BLACK);
m_labelSignal.redraw(fmt::format("{}dB", result->rssi));
tft.setTextColor(TFT_WHITE, TFT_BLACK);
}
else
{
ESP_LOGW("BOBBY", "get_sta_ap_info() failed with %.*s", result.error().size(), result.error().data());
goto showStaStatus;
}
}
else
{
showStaStatus:
m_labelWifiStatus.redraw(wifi_stack::toString(staStatus));
m_labelSignal.clear();
}
m_labelLimit0.redraw(fmt::format("{}A", controllers.front.command.left.iMotMax));
if (staStatus == wifi_stack::WiFiStaStatus::CONNECTED)
{
if (const auto result = wifi_stack::get_ip_info(TCPIP_ADAPTER_IF_STA); result)
m_labelIpAddress.redraw(wifi_stack::toString(result->ip));
else
{
ESP_LOGW("BOBBY", "get_ip_info() failed with %.*s", result.error().size(), result.error().data());
goto clearIp;
}
}
else
{
clearIp:
m_labelIpAddress.clear();
}
m_labelLimit1.redraw(fmt::format("{}A", controllers.front.command.left.iDcMax));
tft.setTextColor(performance.last < 35 ? TFT_ORANGE : TFT_WHITE, TFT_BLACK);
m_labelPerformance.redraw(std::to_string(performance.last));
tft.setTextColor(TFT_WHITE, TFT_BLACK);
{
const auto freeMem = heap_caps_get_free_size(MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
tft.setTextColor(freeMem < 70000 ? TFT_ORANGE : TFT_WHITE, TFT_BLACK);
m_labelFreeMem.redraw(fmt::format("{}K", freeMem/1000));
tft.setTextColor(TFT_WHITE, TFT_BLACK);
}
m_labelMode.redraw(currentMode->displayName());
m_labelName.redraw(deviceName);
const auto profile = settingsPersister.currentlyOpenProfileIndex();
m_labelProfile.redraw(profile ? std::to_string(*profile) : "-");
}
void StatusDisplay::confirm()
{
switchScreen<MainMenu>();
}
void StatusDisplay::rotate(int offset)
{
Base::rotate(offset);
if (offset < 0)
#ifdef FEATURE_BMS
switchScreen<BmsDisplay>();
#else
switchScreen<MetersDisplay>();
#endif
else if (offset > 0)
switchScreen<MetersDisplay>();
}
StatusDisplay::BoardStatus::BoardStatus(int y) :
m_y{y},
m_labelLeftPwm{65, y}, // 80, 22
m_labelRightPwm{155, y}, // 80, 22
m_labelVoltage{30, y+25}, // 85, 22
m_labelTemperature{150, y+25}, // 85, 22
m_leftMotor{y+50},
m_rightMotor{y+75}
{}
void StatusDisplay::BoardStatus::start()
{
tft.setTextFont(4);
tft.drawString("pwm:", 0, m_y);
m_labelLeftPwm.start();
m_labelRightPwm.start();
m_initialRedraw = true;
}
void StatusDisplay::BoardStatus::redraw(const Controller &controller)
{
tft.setTextFont(4);
m_labelLeftPwm.redraw(std::to_string(controller.command.left.pwm));
m_labelRightPwm.redraw(std::to_string(controller.command.right.pwm));
if (controller.feedbackValid != m_lastFeedbackValid || m_initialRedraw)
{
tft.fillRect(0, m_y+25, tft.width(), 75, TFT_BLACK);
if (controller.feedbackValid)
{
tft.setTextColor(TFT_WHITE);
tft.drawString("U=", 0, m_y+25, 4);
m_labelVoltage.start();
tft.drawString("T=", 120, m_y+25, 4);
m_labelTemperature.start();
tft.drawString("l:", 0, m_y+50, 4);
m_leftMotor.start();
tft.drawString("r:", 0, m_y+75, 4);
m_rightMotor.start();
tft.setTextColor(TFT_WHITE, TFT_BLACK);
}
else
{
tft.setTextColor(TFT_RED);
tft.drawString("No data!", 60, m_y+50, 4);
tft.setTextColor(TFT_WHITE, TFT_BLACK);
tft.setSwapBytes(true);
tft.pushImage(10, m_y+40, bobbyicons::alert.WIDTH, bobbyicons::alert.HEIGHT, bobbyicons::alert.buffer);
tft.setSwapBytes(false);
}
m_lastFeedbackValid = controller.feedbackValid;
m_initialRedraw = false;
}
if (controller.feedbackValid)
{
m_labelVoltage.redraw(fmt::format("{:.2f}V", controller.getCalibratedVoltage()));
m_labelTemperature.redraw(fmt::format("{:.2f}C", fixBoardTemp(controller.feedback.boardTemp)));
m_leftMotor.redraw(controller.feedback.left);
m_rightMotor.redraw(controller.feedback.right);
}
}
StatusDisplay::BoardStatus::MotorStatus::MotorStatus(int y) :
m_labelError{18, y}, // 18, 22,
m_labelCurrent{40, y}, // 85, 22
m_labelSpeed{135, y}, // 75, 22
m_labelHallSensors{210, y} // 30, 15
{}
void StatusDisplay::BoardStatus::MotorStatus::start()
{
m_labelError.start();
m_labelCurrent.start();
m_labelSpeed.start();
m_labelHallSensors.start();
}
void StatusDisplay::BoardStatus::MotorStatus::redraw(const bobbycar::protocol::serial::MotorFeedback &motor)
{
tft.setTextFont(4);
tft.setTextColor(motor.error?TFT_RED:TFT_GREEN, TFT_BLACK);
m_labelError.redraw(std::to_string(motor.error));
tft.setTextColor(TFT_WHITE, TFT_BLACK);
m_labelCurrent.redraw(fmt::format("{:.2f}A", fixCurrent(motor.dcLink)));
m_labelSpeed.redraw(fmt::format("{:.2f}", convertToKmh(motor.speed)));
tft.setTextFont(2);
m_labelHallSensors.redraw(hallString(motor));
tft.setTextColor(TFT_WHITE, TFT_BLACK);
}

View File

@ -4,51 +4,36 @@
#include <esp_heap_caps.h>
// 3rdparty lib includes
#include <fmt/core.h>
#include <espwifistack.h>
#include <display.h>
#include <actions/switchscreenaction.h>
#include <widgets/label.h>
#include <widgets/progressbar.h>
// local includes
#include "display.h"
#include "actions/switchscreenaction.h"
#include "modeinterface.h"
#include "globals.h"
#include "utils.h"
#include "widgets/label.h"
#include "widgets/progressbar.h"
#include "icons/alert.h"
#include "battery.h"
// forward declares
namespace {
class MainMenu;
class BmsDisplay;
class MetersDisplay;
static uint16_t counter = 24;
}
namespace {
class StatusDisplay : public Display, public ConfirmActionInterface<SwitchScreenAction<MainMenu>>, public DummyBack
class StatusDisplay :
public espgui::Display,
public espgui::DummyBack
{
using Base = espgui::Display;
public:
void initScreen() override;
void redraw() override;
void confirm() override;
void rotate(int offset) override;
private:
class BoardStatus
{
public:
BoardStatus(int y) :
m_y{y},
m_labelLeftPwm{65, y}, // 80, 22
m_labelRightPwm{155, y}, // 80, 22
m_labelVoltage{30, y+25}, // 85, 22
m_labelTemperature{150, y+25}, // 85, 22
m_leftMotor{y+50},
m_rightMotor{y+75}
{}
BoardStatus(int y);
void start();
void redraw(const Controller &controller);
@ -57,21 +42,16 @@ private:
class MotorStatus
{
public:
MotorStatus(int y) :
m_labelError{18, y}, // 18, 22,
m_labelCurrent{40, y}, // 85, 22
m_labelSpeed{135, y}, // 75, 22
m_labelHallSensors{210, y} // 30, 15
{}
MotorStatus(int y);
void start();
void redraw(const bobbycar::protocol::serial::MotorFeedback &motor);
private:
Label m_labelError;
Label m_labelCurrent;
Label m_labelSpeed;
Label m_labelHallSensors;
espgui::Label m_labelError;
espgui::Label m_labelCurrent;
espgui::Label m_labelSpeed;
espgui::Label m_labelHallSensors;
};
const int m_y;
@ -79,268 +59,41 @@ private:
bool m_initialRedraw;
bool m_lastFeedbackValid;
Label m_labelLeftPwm;
Label m_labelRightPwm;
espgui::Label m_labelLeftPwm;
espgui::Label m_labelRightPwm;
Label m_labelVoltage;
Label m_labelTemperature;
espgui::Label m_labelVoltage;
espgui::Label m_labelTemperature;
MotorStatus m_leftMotor;
MotorStatus m_rightMotor;
};
Label m_labelRawGas{45, 0}; // 40, 15
Label m_labelGas{90, 0}; // 60, 15
ProgressBar m_progressBarGas{150, 0, 90, 15, 0, 1000};
espgui::Label m_labelRawGas{45, 0}; // 40, 15
espgui::Label m_labelGas{90, 0}; // 60, 15
espgui::ProgressBar m_progressBarGas{150, 0, 90, 15, 0, 1000};
Label m_labelRawBrems{45, 15}; // 40, 15
Label m_labelBrems{90, 15}; // 60, 15
ProgressBar m_progressBarBrems{150, 15, 90, 15, 0, 1000};
espgui::Label m_labelRawBrems{45, 15}; // 40, 15
espgui::Label m_labelBrems{90, 15}; // 60, 15
espgui::ProgressBar m_progressBarBrems{150, 15, 90, 15, 0, 1000};
Label m_batterypercent{0, 30};
Label m_watthoursleft{110, 30};
Label m_kilometersleft{175, 30};
espgui::Label m_batterypercent{0, 30};
espgui::Label m_watthoursleft{110, 30};
espgui::Label m_kilometersleft{175, 30};
BoardStatus m_frontStatus{45};
BoardStatus m_backStatus{145};
Label m_labelWifiStatus{35, bottomLines[0]}; // 120, 15
Label m_labelLimit0{205, bottomLines[0]}; // 35, 15
Label m_labelIpAddress{25, bottomLines[1]}; // 130, 15
Label m_labelSignal{125, bottomLines[1]}; // 130, 15
Label m_labelLimit1{205, bottomLines[1]}; // 35, 15
Label m_labelPerformance{40, bottomLines[2]}; // 40, 15
Label m_labelFreeMem{70, bottomLines[2]}; // 40, 15
Label m_labelMode{165, bottomLines[2]}; // 75, 15
Label m_labelName{40, bottomLines[3]}; // 40, 15
Label m_labelProfile{205, bottomLines[3]}; // 35, 15
espgui::Label m_labelWifiStatus{35, bottomLines[0]}; // 120, 15
espgui::Label m_labelLimit0{205, bottomLines[0]}; // 35, 15
espgui::Label m_labelIpAddress{25, bottomLines[1]}; // 130, 15
espgui::Label m_labelSignal{125, bottomLines[1]}; // 130, 15
espgui::Label m_labelLimit1{205, bottomLines[1]}; // 35, 15
espgui::Label m_labelPerformance{40, bottomLines[2]}; // 40, 15
espgui::Label m_labelFreeMem{70, bottomLines[2]}; // 40, 15
espgui::Label m_labelMode{165, bottomLines[2]}; // 75, 15
espgui::Label m_labelName{40, bottomLines[3]}; // 40, 15
espgui::Label m_labelProfile{205, bottomLines[3]}; // 35, 15
static const constexpr int bottomLines[4] { 251, 266, 281, 296 };
};
void StatusDisplay::initScreen()
{
tft.fillScreen(TFT_BLACK);
tft.setTextFont(2);
tft.setTextColor(TFT_WHITE);
tft.drawString("gas", 0, 0);
m_labelRawGas.start();
m_labelGas.start();
m_progressBarGas.start();
tft.drawString("brems", 0, 15);
m_labelRawBrems.start();
m_labelBrems.start();
m_progressBarBrems.start();
m_batterypercent.start();
m_watthoursleft.start();
m_kilometersleft.start();
m_frontStatus.start();
m_backStatus.start();
tft.setTextFont(2);
tft.drawString("WiFi:", 0, bottomLines[0]);
m_labelWifiStatus.start();
tft.drawString("Lim0:", 173, bottomLines[0]);
m_labelLimit0.start();
tft.drawString("IP:", 0, bottomLines[1]);
m_labelIpAddress.start();
m_labelSignal.start();
tft.drawString("Lim1:", 173, bottomLines[1]);
m_labelLimit1.start();
tft.drawString("Perf:", 0, bottomLines[2]);
m_labelPerformance.start();
m_labelFreeMem.start();
tft.drawString("Mode:", 125, bottomLines[2]);
m_labelMode.start();
tft.drawString("Name:", 0, bottomLines[3]);
m_labelName.start();
m_labelProfile.start();
tft.setTextColor(TFT_WHITE, TFT_BLACK);
counter = 0;
}
void StatusDisplay::redraw()
{
tft.setTextFont(2);
m_labelRawGas.redraw(raw_gas ? std::to_string(*raw_gas) : "?");
m_labelGas.redraw(gas ? fmt::format("{:.2f}", *gas) : "?");
m_progressBarGas.redraw(gas ? *gas : 0);
m_labelRawBrems.redraw(raw_brems ? std::to_string(*raw_brems) : "?");
m_labelBrems.redraw(brems ? fmt::format("{:.2f}", *brems) : "?");
m_progressBarBrems.redraw(brems ? *brems : 0);
if (counter < 1)
{
counter = 25;
m_batterypercent.redraw(getBatteryPercentageString());
m_watthoursleft.redraw(getBatteryRemainingWattHoursString());
m_kilometersleft.redraw(getRemainingRangeString());
}
else
counter--;
m_frontStatus.redraw(controllers.front);
m_backStatus.redraw(controllers.back);
tft.setTextFont(2);
const auto staStatus = wifi_stack::get_sta_status();
if (staStatus == wifi_stack::WiFiStaStatus::CONNECTED)
{
if (const auto result = wifi_stack::get_sta_ap_info(); result)
{
m_labelWifiStatus.redraw(std::string_view{reinterpret_cast<const char*>(result->ssid)});
tft.setTextColor(result->rssi < -80 ? TFT_ORANGE : TFT_WHITE, TFT_BLACK);
m_labelSignal.redraw(fmt::format("{}dB", result->rssi));
tft.setTextColor(TFT_WHITE, TFT_BLACK);
}
else
{
ESP_LOGW("BOBBY", "get_sta_ap_info() failed with %.*s", result.error().size(), result.error().data());
goto showStaStatus;
}
}
else
{
showStaStatus:
m_labelWifiStatus.redraw(wifi_stack::toString(staStatus));
m_labelSignal.clear();
}
m_labelLimit0.redraw(fmt::format("{}A", controllers.front.command.left.iMotMax));
if (staStatus == wifi_stack::WiFiStaStatus::CONNECTED)
{
if (const auto result = wifi_stack::get_ip_info(TCPIP_ADAPTER_IF_STA); result)
m_labelIpAddress.redraw(wifi_stack::toString(result->ip));
else
{
ESP_LOGW("BOBBY", "get_ip_info() failed with %.*s", result.error().size(), result.error().data());
goto clearIp;
}
}
else
{
clearIp:
m_labelIpAddress.clear();
}
m_labelLimit1.redraw(fmt::format("{}A", controllers.front.command.left.iDcMax));
tft.setTextColor(performance.last < 35 ? TFT_ORANGE : TFT_WHITE, TFT_BLACK);
m_labelPerformance.redraw(std::to_string(performance.last));
tft.setTextColor(TFT_WHITE, TFT_BLACK);
{
const auto freeMem = heap_caps_get_free_size(MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT);
tft.setTextColor(freeMem < 70000 ? TFT_ORANGE : TFT_WHITE, TFT_BLACK);
m_labelFreeMem.redraw(fmt::format("{}K", freeMem/1000));
tft.setTextColor(TFT_WHITE, TFT_BLACK);
}
m_labelMode.redraw(currentMode->displayName());
m_labelName.redraw(deviceName);
const auto profile = settingsPersister.currentlyOpenProfileIndex();
m_labelProfile.redraw(profile ? std::to_string(*profile) : "-");
}
void StatusDisplay::rotate(int offset)
{
counter = 0;
if (offset < 0)
#ifdef FEATURE_BMS
switchScreen<BmsDisplay>();
#else
switchScreen<MetersDisplay>();
#endif
else if (offset > 0)
switchScreen<MetersDisplay>();
}
void StatusDisplay::BoardStatus::start()
{
tft.setTextFont(4);
tft.drawString("pwm:", 0, m_y);
m_labelLeftPwm.start();
m_labelRightPwm.start();
m_initialRedraw = true;
}
void StatusDisplay::BoardStatus::redraw(const Controller &controller)
{
tft.setTextFont(4);
m_labelLeftPwm.redraw(std::to_string(controller.command.left.pwm));
m_labelRightPwm.redraw(std::to_string(controller.command.right.pwm));
if (controller.feedbackValid != m_lastFeedbackValid || m_initialRedraw)
{
tft.fillRect(0, m_y+25, tft.width(), 75, TFT_BLACK);
if (controller.feedbackValid)
{
tft.setTextColor(TFT_WHITE);
tft.drawString("U=", 0, m_y+25, 4);
m_labelVoltage.start();
tft.drawString("T=", 120, m_y+25, 4);
m_labelTemperature.start();
tft.drawString("l:", 0, m_y+50, 4);
m_leftMotor.start();
tft.drawString("r:", 0, m_y+75, 4);
m_rightMotor.start();
tft.setTextColor(TFT_WHITE, TFT_BLACK);
}
else
{
tft.setTextColor(TFT_RED);
tft.drawString("No data!", 60, m_y+50, 4);
tft.setTextColor(TFT_WHITE, TFT_BLACK);
tft.setSwapBytes(true);
tft.pushImage(10, m_y+40, bobbyicons::alert.WIDTH, bobbyicons::alert.HEIGHT, bobbyicons::alert.buffer);
tft.setSwapBytes(false);
}
m_lastFeedbackValid = controller.feedbackValid;
m_initialRedraw = false;
}
if (controller.feedbackValid)
{
m_labelVoltage.redraw(fmt::format("{:.2f}V", controller.getCalibratedVoltage(settings.battery.applyCalibration)));
m_labelTemperature.redraw(fmt::format("{:.2f}C", fixBoardTemp(controller.feedback.boardTemp)));
m_leftMotor.redraw(controller.feedback.left);
m_rightMotor.redraw(controller.feedback.right);
}
}
void StatusDisplay::BoardStatus::MotorStatus::start()
{
m_labelError.start();
m_labelCurrent.start();
m_labelSpeed.start();
m_labelHallSensors.start();
}
void StatusDisplay::BoardStatus::MotorStatus::redraw(const bobbycar::protocol::serial::MotorFeedback &motor)
{
tft.setTextFont(4);
tft.setTextColor(motor.error?TFT_RED:TFT_GREEN, TFT_BLACK);
m_labelError.redraw(std::to_string(motor.error));
tft.setTextColor(TFT_WHITE, TFT_BLACK);
m_labelCurrent.redraw(fmt::format("{:.2f}A", fixCurrent(motor.dcLink)));
m_labelSpeed.redraw(fmt::format("{:.2f}", convertToKmh(motor.speed)));
tft.setTextFont(2);
m_labelHallSensors.redraw(hallString(motor));
tft.setTextColor(TFT_WHITE, TFT_BLACK);
}
}

View File

@ -20,98 +20,6 @@ using namespace std::chrono_literals;
#include "bobbycar-serial.h"
#include "macros_bobbycar.h"
#include "globals.h"
#include "modes/defaultmode.h"
#include "modes/tempomatmode.h"
#include "displays/menus/aboutmenu.h"
#include "displays/menus/accesspointwifisettingsmenu.h"
#ifdef FEATURE_BLUETOOTH
#include "displays/menus/bluetoothsettingsmenu.h"
#endif
#ifdef FEATURE_BLE
#include "displays/menus/blesettingsmenu.h"
#endif
#ifdef FEATURE_CLOUD
#include "displays/menus/cloudsettingsmenu.h"
#endif
#ifdef FEATURE_BMS
#include "displays/menus/bmsmenu.h"
#endif
#include "displays/menus/buzzermenu.h"
#include "displays/menus/commanddebugmenu.h"
#include "displays/menus/crashmenu.h"
#include "displays/menus/debugmenu.h"
#include "displays/menus/defaultmodesettingsmenu.h"
#include "displays/menus/demosmenu.h"
#include "displays/menus/dynamicdebugmenu.h"
#include "displays/menus/enablemenu.h"
#include "displays/menus/feedbackdebugmenu.h"
#ifdef FEATURE_GAMETRAK
#include "displays/menus/gametrakmodesettingsmenu.h"
#endif
#include "displays/menus/genericwifisettingsmenu.h"
#include "displays/menus/graphsmenu.h"
#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/lockscreensettingsmenu.h"
#include "displays/menus/mainmenu.h"
#include "displays/menus/tempomatmodesettingsmenu.h"
#include "displays/menus/modessettingsmenu.h"
#ifdef FEATURE_LEDSTRIP
#include "displays/ledstripcolorsdisplay.h"
#endif
#ifdef FEATURE_MOSFETS
#include "displays/menus/mosfetsmenu.h"
#endif
#include "displays/menus/motorfeedbackdebugmenu.h"
#include "displays/menus/motorstatedebugmenu.h"
#include "displays/menus/profilesmenu.h"
#include "displays/menus/presetsmenu.h"
#include "displays/menus/boardcomputerhardwaresettingsmenu.h"
#include "displays/menus/selectmodemenu.h"
#include "displays/menus/settingsmenu.h"
#include "displays/menus/stationwifisettingsmenu.h"
#include "displays/menus/timersmenu.h"
#include "displays/menus/timesettingsmenu.h"
#include "displays/menus/wifiscanmenu.h"
#include "displays/menus/wifisettingsmenu.h"
#ifdef FEATURE_BMS
#include "displays/bmsdisplay.h"
#endif
#include "displays/calibratedisplay.h"
#ifdef FEATURE_DPAD_5WIRESW
#include "displays/dpad5wiredebugdisplay.h"
#endif
#ifdef FEATURE_DPAD_5WIRESW_2OUT
#include "displays/dpad5wire2outdebugdisplay.h"
#endif
#ifdef FEATURE_DPAD_6WIRESW
#include "displays/dpad6wiredebugdisplay.h"
#endif
#include "displays/gameoflifedisplay.h"
#ifdef FEATURE_GARAGE
#include "displays/garagedisplay.h"
#endif
#ifdef FEATURE_LOCKSCREEN
#include "displays/gametrakcalibratedisplay.h"
#endif
#include "displays/lockscreen.h"
#include "displays/metersdisplay.h"
#include "displays/pingpongdisplay.h"
#include "displays/poweroffdisplay.h"
#include "displays/powersupplydisplay.h"
#include "displays/spirodisplay.h"
#include "displays/starfielddisplay.h"
#include "displays/statusdisplay.h"
#ifdef FEATURE_OTA
#include "displays/updatedisplay.h"
#include "displays/menus/otamenu.h"
#include "displays/menus/selectotabuildmenu.h"
#endif
#include "screens.h"
#include "dpad.h"
#ifdef FEATURE_DPAD_3WIRESW
@ -160,6 +68,9 @@ using namespace std::chrono_literals;
#ifdef FEATURE_LEDSTRIP
#include "ledstrip.h"
#endif
#include "modes/defaultmode.h"
#include "displays/statusdisplay.h"
#include "displays/calibratedisplay.h"
namespace {
std::optional<espchrono::millis_clock::time_point> lastWifiUpdate;
@ -362,9 +273,9 @@ extern "C" void app_main()
#else
if (!gas || !brems || *gas > 200.f || *brems > 200.f)
switchScreen<CalibrateDisplay>(true);
espgui::switchScreen<CalibrateDisplay>(true);
else
switchScreen<StatusDisplay>();
espgui::switchScreen<StatusDisplay>();
#endif
while (true)

View File

@ -0,0 +1,93 @@
#include "screens.h"
// 3rdparty lib includes
#include <tftinstance.h>
// local includes
#include "globals.h"
#include "utils.h"
#include "icons/logo.h"
#include "buttons.h"
using namespace espgui;
Label bootLabel{32, 250};
void initScreen()
{
tft.init();
tft.fillScreen(TFT_WHITE);
tft.setTextColor(TFT_BLACK, TFT_WHITE);
tft.setTextFont(4);
tft.pushImage(0, 40, bobbyicons::logo.WIDTH, bobbyicons::logo.HEIGHT, bobbyicons::logo.buffer);
tft.drawString("Bobbycar-OS", 32, 200);
tft.drawString("booting...", 32, 225);
bootLabel.start();
}
void updateDisplay()
{
if (rotated)
{
const auto rotatedCopy = rotated;
rotated = 0;
if (currentDisplay)
currentDisplay->rotate(rotatedCopy);
}
if (requestFullRedraw)
{
requestFullRedraw = false;
tft.init();
if (currentDisplay)
currentDisplay->initScreen();
}
if (confirmButtonPressed)
{
confirmButtonPressed = false;
if (currentDisplay)
currentDisplay->confirm();
}
if (confirmButtonLongPressed)
{
confirmButtonLongPressed = false;
//Serial.println("todo: implement long press for confirm");
}
if (backButtonPressed)
{
backButtonPressed = false;
if (currentDisplay)
currentDisplay->back();
}
if (backButtonLongPressed)
{
backButtonLongPressed = false;
//Serial.println("todo: implement long press for back");
}
if (currentDisplay)
currentDisplay->update();
if (changeScreenCallback)
{
changeScreenCallback();
changeScreenCallback = {};
}
}
void redrawDisplay()
{
if (currentDisplay)
{
currentDisplay->redraw();
}
}

View File

@ -3,94 +3,12 @@
// system includes
#include <optional>
// local includes
#include "globals.h"
#include "utils.h"
#include "widgets/label.h"
#include "icons/logo.h"
#include "screenmanager.h"
// 3rdparty lib includes
#include <widgets/label.h>
#include <screenmanager.h>
using namespace espgui;
extern espgui::Label bootLabel;
namespace {
Label bootLabel{32, 250};
void initScreen()
{
tft.init();
tft.fillScreen(TFT_WHITE);
tft.setTextColor(TFT_BLACK, TFT_WHITE);
tft.setTextFont(4);
tft.pushImage(0, 40, bobbyicons::logo.WIDTH, bobbyicons::logo.HEIGHT, bobbyicons::logo.buffer);
tft.drawString("Bobbycar-OS", 32, 200);
tft.drawString("booting...", 32, 225);
bootLabel.start();
}
void updateDisplay()
{
if (rotated)
{
const auto rotatedCopy = rotated;
rotated = 0;
if (currentDisplay)
currentDisplay->rotate(rotatedCopy);
}
if (requestFullRedraw)
{
requestFullRedraw = false;
tft.init();
if (currentDisplay)
currentDisplay->initScreen();
}
if (confirmButtonPressed)
{
confirmButtonPressed = false;
if (currentDisplay)
currentDisplay->confirm();
}
if (confirmButtonLongPressed)
{
confirmButtonLongPressed = false;
//Serial.println("todo: implement long press for confirm");
}
if (backButtonPressed)
{
backButtonPressed = false;
if (currentDisplay)
currentDisplay->back();
}
if (backButtonLongPressed)
{
backButtonLongPressed = false;
//Serial.println("todo: implement long press for back");
}
if (currentDisplay)
currentDisplay->update();
if (changeScreenCallback)
{
changeScreenCallback();
changeScreenCallback = {};
}
}
void redrawDisplay()
{
if (currentDisplay)
{
currentDisplay->redraw();
}
}
}
void initScreen();
void updateDisplay();
void redrawDisplay();

View File

@ -0,0 +1,121 @@
#include "serialhandler.h"
// Arduino includes
#include <HardwareSerial.h>
// 3rdparty lib includes
#include <tftinstance.h>
// local includes
#include "globals.h"
#include "utils.h"
#include "screens.h"
#include "buttons.h"
using namespace espgui;
//wl_status_t last_status;
//IPAddress last_ip;
void handleSerial()
{
//const auto status = WiFi.status();
//if (last_status != status)
//{
//Serial.print("Status changed to: ");
//Serial.println(to_string(status).c_str());
//last_status = status;
//}
//const auto ip = WiFi.localIP();
//if (last_ip != ip)
//{
//Serial.print("IP changed to: ");
//Serial.println(to_string(ip).c_str());
//last_ip = ip;
//}
while(Serial.available())
{
const auto c = Serial.read();
switch (c)
{
case 'i':
case 'I':
tft.init();
break;
case 'p':
case 'P':
{
const auto firstPower = controllers.front.command.poweroff;
for (Controller &controller : controllers)
controller.command.poweroff = !firstPower;
break;
}
case 'l':
case 'L':
{
const auto firstLed = controllers.front.command.led;
for (Controller &controller : controllers)
controller.command.led = !firstLed;
break;
}
case 'r':
case 'R':
loadSettings();
break;
case 's':
case 'S':
saveSettings();
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
for (Controller &controller : controllers)
controller.command.buzzer.freq = c-'0';
break;
case 'A':
InputDispatcher::rotate(-1);
break;
case 'B':
InputDispatcher::rotate(1);
break;
case 'C':
InputDispatcher::confirmButton(true);
InputDispatcher::confirmButton(false);
break;
case 'D':
InputDispatcher::backButton(true);
InputDispatcher::backButton(false);
break;
case 'z':
case 'Z':
#ifndef LEDSTRIP_WRONG_DIRECTION
InputDispatcher::blinkLeftButton(true);
InputDispatcher::blinkLeftButton(false);
#else
InputDispatcher::blinkRightButton(true);
InputDispatcher::blinkRightButton(false);
#endif
break;
case 'u':
case 'U':
#ifndef LEDSTRIP_WRONG_DIRECTION
InputDispatcher::blinkRightButton(true);
InputDispatcher::blinkRightButton(false);
#else
InputDispatcher::blinkLeftButton(true);
InputDispatcher::blinkLeftButton(false);
#endif
break;
}
}
}

View File

@ -1,115 +1,6 @@
#pragma once
#include <HardwareSerial.h>
//extern wl_status_t last_status;
//extern IPAddress last_ip;
#include "globals.h"
#include "utils.h"
#include "screens.h"
namespace {
//wl_status_t last_status;
//IPAddress last_ip;
void handleSerial()
{
//const auto status = WiFi.status();
//if (last_status != status)
//{
//Serial.print("Status changed to: ");
//Serial.println(to_string(status).c_str());
//last_status = status;
//}
//const auto ip = WiFi.localIP();
//if (last_ip != ip)
//{
//Serial.print("IP changed to: ");
//Serial.println(to_string(ip).c_str());
//last_ip = ip;
//}
while(Serial.available())
{
const auto c = Serial.read();
switch (c)
{
case 'i':
case 'I':
tft.init();
break;
case 'p':
case 'P':
{
const auto firstPower = controllers.front.command.poweroff;
for (Controller &controller : controllers)
controller.command.poweroff = !firstPower;
break;
}
case 'l':
case 'L':
{
const auto firstLed = controllers.front.command.led;
for (Controller &controller : controllers)
controller.command.led = !firstLed;
break;
}
case 'r':
case 'R':
loadSettings();
break;
case 's':
case 'S':
saveSettings();
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
for (Controller &controller : controllers)
controller.command.buzzer.freq = c-'0';
break;
case 'A':
InputDispatcher::rotate(-1);
break;
case 'B':
InputDispatcher::rotate(1);
break;
case 'C':
InputDispatcher::confirmButton(true);
InputDispatcher::confirmButton(false);
break;
case 'D':
InputDispatcher::backButton(true);
InputDispatcher::backButton(false);
break;
case 'z':
case 'Z':
#ifndef LEDSTRIP_WRONG_DIRECTION
InputDispatcher::blinkLeftButton(true);
InputDispatcher::blinkLeftButton(false);
#else
InputDispatcher::blinkRightButton(true);
InputDispatcher::blinkRightButton(false);
#endif
break;
case 'u':
case 'U':
#ifndef LEDSTRIP_WRONG_DIRECTION
InputDispatcher::blinkRightButton(true);
InputDispatcher::blinkRightButton(false);
#else
InputDispatcher::blinkLeftButton(true);
InputDispatcher::blinkLeftButton(false);
#endif
break;
}
}
}
}
void handleSerial();

View File

@ -30,13 +30,13 @@ void pushStats()
statistics::sumCurrent.push_back(sumCurrent);
if (controllers.front.feedbackValid)
{
statistics::frontVoltage.push_back(controllers.front.getCalibratedVoltage(settings.battery.applyCalibration));
statistics::frontVoltage.push_back(controllers.front.getCalibratedVoltage());
statistics::frontLeftCurrent.push_back(fixCurrent(controllers.front.feedback.left.dcLink));
statistics::frontRightCurrent.push_back(fixCurrent(controllers.front.feedback.right.dcLink));
}
if (controllers.back.feedbackValid)
{
statistics::backVoltage.push_back(controllers.back.getCalibratedVoltage(settings.battery.applyCalibration));
statistics::backVoltage.push_back(controllers.back.getCalibratedVoltage());
statistics::backLeftCurrent.push_back(fixCurrent(controllers.back.feedback.left.dcLink));
statistics::backRightCurrent.push_back(fixCurrent(controllers.back.feedback.right.dcLink));
}

View File

@ -1,6 +1,5 @@
#pragma once
namespace {
//AboutMenu
constexpr char TEXT_ABOUT[] = "About";
constexpr char TEXT_BACK[] = "Back";
@ -498,4 +497,3 @@ constexpr char TEXT_LEDSTRIPCOLORMENU[] = "Customize Ledstrip";
#ifdef FEATURE_CAN
constexpr char TEXT_POWERSUPPLY[] = "Powersupply";
#endif
}

View File

@ -17,6 +17,7 @@
#include <changevaluedisplay.h>
#include <lockhelper.h>
#include <tickchrono.h>
#include <screenmanager.h>
// local includes
#include "buttons.h"
@ -91,20 +92,20 @@ esp_err_t webserver_root_handler(httpd_req_t *req)
"<a href=\"/triggerButton?button=profile3\">Profile3</a> ";
}
if (auto constCurrentDisplay = static_cast<const Display *>(currentDisplay.get()))
if (auto currentDisplay = static_cast<const espgui::Display *>(espgui::currentDisplay.get()))
{
if (const auto *textInterface = constCurrentDisplay->asTextInterface())
if (const auto *textInterface = currentDisplay->asTextInterface())
{
HtmlTag h2Tag{"h2", body};
body += esphttpdutils::htmlentities(textInterface->text());
}
if (const auto *menuDisplay = constCurrentDisplay->asMenuDisplay())
if (const auto *menuDisplay = currentDisplay->asMenuDisplay())
{
HtmlTag ulTag{"ul", body};
int i{0};
menuDisplay->runForEveryMenuItem([&,selectedIndex=menuDisplay->selectedIndex()](const MenuItem &menuItem){
menuDisplay->runForEveryMenuItem([&,selectedIndex=menuDisplay->selectedIndex()](const espgui::MenuItem &menuItem){
HtmlTag liTag = i == selectedIndex ?
HtmlTag{"li", "style=\"border: 1px solid black;\"", body} :
HtmlTag{"li", body};
@ -113,7 +114,7 @@ esp_err_t webserver_root_handler(httpd_req_t *req)
i++;
});
}
else if (const auto *changeValueDisplay = constCurrentDisplay->asChangeValueDisplayInterface())
else if (const auto *changeValueDisplay = currentDisplay->asChangeValueDisplayInterface())
{
HtmlTag formTag{"form", "action=\"/setValue\" method=\"GET\"", body};
body += fmt::format("<input type=\"number\" name=\"value\" value=\"{}\" />", changeValueDisplay->shownValue());
@ -308,17 +309,17 @@ esp_err_t webserver_triggerItem_handler(httpd_req_t *req)
}
}
if (!currentDisplay)
if (!espgui::currentDisplay)
{
constexpr const std::string_view msg = "currentDisplay is null";
constexpr const std::string_view msg = "espgui::currentDisplay is null";
ESP_LOGW(TAG, "%.*s", msg.size(), msg.data());
CALL_AND_EXIT(esphttpdutils::webserver_resp_send, req, esphttpdutils::ResponseStatus::BadRequest, "text/plain", msg);
}
auto *menuDisplay = currentDisplay->asMenuDisplay();
auto *menuDisplay = espgui::currentDisplay->asMenuDisplay();
if (!menuDisplay)
{
constexpr const std::string_view msg = "currentDisplay is not a menu display";
constexpr const std::string_view msg = "espgui::currentDisplay is not a menu display";
ESP_LOGW(TAG, "%.*s", msg.size(), msg.data());
CALL_AND_EXIT(esphttpdutils::webserver_resp_send, req, esphttpdutils::ResponseStatus::BadRequest, "text/plain", msg);
}
@ -394,17 +395,17 @@ esp_err_t webserver_setValue_handler(httpd_req_t *req)
}
}
if (!currentDisplay)
if (!espgui::currentDisplay)
{
constexpr const std::string_view msg = "currentDisplay is null";
constexpr const std::string_view msg = "espgui::currentDisplay is null";
ESP_LOGW(TAG, "%.*s", msg.size(), msg.data());
CALL_AND_EXIT(esphttpdutils::webserver_resp_send, req, esphttpdutils::ResponseStatus::BadRequest, "text/plain", msg);
}
auto *changeValueDisplay = currentDisplay->asChangeValueDisplayInterface();
auto *changeValueDisplay = espgui::currentDisplay->asChangeValueDisplayInterface();
if (!changeValueDisplay)
{
constexpr const std::string_view msg = "currentDisplay is not a change value display";
constexpr const std::string_view msg = "espgui::currentDisplay is not a change value display";
ESP_LOGW(TAG, "%.*s", msg.size(), msg.data());
CALL_AND_EXIT(esphttpdutils::webserver_resp_send, req, esphttpdutils::ResponseStatus::BadRequest, "text/plain", msg);
}

View File

@ -5,6 +5,7 @@
#include <esp_http_server.h>
#endif
#include <esp_log.h>
#include <esp_ota_ops.h>
// 3rdparty lib includes
#include <htmlbuilder.h>
@ -13,6 +14,7 @@
#include <esphttpdutils.h>
#include <lockhelper.h>
#include <tickchrono.h>
#include <espstrutils.h>
// local includes
#ifdef FEATURE_OTA