Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add new battery mappings #253

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 35 additions & 11 deletions src/batterymonitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,19 +101,43 @@ void BatteryMonitor::Loop()
#endif
if (voltage > 0) //valid measurement
{
// Estimate battery level, 3.2V is 0%, 4.17V is 100% (1.0)
if (voltage > 3.975f)
level = (voltage - 2.920f) * 0.8f;
else if (voltage > 3.678f)
level = (voltage - 3.300f) * 1.25f;
else if (voltage > 3.489f)
level = (voltage - 3.400f) * 1.7f;
else if (voltage > 3.360f)
level = (voltage - 3.300f) * 0.8f;
#if BATTERY_REGULATOR == REG_BUCK
// Estimate battery level, 3.2V is 0%, 3.87V is 50%, 4.15V is 100% (1.0)
// Mapped from battery discharge with buck regulating to 2.8V
if (voltage > 4.075)
level = MAP(voltage, 4.075, 4.15, 0.95, 1);
else if (voltage > 3.775)
level = MAP(voltage, 3.775, 4.075, 0.3, 0.95);
else if (voltage > 3.45)
level = MAP(voltage, 3.45, 3.775, 0.05, 0.3);
else
level = (voltage - 3.200f) * 0.3f;

level = MAP(voltage, 3.2, 3.45, 0, 0.05);
#elif BATTERY_REGULATOR == REG_LDO
// Estimate battery level, 3.2V is 0%, 3.77V is 50%, 4.15V is 100% (1.0)
// Mapped from battery discharge with ldo
if (voltage > 4.025)
level = MAP(voltage, 4.025, 4.15, 0.95, 1);
else if (voltage > 3.65)
level = MAP(voltage, 3.65, 4.025, 0.3, 0.95);
else if (voltage > 3.4)
level = MAP(voltage, 3.4, 3.65, 0.05, 0.3);
else
level = MAP(voltage, 3.2, 3.4, 0, 0.05);
#elif BATTERY_REGULATOR == REG_LEGACY
// Estimate battery level, 3.2V is 0%, 3.7V is 50%, 4.17V is 100% (1.0)
// Mapped from unknown data?
if (voltage > 3.975)
level = MAP(voltage, 3.975, 4.17, 0.84375, 1);
else if (voltage > 3.677)
level = MAP(voltage, 3.677, 3.975, 0.4709, 0.84375);
else if (voltage > 3.489)
level = MAP(voltage, 3.489, 3.677, 0.1512, 0.4709);
else if (voltage > 3.36)
level = MAP(voltage, 3.36, 3.489, 0.048, 0.1512);
else
level = MAP(voltage, 3.2, 3.36, 0, 0.048);
level = (level - 0.05f) / 0.95f; // Cut off the last 5% (3.36V)
#endif

if (level > 1)
level = 1;
Expand Down
6 changes: 6 additions & 0 deletions src/batterymonitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@
#define BATTERY_SHIELD_R2 220.0
#endif

#ifndef BATTERY_REGULATOR
#define BATTERY_REGULATOR REG_LDO
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To keep backwards compatibility the fallback should be legacy behavior imo.

Suggested change
#define BATTERY_REGULATOR REG_LDO
#define BATTERY_REGULATOR REG_LEGACY

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the legacy mapping is not based on anything, though, what other reason would be to not use the new mapping as default/fallback?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean fair, but then why even keep it around in the first place. At the very least it should be official slime option as default then imo. I'll be setting up a test today.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

official slime uses a buck regulator, which will draw roughly constant power, the discharge characteristic is different than most diy boards which have a linear ldo regulator, which will draw roughly constant current

#endif

#if BATTERY_MONITOR == BAT_EXTERNAL
#ifndef PIN_BATTERY_LEVEL
#error Internal ADC enabled without pin! Please select a pin.
Expand All @@ -66,6 +70,8 @@
#define ADCMultiplier 3.3 / 1023.0 * 14.2 / 9.1
#endif

#define MAP(x, in_min, in_max, out_min, out_max) ((x - in_min) / (in_max - in_min) * (out_max - out_min) + out_min)

class BatteryMonitor
{
public:
Expand Down
4 changes: 4 additions & 0 deletions src/consts.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@
#define BAT_MCP3021 3
#define BAT_INTERNAL_MCP3021 4

#define REG_BUCK 1
#define REG_LDO 2
#define REG_LEGACY 3

#define LED_OFF 255

#define POWER_SAVING_LEGACY 0 // No sleeping, but PS enabled
Expand Down
9 changes: 9 additions & 0 deletions src/defines.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,12 @@ IMU_DESC_ENTRY(IMU_BMP160, PRIMARY_IMU_ADDRESS_ONE, IMU_ROTATION, PIN_IMU_SCL, P
// BAT_MCP3021 for external ADC connected over I2C
#define BATTERY_MONITOR BAT_EXTERNAL

// Battery voltage mapping options
// REG_BUCK if the board uses step-down or buck regulator (2.8V)
// REG_LDO if the board uses ldo linear regulator
// REG_LEGACY to use the old conversion behavior
// #define BATTERY_REGULATOR REG_LDO

// BAT_EXTERNAL definition override
// D1 Mini boards with ESP8266 have internal resistors. For these boards you only have to adjust BATTERY_SHIELD_RESISTANCE.
// For other boards you can now adjust the other resistor values.
Expand Down Expand Up @@ -97,6 +103,9 @@ IMU_DESC_ENTRY(IMU_BMP160, PRIMARY_IMU_ADDRESS_ONE, IMU_ROTATION, PIN_IMU_SCL, P
#ifndef BATTERY_SHIELD_R2
#define BATTERY_SHIELD_R2 40.2
#endif
#ifndef BATTERY_REGULATOR
#define BATTERY_REGULATOR REG_BUCK
#endif
#elif BOARD == BOARD_SLIMEVR_LEGACY || BOARD == BOARD_SLIMEVR_DEV
#define PIN_IMU_SDA 4
#define PIN_IMU_SCL 5
Expand Down
Loading