Added proper support for INA sensors in Power class. Added define HAS_BATTERY to enablesbattery-related code.

This commit is contained in:
Winston Lowe 2025-06-02 01:13:55 +00:00
parent 284b8bcff2
commit 1526781b83
6 changed files with 49 additions and 22 deletions

View File

@ -214,13 +214,29 @@ static void adcDisable()
#endif
}
#endif
#endif //BATTERY_PIN
/**
* A simple battery level sensor that assumes the battery voltage is attached via a voltage-divider to an analog input
*/
class AnalogBatteryLevel : public HasBatteryLevel
{
private:
/// If we see a battery voltage higher than physics allows - assume charger is pumping
/// in power
/// For heltecs with no battery connected, the measured voltage is 2204, so
// need to be higher than that, in this case is 2500mV (3000-500)
const uint16_t OCV[NUM_OCV_POINTS] = {OCV_ARRAY};
const float chargingVolt = (OCV[0] + 10) * NUM_CELLS;
const float noBatVolt = (OCV[NUM_OCV_POINTS - 1] - 500) * NUM_CELLS;
// Start value from minimum voltage for the filter to not start from 0
// that could trigger some events.
// This value is over-written by the first ADC reading, it the voltage seems reasonable.
bool initial_read_done = false;
float last_read_value = (OCV[NUM_OCV_POINTS - 1] * NUM_CELLS);
uint32_t last_read_time_ms = 0;
public:
/**
* Battery state of charge, from 0 to 100 or -1 for unknown
@ -475,22 +491,6 @@ class AnalogBatteryLevel : public HasBatteryLevel
return isVbusIn();
}
private:
/// If we see a battery voltage higher than physics allows - assume charger is pumping
/// in power
/// For heltecs with no battery connected, the measured voltage is 2204, so
// need to be higher than that, in this case is 2500mV (3000-500)
const uint16_t OCV[NUM_OCV_POINTS] = {OCV_ARRAY};
const float chargingVolt = (OCV[0] + 10) * NUM_CELLS;
const float noBatVolt = (OCV[NUM_OCV_POINTS - 1] - 500) * NUM_CELLS;
// Start value from minimum voltage for the filter to not start from 0
// that could trigger some events.
// This value is over-written by the first ADC reading, it the voltage seems reasonable.
bool initial_read_done = false;
float last_read_value = (OCV[NUM_OCV_POINTS - 1] * NUM_CELLS);
uint32_t last_read_time_ms = 0;
#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && defined(HAS_RAKPROT)
uint16_t getRAKVoltage() { return rak9154Sensor.getBusVoltageMv(); }
@ -502,7 +502,6 @@ class AnalogBatteryLevel : public HasBatteryLevel
return rak9154Sensor.isRunning();
}
#endif
#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && !defined(ARCH_STM32WL)
uint16_t getINAVoltage()
{
@ -654,6 +653,23 @@ bool Power::analogInit()
#endif
}
/**
* Initializes the INA sensor for power monitoring.
*
* @return true if the INA sensor is ready, false otherwise.
*/
bool Power::inaInit()
{
#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && !defined(ARCH_STM32WL)
bool result = analogLevel.hasINA();
batteryLevel = &analogLevel;
LOG_DEBUG("Power::inaInit INA sensor is %s", result ? "ready" : "not ready yet");
return result;
#endif
return false;
}
/**
* Initializes the Power class.
*
@ -667,6 +683,8 @@ bool Power::setup()
found = lipoInit();
if (!found)
found = analogInit();
if (!found)
found = inaInit();
#ifdef NRF_APM
found = true;

View File

@ -34,7 +34,7 @@ void PowerFSM_setup(){};
static bool isPowered()
{
// Circumvent the battery sensing logic and assumes constant power if no battery pin or power mgmt IC
#if !defined(BATTERY_PIN) && !defined(HAS_AXP192) && !defined(HAS_AXP2101) && !defined(NRF_APM)
#if !defined(HAS_BATTERY) && !defined(BATTERY_PIN) && !defined(HAS_AXP192) && !defined(HAS_AXP2101) && !defined(NRF_APM)
return true;
#endif

View File

@ -61,14 +61,14 @@ class PowerStatus : public Status
/**
* Note: for boards with battery pin or PMU, 0% battery means 'unknown/this board doesn't have a battery installed'
*/
#if defined(HAS_PMU) || defined(BATTERY_PIN)
#if defined(HAS_PMU) || defined(BATTERY_PIN) || defined(HAS_BATTERY)
uint8_t getBatteryChargePercent() const { return getHasBattery() ? batteryChargePercent : 0; }
#endif
/**
* Note: for boards without battery pin and PMU, 101% battery means 'the board is using external power'
*/
#if !defined(HAS_PMU) && !defined(BATTERY_PIN)
#if !defined(HAS_PMU) && !defined(BATTERY_PIN) && !defined(HAS_BATTERY)
uint8_t getBatteryChargePercent() const { return getHasBattery() ? batteryChargePercent : 101; }
#endif

View File

@ -297,6 +297,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef HAS_BLUETOOTH
#define HAS_BLUETOOTH 0
#endif
#ifndef HAS_BATTERY
#define HAS_BATTERY 0
#endif
#ifndef HW_VENDOR
#error HW_VENDOR must be defined

View File

@ -122,7 +122,8 @@ class Power : private concurrency::OSThread
bool analogInit();
/// Setup a Lipo battery level sensor
bool lipoInit();
/// Setup INA battery level sensor
bool inaInit();
private:
// open circuit voltage lookup table
uint8_t low_voltage_counter;

View File

@ -23,6 +23,11 @@
// ratio of voltage divider = 3.0 (R17=200k, R18=100k)
// #define ADC_MULTIPLIER 3.1 // 3.0 + a bit for being optimistic
// Enables battery-related code and requires BATTERY_IMMUTABLE to be defined.
// Ensure a valid address is configured for the INA sensor from which voltage readings are to be obtained.
// #define HAS_BATTERY
// #define BATTERY_IMMUTABLE
#define HAS_CPU_SHUTDOWN 1
#define USE_SX1262