From 11a461bfdd057c8d8d4829dcbefc7932f17beba9 Mon Sep 17 00:00:00 2001 From: CommanderRedYT Date: Sun, 27 Feb 2022 23:42:55 +0100 Subject: [PATCH 1/9] Added basic battery graph display --- main/CMakeLists.txt | 4 ++- main/displays/batterygraphdisplay.cpp | 38 +++++++++++++++++++++++++++ main/displays/batterygraphdisplay.h | 17 ++++++++++++ main/displays/menus/batterymenu.cpp | 4 +++ 4 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 main/displays/batterygraphdisplay.cpp create mode 100644 main/displays/batterygraphdisplay.h diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index 178b088..37241cb 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -42,8 +42,8 @@ set(headers bobbycheckbox.h bobbyerrorhandler.h bobbyquickactions.h - bobbytypesafeenum.h bobbyschedulertask.h + bobbytypesafeenum.h buildserver.h can.h changevaluedisplay_bluetoothmode.h @@ -59,6 +59,7 @@ set(headers debugcolorhelpers.h debuginputhandler.h debugtexthelpers.h + displays/batterygraphdisplay.h displays/bmsdisplay.h displays/bobbychangevaluedisplay.h displays/bobbydisplay.h @@ -294,6 +295,7 @@ set(sources debugcolorhelpers.cpp debuginputhandler.cpp debugtexthelpers.cpp + displays/batterygraphdisplay.cpp displays/bmsdisplay.cpp displays/bobbychangevaluedisplay.cpp displays/bobbydisplay.cpp diff --git a/main/displays/batterygraphdisplay.cpp b/main/displays/batterygraphdisplay.cpp new file mode 100644 index 0000000..9f699ba --- /dev/null +++ b/main/displays/batterygraphdisplay.cpp @@ -0,0 +1,38 @@ +#include "batterygraphdisplay.h" + +// 3rdparty lib includes +#include + +// local includes +#include "displays/menus/batterymenu.h" + +namespace { + constexpr char TEXT_BATTERY_GRAPH[] = "Battery Level"; +} // namespace + +void BatteryGraphDisplay::initScreen() { + Base::initScreen(); +} + +std::string BatteryGraphDisplay::text() const { + return TEXT_BATTERY_GRAPH; +} + +void BatteryGraphDisplay::redraw() { + Base::redraw(); +} + +void BatteryGraphDisplay::buttonPressed(espgui::Button button) +{ + Base::buttonPressed(button); + + switch (button) + { + using espgui::Button; + case Button::Left: + case Button::Right: + espgui::switchScreen(); + break; + default:; + } +} diff --git a/main/displays/batterygraphdisplay.h b/main/displays/batterygraphdisplay.h new file mode 100644 index 0000000..1e08061 --- /dev/null +++ b/main/displays/batterygraphdisplay.h @@ -0,0 +1,17 @@ +#pragma once + +// 3rdparty lib includes + +// local includes +#include "bobbydisplaywithtitle.h" + +class BatteryGraphDisplay : public BobbyDisplayWithTitle { + using Base = BobbyDisplayWithTitle; + +public: + std::string text() const override; + void initScreen() override; + void redraw() override; + + void buttonPressed(espgui::Button button) override; +}; diff --git a/main/displays/menus/batterymenu.cpp b/main/displays/menus/batterymenu.cpp index c027654..022fb33 100644 --- a/main/displays/menus/batterymenu.cpp +++ b/main/displays/menus/batterymenu.cpp @@ -14,8 +14,10 @@ // Local includes #include "accessors/settingsaccessors.h" #include "battery.h" +#include "displays/batterygraphdisplay.h" #include "displays/bobbychangevaluedisplay.h" #include "displays/calibratevoltagedisplay.h" +#include "icons/graph.h" #include "icons/settings.h" #include "mainmenu.h" #include "typesafeenumchangemenu.h" @@ -26,6 +28,7 @@ constexpr char TEXT_BATTERY[] = "Battery"; constexpr char TEXT_CELL_SERIES[] = "Cells (Series)"; constexpr char TEXT_CELL_PARALLEL[] = "Cells (Parallel)"; constexpr char TEXT_SELECT_CELL_TYPE[] = "Select Cell Type"; +constexpr char TEXT_SHOW_BATTERY_GRAPH[] = "Battery Graph"; constexpr char TEXT_BATTERY_CALIBRATE[] = "Calibrate Voltages"; constexpr char TEXT_BATTERY_WHKM[] = "Wh per km"; constexpr char TEXT_BATTERY_APPLYCALIB[] = "Apply calibration"; @@ -78,6 +81,7 @@ BatteryMenu::BatteryMenu() constructMenuItem, SwitchScreenAction>>(); constructMenuItem, SwitchScreenAction>>(); constructMenuItem>(&configs.battery.cellType); + constructMenuItem, SwitchScreenAction, StaticMenuItemIcon<&bobbyicons::graph>>>(); constructMenuItem>(); constructMenuItem>(); constructMenuItem, SwitchScreenAction, StaticMenuItemIcon<&bobbyicons::settings>>>(); From 9dc4ff7d4ef86af29c985b8865636dd49368d4fd Mon Sep 17 00:00:00 2001 From: CommanderRedYT Date: Mon, 28 Feb 2022 00:26:17 +0100 Subject: [PATCH 2/9] Reworked battery curves --- main/battery.cpp | 178 +++++++++++++++++++++++++---------------------- main/battery.h | 116 +++++++++++++++++++++++++++++- 2 files changed, 207 insertions(+), 87 deletions(-) diff --git a/main/battery.cpp b/main/battery.cpp index 9ed64d4..7bd2f33 100644 --- a/main/battery.cpp +++ b/main/battery.cpp @@ -9,10 +9,6 @@ #include "globals.h" #include "newsettings.h" -#define CURVE(higherVoltage,lowerVoltage,fromAh,toAh) \ -if (cellVoltage >= lowerVoltage && cellVoltage <= higherVoltage) \ - return 100 * (expected_ah - cpputils::mapValue(cellVoltage, higherVoltage, lowerVoltage, fromAh, toAh)) / expected_ah; - float getBatteryPercentage(float batVoltage, BatteryCellType cellType) { const float cellVoltage = batVoltage / configs.battery.cellsSeries.value; @@ -21,116 +17,52 @@ float getBatteryPercentage(float batVoltage, BatteryCellType cellType) { case BatteryCellType::_22P: { - const float expected_ah = 2.2; + const float expected_ah = BAT_MIN_AH_22P; 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) + BAT_CURVE_22P(PERCENTAGE); break; } case BatteryCellType::MH1: { - const float expected_ah = 3.2; + const float expected_ah = BAT_MIN_AH_MH1; 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) + BAT_CURVE_MH1(PERCENTAGE); break; } case BatteryCellType::HG2: { - const float expected_ah = 3.0; + const float expected_ah = BAT_MIN_AH_HG2; 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) + BAT_CURVE_HG2(PERCENTAGE); break; } case BatteryCellType::VTC5: { - const float expected_ah = 2.6; + const float expected_ah = BAT_MIN_AH_VTC5; 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) + BAT_CURVE_VTC5(PERCENTAGE); break; } case BatteryCellType::BAK_25R: { - const float expected_ah = 2.5; + const float expected_ah = BAT_MIN_AH_BAK_25R; if(cellVoltage > 4.15){ return 100; } - CURVE(4.15, 4.06, 0, 0.25) - CURVE(4.06, 3.96, 0.25, 0.5) - CURVE(3.96, 3.88, 0.5, 0.75) - CURVE(3.88, 3.77, 0.75, 1) - CURVE(3.77, 3.68, 1, 1.25) - CURVE(3.68, 3.62, 1.25, 1.5) - CURVE(3.62, 3.56, 1.5, 1.75) - CURVE(3.56, 3.47, 1.75, 2) - CURVE(3.47, 3.31, 2, 2.25) - CURVE(3.31, 2.50, 2.25, 2.5) + BAT_CURVE_25R(PERCENTAGE); break; } case BatteryCellType::HE4: { - const float expected_ah = 2.3; + const float expected_ah = BAT_MIN_AH_HE4; if(cellVoltage > 4.15){ return 100; } - CURVE(4.15, 4.02, 0, 0.25) - CURVE(4.02, 3.91, 0.25, 0.5) - CURVE(3.91, 3.81, 0.5, 0.75) - CURVE(3.81, 3.72, 0.75, 1) - CURVE(3.72, 3.61, 1, 1.25) - CURVE(3.61, 3.62, 1.25, 1.5) - CURVE(3.62, 3.53, 1.5, 1.75) - CURVE(3.53, 3.45, 1.75, 2) - CURVE(3.45, 3.21, 2, 2.25) - CURVE(3.21, 2.80, 2.25, 2.3) + BAT_CURVE_HE4(PERCENTAGE); break; } } @@ -194,11 +126,6 @@ std::string getBatteryRemainingWattHoursString() return fmt::format("{:.1f}Wh", getRemainingWattHours()); } -std::string getBatteryCellTypeString() -{ - return fmt::format("Cells: {}", toString(BatteryCellType(configs.battery.cellType.value))); -} - std::string getRemainingRangeString() { return fmt::format("{:.1f} km", getRemainingWattHours() / configs.battery.watthoursPerKilometer.value); @@ -213,6 +140,87 @@ std::string getBatteryDebugString() return "No Battery"; } +float getMinBatVoltage(BatteryCellType cellType) { + switch (cellType) + { + case BatteryCellType::_22P: + { + const float expected_ah = BAT_MIN_AH_22P; + BAT_CURVE_22P(GET_MINIMUM_BAT_VOLTAGE); + break; + } + case BatteryCellType::HG2: + { + const float expected_ah = BAT_MIN_AH_HG2; + BAT_CURVE_HG2(GET_MINIMUM_BAT_VOLTAGE); + break; + } + case BatteryCellType::MH1: + { + const float expected_ah = BAT_MIN_AH_MH1; + BAT_CURVE_MH1(GET_MINIMUM_BAT_VOLTAGE); + break; + } + case BatteryCellType::VTC5: + { + const float expected_ah = BAT_MIN_AH_VTC5; + BAT_CURVE_VTC5(GET_MINIMUM_BAT_VOLTAGE); + break; + } + case BatteryCellType::BAK_25R: + { + const float expected_ah = BAT_MIN_AH_BAK_25R; + BAT_CURVE_25R(GET_MINIMUM_BAT_VOLTAGE); + break; + } + case BatteryCellType::HE4: + { + const float expected_ah = BAT_MIN_AH_HE4; + BAT_CURVE_HE4(GET_MINIMUM_BAT_VOLTAGE); + break; + } + } + return 0.f; +} + +float getMaxBatVoltage(BatteryCellType cellType) +{ + switch (cellType) + { + case BatteryCellType::_22P: + { + BAT_CURVE_22P(GET_MAXIMUM_BAT_VOLTAGE); + break; + } + case BatteryCellType::HG2: + { + BAT_CURVE_HG2(GET_MAXIMUM_BAT_VOLTAGE); + break; + } + case BatteryCellType::MH1: + { + BAT_CURVE_MH1(GET_MAXIMUM_BAT_VOLTAGE); + break; + } + case BatteryCellType::VTC5: + { + BAT_CURVE_VTC5(GET_MAXIMUM_BAT_VOLTAGE); + break; + } + case BatteryCellType::BAK_25R: + { + BAT_CURVE_25R(GET_MAXIMUM_BAT_VOLTAGE); + break; + } + case BatteryCellType::HE4: + { + BAT_CURVE_HE4(GET_MAXIMUM_BAT_VOLTAGE); + break; + } + } + return 0.f; +} + namespace battery { std::optional bootBatPercentage; std::optional bootBatWh; diff --git a/main/battery.h b/main/battery.h index 190024f..a898ff8 100644 --- a/main/battery.h +++ b/main/battery.h @@ -6,6 +6,117 @@ // local includes #include +// battery curves +#define PERCENTAGE(higherVoltage,lowerVoltage,fromAh,toAh) \ +if (cellVoltage >= lowerVoltage && cellVoltage <= higherVoltage) \ + return 100 * (expected_ah - cpputils::mapValue(cellVoltage, higherVoltage, lowerVoltage, fromAh, toAh)) / expected_ah; + +#define GET_MINIMUM_VOLTAGE(higherVoltage,lowerVoltage,fromAh,toAh) \ + if (expected_ah >= toAh) \ + return lowerVoltage; + +#define GET_MAXIMUM_VOLTAGE(higherVoltage,lowerVoltage,fromAh,toAh) \ + if (fromAh == 0) \ + return higherVoltage; + +#define GET_MINIMUM_BAT_VOLTAGE(higherVoltage,lowerVoltage,fromAh,toAh) \ + if (expected_ah >= toAh) \ + return lowerVoltage * configs.battery.cellsSeries.value; + +#define GET_MAXIMUM_BAT_VOLTAGE(higherVoltage,lowerVoltage,fromAh,toAh) \ + if (fromAh == 0) \ + return higherVoltage * configs.battery.cellsSeries.value; + +// 22P +#define BAT_MIN_AH_22P 2.2 +#define BAT_CURVE_22P(func) \ + func(4.15, 4.04, 0, 0.25) \ + func(4.04, 3.95, 0.25, 0.5) \ + func(3.95, 3.86, 0.5, 0.75) \ + func(3.86, 3.74, 0.75, 1.0) \ + func(3.74, 3.64, 1.0, 1.25) \ + func(3.64, 3.59, 1.25, 1.5) \ + func(3.59, 3.54, 1.5, 1.75) \ + func(3.54, 3.43, 1.75, 2.0) \ + func(3.43, 3.35, 2.0, 2.1) \ + func(3.35, 2.50, 2.1, 2.2) + +// MH1 +#define BAT_MIN_AH_MH1 3.2 +#define BAT_CURVE_MH1(func) \ + func(4.15, 4.09, 0, 0.25) \ + func(4.09, 4.04, 0.25, 0.5) \ + func(4.04, 3.95, 0.5, 0.75) \ + func(3.95, 3.88, 0.75, 1.0) \ + func(3.88, 3.79, 1.0, 1.25) \ + func(3.79, 3.70, 1.25, 1.5) \ + func(3.70, 3.65, 1.5, 1.75) \ + func(3.65, 3.60, 1.75, 2.0) \ + func(3.60, 3.56, 2.0, 2.25) \ + func(3.56, 3.50, 2.25, 2.5) \ + func(3.50, 3.40, 2.5, 2.75) \ + func(3.40, 3.30, 2.75, 3.0) \ + func(3.30, 2.5, 3.0, 3.2) + +// HG2 +#define BAT_MIN_AH_HG2 3.0 +#define BAT_CURVE_HG2(func) \ + func(4.15, 4.08, 0, 0.25) \ + func(4.08, 4.01, 0.25, 0.5) \ + func(4.01, 3.92, 0.5, 0.75) \ + func(3.92, 3.84, 0.75, 1.0) \ + func(3.84, 3.75, 1.0, 1.25) \ + func(3.75, 3.67, 1.25, 1.5) \ + func(3.67, 3.62, 1.5, 1.75) \ + func(3.62, 3.55, 1.75, 2.0) \ + func(3.55, 3.44, 2.0, 2.25) \ + func(3.44, 3.30, 2.25, 2.5) \ + func(3.30, 3.05, 2.5, 2.75) \ + func(3.05, 2.50, 2.75, 3.0) + +// VTC5 +#define BAT_MIN_AH_VTC5 2.6 +#define BAT_CURVE_VTC5(func) \ + func(4.15, 4.08, 0, 0.25) \ + func(4.08, 3.98, 0.25, 0.5) \ + func(3.98, 3.89, 0.5, 0.75) \ + func(3.89, 3.79, 0.75, 1.0) \ + func(3.79, 3.71, 1.0, 1.25) \ + func(3.71, 3.64, 1.25, 1.5) \ + func(3.64, 3.53, 1.5, 1.75) \ + func(3.53, 3.44, 1.75, 2.0) \ + func(3.44, 3.20, 2.0, 2.25) \ + func(3.20, 2.80, 2.25, 2.5) \ + func(2.80, 2.50, 2.5, 2.60) + +// BAK_25R +#define BAT_MIN_AH_BAK_25R 2.5 +#define BAT_CURVE_25R(func) \ + func(4.15, 4.06, 0, 0.25) \ + func(4.06, 3.96, 0.25, 0.5) \ + func(3.96, 3.88, 0.5, 0.75) \ + func(3.88, 3.77, 0.75, 1) \ + func(3.77, 3.68, 1, 1.25) \ + func(3.68, 3.62, 1.25, 1.5) \ + func(3.62, 3.56, 1.5, 1.75) \ + func(3.56, 3.47, 1.75, 2) \ + func(3.47, 3.31, 2, 2.25) \ + func(3.31, 2.50, 2.25, 2.5) + +// HE4 +#define BAT_MIN_AH_HE4 2.3 +#define BAT_CURVE_HE4(func) \ + func(4.15, 4.02, 0, 0.25) \ + func(4.02, 3.91, 0.25, 0.5) \ + func(3.91, 3.81, 0.5, 0.75) \ + func(3.81, 3.72, 0.75, 1) \ + func(3.72, 3.61, 1, 1.25) \ + func(3.61, 3.62, 1.25, 1.5) \ + func(3.62, 3.53, 1.5, 1.75) \ + func(3.53, 3.45, 1.75, 2) \ + func(3.45, 3.21, 2, 2.25) \ + func(3.21, 2.80, 2.25, 2.3) + #define BatteryCellTypeValues(x) \ x(_22P) \ x(HG2) \ @@ -21,12 +132,13 @@ float getRemainingWattHours(); float getBatteryWattHours(); +float getMinBatVoltage(BatteryCellType cellType); +float getMaxBatVoltage(BatteryCellType cellType); + std::string getBatteryPercentageString(); std::string getBatteryRemainingWattHoursString(); -std::string getBatteryCellTypeString(); - std::string getRemainingRangeString(); std::string getBatteryDebugString(); From 73d01e8516e42004da89b1ff72b57380d11de3dc Mon Sep 17 00:00:00 2001 From: CommanderRedYT Date: Mon, 28 Feb 2022 00:34:51 +0100 Subject: [PATCH 3/9] Added functions to get the count of known battery points --- main/battery.cpp | 36 ++++++++++++++++++++++++++++++++++++ main/battery.h | 2 ++ 2 files changed, 38 insertions(+) diff --git a/main/battery.cpp b/main/battery.cpp index 7bd2f33..e8cdfff 100644 --- a/main/battery.cpp +++ b/main/battery.cpp @@ -221,6 +221,42 @@ float getMaxBatVoltage(BatteryCellType cellType) return 0.f; } +uint8_t count_curve_points(BatteryCellType cellType) +{ +#define COUNT_CURVE_POINTS(higherVoltage,lowerVoltage,fromAh,toAh) \ + count++; + + uint8_t count = 0; + switch (cellType) + { + case BatteryCellType::_22P: + { + BAT_CURVE_22P(COUNT_CURVE_POINTS); + } + case BatteryCellType::HG2: + { + BAT_CURVE_HG2(COUNT_CURVE_POINTS); + } + case BatteryCellType::MH1: + { + BAT_CURVE_MH1(COUNT_CURVE_POINTS); + } + case BatteryCellType::VTC5: + { + BAT_CURVE_VTC5(COUNT_CURVE_POINTS); + } + case BatteryCellType::BAK_25R: + { + BAT_CURVE_25R(COUNT_CURVE_POINTS); + } + case BatteryCellType::HE4: + { + BAT_CURVE_HE4(COUNT_CURVE_POINTS); + } + } + return count; +} + namespace battery { std::optional bootBatPercentage; std::optional bootBatWh; diff --git a/main/battery.h b/main/battery.h index a898ff8..cc92dee 100644 --- a/main/battery.h +++ b/main/battery.h @@ -148,6 +148,8 @@ std::string getBatteryAdvancedPercentageString(); float getPercentageByWh(float wh); float getTarget_mAh(); +uint8_t count_curve_points(BatteryCellType cellType); + namespace battery { extern std::optional bootBatPercentage; extern std::optional bootBatWh; From 7f6fa967c8ecd54de81d741a1307b7142e1f16b0 Mon Sep 17 00:00:00 2001 From: CommanderRedYT Date: Mon, 28 Feb 2022 01:08:13 +0100 Subject: [PATCH 4/9] Added some more code --- main/battery.cpp | 42 +++++++++++++++++++++++++++ main/battery.h | 7 +++++ main/displays/batterygraphdisplay.cpp | 13 +++++++-- main/displays/batterygraphdisplay.h | 2 -- 4 files changed, 59 insertions(+), 5 deletions(-) diff --git a/main/battery.cpp b/main/battery.cpp index e8cdfff..1a26210 100644 --- a/main/battery.cpp +++ b/main/battery.cpp @@ -257,6 +257,48 @@ uint8_t count_curve_points(BatteryCellType cellType) return count; } +std::optional get_point_n_voltages(BatteryCellType cellType, uint8_t num) +{ + #define GET_POINT_N_VOLTAGES(higherVoltage,lowerVoltage,fromAh,toAh) \ + if (count == num) { \ + uint16_t minVoltage = (lowerVoltage) * 100; \ + uint16_t maxVoltage = (higherVoltage) * 100; \ + return CalibrationPointVoltages{ .minVoltage=minVoltage, .maxVoltage=maxVoltage }; \ + } \ + count++; + + uint8_t count = 0; + CalibrationPointVoltages point; + switch (cellType) + { + case BatteryCellType::_22P: + { + BAT_CURVE_22P(GET_POINT_N_VOLTAGES); + } + case BatteryCellType::HG2: + { + BAT_CURVE_HG2(GET_POINT_N_VOLTAGES); + } + case BatteryCellType::MH1: + { + BAT_CURVE_MH1(GET_POINT_N_VOLTAGES); + } + case BatteryCellType::VTC5: + { + BAT_CURVE_VTC5(GET_POINT_N_VOLTAGES); + } + case BatteryCellType::BAK_25R: + { + BAT_CURVE_25R(GET_POINT_N_VOLTAGES); + } + case BatteryCellType::HE4: + { + BAT_CURVE_HE4(GET_POINT_N_VOLTAGES); + } + } + return std::nullopt; +} + namespace battery { std::optional bootBatPercentage; std::optional bootBatWh; diff --git a/main/battery.h b/main/battery.h index cc92dee..ac8c6f6 100644 --- a/main/battery.h +++ b/main/battery.h @@ -6,6 +6,11 @@ // local includes #include +typedef struct { + uint16_t minVoltage; + uint16_t maxVoltage; +} CalibrationPointVoltages; + // battery curves #define PERCENTAGE(higherVoltage,lowerVoltage,fromAh,toAh) \ if (cellVoltage >= lowerVoltage && cellVoltage <= higherVoltage) \ @@ -150,6 +155,8 @@ float getTarget_mAh(); uint8_t count_curve_points(BatteryCellType cellType); +std::optional get_point_n_voltages(BatteryCellType cellType, uint8_t num); + namespace battery { extern std::optional bootBatPercentage; extern std::optional bootBatWh; diff --git a/main/displays/batterygraphdisplay.cpp b/main/displays/batterygraphdisplay.cpp index 9f699ba..ff63cb1 100644 --- a/main/displays/batterygraphdisplay.cpp +++ b/main/displays/batterygraphdisplay.cpp @@ -4,22 +4,29 @@ #include // local includes +#include "globals.h" #include "displays/menus/batterymenu.h" namespace { constexpr char TEXT_BATTERY_GRAPH[] = "Battery Level"; } // namespace -void BatteryGraphDisplay::initScreen() { +void BatteryGraphDisplay::initScreen() +{ Base::initScreen(); } -std::string BatteryGraphDisplay::text() const { +std::string BatteryGraphDisplay::text() const +{ return TEXT_BATTERY_GRAPH; } -void BatteryGraphDisplay::redraw() { +void BatteryGraphDisplay::redraw() +{ + using namespace espgui; Base::redraw(); + + // tft.drawLine() code } void BatteryGraphDisplay::buttonPressed(espgui::Button button) diff --git a/main/displays/batterygraphdisplay.h b/main/displays/batterygraphdisplay.h index 1e08061..d481b8f 100644 --- a/main/displays/batterygraphdisplay.h +++ b/main/displays/batterygraphdisplay.h @@ -1,7 +1,5 @@ #pragma once -// 3rdparty lib includes - // local includes #include "bobbydisplaywithtitle.h" From b48a40742e52099afb0a07011be0e12871e994f0 Mon Sep 17 00:00:00 2001 From: CommanderRedYT Date: Mon, 28 Feb 2022 01:45:03 +0100 Subject: [PATCH 5/9] Added basic percentage display --- main/displays/batterygraphdisplay.cpp | 18 ++++++++++++++++++ main/displays/batterygraphdisplay.h | 3 +++ 2 files changed, 21 insertions(+) diff --git a/main/displays/batterygraphdisplay.cpp b/main/displays/batterygraphdisplay.cpp index ff63cb1..25261c7 100644 --- a/main/displays/batterygraphdisplay.cpp +++ b/main/displays/batterygraphdisplay.cpp @@ -2,8 +2,10 @@ // 3rdparty lib includes #include +#include // local includes +#include "battery.h" #include "globals.h" #include "displays/menus/batterymenu.h" @@ -26,6 +28,22 @@ void BatteryGraphDisplay::redraw() using namespace espgui; Base::redraw(); + if (const auto avgVoltage = controllers.getAvgVoltage(); avgVoltage) + { + if (*avgVoltage == m_lastBatVoltage) + return; + const auto cellType = configs.battery.cellType.value; + + uint16_t onePercent = tft.width() / 100; + uint16_t xOffset = onePercent * getBatteryPercentage(*avgVoltage, cellType); + uint16_t lastXOffset = onePercent * getBatteryPercentage(m_lastBatVoltage, cellType); + + // clear the old one and draw the new one + tft.fillRect(lastXOffset, 40, onePercent, tft.height() - 40, TFT_BLACK); + tft.fillRect(xOffset, 40, onePercent, tft.height() - 40, TFT_WHITE); + m_lastBatVoltage = *avgVoltage; + } + // tft.drawLine() code } diff --git a/main/displays/batterygraphdisplay.h b/main/displays/batterygraphdisplay.h index d481b8f..725a723 100644 --- a/main/displays/batterygraphdisplay.h +++ b/main/displays/batterygraphdisplay.h @@ -12,4 +12,7 @@ public: void redraw() override; void buttonPressed(espgui::Button button) override; + +private: + float m_lastBatVoltage{0}; }; From cb1065ccb451e4dd3b239234da30e607419f5953 Mon Sep 17 00:00:00 2001 From: CommanderRedYT Date: Mon, 28 Feb 2022 21:59:28 +0100 Subject: [PATCH 6/9] More changes for battery graph --- main/battery.cpp | 12 ++++++++++++ main/battery.h | 4 ++++ main/displays/batterygraphdisplay.cpp | 24 +++++++++++++++++++----- 3 files changed, 35 insertions(+), 5 deletions(-) diff --git a/main/battery.cpp b/main/battery.cpp index 1a26210..f12d773 100644 --- a/main/battery.cpp +++ b/main/battery.cpp @@ -232,26 +232,32 @@ uint8_t count_curve_points(BatteryCellType cellType) case BatteryCellType::_22P: { BAT_CURVE_22P(COUNT_CURVE_POINTS); + break; } case BatteryCellType::HG2: { BAT_CURVE_HG2(COUNT_CURVE_POINTS); + break; } case BatteryCellType::MH1: { BAT_CURVE_MH1(COUNT_CURVE_POINTS); + break; } case BatteryCellType::VTC5: { BAT_CURVE_VTC5(COUNT_CURVE_POINTS); + break; } case BatteryCellType::BAK_25R: { BAT_CURVE_25R(COUNT_CURVE_POINTS); + break; } case BatteryCellType::HE4: { BAT_CURVE_HE4(COUNT_CURVE_POINTS); + break; } } return count; @@ -274,26 +280,32 @@ std::optional get_point_n_voltages(BatteryCellType cel case BatteryCellType::_22P: { BAT_CURVE_22P(GET_POINT_N_VOLTAGES); + break; } case BatteryCellType::HG2: { BAT_CURVE_HG2(GET_POINT_N_VOLTAGES); + break; } case BatteryCellType::MH1: { BAT_CURVE_MH1(GET_POINT_N_VOLTAGES); + break; } case BatteryCellType::VTC5: { BAT_CURVE_VTC5(GET_POINT_N_VOLTAGES); + break; } case BatteryCellType::BAK_25R: { BAT_CURVE_25R(GET_POINT_N_VOLTAGES); + break; } case BatteryCellType::HE4: { BAT_CURVE_HE4(GET_POINT_N_VOLTAGES); + break; } } return std::nullopt; diff --git a/main/battery.h b/main/battery.h index ac8c6f6..02846c1 100644 --- a/main/battery.h +++ b/main/battery.h @@ -32,6 +32,10 @@ if (cellVoltage >= lowerVoltage && cellVoltage <= higherVoltage) \ if (fromAh == 0) \ return higherVoltage * configs.battery.cellsSeries.value; + +// All curves here have to follow the same order (highest-voltage first) +// as some functions require this to display data in correct order + // 22P #define BAT_MIN_AH_22P 2.2 #define BAT_CURVE_22P(func) \ diff --git a/main/displays/batterygraphdisplay.cpp b/main/displays/batterygraphdisplay.cpp index 25261c7..8a5ea18 100644 --- a/main/displays/batterygraphdisplay.cpp +++ b/main/displays/batterygraphdisplay.cpp @@ -1,4 +1,5 @@ #include "batterygraphdisplay.h" +constexpr const char * const TAG = "BatteryGraphDisplay"; // 3rdparty lib includes #include @@ -8,14 +9,27 @@ #include "battery.h" #include "globals.h" #include "displays/menus/batterymenu.h" +#include "newsettings.h" namespace { constexpr char TEXT_BATTERY_GRAPH[] = "Battery Level"; + constexpr const uint8_t TOP_OFFSET = 40; } // namespace void BatteryGraphDisplay::initScreen() { Base::initScreen(); + const auto points = count_curve_points(configs.battery.cellType.value); + ESP_LOGI(TAG, "Battery graph points: %d, cell type: %s", points, toString(configs.battery.cellType.value).c_str()); + const auto available_space = espgui::tft.height() - TOP_OFFSET; + const uint16_t onePercent = espgui::tft.width() / 100; + for (uint8_t i = 0; points >= i; i++) { + // draw lines between point->minVoltage and point->maxVoltage from left to right + if (const auto point = get_point_n_voltages(configs.battery.cellType.value, points - i); point) + { + // draw line between minVoltage and maxVoltage of point. When implemented, please contact @CommanderRedYT so that he can move and optimize the code + } + } } std::string BatteryGraphDisplay::text() const @@ -34,13 +48,13 @@ void BatteryGraphDisplay::redraw() return; const auto cellType = configs.battery.cellType.value; - uint16_t onePercent = tft.width() / 100; - uint16_t xOffset = onePercent * getBatteryPercentage(*avgVoltage, cellType); - uint16_t lastXOffset = onePercent * getBatteryPercentage(m_lastBatVoltage, cellType); + const uint16_t onePercent = tft.width() / 100; + const uint16_t xOffset = onePercent * getBatteryPercentage(*avgVoltage, cellType); + const uint16_t lastXOffset = onePercent * getBatteryPercentage(m_lastBatVoltage, cellType); // clear the old one and draw the new one - tft.fillRect(lastXOffset, 40, onePercent, tft.height() - 40, TFT_BLACK); - tft.fillRect(xOffset, 40, onePercent, tft.height() - 40, TFT_WHITE); + tft.fillRect(lastXOffset, TOP_OFFSET, onePercent, tft.height() - TOP_OFFSET, TFT_BLACK); + tft.fillRect(xOffset, TOP_OFFSET, onePercent, tft.height() - TOP_OFFSET, TFT_WHITE); m_lastBatVoltage = *avgVoltage; } From 177220df6b8d269fc21fae8b6fdb27c9e0ca2b7d Mon Sep 17 00:00:00 2001 From: CommanderRedYT Date: Thu, 3 Mar 2022 22:41:39 +0100 Subject: [PATCH 7/9] Added float map (might need debugging) --- main/utils.cpp | 8 ++++++++ main/utils.h | 1 + 2 files changed, 9 insertions(+) diff --git a/main/utils.cpp b/main/utils.cpp index 0a1ed6d..4304e3e 100644 --- a/main/utils.cpp +++ b/main/utils.cpp @@ -330,3 +330,11 @@ std::string get_wifi_security_string(wifi_auth_mode_t authMode) return "unknown"; } } + +float float_map(float x, float in_min, float in_max, float out_min, float out_max) { + const float dividend = out_max - out_min; + const float divisor = in_max - in_min; + const float delta = x - in_min; + + return (delta * dividend + (divisor / 2.f)) / divisor + out_min; +} diff --git a/main/utils.h b/main/utils.h index af9ec73..bb87bf7 100644 --- a/main/utils.h +++ b/main/utils.h @@ -79,3 +79,4 @@ inline CRGB UINT32_TO_CRGB(uint32_t color) } std::string get_wifi_security_string(wifi_auth_mode_t authMode); +float float_map(float x, float in_min, float in_max, float out_min, float out_max); From a222d682649b13556133567798a4e91ccadf32e5 Mon Sep 17 00:00:00 2001 From: CommanderRedYT Date: Thu, 3 Mar 2022 22:42:28 +0100 Subject: [PATCH 8/9] Implemented float_map, but result is unexpected (see batterygraphdisplay.cpp:33) --- main/displays/batterygraphdisplay.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/main/displays/batterygraphdisplay.cpp b/main/displays/batterygraphdisplay.cpp index 8a5ea18..dff301e 100644 --- a/main/displays/batterygraphdisplay.cpp +++ b/main/displays/batterygraphdisplay.cpp @@ -7,9 +7,10 @@ constexpr const char * const TAG = "BatteryGraphDisplay"; // local includes #include "battery.h" -#include "globals.h" #include "displays/menus/batterymenu.h" +#include "globals.h" #include "newsettings.h" +#include "utils.h" namespace { constexpr char TEXT_BATTERY_GRAPH[] = "Battery Level"; @@ -21,13 +22,21 @@ void BatteryGraphDisplay::initScreen() Base::initScreen(); const auto points = count_curve_points(configs.battery.cellType.value); ESP_LOGI(TAG, "Battery graph points: %d, cell type: %s", points, toString(configs.battery.cellType.value).c_str()); - const auto available_space = espgui::tft.height() - TOP_OFFSET; - const uint16_t onePercent = espgui::tft.width() / 100; + const auto max_height = espgui::tft.height() - TOP_OFFSET; + const auto max_width = espgui::tft.width(); + const uint16_t part = max_width / points; for (uint8_t i = 0; points >= i; i++) { // draw lines between point->minVoltage and point->maxVoltage from left to right if (const auto point = get_point_n_voltages(configs.battery.cellType.value, points - i); point) { - // draw line between minVoltage and maxVoltage of point. When implemented, please contact @CommanderRedYT so that he can move and optimize the code + // TODO: Fix float_map to not be broken + // Current output: float_map(335, 2.55, 4.5, 0, 280) = 47736 + const int x1 = part * i; + const int y1 = float_map(point->minVoltage, 2.55, 4.5, 0, max_height); + const int x2 = part * (i + 1); + const int y2 = float_map(point->maxVoltage, 2.55, 4.5, 0, max_height); + espgui::tft.drawLine(x1, y1, x2, y2, TFT_WHITE); + ESP_LOGI(TAG, "espgui::tft.drawLine(%d, %d, %d, %d, TFT_WHITE);", x1, y1, x2, y2); } } } From e40253c70f5c06ce28fa407275e162b1ccdcbb33 Mon Sep 17 00:00:00 2001 From: CommanderRedYT Date: Fri, 4 Mar 2022 21:30:13 +0100 Subject: [PATCH 9/9] Fixed everything --- main/battery.cpp | 15 ++++++--------- main/battery.h | 10 +++++----- main/displays/batterygraphdisplay.cpp | 18 +++++++++--------- 3 files changed, 20 insertions(+), 23 deletions(-) diff --git a/main/battery.cpp b/main/battery.cpp index f12d773..2bd8e83 100644 --- a/main/battery.cpp +++ b/main/battery.cpp @@ -140,50 +140,47 @@ std::string getBatteryDebugString() return "No Battery"; } -float getMinBatVoltage(BatteryCellType cellType) { +float getMinBatCellVoltage(BatteryCellType cellType) { + float minimumVoltage = std::numeric_limits::max(); switch (cellType) { case BatteryCellType::_22P: { - const float expected_ah = BAT_MIN_AH_22P; BAT_CURVE_22P(GET_MINIMUM_BAT_VOLTAGE); break; } case BatteryCellType::HG2: { - const float expected_ah = BAT_MIN_AH_HG2; BAT_CURVE_HG2(GET_MINIMUM_BAT_VOLTAGE); break; } case BatteryCellType::MH1: { - const float expected_ah = BAT_MIN_AH_MH1; BAT_CURVE_MH1(GET_MINIMUM_BAT_VOLTAGE); break; } case BatteryCellType::VTC5: { - const float expected_ah = BAT_MIN_AH_VTC5; BAT_CURVE_VTC5(GET_MINIMUM_BAT_VOLTAGE); break; } case BatteryCellType::BAK_25R: { - const float expected_ah = BAT_MIN_AH_BAK_25R; BAT_CURVE_25R(GET_MINIMUM_BAT_VOLTAGE); break; } case BatteryCellType::HE4: { - const float expected_ah = BAT_MIN_AH_HE4; BAT_CURVE_HE4(GET_MINIMUM_BAT_VOLTAGE); break; } + default: + return 0.f; } - return 0.f; + return minimumVoltage; } -float getMaxBatVoltage(BatteryCellType cellType) +float getMaxBatCellVoltage(BatteryCellType cellType) { switch (cellType) { diff --git a/main/battery.h b/main/battery.h index 02846c1..473d8fd 100644 --- a/main/battery.h +++ b/main/battery.h @@ -25,12 +25,12 @@ if (cellVoltage >= lowerVoltage && cellVoltage <= higherVoltage) \ return higherVoltage; #define GET_MINIMUM_BAT_VOLTAGE(higherVoltage,lowerVoltage,fromAh,toAh) \ - if (expected_ah >= toAh) \ - return lowerVoltage * configs.battery.cellsSeries.value; + if (lowerVoltage < minimumVoltage) \ + minimumVoltage = lowerVoltage; #define GET_MAXIMUM_BAT_VOLTAGE(higherVoltage,lowerVoltage,fromAh,toAh) \ if (fromAh == 0) \ - return higherVoltage * configs.battery.cellsSeries.value; + return higherVoltage; // All curves here have to follow the same order (highest-voltage first) @@ -141,8 +141,8 @@ float getRemainingWattHours(); float getBatteryWattHours(); -float getMinBatVoltage(BatteryCellType cellType); -float getMaxBatVoltage(BatteryCellType cellType); +float getMinBatCellVoltage(BatteryCellType cellType); +float getMaxBatCellVoltage(BatteryCellType cellType); std::string getBatteryPercentageString(); diff --git a/main/displays/batterygraphdisplay.cpp b/main/displays/batterygraphdisplay.cpp index dff301e..615ab09 100644 --- a/main/displays/batterygraphdisplay.cpp +++ b/main/displays/batterygraphdisplay.cpp @@ -21,20 +21,20 @@ void BatteryGraphDisplay::initScreen() { Base::initScreen(); const auto points = count_curve_points(configs.battery.cellType.value); - ESP_LOGI(TAG, "Battery graph points: %d, cell type: %s", points, toString(configs.battery.cellType.value).c_str()); - const auto max_height = espgui::tft.height() - TOP_OFFSET; - const auto max_width = espgui::tft.width(); + const auto max_height = espgui::tft.height() - 1; + const auto max_width = espgui::tft.width() - 4; const uint16_t part = max_width / points; + const auto min_voltage = getMinBatCellVoltage(configs.battery.cellType.value); + const auto max_voltage = getMaxBatCellVoltage(configs.battery.cellType.value); + ESP_LOGI(TAG, "min_voltage: %f, max_voltage: %f", min_voltage, max_voltage); for (uint8_t i = 0; points >= i; i++) { // draw lines between point->minVoltage and point->maxVoltage from left to right if (const auto point = get_point_n_voltages(configs.battery.cellType.value, points - i); point) { - // TODO: Fix float_map to not be broken - // Current output: float_map(335, 2.55, 4.5, 0, 280) = 47736 - const int x1 = part * i; - const int y1 = float_map(point->minVoltage, 2.55, 4.5, 0, max_height); - const int x2 = part * (i + 1); - const int y2 = float_map(point->maxVoltage, 2.55, 4.5, 0, max_height); + const int x1 = 2 + part * (points - i + 1); + const int y1 = float_map(point->minVoltage / 100.f, min_voltage, max_voltage, max_height, TOP_OFFSET); + const int x2 = 2 + part * (points - i); + const int y2 = float_map(point->maxVoltage / 100.f, min_voltage, max_voltage, max_height, TOP_OFFSET); espgui::tft.drawLine(x1, y1, x2, y2, TFT_WHITE); ESP_LOGI(TAG, "espgui::tft.drawLine(%d, %d, %d, %d, TFT_WHITE);", x1, y1, x2, y2); }