Implement CardputerPower and improve EstimatedPower driver (#335)

This commit is contained in:
Ken Van Hoeylandt
2025-09-14 15:42:10 +02:00
committed by GitHub
parent d5c94c7a8a
commit ce8ac61d42
9 changed files with 167 additions and 21 deletions
@@ -2,19 +2,14 @@
#include <Tactility/Log.h>
#include <algorithm>
constexpr auto TAG = "EstimatePower";
constexpr auto TAG = "ChargeFromAdcV";
constexpr auto MAX_VOLTAGE_SAMPLES = 15;
uint8_t ChargeFromAdcVoltage::estimateChargeLevelFromVoltage(uint32_t milliVolt) const {
const float volts = std::min((float)milliVolt / 1000.f, configuration.batteryVoltageMax);
const float voltage_percentage = (volts - configuration.batteryVoltageMin) / (configuration.batteryVoltageMax - configuration.batteryVoltageMin);
const float voltage_factor = std::min(1.0f, voltage_percentage);
const auto charge_level = (uint8_t) (voltage_factor * 100.f);
TT_LOG_V(TAG, "mV = %lu, scaled = %.2f, factor = %.2f, result = %d", milliVolt, volts, voltage_factor, charge_level);
return charge_level;
}
ChargeFromAdcVoltage::ChargeFromAdcVoltage(const Configuration& configuration) : configuration(configuration) {
ChargeFromAdcVoltage::ChargeFromAdcVoltage(
const Configuration& configuration,
float voltageMin,
float voltageMax
) : configuration(configuration), chargeFromVoltage(voltageMin, voltageMax) {
if (adc_oneshot_new_unit(&configuration.adcConfig, &adcHandle) != ESP_OK) {
TT_LOG_E(TAG, "ADC config failed");
return;
@@ -1,5 +1,6 @@
#pragma once
#include <ChargeFromVoltage.h>
#include <esp_adc/adc_oneshot.h>
class ChargeFromAdcVoltage {
@@ -7,11 +8,9 @@ class ChargeFromAdcVoltage {
public:
struct Configuration {
adc_channel_t adcChannel = ADC_CHANNEL_3;
float adcMultiplier = 1.0f;
float adcRefVoltage = 3.3f;
float batteryVoltageMin = 3.2f;
float batteryVoltageMax = 4.2f;
adc_channel_t adcChannel = ADC_CHANNEL_3;
adc_oneshot_unit_init_cfg_t adcConfig = {
.unit_id = ADC_UNIT_1,
.clk_src = ADC_RTC_CLK_SRC_DEFAULT,
@@ -27,16 +26,17 @@ private:
adc_oneshot_unit_handle_t adcHandle = nullptr;
Configuration configuration;
ChargeFromVoltage chargeFromVoltage;
public:
explicit ChargeFromAdcVoltage(const Configuration& configuration);
explicit ChargeFromAdcVoltage(const Configuration& configuration, float voltageMin = 3.2f, float voltageMax = 4.2f);
~ChargeFromAdcVoltage();
uint8_t estimateChargeLevelFromVoltage(uint32_t milliVolt) const;
bool readBatteryVoltageSampled(uint32_t& output) const;
bool readBatteryVoltageOnce(uint32_t& output) const;
uint8_t estimateChargeLevelFromVoltage(uint32_t milliVolt) const { return chargeFromVoltage.estimateCharge(milliVolt); }
};
@@ -0,0 +1,16 @@
#include "ChargeFromVoltage.h"
#include <Tactility/Log.h>
constexpr auto* TAG = "ChargeFromVoltage";
uint8_t ChargeFromVoltage::estimateCharge(uint32_t milliVolt) const {
const float volts = std::min((float)milliVolt / 1000.f, batteryVoltageMax);
if (volts < batteryVoltageMin) {
return 0;
}
const float voltage_percentage = (volts - batteryVoltageMin) / (batteryVoltageMax - batteryVoltageMin);
const float voltage_factor = std::min(1.0f, voltage_percentage);
const auto charge_level = (uint8_t) (voltage_factor * 100.f);
TT_LOG_D(TAG, "mV = %lu, scaled = %.2f, factor = %.2f, result = %d", milliVolt, volts, voltage_factor, charge_level);
return charge_level;
}
@@ -0,0 +1,22 @@
#pragma once
#include <cstdint>
class ChargeFromVoltage {
float batteryVoltageMin;
float batteryVoltageMax;
public:
explicit ChargeFromVoltage(float voltageMin = 3.2f, float voltageMax = 4.2f) :
batteryVoltageMin(voltageMin),
batteryVoltageMax(voltageMax)
{}
/**
* @param milliVolt
* @return a value in the rage of [0, 100] which represents [0%, 100%] charge
*/
uint8_t estimateCharge(uint32_t milliVolt) const;
};