mirror of
https://github.com/MrUnknownDE/OpenIris-ESPIDF.git
synced 2026-04-19 06:23:44 +02:00
Move the battery power calculation part to the BatteryMonitor class
This commit is contained in:
@@ -71,3 +71,52 @@ int BatteryMonitor::getBatteryMilliVolts() const
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
float BatteryMonitor::voltageToPercentage(int voltage_mv)
|
||||
{
|
||||
const float volts = static_cast<float>(voltage_mv);
|
||||
|
||||
// Handle boundary conditions
|
||||
if (volts >= soc_lookup_.front().voltage_mv)
|
||||
return soc_lookup_.front().soc;
|
||||
|
||||
if (volts <= soc_lookup_.back().voltage_mv)
|
||||
return soc_lookup_.back().soc;
|
||||
|
||||
// Linear interpolation between lookup table points
|
||||
for (size_t i = 0; i < soc_lookup_.size() - 1; ++i)
|
||||
{
|
||||
const auto &high = soc_lookup_[i];
|
||||
const auto &low = soc_lookup_[i + 1];
|
||||
|
||||
if (volts <= high.voltage_mv && volts >= low.voltage_mv)
|
||||
{
|
||||
const float voltage_span = high.voltage_mv - low.voltage_mv;
|
||||
if (voltage_span <= 0.0f)
|
||||
{
|
||||
return low.soc;
|
||||
}
|
||||
const float ratio = (volts - low.voltage_mv) / voltage_span;
|
||||
return low.soc + ratio * (high.soc - low.soc);
|
||||
}
|
||||
}
|
||||
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
BatteryStatus BatteryMonitor::getBatteryStatus() const
|
||||
{
|
||||
BatteryStatus status = {0, 0.0f, false};
|
||||
|
||||
#if CONFIG_MONITORING_BATTERY_ENABLE
|
||||
const int mv = getBatteryMilliVolts();
|
||||
if (mv <= 0)
|
||||
return status;
|
||||
|
||||
status.voltage_mv = mv;
|
||||
status.percentage = std::clamp(voltageToPercentage(mv), 0.0f, 100.0f);
|
||||
status.valid = true;
|
||||
#endif
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -14,15 +14,31 @@
|
||||
* +-----------------------+
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cmath>
|
||||
#include "AdcSampler.hpp"
|
||||
#include "sdkconfig.h"
|
||||
#include <cmath>
|
||||
|
||||
|
||||
/**
|
||||
* @struct BatteryStatus
|
||||
* @brief Battery status information
|
||||
*/
|
||||
struct BatteryStatus
|
||||
{
|
||||
int voltage_mv; // Battery voltage in millivolts
|
||||
float percentage; // State of charge percentage (0-100%)
|
||||
bool valid; // Whether the reading is valid
|
||||
};
|
||||
|
||||
/**
|
||||
* @class BatteryMonitor
|
||||
* @brief Monitors battery voltage through a resistor divider
|
||||
* @brief Monitors battery voltage and calculates state of charge for Li-ion batteries
|
||||
*
|
||||
* Uses AdcSampler (BSP layer) for hardware abstraction.
|
||||
* Includes voltage-to-SOC lookup table for typical Li-ion/Li-Po batteries.
|
||||
*
|
||||
* Configuration is done via Kconfig options:
|
||||
* - CONFIG_MONITORING_BATTERY_ENABLE
|
||||
* - CONFIG_MONITORING_BATTERY_ADC_GPIO
|
||||
@@ -39,10 +55,29 @@ public:
|
||||
// Initialize battery monitoring hardware
|
||||
bool setup();
|
||||
|
||||
// Read once, update filter, and return battery voltage in mV (after divider compensation), 0 on failure
|
||||
/**
|
||||
* @brief Read battery voltage (with divider compensation)
|
||||
* @return Battery voltage in millivolts, 0 on failure
|
||||
*/
|
||||
int getBatteryMilliVolts() const;
|
||||
|
||||
// Whether monitoring is enabled by Kconfig and supported by BSP
|
||||
/**
|
||||
* @brief Calculate battery state of charge from voltage
|
||||
* @param voltage_mv Battery voltage in millivolts
|
||||
* @return State of charge percentage (0-100%)
|
||||
*/
|
||||
static float voltageToPercentage(int voltage_mv);
|
||||
|
||||
/**
|
||||
* @brief Get complete battery status (voltage + percentage)
|
||||
* @return BatteryStatus struct with voltage, percentage, and validity
|
||||
*/
|
||||
BatteryStatus getBatteryStatus() const;
|
||||
|
||||
/**
|
||||
* @brief Check if battery monitoring is enabled and supported
|
||||
* @return true if enabled and ADC is supported
|
||||
*/
|
||||
static constexpr bool isEnabled()
|
||||
{
|
||||
#ifdef CONFIG_MONITORING_BATTERY_ENABLE
|
||||
@@ -53,6 +88,34 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
float scale_{1.0f}; // Voltage divider scaling factor
|
||||
/**
|
||||
* @brief Li-ion/Li-Po voltage to SOC lookup table entry
|
||||
*/
|
||||
struct VoltageSOC
|
||||
{
|
||||
float voltage_mv;
|
||||
float soc;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Typical Li-ion single cell discharge curve lookup table
|
||||
* Based on typical 3.7V nominal Li-ion/Li-Po cell characteristics
|
||||
*/
|
||||
static constexpr std::array<VoltageSOC, 12> soc_lookup_ = {{
|
||||
{4200.0f, 100.0f}, // Fully charged
|
||||
{4060.0f, 90.0f},
|
||||
{3980.0f, 80.0f},
|
||||
{3920.0f, 70.0f},
|
||||
{3870.0f, 60.0f},
|
||||
{3820.0f, 50.0f},
|
||||
{3790.0f, 40.0f},
|
||||
{3770.0f, 30.0f},
|
||||
{3740.0f, 20.0f},
|
||||
{3680.0f, 10.0f},
|
||||
{3450.0f, 5.0f}, // Low battery warning
|
||||
{3300.0f, 0.0f}, // Empty / cutoff voltage
|
||||
}};
|
||||
|
||||
float scale_{1.0f}; // Voltage divider scaling factor
|
||||
mutable AdcSampler adc_; // ADC sampler instance (BSP layer)
|
||||
};
|
||||
|
||||
@@ -127,10 +127,11 @@ void MonitoringManager::run()
|
||||
#if CONFIG_MONITORING_BATTERY_ENABLE
|
||||
if (BatteryMonitor::isEnabled() && now_tick >= next_tick_bat)
|
||||
{
|
||||
const int mv = bm_.getBatteryMilliVolts();
|
||||
if (mv > 0)
|
||||
const auto status = bm_.getBatteryStatus();
|
||||
if (status.valid)
|
||||
{
|
||||
last_battery_mv_.store(mv);
|
||||
std::lock_guard<std::mutex> lock(battery_mutex_);
|
||||
last_battery_status_ = status;
|
||||
}
|
||||
next_tick_bat = now_tick + batt_period;
|
||||
}
|
||||
@@ -161,11 +162,14 @@ float MonitoringManager::getCurrentMilliAmps() const
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
float MonitoringManager::getBatteryVoltageMilliVolts() const
|
||||
BatteryStatus MonitoringManager::getBatteryStatus() const
|
||||
{
|
||||
#if CONFIG_MONITORING_BATTERY_ENABLE
|
||||
if (BatteryMonitor::isEnabled())
|
||||
return static_cast<float>(last_battery_mv_.load());
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(battery_mutex_);
|
||||
return last_battery_status_;
|
||||
}
|
||||
#endif
|
||||
return 0.0f;
|
||||
return {0, 0.0f, false};
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/task.h>
|
||||
#include <atomic>
|
||||
#include <mutex>
|
||||
#include "BatteryMonitor.hpp"
|
||||
#include "CurrentMonitor.hpp"
|
||||
|
||||
@@ -47,8 +48,8 @@ public:
|
||||
|
||||
// Latest filtered current in mA
|
||||
float getCurrentMilliAmps() const;
|
||||
// Latest battery voltage in mV
|
||||
float getBatteryVoltageMilliVolts() const;
|
||||
// Get complete battery status (voltage + percentage + validity)
|
||||
BatteryStatus getBatteryStatus() const;
|
||||
|
||||
// Check if any monitoring feature is enabled
|
||||
static constexpr bool isEnabled()
|
||||
@@ -62,7 +63,8 @@ private:
|
||||
|
||||
TaskHandle_t task_{nullptr};
|
||||
std::atomic<float> last_current_ma_{0.0f};
|
||||
std::atomic<int> last_battery_mv_{0};
|
||||
BatteryStatus last_battery_status_{0, 0.0f, false};
|
||||
mutable std::mutex battery_mutex_; // Protect non-atomic BatteryStatus
|
||||
|
||||
CurrentMonitor cm_;
|
||||
BatteryMonitor bm_;
|
||||
|
||||
Reference in New Issue
Block a user