Files
bobbycar-boardcomputer-firm…/main/displays/statusdisplay.h

266 lines
7.8 KiB
C++

#pragma once
// 3rdparty lib includes
#include <fmt/core.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"
// forward declares
namespace {
class MainMenu;
class BmsDisplay;
class MetersDisplay;
}
namespace {
class StatusDisplay : public Display, public ConfirmActionInterface<SwitchScreenAction<MainMenu>>, public DummyBack
{
public:
void initScreen() override;
void redraw() 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}
{}
void start();
void redraw(const Controller &controller);
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
{}
void start();
void redraw(const bobbycar::protocol::serial::MotorFeedback &motor);
private:
Label m_labelError;
Label m_labelCurrent;
Label m_labelSpeed;
Label m_labelHallSensors;
};
const int m_y;
bool m_initialRedraw;
bool m_lastFeedbackValid;
Label m_labelLeftPwm;
Label m_labelRightPwm;
Label m_labelVoltage;
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};
Label m_labelRawBrems{45, 15}; // 40, 15
Label m_labelBrems{90, 15}; // 60, 15
ProgressBar m_progressBarBrems{150, 15, 90, 15, 0, 1000};
BoardStatus m_frontStatus{42};
BoardStatus m_backStatus{142};
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_labelLimit1{205, bottomLines[1]}; // 35, 15
Label m_labelPerformance{85, 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
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_frontStatus.start();
m_backStatus.start();
tft.setTextFont(2);
tft.drawString("WiFi:", 0, bottomLines[0]);
m_labelWifiStatus.start();
tft.drawString("Limit0:", 160, bottomLines[0]);
m_labelLimit0.start();
tft.drawString("IP:", 0, bottomLines[1]);
m_labelIpAddress.start();
tft.drawString("Limit1:", 160, bottomLines[1]);
m_labelLimit1.start();
tft.drawString("Performance:", 0, bottomLines[2]);
m_labelPerformance.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()
{
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_frontStatus.redraw(controllers.front);
m_backStatus.redraw(controllers.back);
tft.setTextFont(2);
//m_labelWifiStatus.redraw(to_string(WiFi.status()));
m_labelLimit0.redraw(std::to_string(controllers.front.command.left.iMotMax) + "A");
//m_labelIpAddress.redraw(to_string(WiFi.localIP()));
m_labelLimit1.redraw(std::to_string(controllers.front.command.left.iDcMax) + "A");
m_labelPerformance.redraw(std::to_string(performance.last));
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)
{
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(!settings.boardcomputerHardware.swapScreenBytes);
tft.pushImage(10, m_y+40, icons::alert.WIDTH, icons::alert.HEIGHT, icons::alert.buffer);
tft.setSwapBytes(settings.boardcomputerHardware.swapScreenBytes);
}
m_lastFeedbackValid = controller.feedbackValid;
m_initialRedraw = false;
}
if (controller.feedbackValid)
{
m_labelVoltage.redraw(fmt::format("{:.2f}V", fixBatVoltage(controller.feedback.batVoltage)));
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);
}
}