battery percentage calculation improved
This commit is contained in:
parent
e40693ec88
commit
316517337a
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
#include "i2c.h"
|
#include "i2c.h"
|
||||||
#include "reset.h"
|
#include "reset.h"
|
||||||
|
#include "lorawan.h"
|
||||||
|
|
||||||
#define DEFAULT_VREF 1100 // tbd: use adc2_vref_to_gpio() for better estimate
|
#define DEFAULT_VREF 1100 // tbd: use adc2_vref_to_gpio() for better estimate
|
||||||
#define NO_OF_SAMPLES 64 // we do some multisampling to get better values
|
#define NO_OF_SAMPLES 64 // we do some multisampling to get better values
|
||||||
@ -15,11 +16,12 @@
|
|||||||
#define BAT_MAX_VOLTAGE 4200 // millivolts
|
#define BAT_MAX_VOLTAGE 4200 // millivolts
|
||||||
#endif
|
#endif
|
||||||
#ifndef BAT_MIN_VOLTAGE
|
#ifndef BAT_MIN_VOLTAGE
|
||||||
#define BAT_MIN_VOLTAGE 2800 // millivolts
|
#define BAT_MIN_VOLTAGE 3100 // millivolts
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
typedef uint8_t (*mapFn_t)(uint16_t, uint16_t, uint16_t);
|
||||||
|
|
||||||
uint16_t read_voltage(void);
|
uint16_t read_voltage(void);
|
||||||
uint8_t read_battlevel(void);
|
|
||||||
void calibrate_voltage(void);
|
void calibrate_voltage(void);
|
||||||
bool batt_sufficient(void);
|
bool batt_sufficient(void);
|
||||||
|
|
||||||
@ -34,4 +36,67 @@ void AXP192_showstatus(void);
|
|||||||
|
|
||||||
#endif // HAS_PMU
|
#endif // HAS_PMU
|
||||||
|
|
||||||
|
// The following map functions were taken from
|
||||||
|
|
||||||
|
/*
|
||||||
|
Battery.h - Battery library
|
||||||
|
Copyright (c) 2014 Roberto Lo Giacco.
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License as
|
||||||
|
published by the Free Software Foundation, either version 3 of the
|
||||||
|
License, or (at your option) any later version.
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//
|
||||||
|
// Plots of the functions below available at
|
||||||
|
// https://www.desmos.com/calculator/x0esk5bsrk
|
||||||
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Symmetric sigmoidal approximation
|
||||||
|
* https://www.desmos.com/calculator/7m9lu26vpy
|
||||||
|
*
|
||||||
|
* c - c / (1 + k*x/v)^3
|
||||||
|
*/
|
||||||
|
static inline uint8_t sigmoidal(uint16_t voltage, uint16_t minVoltage, uint16_t maxVoltage) {
|
||||||
|
// slow
|
||||||
|
// uint8_t result = 110 - (110 / (1 + pow(1.468 * (voltage - minVoltage)/(maxVoltage - minVoltage), 6)));
|
||||||
|
|
||||||
|
// steep
|
||||||
|
// uint8_t result = 102 - (102 / (1 + pow(1.621 * (voltage - minVoltage)/(maxVoltage - minVoltage), 8.1)));
|
||||||
|
|
||||||
|
// normal
|
||||||
|
uint8_t result = 105 - (105 / (1 + pow(1.724 * (voltage - minVoltage)/(maxVoltage - minVoltage), 5.5)));
|
||||||
|
return result >= 100 ? 100 : result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asymmetric sigmoidal approximation
|
||||||
|
* https://www.desmos.com/calculator/oyhpsu8jnw
|
||||||
|
*
|
||||||
|
* c - c / [1 + (k*x/v)^4.5]^3
|
||||||
|
*/
|
||||||
|
static inline uint8_t asigmoidal(uint16_t voltage, uint16_t minVoltage, uint16_t maxVoltage) {
|
||||||
|
uint8_t result = 101 - (101 / pow(1 + pow(1.33 * (voltage - minVoltage)/(maxVoltage - minVoltage) ,4.5), 3));
|
||||||
|
return result >= 100 ? 100 : result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Linear mapping
|
||||||
|
* https://www.desmos.com/calculator/sowyhttjta
|
||||||
|
*
|
||||||
|
* x * 100 / v
|
||||||
|
*/
|
||||||
|
static inline uint8_t linear(uint16_t voltage, uint16_t minVoltage, uint16_t maxVoltage) {
|
||||||
|
return (unsigned long)(voltage - minVoltage) * 100 / (maxVoltage - minVoltage);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t read_battlevel(mapFn_t mapFunction = &sigmoidal);
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -68,10 +68,6 @@ void doHousekeeping() {
|
|||||||
#if (defined BAT_MEASURE_ADC || defined HAS_PMU)
|
#if (defined BAT_MEASURE_ADC || defined HAS_PMU)
|
||||||
batt_level = read_battlevel();
|
batt_level = read_battlevel();
|
||||||
ESP_LOGI(TAG, "Battery: %d%%", batt_level);
|
ESP_LOGI(TAG, "Battery: %d%%", batt_level);
|
||||||
#if (HAS_LORA)
|
|
||||||
// to come with future LMIC version
|
|
||||||
// lora_setBattLevel(batt_level);
|
|
||||||
#endif
|
|
||||||
#ifdef HAS_PMU
|
#ifdef HAS_PMU
|
||||||
AXP192_showstatus();
|
AXP192_showstatus();
|
||||||
#endif
|
#endif
|
||||||
|
@ -485,12 +485,10 @@ void lora_setBattLevel(uint8_t batt_percent) {
|
|||||||
#endif // HAS_PMU
|
#endif // HAS_PMU
|
||||||
|
|
||||||
else
|
else
|
||||||
lmic_batt_level = static_cast<uint8_t>(
|
lmic_batt_level =
|
||||||
(float)batt_percent /
|
batt_percent / 100.0 * (MCMD_DEVS_BATT_MAX - MCMD_DEVS_BATT_MIN + 1);
|
||||||
(float)(MCMD_DEVS_BATT_MAX - MCMD_DEVS_BATT_MIN + 1) * 100.0f);
|
|
||||||
|
|
||||||
LMIC_setBattLevel(lmic_batt_level);
|
LMIC_setBattLevel(lmic_batt_level);
|
||||||
ESP_LOGD(TAG, "lmic_batt_level = %d", lmic_batt_level);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// event EV_RXCOMPLETE message handler
|
// event EV_RXCOMPLETE message handler
|
||||||
|
@ -210,19 +210,29 @@ uint16_t read_voltage(void) {
|
|||||||
return voltage;
|
return voltage;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t read_battlevel() {
|
uint8_t read_battlevel(mapFn_t mapFunction) {
|
||||||
|
|
||||||
// return the battery level in values 0 ... 255 [percent],
|
// returns the estimated battery level in values 0 ... 100 [percent],
|
||||||
// values > 100 probably mean external power, depending on hardware
|
|
||||||
|
|
||||||
const uint16_t batt_voltage = read_voltage();
|
const uint16_t batt_voltage = read_voltage();
|
||||||
float batt_percent_fl = (float)(batt_voltage - BAT_MIN_VOLTAGE) /
|
uint8_t batt_percent;
|
||||||
(float)(BAT_MAX_VOLTAGE - BAT_MIN_VOLTAGE) * 100.0f;
|
|
||||||
const uint8_t batt_percent = static_cast<uint8_t>(batt_percent_fl);
|
|
||||||
|
|
||||||
ESP_LOGD(TAG, "batt_voltage = %dmV / batt_percent = %u%%", batt_voltage,
|
if (batt_voltage <= BAT_MIN_VOLTAGE)
|
||||||
|
batt_percent = 0;
|
||||||
|
else if (batt_voltage >= BAT_MAX_VOLTAGE)
|
||||||
|
batt_percent = 100;
|
||||||
|
else
|
||||||
|
batt_percent =
|
||||||
|
(*mapFunction)(batt_voltage, BAT_MIN_VOLTAGE, BAT_MAX_VOLTAGE);
|
||||||
|
|
||||||
|
ESP_LOGD(TAG, "batt_voltage = %dmV / batt_percent = %d%%", batt_voltage,
|
||||||
batt_percent);
|
batt_percent);
|
||||||
|
|
||||||
|
#if (HAS_LORA)
|
||||||
|
// to come with future LMIC version
|
||||||
|
// lora_setBattLevel(batt_percent);
|
||||||
|
#endif
|
||||||
|
|
||||||
return batt_percent;
|
return batt_percent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user