diff --git a/usermods/Battery/battery_defaults.h b/usermods/Battery/battery_defaults.h index f1abe56c..c682cb45 100644 --- a/usermods/Battery/battery_defaults.h +++ b/usermods/Battery/battery_defaults.h @@ -18,7 +18,12 @@ // 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 - #define USERMOD_BATTERY_MIN_VOLTAGE 2.6f + #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 #endif #ifndef USERMOD_BATTERY_MAX_VOLTAGE diff --git a/usermods/Battery/readme.md b/usermods/Battery/readme.md index 5a667870..d55573ab 100644 --- a/usermods/Battery/readme.md +++ b/usermods/Battery/readme.md @@ -36,6 +36,7 @@ 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) | @@ -79,6 +80,13 @@ Specification from: [Molicel INR18650-M35A, 3500mAh 10A Lithium-ion battery, 3. ## 📝 Change Log +2023-01-04 + +- basic support for LiPo rechargeable batteries ( `-D USERMOD_BATTERY_USE_LIPO`) +- improved support for esp32 (read calibrated voltage) +- corrected config saving (measurement pin, and battery min/max were lost) +- various bugfixes + 2022-12-25 - added "auto-off" feature diff --git a/usermods/Battery/usermod_v2_Battery.h b/usermods/Battery/usermod_v2_Battery.h index 64e13ec6..ac34a7e4 100644 --- a/usermods/Battery/usermod_v2_Battery.h +++ b/usermods/Battery/usermod_v2_Battery.h @@ -176,20 +176,44 @@ class UsermodBattery : public Usermod initializing = false; +#ifdef ARDUINO_ARCH_ESP32 + // use calibrated millivolts analogread on esp32 (150 mV ~ 2450 mV) + rawValue = analogReadMilliVolts(batteryPin); + // calculate the voltage + voltage = (rawValue / 1000.0f) + calibration; + // usually a voltage divider (50%) is used on ESP32, so we need to multiply by 2 + voltage *= 2.0f; +#else // read battery raw input rawValue = analogRead(batteryPin); // calculate the voltage voltage = ((rawValue / getAdcPrecision()) * maxBatteryVoltage) + calibration; - // check if voltage is within specified voltage range - voltage = voltagemaxBatteryVoltage?-1.0f:voltage; +#endif + // check if voltage is within specified voltage range, allow 10% over/under voltage + voltage = ((voltage < minBatteryVoltage * 0.85f) || (voltage > maxBatteryVoltage * 1.1f)) ? -1.0f : voltage; // 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 */ - batteryLevel = mapf(voltage, minBatteryVoltage, maxBatteryVoltage, 0, 100); + #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; @@ -329,7 +353,7 @@ class UsermodBattery : public Usermod { JsonObject battery = root.createNestedObject(FPSTR(_name)); // usermodname #ifdef ARDUINO_ARCH_ESP32 - battery["pin"] = batteryPin; + battery[F("pin")] = batteryPin; #endif // battery[F("time-left")] = calculateTimeLeftEnabled; @@ -409,8 +433,8 @@ 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); + setMinBatteryVoltage(battery[F("min-voltage")] | minBatteryVoltage); + setMaxBatteryVoltage(battery[F("max-voltage")] | maxBatteryVoltage); setTotalBatteryCapacity(battery[F("capacity")] | totalBatteryCapacity); setCalibration(battery[F("calibration")] | calibration); setReadingInterval(battery[FPSTR(_readInterval)] | readingInterval); @@ -432,14 +456,14 @@ class UsermodBattery : public Usermod if (!initDone) { // first run: reading from cfg.json - newBatteryPin = batteryPin; + batteryPin = newBatteryPin; DEBUG_PRINTLN(F(" config loaded.")); } else { DEBUG_PRINTLN(F(" config (re)loaded.")); - // changing paramters from settings page + // changing parameters from settings page if (newBatteryPin != batteryPin) { // deallocate pin @@ -547,7 +571,11 @@ class UsermodBattery : public Usermod */ void setMaxBatteryVoltage(float voltage) { - maxBatteryVoltage = max(getMinBatteryVoltage()+1.0f, voltage); + #ifdef USERMOD_BATTERY_USE_LIPO + maxBatteryVoltage = max(getMinBatteryVoltage()+0.7f, voltage); + #else + maxBatteryVoltage = max(getMinBatteryVoltage()+1.0f, voltage); + #endif }