mirror of
https://github.com/wled/WLED.git
synced 2025-07-09 20:06:33 +00:00
Merge pull request #3003 from itCarl/usermod-battery-update2023
Usermod Battery 🔋 Added Support for different battery types, Optimized file structure
This commit is contained in:
commit
47e1cbdaff
160
usermods/Battery/UMBattery.h
Normal file
160
usermods/Battery/UMBattery.h
Normal file
@ -0,0 +1,160 @@
|
||||
#ifndef UMBBattery_h
|
||||
#define UMBBattery_h
|
||||
|
||||
#include "battery_defaults.h"
|
||||
|
||||
/**
|
||||
* Battery base class
|
||||
* all other battery classes should inherit from this
|
||||
*/
|
||||
class UMBattery
|
||||
{
|
||||
private:
|
||||
|
||||
protected:
|
||||
float minVoltage;
|
||||
float maxVoltage;
|
||||
float voltage;
|
||||
int8_t level = 100;
|
||||
float calibration; // offset or calibration value to fine tune the calculated voltage
|
||||
float voltageMultiplier; // ratio for the voltage divider
|
||||
|
||||
float linearMapping(float v, float min, float max, float oMin = 0.0f, float oMax = 100.0f)
|
||||
{
|
||||
return (v-min) * (oMax-oMin) / (max-min) + oMin;
|
||||
}
|
||||
|
||||
public:
|
||||
UMBattery()
|
||||
{
|
||||
this->setVoltageMultiplier(USERMOD_BATTERY_VOLTAGE_MULTIPLIER);
|
||||
this->setCalibration(USERMOD_BATTERY_CALIBRATION);
|
||||
}
|
||||
|
||||
virtual void update(batteryConfig cfg)
|
||||
{
|
||||
if(cfg.minVoltage) this->setMinVoltage(cfg.minVoltage);
|
||||
if(cfg.maxVoltage) this->setMaxVoltage(cfg.maxVoltage);
|
||||
if(cfg.level) this->setLevel(cfg.level);
|
||||
if(cfg.calibration) this->setCalibration(cfg.calibration);
|
||||
if(cfg.voltageMultiplier) this->setVoltageMultiplier(cfg.voltageMultiplier);
|
||||
}
|
||||
|
||||
/**
|
||||
* Corresponding battery curves
|
||||
* calculates the level in % (0-100) with given voltage and possible voltage range
|
||||
*/
|
||||
virtual float mapVoltage(float v, float min, float max) = 0;
|
||||
// {
|
||||
// example implementation, linear mapping
|
||||
// return (v-min) * 100 / (max-min);
|
||||
// };
|
||||
|
||||
virtual void calculateAndSetLevel(float voltage) = 0;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* Getter and Setter
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Get lowest configured battery voltage
|
||||
*/
|
||||
virtual float getMinVoltage()
|
||||
{
|
||||
return this->minVoltage;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set lowest battery voltage
|
||||
* can't be below 0 volt
|
||||
*/
|
||||
virtual void setMinVoltage(float voltage)
|
||||
{
|
||||
this->minVoltage = max(0.0f, voltage);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get highest configured battery voltage
|
||||
*/
|
||||
virtual float getMaxVoltage()
|
||||
{
|
||||
return this->maxVoltage;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set highest battery voltage
|
||||
* can't be below minVoltage
|
||||
*/
|
||||
virtual void setMaxVoltage(float voltage)
|
||||
{
|
||||
this->maxVoltage = max(getMinVoltage()+.5f, voltage);
|
||||
}
|
||||
|
||||
float getVoltage()
|
||||
{
|
||||
return this->voltage;
|
||||
}
|
||||
|
||||
/**
|
||||
* check if voltage is within specified voltage range, allow 10% over/under voltage
|
||||
*/
|
||||
void setVoltage(float voltage)
|
||||
{
|
||||
// this->voltage = ( (voltage < this->getMinVoltage() * 0.85f) || (voltage > this->getMaxVoltage() * 1.1f) )
|
||||
// ? -1.0f
|
||||
// : voltage;
|
||||
this->voltage = voltage;
|
||||
}
|
||||
|
||||
float getLevel()
|
||||
{
|
||||
return this->level;
|
||||
}
|
||||
|
||||
void setLevel(float level)
|
||||
{
|
||||
this->level = constrain(level, 0.0f, 110.0f);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the configured calibration value
|
||||
* a offset value to fine-tune the calculated voltage.
|
||||
*/
|
||||
virtual float getCalibration()
|
||||
{
|
||||
return calibration;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the voltage calibration offset value
|
||||
* a offset value to fine-tune the calculated voltage.
|
||||
*/
|
||||
virtual void setCalibration(float offset)
|
||||
{
|
||||
calibration = offset;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the configured calibration value
|
||||
* a value to set the voltage divider ratio
|
||||
*/
|
||||
virtual float getVoltageMultiplier()
|
||||
{
|
||||
return voltageMultiplier;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the voltage multiplier value
|
||||
* a value to set the voltage divider ratio.
|
||||
*/
|
||||
virtual void setVoltageMultiplier(float multiplier)
|
||||
{
|
||||
voltageMultiplier = multiplier;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
@ -1,3 +1,8 @@
|
||||
#ifndef UMBDefaults_h
|
||||
#define UMBDefaults_h
|
||||
|
||||
#include "wled.h"
|
||||
|
||||
// pin defaults
|
||||
// for the esp32 it is best to use the ADC1: GPIO32 - GPIO39
|
||||
// https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/adc.html
|
||||
@ -14,19 +19,55 @@
|
||||
#define USERMOD_BATTERY_MEASUREMENT_INTERVAL 30000
|
||||
#endif
|
||||
|
||||
// default for 18650 battery
|
||||
// https://batterybro.com/blogs/18650-wholesale-battery-reviews/18852515-when-to-recycle-18650-batteries-and-how-to-start-a-collection-center-in-your-vape-shop
|
||||
// Discharge voltage: 2.5 volt + .1 for personal safety
|
||||
#ifndef USERMOD_BATTERY_MIN_VOLTAGE
|
||||
#ifdef USERMOD_BATTERY_USE_LIPO
|
||||
// LiPo "1S" Batteries should not be dischared below 3V !!
|
||||
#define USERMOD_BATTERY_MIN_VOLTAGE 3.2f
|
||||
#else
|
||||
#define USERMOD_BATTERY_MIN_VOLTAGE 2.6f
|
||||
#endif
|
||||
|
||||
/* Default Battery Type
|
||||
* 0 = unkown
|
||||
* 1 = Lipo
|
||||
* 2 = Lion
|
||||
*/
|
||||
#ifndef USERMOD_BATTERY_DEFAULT_TYPE
|
||||
#define USERMOD_BATTERY_DEFAULT_TYPE 0
|
||||
#endif
|
||||
/*
|
||||
*
|
||||
* Unkown 'Battery' defaults
|
||||
*
|
||||
*/
|
||||
#ifndef USERMOD_BATTERY_UNKOWN_MIN_VOLTAGE
|
||||
// Extra save defaults
|
||||
#define USERMOD_BATTERY_UNKOWN_MIN_VOLTAGE 3.3f
|
||||
#endif
|
||||
#ifndef USERMOD_BATTERY_UNKOWN_MAX_VOLTAGE
|
||||
#define USERMOD_BATTERY_UNKOWN_MAX_VOLTAGE 4.2f
|
||||
#endif
|
||||
|
||||
//the default ratio for the voltage divider
|
||||
/*
|
||||
*
|
||||
* Lithium polymer (Li-Po) defaults
|
||||
*
|
||||
*/
|
||||
#ifndef USERMOD_BATTERY_LIPO_MIN_VOLTAGE
|
||||
// LiPo "1S" Batteries should not be dischared below 3V !!
|
||||
#define USERMOD_BATTERY_LIPO_MIN_VOLTAGE 3.2f
|
||||
#endif
|
||||
#ifndef USERMOD_BATTERY_LIPO_MAX_VOLTAGE
|
||||
#define USERMOD_BATTERY_LIPO_MAX_VOLTAGE 4.2f
|
||||
#endif
|
||||
|
||||
/*
|
||||
*
|
||||
* Lithium-ion (Li-Ion) defaults
|
||||
*
|
||||
*/
|
||||
#ifndef USERMOD_BATTERY_LION_MIN_VOLTAGE
|
||||
// default for 18650 battery
|
||||
#define USERMOD_BATTERY_LION_MIN_VOLTAGE 2.6f
|
||||
#endif
|
||||
#ifndef USERMOD_BATTERY_LION_MAX_VOLTAGE
|
||||
#define USERMOD_BATTERY_LION_MAX_VOLTAGE 4.2f
|
||||
#endif
|
||||
|
||||
// the default ratio for the voltage divider
|
||||
#ifndef USERMOD_BATTERY_VOLTAGE_MULTIPLIER
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
#define USERMOD_BATTERY_VOLTAGE_MULTIPLIER 2.0f
|
||||
@ -35,13 +76,8 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef USERMOD_BATTERY_MAX_VOLTAGE
|
||||
#define USERMOD_BATTERY_MAX_VOLTAGE 4.2f
|
||||
#endif
|
||||
|
||||
// a common capacity for single 18650 battery cells is between 2500 and 3600 mAh
|
||||
#ifndef USERMOD_BATTERY_TOTAL_CAPACITY
|
||||
#define USERMOD_BATTERY_TOTAL_CAPACITY 3100
|
||||
#ifndef USERMOD_BATTERY_AVERAGING_ALPHA
|
||||
#define USERMOD_BATTERY_AVERAGING_ALPHA 0.1f
|
||||
#endif
|
||||
|
||||
// offset or calibration value to fine tune the calculated voltage
|
||||
@ -49,11 +85,6 @@
|
||||
#define USERMOD_BATTERY_CALIBRATION 0
|
||||
#endif
|
||||
|
||||
// calculate remaining time / the time that is left before the battery runs out of power
|
||||
// #ifndef USERMOD_BATTERY_CALCULATE_TIME_LEFT_ENABLED
|
||||
// #define USERMOD_BATTERY_CALCULATE_TIME_LEFT_ENABLED false
|
||||
// #endif
|
||||
|
||||
// auto-off feature
|
||||
#ifndef USERMOD_BATTERY_AUTO_OFF_ENABLED
|
||||
#define USERMOD_BATTERY_AUTO_OFF_ENABLED true
|
||||
@ -78,4 +109,26 @@
|
||||
|
||||
#ifndef USERMOD_BATTERY_LOW_POWER_INDICATOR_DURATION
|
||||
#define USERMOD_BATTERY_LOW_POWER_INDICATOR_DURATION 5
|
||||
#endif
|
||||
|
||||
// battery types
|
||||
typedef enum
|
||||
{
|
||||
unknown=0,
|
||||
lipo=1,
|
||||
lion=2
|
||||
} batteryType;
|
||||
|
||||
// used for initial configuration after boot
|
||||
typedef struct bconfig_t
|
||||
{
|
||||
batteryType type;
|
||||
float minVoltage;
|
||||
float maxVoltage;
|
||||
float voltage; // current voltage
|
||||
int8_t level; // current level
|
||||
float calibration; // offset or calibration value to fine tune the calculated voltage
|
||||
float voltageMultiplier;
|
||||
} batteryConfig;
|
||||
|
||||
#endif
|
@ -36,13 +36,12 @@ define `USERMOD_BATTERY` in `wled00/my_config.h`
|
||||
| Name | Unit | Description |
|
||||
| ----------------------------------------------- | ----------- |-------------------------------------------------------------------------------------- |
|
||||
| `USERMOD_BATTERY` | | define this (in `my_config.h`) to have this usermod included wled00\usermods_list.cpp |
|
||||
| `USERMOD_BATTERY_USE_LIPO` | | define this (in `my_config.h`) if you use LiPo rechargeables (1S) |
|
||||
| `USERMOD_BATTERY_MEASUREMENT_PIN` | | defaults to A0 on ESP8266 and GPIO35 on ESP32 |
|
||||
| `USERMOD_BATTERY_MEASUREMENT_INTERVAL` | ms | battery check interval. defaults to 30 seconds |
|
||||
| `USERMOD_BATTERY_MIN_VOLTAGE` | v | minimum battery voltage. default is 2.6 (18650 battery standard) |
|
||||
| `USERMOD_BATTERY_MAX_VOLTAGE` | v | maximum battery voltage. default is 4.2 (18650 battery standard) |
|
||||
| `USERMOD_BATTERY_TOTAL_CAPACITY` | mAh | the capacity of all cells in parallel summed up |
|
||||
| `USERMOD_BATTERY_CALIBRATION` | | offset / calibration number, fine tune the measured voltage by the microcontroller |
|
||||
| `USERMOD_BATTERY_{TYPE}_MIN_VOLTAGE` | v | minimum battery voltage. default is 2.6 (18650 battery standard) |
|
||||
| `USERMOD_BATTERY_{TYPE}_MAX_VOLTAGE` | v | maximum battery voltage. default is 4.2 (18650 battery standard) |
|
||||
| `USERMOD_BATTERY_{TYPE}_TOTAL_CAPACITY` | mAh | the capacity of all cells in parallel summed up |
|
||||
| `USERMOD_BATTERY_{TYPE}_CALIBRATION` | | offset / calibration number, fine tune the measured voltage by the microcontroller |
|
||||
| Auto-Off | --- | --- |
|
||||
| `USERMOD_BATTERY_AUTO_OFF_ENABLED` | true/false | enables auto-off |
|
||||
| `USERMOD_BATTERY_AUTO_OFF_THRESHOLD` | % (0-100) | when this threshold is reached master power turns off |
|
||||
@ -54,6 +53,13 @@ define `USERMOD_BATTERY` in `wled00/my_config.h`
|
||||
|
||||
All parameters can be configured at runtime via the Usermods settings page.
|
||||
|
||||
**NOTICE:** Each Battery type can be pre-configured individualy (in `my_config.h`)
|
||||
|
||||
| Name | Alias | `my_config.h` example |
|
||||
| --------------- | ------------- | ------------------------------------- |
|
||||
| Lithium Polymer | lipo (Li-Po) | `USERMOD_BATTERY_lipo_MIN_VOLTAGE` |
|
||||
| Lithium Ionen | lion (Li-Ion) | `USERMOD_BATTERY_lion_TOTAL_CAPACITY` |
|
||||
|
||||
## ⚠️ Important
|
||||
|
||||
- Make sure you know your battery specifications! All batteries are **NOT** the same!
|
||||
@ -80,6 +86,11 @@ Specification from: [Molicel INR18650-M35A, 3500mAh 10A Lithium-ion battery, 3.
|
||||
|
||||
## 📝 Change Log
|
||||
|
||||
2024-04-30
|
||||
|
||||
- integrate factory pattern to make it easier to add other / custom battery types
|
||||
- update readme
|
||||
|
||||
2023-01-04
|
||||
|
||||
- basic support for LiPo rechargeable batteries ( `-D USERMOD_BATTERY_USE_LIPO`)
|
||||
|
38
usermods/Battery/types/LionUMBattery.h
Normal file
38
usermods/Battery/types/LionUMBattery.h
Normal file
@ -0,0 +1,38 @@
|
||||
#ifndef UMBLion_h
|
||||
#define UMBLion_h
|
||||
|
||||
#include "../battery_defaults.h"
|
||||
#include "../UMBattery.h"
|
||||
|
||||
/**
|
||||
* LiOn Battery
|
||||
*
|
||||
*/
|
||||
class LionUMBattery : public UMBattery
|
||||
{
|
||||
private:
|
||||
|
||||
public:
|
||||
LionUMBattery() : UMBattery()
|
||||
{
|
||||
this->setMinVoltage(USERMOD_BATTERY_LION_MIN_VOLTAGE);
|
||||
this->setMaxVoltage(USERMOD_BATTERY_LION_MAX_VOLTAGE);
|
||||
}
|
||||
|
||||
float mapVoltage(float v, float min, float max) override
|
||||
{
|
||||
return this->linearMapping(v, min, max); // basic mapping
|
||||
};
|
||||
|
||||
void calculateAndSetLevel(float voltage) override
|
||||
{
|
||||
this->setLevel(this->mapVoltage(voltage, this->getMinVoltage(), this->getMaxVoltage()));
|
||||
};
|
||||
|
||||
virtual void setMaxVoltage(float voltage) override
|
||||
{
|
||||
this->maxVoltage = max(getMinVoltage()+1.0f, voltage);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
54
usermods/Battery/types/LipoUMBattery.h
Normal file
54
usermods/Battery/types/LipoUMBattery.h
Normal file
@ -0,0 +1,54 @@
|
||||
#ifndef UMBLipo_h
|
||||
#define UMBLipo_h
|
||||
|
||||
#include "../battery_defaults.h"
|
||||
#include "../UMBattery.h"
|
||||
|
||||
/**
|
||||
* LiPo Battery
|
||||
*
|
||||
*/
|
||||
class LipoUMBattery : public UMBattery
|
||||
{
|
||||
private:
|
||||
|
||||
public:
|
||||
LipoUMBattery() : UMBattery()
|
||||
{
|
||||
this->setMinVoltage(USERMOD_BATTERY_LIPO_MIN_VOLTAGE);
|
||||
this->setMaxVoltage(USERMOD_BATTERY_LIPO_MAX_VOLTAGE);
|
||||
}
|
||||
|
||||
/**
|
||||
* LiPo batteries have a differnt discharge curve, see
|
||||
* https://blog.ampow.com/lipo-voltage-chart/
|
||||
*/
|
||||
float mapVoltage(float v, float min, float max) override
|
||||
{
|
||||
float lvl = 0.0f;
|
||||
lvl = this->linearMapping(v, min, max); // basic mapping
|
||||
|
||||
if (lvl < 40.0f)
|
||||
lvl = this->linearMapping(lvl, 0, 40, 0, 12); // last 45% -> drops very quickly
|
||||
else {
|
||||
if (lvl < 90.0f)
|
||||
lvl = this->linearMapping(lvl, 40, 90, 12, 95); // 90% ... 40% -> almost linear drop
|
||||
else // level > 90%
|
||||
lvl = this->linearMapping(lvl, 90, 105, 95, 100); // highest 15% -> drop slowly
|
||||
}
|
||||
|
||||
return lvl;
|
||||
};
|
||||
|
||||
void calculateAndSetLevel(float voltage) override
|
||||
{
|
||||
this->setLevel(this->mapVoltage(voltage, this->getMinVoltage(), this->getMaxVoltage()));
|
||||
};
|
||||
|
||||
virtual void setMaxVoltage(float voltage) override
|
||||
{
|
||||
this->maxVoltage = max(getMinVoltage()+0.7f, voltage);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
39
usermods/Battery/types/UnkownUMBattery.h
Normal file
39
usermods/Battery/types/UnkownUMBattery.h
Normal file
@ -0,0 +1,39 @@
|
||||
#ifndef UMBUnkown_h
|
||||
#define UMBUnkown_h
|
||||
|
||||
#include "../battery_defaults.h"
|
||||
#include "../UMBattery.h"
|
||||
|
||||
/**
|
||||
* Unkown / Default Battery
|
||||
*
|
||||
*/
|
||||
class UnkownUMBattery : public UMBattery
|
||||
{
|
||||
private:
|
||||
|
||||
public:
|
||||
UnkownUMBattery() : UMBattery()
|
||||
{
|
||||
this->setMinVoltage(USERMOD_BATTERY_UNKOWN_MIN_VOLTAGE);
|
||||
this->setMaxVoltage(USERMOD_BATTERY_UNKOWN_MAX_VOLTAGE);
|
||||
}
|
||||
|
||||
void update(batteryConfig cfg)
|
||||
{
|
||||
if(cfg.minVoltage) this->setMinVoltage(cfg.minVoltage); else this->setMinVoltage(USERMOD_BATTERY_UNKOWN_MIN_VOLTAGE);
|
||||
if(cfg.maxVoltage) this->setMaxVoltage(cfg.maxVoltage); else this->setMaxVoltage(USERMOD_BATTERY_UNKOWN_MAX_VOLTAGE);
|
||||
}
|
||||
|
||||
float mapVoltage(float v, float min, float max) override
|
||||
{
|
||||
return this->linearMapping(v, min, max); // basic mapping
|
||||
};
|
||||
|
||||
void calculateAndSetLevel(float voltage) override
|
||||
{
|
||||
this->setLevel(this->mapVoltage(voltage, this->getMinVoltage(), this->getMaxVoltage()));
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
@ -2,12 +2,15 @@
|
||||
|
||||
#include "wled.h"
|
||||
#include "battery_defaults.h"
|
||||
#include "UMBattery.h"
|
||||
#include "types/UnkownUMBattery.h"
|
||||
#include "types/LionUMBattery.h"
|
||||
#include "types/LiPoUMBattery.h"
|
||||
|
||||
/*
|
||||
* Usermod by Maximilian Mewes
|
||||
* Mail: mewes.maximilian@gmx.de
|
||||
* GitHub: itCarl
|
||||
* Date: 25.12.2022
|
||||
* E-mail: mewes.maximilian@gmx.de
|
||||
* Created at: 25.12.2022
|
||||
* If you have any questions, please feel free to contact me.
|
||||
*/
|
||||
class UsermodBattery : public Usermod
|
||||
@ -15,47 +18,32 @@ class UsermodBattery : public Usermod
|
||||
private:
|
||||
// battery pin can be defined in my_config.h
|
||||
int8_t batteryPin = USERMOD_BATTERY_MEASUREMENT_PIN;
|
||||
|
||||
UMBattery* bat = new UnkownUMBattery();
|
||||
batteryConfig cfg;
|
||||
|
||||
// how often to read the battery voltage
|
||||
unsigned long readingInterval = USERMOD_BATTERY_MEASUREMENT_INTERVAL;
|
||||
unsigned long nextReadTime = 0;
|
||||
unsigned long lastReadTime = 0;
|
||||
// battery min. voltage
|
||||
float minBatteryVoltage = USERMOD_BATTERY_MIN_VOLTAGE;
|
||||
// battery max. voltage
|
||||
float maxBatteryVoltage = USERMOD_BATTERY_MAX_VOLTAGE;
|
||||
// all battery cells summed up
|
||||
unsigned int totalBatteryCapacity = USERMOD_BATTERY_TOTAL_CAPACITY;
|
||||
// raw analog reading
|
||||
float rawValue = 0.0f;
|
||||
// calculated voltage
|
||||
float voltage = maxBatteryVoltage;
|
||||
// between 0 and 1, to control strength of voltage smoothing filter
|
||||
float alpha = 0.05f;
|
||||
// multiplier for the voltage divider that is in place between ADC pin and battery, default will be 2 but might be adapted to readout voltages over ~5v ESP32 or ~6.6v ESP8266
|
||||
float voltageMultiplier = USERMOD_BATTERY_VOLTAGE_MULTIPLIER;
|
||||
// mapped battery level based on voltage
|
||||
int8_t batteryLevel = 100;
|
||||
// offset or calibration value to fine tune the calculated voltage
|
||||
float calibration = USERMOD_BATTERY_CALIBRATION;
|
||||
|
||||
// time left estimation feature
|
||||
// bool calculateTimeLeftEnabled = USERMOD_BATTERY_CALCULATE_TIME_LEFT_ENABLED;
|
||||
// float estimatedTimeLeft = 0.0;
|
||||
float alpha = USERMOD_BATTERY_AVERAGING_ALPHA;
|
||||
|
||||
// auto shutdown/shutoff/master off feature
|
||||
bool autoOffEnabled = USERMOD_BATTERY_AUTO_OFF_ENABLED;
|
||||
int8_t autoOffThreshold = USERMOD_BATTERY_AUTO_OFF_THRESHOLD;
|
||||
uint8_t autoOffThreshold = USERMOD_BATTERY_AUTO_OFF_THRESHOLD;
|
||||
|
||||
// low power indicator feature
|
||||
bool lowPowerIndicatorEnabled = USERMOD_BATTERY_LOW_POWER_INDICATOR_ENABLED;
|
||||
int8_t lowPowerIndicatorPreset = USERMOD_BATTERY_LOW_POWER_INDICATOR_PRESET;
|
||||
int8_t lowPowerIndicatorThreshold = USERMOD_BATTERY_LOW_POWER_INDICATOR_THRESHOLD;
|
||||
int8_t lowPowerIndicatorReactivationThreshold = lowPowerIndicatorThreshold+10;
|
||||
int8_t lowPowerIndicatorDuration = USERMOD_BATTERY_LOW_POWER_INDICATOR_DURATION;
|
||||
uint8_t lowPowerIndicatorPreset = USERMOD_BATTERY_LOW_POWER_INDICATOR_PRESET;
|
||||
uint8_t lowPowerIndicatorThreshold = USERMOD_BATTERY_LOW_POWER_INDICATOR_THRESHOLD;
|
||||
uint8_t lowPowerIndicatorReactivationThreshold = lowPowerIndicatorThreshold+10;
|
||||
uint8_t lowPowerIndicatorDuration = USERMOD_BATTERY_LOW_POWER_INDICATOR_DURATION;
|
||||
bool lowPowerIndicationDone = false;
|
||||
unsigned long lowPowerActivationTime = 0; // used temporary during active time
|
||||
int8_t lastPreset = 0;
|
||||
uint8_t lastPreset = 0;
|
||||
|
||||
//
|
||||
bool initDone = false;
|
||||
bool initializing = true;
|
||||
|
||||
@ -67,22 +55,17 @@ class UsermodBattery : public Usermod
|
||||
static const char _preset[];
|
||||
static const char _duration[];
|
||||
static const char _init[];
|
||||
|
||||
|
||||
// custom map function
|
||||
// https://forum.arduino.cc/t/floating-point-using-map-function/348113/2
|
||||
double mapf(double x, double in_min, double in_max, double out_min, double out_max)
|
||||
{
|
||||
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper for rounding floating point values
|
||||
*/
|
||||
float dot2round(float x)
|
||||
{
|
||||
float nx = (int)(x * 100 + .5);
|
||||
return (float)(nx / 100);
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* Turn off all leds
|
||||
*/
|
||||
void turnOff()
|
||||
@ -91,15 +74,15 @@ class UsermodBattery : public Usermod
|
||||
stateUpdated(CALL_MODE_DIRECT_CHANGE);
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* Indicate low power by activating a configured preset for a given time and then switching back to the preset that was selected previously
|
||||
*/
|
||||
void lowPowerIndicator()
|
||||
{
|
||||
if (!lowPowerIndicatorEnabled) return;
|
||||
if (batteryPin < 0) return; // no measurement
|
||||
if (lowPowerIndicationDone && lowPowerIndicatorReactivationThreshold <= batteryLevel) lowPowerIndicationDone = false;
|
||||
if (lowPowerIndicatorThreshold <= batteryLevel) return;
|
||||
if (lowPowerIndicationDone && lowPowerIndicatorReactivationThreshold <= bat->getLevel()) lowPowerIndicationDone = false;
|
||||
if (lowPowerIndicatorThreshold <= bat->getLevel()) return;
|
||||
if (lowPowerIndicationDone) return;
|
||||
if (lowPowerActivationTime <= 1) {
|
||||
lowPowerActivationTime = millis();
|
||||
@ -114,26 +97,39 @@ class UsermodBattery : public Usermod
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* read the battery voltage in different ways depending on the architecture
|
||||
*/
|
||||
float readVoltage()
|
||||
{
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
// use calibrated millivolts analogread on esp32 (150 mV ~ 2450 mV default attentuation) and divide by 1000 to get from milivolts to volts and multiply by voltage multiplier and apply calibration value
|
||||
return (analogReadMilliVolts(batteryPin) / 1000.0f) * voltageMultiplier + calibration;
|
||||
return (analogReadMilliVolts(batteryPin) / 1000.0f) * bat->getVoltageMultiplier() + bat->getCalibration();
|
||||
#else
|
||||
// use analog read on esp8266 ( 0V ~ 1V no attenuation options) and divide by ADC precision 1023 and multiply by voltage multiplier and apply calibration value
|
||||
return (analogRead(batteryPin) / 1023.0f) * voltageMultiplier + calibration;
|
||||
return (analogRead(batteryPin) / 1023.0f) * bat->getVoltageMultiplier() + bat->getCalibration();
|
||||
#endif
|
||||
}
|
||||
|
||||
public:
|
||||
//Functions called by WLED
|
||||
|
||||
/*
|
||||
/**
|
||||
* setup() is called once at boot. WiFi is not yet connected at this point.
|
||||
* You can use it to initialize variables, sensors or similar.
|
||||
*/
|
||||
void setup()
|
||||
{
|
||||
// plug in the right battery type
|
||||
if(cfg.type == (batteryType)lipo) {
|
||||
bat = new LipoUMBattery();
|
||||
} else if(cfg.type == (batteryType)lion) {
|
||||
bat = new LionUMBattery();
|
||||
}
|
||||
|
||||
// update the choosen battery type with configured values
|
||||
bat->update(cfg);
|
||||
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
bool success = false;
|
||||
DEBUG_PRINTLN(F("Allocating battery pin..."));
|
||||
@ -141,7 +137,7 @@ class UsermodBattery : public Usermod
|
||||
if (pinManager.allocatePin(batteryPin, false, PinOwner::UM_Battery)) {
|
||||
DEBUG_PRINTLN(F("Battery pin allocation succeeded."));
|
||||
success = true;
|
||||
voltage = readVoltage();
|
||||
bat->setVoltage(readVoltage());
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
@ -152,7 +148,7 @@ class UsermodBattery : public Usermod
|
||||
}
|
||||
#else //ESP8266 boards have only one analog input pin A0
|
||||
pinMode(batteryPin, INPUT);
|
||||
voltage = readVoltage();
|
||||
bat->setVoltage(readVoltage());
|
||||
#endif
|
||||
|
||||
nextReadTime = millis() + readingInterval;
|
||||
@ -162,7 +158,7 @@ class UsermodBattery : public Usermod
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
* connected() is called every time the WiFi is (re)connected
|
||||
* Use it to initialize network interfaces
|
||||
*/
|
||||
@ -191,43 +187,17 @@ class UsermodBattery : public Usermod
|
||||
if (batteryPin < 0) return; // nothing to read
|
||||
|
||||
initializing = false;
|
||||
float rawValue = readVoltage();
|
||||
|
||||
rawValue = readVoltage();
|
||||
// filter with exponential smoothing because ADC in esp32 is fluctuating too much for a good single readout
|
||||
voltage = voltage + alpha * (rawValue - voltage);
|
||||
|
||||
// check if voltage is within specified voltage range, allow 10% over/under voltage - removed cause this just makes it hard for people to troubleshoot as the voltage in the web gui will say invalid instead of displaying a voltage
|
||||
//voltage = ((voltage < minBatteryVoltage * 0.85f) || (voltage > maxBatteryVoltage * 1.1f)) ? -1.0f : voltage;
|
||||
float filteredVoltage = bat->getVoltage() + alpha * (rawValue - bat->getVoltage());
|
||||
|
||||
bat->setVoltage(filteredVoltage);
|
||||
// translate battery voltage into percentage
|
||||
/*
|
||||
the standard "map" function doesn't work
|
||||
https://www.arduino.cc/reference/en/language/functions/math/map/ notes and warnings at the bottom
|
||||
*/
|
||||
#ifdef USERMOD_BATTERY_USE_LIPO
|
||||
batteryLevel = mapf(voltage, minBatteryVoltage, maxBatteryVoltage, 0, 100); // basic mapping
|
||||
// LiPo batteries have a differnt dischargin curve, see
|
||||
// https://blog.ampow.com/lipo-voltage-chart/
|
||||
if (batteryLevel < 40.0f)
|
||||
batteryLevel = mapf(batteryLevel, 0, 40, 0, 12); // last 45% -> drops very quickly
|
||||
else {
|
||||
if (batteryLevel < 90.0f)
|
||||
batteryLevel = mapf(batteryLevel, 40, 90, 12, 95); // 90% ... 40% -> almost linear drop
|
||||
else // level > 90%
|
||||
batteryLevel = mapf(batteryLevel, 90, 105, 95, 100); // highest 15% -> drop slowly
|
||||
}
|
||||
#else
|
||||
batteryLevel = mapf(voltage, minBatteryVoltage, maxBatteryVoltage, 0, 100);
|
||||
#endif
|
||||
if (voltage > -1.0f) batteryLevel = constrain(batteryLevel, 0.0f, 110.0f);
|
||||
|
||||
// if (calculateTimeLeftEnabled) {
|
||||
// float currentBatteryCapacity = totalBatteryCapacity;
|
||||
// estimatedTimeLeft = (currentBatteryCapacity/strip.currentMilliamps)*60;
|
||||
// }
|
||||
bat->calculateAndSetLevel(filteredVoltage);
|
||||
|
||||
// Auto off -- Master power off
|
||||
if (autoOffEnabled && (autoOffThreshold >= batteryLevel))
|
||||
if (autoOffEnabled && (autoOffThreshold >= bat->getLevel()))
|
||||
turnOff();
|
||||
|
||||
#ifndef WLED_DISABLE_MQTT
|
||||
@ -236,13 +206,13 @@ class UsermodBattery : public Usermod
|
||||
if (WLED_MQTT_CONNECTED) {
|
||||
char buf[64]; // buffer for snprintf()
|
||||
snprintf_P(buf, 63, PSTR("%s/voltage"), mqttDeviceTopic);
|
||||
mqtt->publish(buf, 0, false, String(voltage).c_str());
|
||||
mqtt->publish(buf, 0, false, String(bat->getVoltage()).c_str());
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* addToJsonInfo() can be used to add custom entries to the /json/info part of the JSON API.
|
||||
* Creating an "u" object allows you to add custom key/value pairs to the Info section of the WLED web UI.
|
||||
* Below it is shown how this could be used for e.g. a light sensor
|
||||
@ -262,16 +232,6 @@ class UsermodBattery : public Usermod
|
||||
// info modal display names
|
||||
JsonArray infoPercentage = user.createNestedArray(F("Battery level"));
|
||||
JsonArray infoVoltage = user.createNestedArray(F("Battery voltage"));
|
||||
// if (calculateTimeLeftEnabled)
|
||||
// {
|
||||
// JsonArray infoEstimatedTimeLeft = user.createNestedArray(F("Estimated time left"));
|
||||
// if (initializing) {
|
||||
// infoEstimatedTimeLeft.add(FPSTR(_init));
|
||||
// } else {
|
||||
// infoEstimatedTimeLeft.add(estimatedTimeLeft);
|
||||
// infoEstimatedTimeLeft.add(F(" min"));
|
||||
// }
|
||||
// }
|
||||
JsonArray infoNextUpdate = user.createNestedArray(F("Next update"));
|
||||
|
||||
infoNextUpdate.add((nextReadTime - millis()) / 1000);
|
||||
@ -283,46 +243,104 @@ class UsermodBattery : public Usermod
|
||||
return;
|
||||
}
|
||||
|
||||
if (batteryLevel < 0) {
|
||||
if (bat->getLevel() < 0) {
|
||||
infoPercentage.add(F("invalid"));
|
||||
} else {
|
||||
infoPercentage.add(batteryLevel);
|
||||
infoPercentage.add(bat->getLevel());
|
||||
}
|
||||
infoPercentage.add(F(" %"));
|
||||
|
||||
if (voltage < 0) {
|
||||
if (bat->getVoltage() < 0) {
|
||||
infoVoltage.add(F("invalid"));
|
||||
} else {
|
||||
infoVoltage.add(dot2round(voltage));
|
||||
infoVoltage.add(dot2round(bat->getVoltage()));
|
||||
}
|
||||
infoVoltage.add(F(" V"));
|
||||
}
|
||||
|
||||
void addBatteryToJsonObject(JsonObject& battery, bool forJsonState)
|
||||
{
|
||||
if(forJsonState) { battery[F("type")] = cfg.type; } else {battery[F("type")] = (String)cfg.type; } // has to be a String otherwise it won't get converted to a Dropdown
|
||||
battery[F("min-voltage")] = bat->getMinVoltage();
|
||||
battery[F("max-voltage")] = bat->getMaxVoltage();
|
||||
battery[F("calibration")] = bat->getCalibration();
|
||||
battery[F("voltage-multiplier")] = bat->getVoltageMultiplier();
|
||||
battery[FPSTR(_readInterval)] = readingInterval;
|
||||
|
||||
/*
|
||||
JsonObject ao = battery.createNestedObject(F("auto-off")); // auto off section
|
||||
ao[FPSTR(_enabled)] = autoOffEnabled;
|
||||
ao[FPSTR(_threshold)] = autoOffThreshold;
|
||||
|
||||
JsonObject lp = battery.createNestedObject(F("indicator")); // low power section
|
||||
lp[FPSTR(_enabled)] = lowPowerIndicatorEnabled;
|
||||
lp[FPSTR(_preset)] = lowPowerIndicatorPreset; // dropdown trickery (String)lowPowerIndicatorPreset;
|
||||
lp[FPSTR(_threshold)] = lowPowerIndicatorThreshold;
|
||||
lp[FPSTR(_duration)] = lowPowerIndicatorDuration;
|
||||
}
|
||||
|
||||
void getUsermodConfigFromJsonObject(JsonObject& battery)
|
||||
{
|
||||
getJsonValue(battery[F("type")], cfg.type);
|
||||
getJsonValue(battery[F("min-voltage")], cfg.minVoltage);
|
||||
getJsonValue(battery[F("max-voltage")], cfg.maxVoltage);
|
||||
getJsonValue(battery[F("calibration")], cfg.calibration);
|
||||
getJsonValue(battery[F("voltage-multiplier")], cfg.voltageMultiplier);
|
||||
|
||||
setReadingInterval(battery[FPSTR(_readInterval)] | readingInterval);
|
||||
|
||||
JsonObject ao = battery[F("auto-off")];
|
||||
setAutoOffEnabled(ao[FPSTR(_enabled)] | autoOffEnabled);
|
||||
setAutoOffThreshold(ao[FPSTR(_threshold)] | autoOffThreshold);
|
||||
|
||||
JsonObject lp = battery[F("indicator")];
|
||||
setLowPowerIndicatorEnabled(lp[FPSTR(_enabled)] | lowPowerIndicatorEnabled);
|
||||
setLowPowerIndicatorPreset(lp[FPSTR(_preset)] | lowPowerIndicatorPreset);
|
||||
setLowPowerIndicatorThreshold(lp[FPSTR(_threshold)] | lowPowerIndicatorThreshold);
|
||||
lowPowerIndicatorReactivationThreshold = lowPowerIndicatorThreshold+10;
|
||||
setLowPowerIndicatorDuration(lp[FPSTR(_duration)] | lowPowerIndicatorDuration);
|
||||
|
||||
if(initDone)
|
||||
bat->update(cfg);
|
||||
}
|
||||
|
||||
/**
|
||||
* addToJsonState() can be used to add custom entries to the /json/state part of the JSON API (state object).
|
||||
* Values in the state object may be modified by connected clients
|
||||
*/
|
||||
/*
|
||||
void addToJsonState(JsonObject& root)
|
||||
{
|
||||
JsonObject battery = root.createNestedObject(FPSTR(_name));
|
||||
|
||||
if (battery.isNull())
|
||||
battery = root.createNestedObject(FPSTR(_name));
|
||||
|
||||
addBatteryToJsonObject(battery, true);
|
||||
|
||||
DEBUG_PRINTLN(F("Battery state exposed in JSON API."));
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
* readFromJsonState() can be used to receive data clients send to the /json/state part of the JSON API (state object).
|
||||
* Values in the state object may be modified by connected clients
|
||||
*/
|
||||
/*
|
||||
void readFromJsonState(JsonObject& root)
|
||||
{
|
||||
if (!initDone) return; // prevent crash on boot applyPreset()
|
||||
|
||||
JsonObject battery = root[FPSTR(_name)];
|
||||
|
||||
if (!battery.isNull()) {
|
||||
getUsermodConfigFromJsonObject(battery);
|
||||
|
||||
DEBUG_PRINTLN(F("Battery state read from JSON API."));
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
* addToConfig() can be used to add custom persistent settings to the cfg.json file in the "um" (usermod) object.
|
||||
* It will be called by WLED when settings are actually saved (for example, LED settings are saved)
|
||||
* If you want to force saving the current state, use serializeConfig() in your loop().
|
||||
@ -359,47 +377,41 @@ class UsermodBattery : public Usermod
|
||||
*/
|
||||
void addToConfig(JsonObject& root)
|
||||
{
|
||||
JsonObject battery = root.createNestedObject(FPSTR(_name)); // usermodname
|
||||
JsonObject battery = root.createNestedObject(FPSTR(_name));
|
||||
|
||||
if (battery.isNull()) {
|
||||
battery = root.createNestedObject(FPSTR(_name));
|
||||
}
|
||||
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
battery[F("pin")] = batteryPin;
|
||||
#endif
|
||||
|
||||
// battery[F("time-left")] = calculateTimeLeftEnabled;
|
||||
battery[F("min-voltage")] = minBatteryVoltage;
|
||||
battery[F("max-voltage")] = maxBatteryVoltage;
|
||||
battery[F("capacity")] = totalBatteryCapacity;
|
||||
battery[F("calibration")] = calibration;
|
||||
battery[F("voltage-multiplier")] = voltageMultiplier;
|
||||
battery[FPSTR(_readInterval)] = readingInterval;
|
||||
|
||||
JsonObject ao = battery.createNestedObject(F("auto-off")); // auto off section
|
||||
ao[FPSTR(_enabled)] = autoOffEnabled;
|
||||
ao[FPSTR(_threshold)] = autoOffThreshold;
|
||||
|
||||
JsonObject lp = battery.createNestedObject(F("indicator")); // low power section
|
||||
lp[FPSTR(_enabled)] = lowPowerIndicatorEnabled;
|
||||
lp[FPSTR(_preset)] = lowPowerIndicatorPreset; // dropdown trickery (String)lowPowerIndicatorPreset;
|
||||
lp[FPSTR(_threshold)] = lowPowerIndicatorThreshold;
|
||||
lp[FPSTR(_duration)] = lowPowerIndicatorDuration;
|
||||
addBatteryToJsonObject(battery, false);
|
||||
|
||||
// read voltage in case calibration or voltage multiplier changed to see immediate effect
|
||||
voltage = readVoltage();
|
||||
bat->setVoltage(readVoltage());
|
||||
|
||||
DEBUG_PRINTLN(F("Battery config saved."));
|
||||
}
|
||||
|
||||
void appendConfigData()
|
||||
{
|
||||
oappend(SET_F("addInfo('Battery:min-voltage', 1, 'v');"));
|
||||
oappend(SET_F("addInfo('Battery:max-voltage', 1, 'v');"));
|
||||
oappend(SET_F("addInfo('Battery:capacity', 1, 'mAh');"));
|
||||
oappend(SET_F("addInfo('Battery:interval', 1, 'ms');"));
|
||||
oappend(SET_F("addInfo('Battery:auto-off:threshold', 1, '%');"));
|
||||
oappend(SET_F("addInfo('Battery:indicator:threshold', 1, '%');"));
|
||||
oappend(SET_F("addInfo('Battery:indicator:duration', 1, 's');"));
|
||||
// Total: 462 Bytes
|
||||
oappend(SET_F("td=addDropdown('Battery', 'type');")); // 35 Bytes
|
||||
oappend(SET_F("addOption(td, 'Unkown', '0');")); // 30 Bytes
|
||||
oappend(SET_F("addOption(td, 'LiPo', '1');")); // 28 Bytes
|
||||
oappend(SET_F("addOption(td, 'LiOn', '2');")); // 28 Bytes
|
||||
oappend(SET_F("addInfo('Battery:type',1,'<small style=\"color:orange\">requires reboot</small>');")); // 81 Bytes
|
||||
oappend(SET_F("addInfo('Battery:min-voltage', 1, 'v');")); // 40 Bytes
|
||||
oappend(SET_F("addInfo('Battery:max-voltage', 1, 'v');")); // 40 Bytes
|
||||
oappend(SET_F("addInfo('Battery:interval', 1, 'ms');")); // 38 Bytes
|
||||
oappend(SET_F("addInfo('Battery:auto-off:threshold', 1, '%');")); // 47 Bytes
|
||||
oappend(SET_F("addInfo('Battery:indicator:threshold', 1, '%');")); // 48 Bytes
|
||||
oappend(SET_F("addInfo('Battery:indicator:duration', 1, 's');")); // 47 Bytes
|
||||
|
||||
// cannot quite get this mf to work. its exeeding some buffer limit i think
|
||||
// what i wanted is a list of all presets to select one from
|
||||
// this option list would exeed the oappend() buffer
|
||||
// a list of all presets to select one from
|
||||
// oappend(SET_F("bd=addDropdown('Battery:low-power-indicator', 'preset');"));
|
||||
// the loop generates: oappend(SET_F("addOption(bd, 'preset name', preset id);"));
|
||||
// for(int8_t i=1; i < 42; i++) {
|
||||
@ -412,7 +424,7 @@ class UsermodBattery : public Usermod
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
* readFromConfig() can be used to read back the custom settings you added with addToConfig().
|
||||
* This is called by WLED when settings are loaded (currently this only happens immediately after boot, or after saving on the Usermod Settings page)
|
||||
*
|
||||
@ -445,25 +457,13 @@ class UsermodBattery : public Usermod
|
||||
newBatteryPin = battery[F("pin")] | newBatteryPin;
|
||||
#endif
|
||||
// calculateTimeLeftEnabled = battery[F("time-left")] | calculateTimeLeftEnabled;
|
||||
setMinBatteryVoltage(battery[F("min-voltage")] | minBatteryVoltage);
|
||||
setMaxBatteryVoltage(battery[F("max-voltage")] | maxBatteryVoltage);
|
||||
setTotalBatteryCapacity(battery[F("capacity")] | totalBatteryCapacity);
|
||||
setCalibration(battery[F("calibration")] | calibration);
|
||||
setVoltageMultiplier(battery[F("voltage-multiplier")] | voltageMultiplier);
|
||||
setMinBatteryVoltage(battery[F("min-voltage")] | bat->getMinVoltage());
|
||||
setMaxBatteryVoltage(battery[F("max-voltage")] | bat->getMaxVoltage());
|
||||
setCalibration(battery[F("calibration")] | bat->getCalibration());
|
||||
setVoltageMultiplier(battery[F("voltage-multiplier")] | bat->getVoltageMultiplier());
|
||||
setReadingInterval(battery[FPSTR(_readInterval)] | readingInterval);
|
||||
|
||||
JsonObject ao = battery[F("auto-off")];
|
||||
setAutoOffEnabled(ao[FPSTR(_enabled)] | autoOffEnabled);
|
||||
setAutoOffThreshold(ao[FPSTR(_threshold)] | autoOffThreshold);
|
||||
|
||||
JsonObject lp = battery[F("indicator")];
|
||||
setLowPowerIndicatorEnabled(lp[FPSTR(_enabled)] | lowPowerIndicatorEnabled);
|
||||
setLowPowerIndicatorPreset(lp[FPSTR(_preset)] | lowPowerIndicatorPreset); // dropdown trickery (int)lp["preset"]
|
||||
setLowPowerIndicatorThreshold(lp[FPSTR(_threshold)] | lowPowerIndicatorThreshold);
|
||||
lowPowerIndicatorReactivationThreshold = lowPowerIndicatorThreshold+10;
|
||||
setLowPowerIndicatorDuration(lp[FPSTR(_duration)] | lowPowerIndicatorDuration);
|
||||
|
||||
DEBUG_PRINT(FPSTR(_name));
|
||||
getUsermodConfigFromJsonObject(battery);
|
||||
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
if (!initDone)
|
||||
@ -491,8 +491,9 @@ class UsermodBattery : public Usermod
|
||||
return !battery[FPSTR(_readInterval)].isNull();
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate a preset sample for low power indication
|
||||
/**
|
||||
* TBD: Generate a preset sample for low power indication
|
||||
* a button on the config page would be cool, currently not possible
|
||||
*/
|
||||
void generateExamplePreset()
|
||||
{
|
||||
@ -529,7 +530,7 @@ class UsermodBattery : public Usermod
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
/**
|
||||
* getId() allows you to optionally give your V2 usermod an unique ID (please define it in const.h!).
|
||||
* This could be used in the future for the system to determine whether your usermod is installed.
|
||||
*/
|
||||
@ -538,13 +539,23 @@ class UsermodBattery : public Usermod
|
||||
return USERMOD_ID_BATTERY;
|
||||
}
|
||||
|
||||
/**
|
||||
* get currently active battery type
|
||||
*/
|
||||
batteryType getBatteryType()
|
||||
{
|
||||
return cfg.type;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
unsigned long getReadingInterval()
|
||||
{
|
||||
return readingInterval;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* minimum repetition is 3000ms (3s)
|
||||
*/
|
||||
void setReadingInterval(unsigned long newReadingInterval)
|
||||
@ -552,105 +563,84 @@ class UsermodBattery : public Usermod
|
||||
readingInterval = max((unsigned long)3000, newReadingInterval);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
* Get lowest configured battery voltage
|
||||
*/
|
||||
float getMinBatteryVoltage()
|
||||
{
|
||||
return minBatteryVoltage;
|
||||
return bat->getMinVoltage();
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* Set lowest battery voltage
|
||||
* can't be below 0 volt
|
||||
*/
|
||||
void setMinBatteryVoltage(float voltage)
|
||||
{
|
||||
minBatteryVoltage = max(0.0f, voltage);
|
||||
bat->setMinVoltage(voltage);
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* Get highest configured battery voltage
|
||||
*/
|
||||
float getMaxBatteryVoltage()
|
||||
{
|
||||
return maxBatteryVoltage;
|
||||
return bat->getMaxVoltage();
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* Set highest battery voltage
|
||||
* can't be below minBatteryVoltage
|
||||
*/
|
||||
void setMaxBatteryVoltage(float voltage)
|
||||
{
|
||||
#ifdef USERMOD_BATTERY_USE_LIPO
|
||||
maxBatteryVoltage = max(getMinBatteryVoltage()+0.7f, voltage);
|
||||
#else
|
||||
maxBatteryVoltage = max(getMinBatteryVoltage()+1.0f, voltage);
|
||||
#endif
|
||||
bat->setMaxVoltage(voltage);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get the capacity of all cells in parralel sumed up
|
||||
* unit: mAh
|
||||
*/
|
||||
unsigned int getTotalBatteryCapacity()
|
||||
{
|
||||
return totalBatteryCapacity;
|
||||
}
|
||||
|
||||
void setTotalBatteryCapacity(unsigned int capacity)
|
||||
{
|
||||
totalBatteryCapacity = capacity;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
* Get the calculated voltage
|
||||
* formula: (adc pin value / adc precision * max voltage) + calibration
|
||||
*/
|
||||
float getVoltage()
|
||||
{
|
||||
return voltage;
|
||||
return bat->getVoltage();
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* Get the mapped battery level (0 - 100) based on voltage
|
||||
* important: voltage can drop when a load is applied, so its only an estimate
|
||||
*/
|
||||
int8_t getBatteryLevel()
|
||||
{
|
||||
return batteryLevel;
|
||||
return bat->getLevel();
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* Get the configured calibration value
|
||||
* a offset value to fine-tune the calculated voltage.
|
||||
*/
|
||||
float getCalibration()
|
||||
{
|
||||
return calibration;
|
||||
return bat->getCalibration();
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* Set the voltage calibration offset value
|
||||
* a offset value to fine-tune the calculated voltage.
|
||||
*/
|
||||
void setCalibration(float offset)
|
||||
{
|
||||
calibration = offset;
|
||||
bat->setCalibration(offset);
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* Set the voltage multiplier value
|
||||
* A multiplier that may need adjusting for different voltage divider setups
|
||||
*/
|
||||
void setVoltageMultiplier(float multiplier)
|
||||
{
|
||||
voltageMultiplier = multiplier;
|
||||
bat->setVoltageMultiplier(multiplier);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -659,10 +649,10 @@ class UsermodBattery : public Usermod
|
||||
*/
|
||||
float getVoltageMultiplier()
|
||||
{
|
||||
return voltageMultiplier;
|
||||
return bat->getVoltageMultiplier();
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* Get auto-off feature enabled status
|
||||
* is auto-off enabled, true/false
|
||||
*/
|
||||
@ -671,7 +661,7 @@ class UsermodBattery : public Usermod
|
||||
return autoOffEnabled;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* Set auto-off feature status
|
||||
*/
|
||||
void setAutoOffEnabled(bool enabled)
|
||||
@ -679,7 +669,7 @@ class UsermodBattery : public Usermod
|
||||
autoOffEnabled = enabled;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* Get auto-off threshold in percent (0-100)
|
||||
*/
|
||||
int8_t getAutoOffThreshold()
|
||||
@ -687,7 +677,7 @@ class UsermodBattery : public Usermod
|
||||
return autoOffThreshold;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* Set auto-off threshold in percent (0-100)
|
||||
*/
|
||||
void setAutoOffThreshold(int8_t threshold)
|
||||
@ -697,8 +687,7 @@ class UsermodBattery : public Usermod
|
||||
autoOffThreshold = lowPowerIndicatorEnabled /*&& autoOffEnabled*/ ? min(lowPowerIndicatorThreshold-1, (int)autoOffThreshold) : autoOffThreshold;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
* Get low-power-indicator feature enabled status
|
||||
* is the low-power-indicator enabled, true/false
|
||||
*/
|
||||
@ -707,7 +696,7 @@ class UsermodBattery : public Usermod
|
||||
return lowPowerIndicatorEnabled;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* Set low-power-indicator feature status
|
||||
*/
|
||||
void setLowPowerIndicatorEnabled(bool enabled)
|
||||
@ -715,7 +704,7 @@ class UsermodBattery : public Usermod
|
||||
lowPowerIndicatorEnabled = enabled;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* Get low-power-indicator preset to activate when low power is detected
|
||||
*/
|
||||
int8_t getLowPowerIndicatorPreset()
|
||||
@ -723,7 +712,7 @@ class UsermodBattery : public Usermod
|
||||
return lowPowerIndicatorPreset;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* Set low-power-indicator preset to activate when low power is detected
|
||||
*/
|
||||
void setLowPowerIndicatorPreset(int8_t presetId)
|
||||
@ -741,7 +730,7 @@ class UsermodBattery : public Usermod
|
||||
return lowPowerIndicatorThreshold;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* Set low-power-indicator threshold in percent (0-100)
|
||||
*/
|
||||
void setLowPowerIndicatorThreshold(int8_t threshold)
|
||||
@ -751,7 +740,7 @@ class UsermodBattery : public Usermod
|
||||
lowPowerIndicatorThreshold = autoOffEnabled /*&& lowPowerIndicatorEnabled*/ ? max(autoOffThreshold+1, (int)lowPowerIndicatorThreshold) : max(5, (int)lowPowerIndicatorThreshold);
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* Get low-power-indicator duration in seconds
|
||||
*/
|
||||
int8_t getLowPowerIndicatorDuration()
|
||||
@ -759,7 +748,7 @@ class UsermodBattery : public Usermod
|
||||
return lowPowerIndicatorDuration;
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* Set low-power-indicator duration in seconds
|
||||
*/
|
||||
void setLowPowerIndicatorDuration(int8_t duration)
|
||||
@ -767,9 +756,8 @@ class UsermodBattery : public Usermod
|
||||
lowPowerIndicatorDuration = duration;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get low-power-indicator status when the indication is done thsi returns true
|
||||
/**
|
||||
* Get low-power-indicator status when the indication is done this returns true
|
||||
*/
|
||||
bool getLowPowerIndicatorDone()
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user