Add Power Scheduler
This commit is contained in:
@@ -10,41 +10,106 @@
|
||||
#include "Power.h"
|
||||
static portMUX_TYPE mux;
|
||||
|
||||
void Power::begin()
|
||||
{
|
||||
// Check if another instance of us already initialized the power scheduler,
|
||||
// if not, we will do it.
|
||||
if (powerScheduler == nullptr)
|
||||
{
|
||||
powerScheduler = PowerScheduler::getPowerScheduler();
|
||||
if (!(powerScheduler->tryAccquirePowerAllowance(CONSUMPTION_ESP_BASE)))
|
||||
{
|
||||
Serial.println("Alledgedly not enough power available to reserve the ESP32s base power consumption. Something is wrong.");
|
||||
return;
|
||||
}
|
||||
void Power::begin() {
|
||||
// Check if another instance of us already initialized the power scheduler,
|
||||
// if not, we will do it.
|
||||
if (powerScheduler == nullptr) {
|
||||
powerScheduler = &PowerScheduler::getPowerScheduler();
|
||||
|
||||
if (!(powerScheduler->tryAccquireCurrentAllowance(
|
||||
PowerParameters::PowerConsumers::ESP,
|
||||
PowerParameters::CurrentConsumptions::CURRENT_ESP_AVG))) {
|
||||
Serial.println("Alledgedly not enough power available to reserve the "
|
||||
"ESP32s base power consumption. Something is wrong.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t Power::getFreePowerBudget(void)
|
||||
{
|
||||
return powerScheduler->getFreePowerBudget();
|
||||
uint16_t Power::getFreeCurrentBudget(void) {
|
||||
return powerScheduler->getFreeCurrentBudget();
|
||||
}
|
||||
|
||||
bool Power::tryAccquirePowerAllowance(uint16_t neededPower)
|
||||
{
|
||||
return powerScheduler->tryAccquirePowerAllowance(neededPower);
|
||||
bool Power::tryAccquireCurrentAllowance(
|
||||
PowerParameters::PowerConsumers consumer, uint16_t neededCurrent,
|
||||
uint16_t requestedDurationMs) {
|
||||
return powerScheduler->tryAccquireCurrentAllowance(consumer, neededCurrent,
|
||||
requestedDurationMs);
|
||||
}
|
||||
|
||||
bool Power::waitForPowerAllowance(uint16_t neededPower, TickType_t TicksToWait)
|
||||
{
|
||||
return powerScheduler->waitForPowerAllowance(neededPower, TicksToWait);
|
||||
bool Power::waitForCurrentAllowance(PowerParameters::PowerConsumers consumer,
|
||||
uint16_t neededCurrent,
|
||||
TickType_t TicksToWait,
|
||||
uint16_t requestedDurationMs) {
|
||||
return powerScheduler->waitForCurrentAllowance(
|
||||
consumer, neededCurrent, TicksToWait, requestedDurationMs);
|
||||
}
|
||||
|
||||
void Power::beginPermanentDeepSleep(void)
|
||||
{
|
||||
return powerScheduler->beginPermanentDeepSleep();
|
||||
void Power::beginPermanentDeepSleep(void) {
|
||||
return powerScheduler->beginPermanentDeepSleep();
|
||||
}
|
||||
|
||||
void Power::releasePower(uint16_t power)
|
||||
{
|
||||
void Power::releaseCurrent(PowerParameters::PowerConsumers consumer) {
|
||||
powerScheduler->releaseCurrent(consumer);
|
||||
}
|
||||
|
||||
float Power::getBatteryVoltage() {
|
||||
// Get the battery voltage from the ADC and convert it to a voltage
|
||||
// using the voltage divider.
|
||||
portENTER_CRITICAL(&mux);
|
||||
// Enable voltage divider
|
||||
digitalWrite(PowerParameters::PinConfig::BAT_ADC_EN, HIGH);
|
||||
// Returns value between 0 and 4095 mapping to between 0 and 3.3V
|
||||
uint16_t batteryAdcValue =
|
||||
analogRead(PowerParameters::PinConfig::BAT_ADC) *
|
||||
(PowerParameters::Battery::BAT_ADC::VOLTAGE_DIVIDER_FACTOR);
|
||||
// Disable voltage divider
|
||||
digitalWrite(PowerParameters::PinConfig::BAT_ADC_EN, LOW);
|
||||
portEXIT_CRITICAL(&mux);
|
||||
// Convert ADC value to voltage
|
||||
float batteryVoltage =
|
||||
(batteryAdcValue * 3.3 / 4095) *
|
||||
PowerParameters::Battery::BAT_ADC::VOLTAGE_DIVIDER_FACTOR;
|
||||
return batteryVoltage;
|
||||
}
|
||||
|
||||
int Power::getBatteryChargePercent() {
|
||||
// Get the battery voltage and calculate the charge state based on the
|
||||
// discharge curve.
|
||||
float batteryVoltage = getBatteryVoltage();
|
||||
float chargeState = 0;
|
||||
// Clamp edge cases
|
||||
if (batteryVoltage >=
|
||||
PowerParameters::Battery::DISCHARGE_CURVE::VOLTAGES[0]) {
|
||||
return PowerParameters::Battery::DISCHARGE_CURVE::CHARGE_STATES[0];
|
||||
}
|
||||
if (batteryVoltage <=
|
||||
PowerParameters::Battery::DISCHARGE_CURVE::VOLTAGES
|
||||
[PowerParameters::Battery::DISCHARGE_CURVE::NUM_POINTS - 1]) {
|
||||
return PowerParameters::Battery::DISCHARGE_CURVE::CHARGE_STATES
|
||||
[PowerParameters::Battery::DISCHARGE_CURVE::NUM_POINTS - 1];
|
||||
}
|
||||
float p1_x, p1_y, p2_x, p2_y;
|
||||
for (int i = 0; i < PowerParameters::Battery::DISCHARGE_CURVE::NUM_POINTS;
|
||||
i++) {
|
||||
if (batteryVoltage >=
|
||||
PowerParameters::Battery::DISCHARGE_CURVE::VOLTAGES[i]) {
|
||||
p1_y = PowerParameters::Battery::DISCHARGE_CURVE::CHARGE_STATES[i];
|
||||
p1_x = PowerParameters::Battery::DISCHARGE_CURVE::VOLTAGES[i];
|
||||
p2_y = PowerParameters::Battery::DISCHARGE_CURVE::CHARGE_STATES[i + 1];
|
||||
p2_x = PowerParameters::Battery::DISCHARGE_CURVE::VOLTAGES[i + 1];
|
||||
chargeState =
|
||||
((p2_y - p1_y) / (p2_x - p1_x)) * (batteryVoltage - p1_x) + p1_y;
|
||||
return chargeState;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PowerScheduler* Power::powerScheduler = nullptr;
|
||||
|
||||
Power::Power() {
|
||||
// Initialize the power scheduler
|
||||
powerScheduler = &PowerScheduler::getPowerScheduler();
|
||||
// Initialize the mutex
|
||||
mux = portMUX_INITIALIZER_UNLOCKED;
|
||||
}
|
||||
Reference in New Issue
Block a user