Skip to content

Commit

Permalink
Merge pull request #3003 from itCarl/usermod-battery-update2023
Browse files Browse the repository at this point in the history
Usermod Battery 🔋 Added Support for different battery types, Optimized file structure
  • Loading branch information
blazoncek committed May 6, 2024
2 parents 2607c44 + 52020cb commit 47e1cbd
Show file tree
Hide file tree
Showing 7 changed files with 576 additions and 233 deletions.
160 changes: 160 additions & 0 deletions usermods/Battery/UMBattery.h
Original file line number Diff line number Diff line change
@@ -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
99 changes: 76 additions & 23 deletions usermods/Battery/battery_defaults.h
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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
Expand All @@ -35,25 +76,15 @@
#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
#ifndef USERMOD_BATTERY_CALIBRATION
#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
Expand All @@ -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
21 changes: 16 additions & 5 deletions usermods/Battery/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
Expand All @@ -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!
Expand All @@ -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`)
Expand Down
38 changes: 38 additions & 0 deletions usermods/Battery/types/LionUMBattery.h
Original file line number Diff line number Diff line change
@@ -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
Loading

0 comments on commit 47e1cbd

Please sign in to comment.