Skip to content

Commit 2b486e8

Browse files
committed
Added basic Battery class for handling battery related stuff
* Use ADC idf version to read voltage * be prepared for handling differnt limits for Li-ION and LiFePo batteries * Prepared for very basic SoC calculations * NOTE: SoC calculation on voltage measurement alone is always vers inprecise * SoC can be simply calculated based on a predefined Lookup table * this is still TODO
1 parent f0c89f4 commit 2b486e8

File tree

4 files changed

+244
-1
lines changed

4 files changed

+244
-1
lines changed
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
/*
2+
* Created on Sun Apr 23 2023
3+
*
4+
* Project: International Elephant Project (Wildlife Conservation International)
5+
*
6+
* The MIT License (MIT)
7+
* Copyright (c) 2023 Fabian Lindner
8+
*
9+
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
10+
* and associated documentation files (the "Software"), to deal in the Software without restriction,
11+
* including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
12+
* and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
13+
* subject to the following conditions:
14+
*
15+
* The above copyright notice and this permission notice shall be included in all copies or substantial
16+
* portions of the Software.
17+
*
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
19+
* TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20+
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21+
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22+
*/
23+
24+
25+
#include <esp_log.h>
26+
#include <driver/adc.h>
27+
#include <esp_adc/adc_oneshot.h>
28+
#include "config.h"
29+
30+
#include "CPPANALOG/analogio.h"
31+
32+
#include "ElocSystem.hpp"
33+
#include "Battery.hpp"
34+
35+
static const char* TAG = "Battery";
36+
37+
//TODO: adjust these limits for Li-ION
38+
static const bat_limits_t C_LiION_LIMITS = {
39+
.Voff = 2.7,
40+
.Vlow = 3.18,
41+
.Vfull = 3.3
42+
};
43+
44+
static const bat_limits_t C_LiFePo_LIMITS = {
45+
.Voff = 2.7,
46+
.Vlow = 3.18,
47+
.Vfull = 3.3
48+
};
49+
50+
51+
Battery::Battery() :
52+
mChargingEnabled(true),
53+
mVoltageOffset(0.0), // TODO: read voltage offset from calibration info file (if present)
54+
mSys(ElocSystem::GetInstance()),
55+
mAdc(BAT_ADC),
56+
mVoltage(0.0),
57+
AVG_WINDOW(5) // TODO make this configureable
58+
{
59+
//TODO: Read from config file if battery charging should be enabled by default
60+
setChargingEnable(mChargingEnabled);
61+
62+
if (!mAdc.CheckCalFuse()) {
63+
ESP_LOGW(TAG, "ADC %d has been uncalibrated!", BAT_ADC);
64+
}
65+
}
66+
67+
Battery::~Battery()
68+
{
69+
}
70+
71+
72+
bat_limits_t Battery::getLimits()
73+
{
74+
if (mSys.hasIoExpander()) {
75+
if (mSys.getIoExpander().hasLiIonBattery()) {
76+
return C_LiION_LIMITS;
77+
}
78+
else {
79+
return C_LiFePo_LIMITS;
80+
}
81+
}
82+
return bat_limits_t();
83+
}
84+
85+
float Battery::getVoltage() {
86+
// disable charging first
87+
if (esp_err_t err = setChargingEnable(false)) {
88+
ESP_LOGI(TAG, "Failed to enable charging %s", esp_err_to_name(err));
89+
}
90+
mVoltage = 0.0;
91+
float accum=0.0;
92+
float avg;
93+
for (int i=0; i<AVG_WINDOW;i++) {
94+
if (mAdc.CheckCalFuse()) {
95+
accum+= static_cast<float>(mAdc.GetVoltage())/1000.0; // CppAdc1::GetVoltage returns mV
96+
}
97+
else {
98+
accum+= mAdc.GetRaw();
99+
}
100+
}
101+
102+
mVoltage=accum/5.0;
103+
104+
105+
if (mChargingEnabled) {
106+
if (esp_err_t err = setChargingEnable(mChargingEnabled))
107+
ESP_LOGI(TAG, "Failed to enable charging %s", esp_err_to_name(err));
108+
}
109+
return mVoltage;
110+
}
111+
112+
float Battery::getSoC()
113+
{
114+
//TODO: Create a table for Voltage - SoC translation per battery type
115+
getVoltage();
116+
float soc = 0.0;
117+
if (mSys.hasIoExpander() && mSys.getIoExpander().hasLiIonBattery()) {
118+
if (mVoltage >= 4.2) {
119+
soc = 100;
120+
}
121+
}
122+
else {
123+
if (mVoltage >= 3.4) {
124+
soc = 100;
125+
}
126+
}
127+
return 0.0f;
128+
}
129+
bool Battery::isLow()
130+
{
131+
//TODO: trigger a voltage measurement if previous measurement is too old
132+
if (mVoltage >= getLimits().Vfull) {
133+
return true;
134+
}
135+
return false;
136+
}
137+
bool Battery::isFull()
138+
{
139+
//TODO: trigger a voltage measurement if previous measurement is too old
140+
if (mVoltage >= getLimits().Vfull) {
141+
return true;
142+
}
143+
return false;
144+
}
145+
bool Battery::isEmpty()
146+
{
147+
return false;
148+
}
149+
esp_err_t Battery::setChargingEnable(bool enable)
150+
{
151+
if (mSys.hasIoExpander()) {
152+
if (esp_err_t err = mSys.getIoExpander().chargeBattery(enable)) {
153+
ESP_LOGI(TAG, "Failed to %s charging %s", enable ? "enable" : "disable", esp_err_to_name(err));
154+
return err;
155+
}
156+
}
157+
return ESP_OK;
158+
}
159+
160+
esp_err_t Battery::setDefaultChargeEn(bool enable)
161+
{
162+
mChargingEnabled = enable;
163+
return setChargingEnable(enable);
164+
}
165+
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*
2+
* Created on Sun Apr 23 2023
3+
*
4+
* Project: International Elephant Project (Wildlife Conservation International)
5+
*
6+
* The MIT License (MIT)
7+
* Copyright (c) 2023 Fabian Lindner
8+
*
9+
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
10+
* and associated documentation files (the "Software"), to deal in the Software without restriction,
11+
* including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
12+
* and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
13+
* subject to the following conditions:
14+
*
15+
* The above copyright notice and this permission notice shall be included in all copies or substantial
16+
* portions of the Software.
17+
*
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
19+
* TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20+
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21+
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22+
*/
23+
24+
#ifndef BATTERY_HPP_
25+
#define BATTERY_HPP_
26+
27+
#include "CPPANALOG/analogio.h"
28+
#include "ElocSystem.hpp"
29+
#include "esp_err.h"
30+
31+
typedef struct {
32+
// use LiFePo defaults: just in case bat_limits_t is used uninitialized
33+
float Voff = 2.7;
34+
float Vlow = 3.18;
35+
float Vfull = 3.3;
36+
}bat_limits_t;
37+
38+
class Battery
39+
{
40+
private:
41+
bool mChargingEnabled;
42+
float mVoltageOffset;
43+
ElocSystem& mSys;
44+
CPPANALOG::CppAdc1 mAdc;
45+
float mVoltage;
46+
47+
const uint32_t AVG_WINDOW;
48+
49+
virtual esp_err_t setChargingEnable(bool enable);
50+
bat_limits_t getLimits();
51+
Battery();
52+
esp_err_t init();
53+
public:
54+
virtual ~Battery();
55+
static Battery& GetInstance() {
56+
static Battery battery;
57+
return battery;
58+
}
59+
60+
virtual float getVoltage();
61+
virtual float getSoC();
62+
63+
bool isLow();
64+
bool isFull();
65+
bool isEmpty();
66+
67+
virtual esp_err_t setDefaultChargeEn(bool enable);
68+
bool isBatteryPresent();
69+
};
70+
71+
72+
#endif // BATTERY_HPP_

eloc610LowPowerPartition/src/config.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include <freertos/FreeRTOS.h>
22
#include <driver/i2s.h>
3+
#include <driver/adc.h>
34
#include "lis3dh_types.h"
45

56

@@ -40,6 +41,7 @@
4041
#define GPIO_BUTTON GPIO_NUM_0
4142
#define OTHER_GPIO_BUTTON GPIO_NUM_0
4243
#define VOLTAGE_PIN GPIO_NUM_34
44+
#define BAT_ADC ADC1_CHANNEL_6
4345

4446
/** Interrupt definitions
4547
* lower levels are lower priorities

eloc610LowPowerPartition/src/main.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include "version.h"
3434

3535
#include "lis3dh.h"
36+
#include "Battery.hpp"
3637
#include "ElocSystem.hpp"
3738
#include "ManualWakeup.hpp"
3839

@@ -674,9 +675,12 @@ I2SSampler *input;
674675
gpio_set_level(STATUS_LED, 0);
675676
gpio_set_level(BATTERY_LED, 0);
676677

677-
ESP_LOGI(TAG, "Setting up System...");
678+
ESP_LOGI(TAG, "Setting up HW System...");
678679
ElocSystem::GetInstance();
679680

681+
ESP_LOGI(TAG, "Setting up Battery...");
682+
Battery::GetInstance();
683+
680684

681685
//delay(30000);
682686

0 commit comments

Comments
 (0)