-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
31 changed files
with
6,116 additions
and
656 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
/* | ||
Battery.cpp - 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/>. | ||
*/ | ||
// https://github.com/rlogiacco/BatterySense | ||
|
||
#include "Battery.h" | ||
#include <Arduino.h> | ||
|
||
Battery::Battery(uint16_t minVoltage, uint16_t maxVoltage, uint8_t sensePin) | ||
{ | ||
this->sensePin = sensePin; | ||
this->activationPin = 0xFF; | ||
this->minVoltage = minVoltage; | ||
this->maxVoltage = maxVoltage; | ||
} | ||
|
||
void Battery::begin(uint16_t refVoltage, float dividerRatio, mapFn_t mapFunction) | ||
{ | ||
this->refVoltage = refVoltage; | ||
this->dividerRatio = dividerRatio; | ||
pinMode(this->sensePin, INPUT); | ||
if (this->activationPin < 0xFF) | ||
pinMode(this->activationPin, OUTPUT); | ||
|
||
this->mapFunction = mapFunction ? mapFunction : &linear; | ||
} | ||
|
||
void Battery::onDemand(uint8_t activationPin, uint8_t activationMode) | ||
{ | ||
if (activationPin < 0xFF) { | ||
this->activationPin = activationPin; | ||
this->activationMode = activationMode; | ||
pinMode(this->activationPin, OUTPUT); | ||
digitalWrite(activationPin, !activationMode); | ||
} | ||
} | ||
|
||
uint8_t Battery::level(uint16_t voltage) | ||
{ | ||
if (voltage <= minVoltage) | ||
return 0; | ||
else if (voltage >= maxVoltage) | ||
return 100; | ||
else | ||
return (*mapFunction)(voltage, minVoltage, maxVoltage); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
/* | ||
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/>. | ||
*/ | ||
|
||
#ifndef BATTERY_H_ | ||
#define BATTERY_H_ | ||
|
||
#include <Arduino.h> | ||
|
||
typedef uint8_t(*mapFn_t)(uint16_t, uint16_t, uint16_t); | ||
|
||
class Battery { | ||
public: | ||
/** | ||
* Creates an instance to monitor battery voltage and level. | ||
* Initialization parameters depend on battery type and configuration. | ||
* | ||
* @param minVoltage is the voltage, expressed in millivolts, corresponding to an empty battery | ||
* @param maxVoltage is the voltage, expressed in millivolts, corresponding to a full battery | ||
* @param sensePin is the analog pin used for sensing the battery voltage | ||
*/ | ||
Battery(uint16_t minVoltage, uint16_t maxVoltage, uint8_t sensePin); | ||
|
||
/** | ||
* Initializes the library by optionally setting additional parameters. | ||
* To obtain the best results use a calibrated reference using the VoltageReference library or equivalent. | ||
* | ||
* @param refVoltage is the board reference voltage, expressed in millivolts | ||
* @param dividerRatio is the multiplier used to obtain the real battery voltage | ||
* @param mapFunction is a pointer to the function used to map the battery voltage to the remaining capacity percentage (defaults to linear mapping) | ||
*/ | ||
void begin(uint16_t refVoltage, float dividerRatio, mapFn_t = 0); | ||
|
||
/** | ||
* Enables on-demand activation of the sensing circuit to limit battery consumption. | ||
* | ||
* @param activationPin is the pin which will be turned HIGH or LOW before starting the battery sensing | ||
* @param activationMode is the optional value to set on the activationPin to enable battery sensing, defaults to LOW | ||
* useful when using a resistor divider to save on battery consumption, but it can be changed to HIGH in case | ||
* you are using a P-CH MOSFET or a PNP BJT | ||
*/ | ||
void onDemand(uint8_t activationPin, uint8_t activationMode = LOW); | ||
|
||
/** | ||
* Activation pin value disabling the on-demand feature. | ||
*/ | ||
static const uint8_t ON_DEMAND_DISABLE = 0xFF; | ||
|
||
/** | ||
* Returns the current battery level as a number between 0 and 100, with 0 indicating an empty battery and 100 a | ||
* full battery. | ||
*/ | ||
uint8_t level(); | ||
uint8_t level(uint16_t voltage); | ||
|
||
/** | ||
* Returns the current battery voltage in millivolts. | ||
*/ | ||
uint16_t voltage(); | ||
|
||
private: | ||
uint16_t refVoltage; | ||
uint16_t minVoltage; | ||
uint16_t maxVoltage; | ||
float dividerRatio; | ||
uint8_t sensePin; | ||
uint8_t activationPin; | ||
uint8_t activationMode; | ||
mapFn_t mapFunction; | ||
}; | ||
|
||
// | ||
// 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); | ||
} | ||
|
||
|
||
|
||
|
||
#endif // BATTERY_H_ |
Oops, something went wrong.