136 lines
4.5 KiB
C++
136 lines
4.5 KiB
C++
/**
|
|
* @file battery.h
|
|
* @author Alexander Klein (alex@kleiax.de)
|
|
* @brief Contains a class for battery monitoring
|
|
* @version 0.1
|
|
* @date 2022-02-05
|
|
*
|
|
* @copyright Copyright (c) 2022
|
|
*
|
|
*/
|
|
|
|
#ifndef BATTERY_H
|
|
#define BATTERY_H
|
|
|
|
#include <stdint.h>
|
|
#include <iostream>
|
|
#include <math.h>
|
|
#include <Arduino.h>
|
|
|
|
/**
|
|
* @brief A class for battery monitoring
|
|
*
|
|
* This class reads the voltage from an analog pin to calculate the
|
|
* charge level of a 3 Cell Li-Poly battery pack. The battery pack have
|
|
* to be after a voltage diveder, so that maximum voltage for the
|
|
* microcontroller is 3.3 Volt.
|
|
*/
|
|
class Battery {
|
|
public:
|
|
/**
|
|
* @brief Construct a new Battery object
|
|
*
|
|
* The voltage devider have to be calculated, so that the input
|
|
* voltage from 3.3 Volt is never exceeded. It is assumed that
|
|
* the microcontroller is connected to the second resistor.
|
|
*
|
|
* @param pin The analog to read from.
|
|
* @param r1 First resistor of the voltage devider.
|
|
* @param r2 Second resistor of the voltage devider.
|
|
*/
|
|
Battery(uint8_t pin, uint32_t r1, uint32_t r2);
|
|
Battery(uint8_t pin);
|
|
|
|
/**
|
|
* @brief Read new values if the delay is reached.
|
|
*
|
|
* @return bool true if new values are calculated
|
|
*/
|
|
bool loop();
|
|
|
|
/**
|
|
* @brief Set the delay to wait befor new values are read
|
|
*
|
|
* @param delay in milliseconds
|
|
*/
|
|
void setDelay(uint16_t delay) {this->delay = delay; }
|
|
|
|
/**
|
|
* @brief Get the delay to wait befor new values are read
|
|
*
|
|
* @return uint16_t delay in milliseconds
|
|
*/
|
|
uint16_t getDelay() {return this->delay; }
|
|
|
|
/**
|
|
* @brief Get the battery voltage
|
|
*
|
|
* @return double in Volt
|
|
*/
|
|
double getBatteryVoltage();
|
|
|
|
/**
|
|
* @brief Get the charge level of the battery
|
|
*
|
|
* @return uint8_t charge level in percent
|
|
*/
|
|
uint8_t getBatteryPercent() {return this->batteryPercent;}
|
|
|
|
/**
|
|
* @brief Checks if the battery is low.
|
|
*
|
|
* The function will also return false if the battery voltage is
|
|
* absurd low. This is for the case that the uController is powered
|
|
* by usb and no battery is connected.
|
|
*
|
|
* @param voltage the limit the battery have to
|
|
* @return true if the battery is low
|
|
* @return false if the battery is high
|
|
*/
|
|
bool isBatteryLow(double voltage);
|
|
|
|
private:
|
|
double calculateInputVoltage();
|
|
void calculateBatteryVoltage();
|
|
void calculateBatteryPercent();
|
|
void readAdcToBuf();
|
|
void initBuffer();
|
|
uint16_t getBufAvg();
|
|
|
|
static const uint8_t bufferSize = 30;
|
|
|
|
uint8_t absurdLowVoltage = 5;
|
|
uint8_t pin;
|
|
uint8_t batteryPercent = 0;
|
|
uint8_t batteryLowPercent = 10;
|
|
uint8_t bufferPos = 0;
|
|
uint8_t delay = 100;
|
|
uint8_t calulationDelayMultiplier = 10;
|
|
uint8_t loopCounter = 0;
|
|
uint16_t adcBuffer[bufferSize];
|
|
uint32_t r1 = 0;
|
|
uint32_t r2 = 0;
|
|
uint64_t lastMillis = 0;
|
|
double batteryVoltage = 0;
|
|
|
|
const float capacityVoltages[21] = {9.82, 10.83, 11.06, 11.12, // 0 5 10 15
|
|
11.18, 11.24, 11.3, 11.36, // 20 25 30 35
|
|
11.39, 11.45, 11.51, 11.56, // 40 45 50 55
|
|
11.62, 11.74, 11.86, 11.95, // 60 65 70 75
|
|
12.07, 12.25, 12.33, 12.45, // 80 85 90 95
|
|
12.6 };
|
|
|
|
const uint8_t rawAdcVoltagesCount = 60;
|
|
const double startVoltage = 7;
|
|
const double stepVoltage = 0.1;
|
|
const uint16_t rawAdcVoltages[60] = // from 7.0V to 12.9V in 0.1V steps
|
|
{1820, 1851, 1880, 1910, 1937, 1967, 1992, 2020, 2048, 2080,
|
|
2109, 2136, 2163, 2189, 2218, 2244, 2273, 2302, 2334, 2363,
|
|
2391, 2415, 2441, 2471, 2499, 2531, 2557, 2587, 2617, 2646,
|
|
2674, 2699, 2730, 2761, 2791, 2816, 2843, 2872, 2900, 2930,
|
|
2958, 2991, 3017, 3049, 3080, 3115, 3144, 3178, 3208, 3242,
|
|
3276, 3313, 3346, 3389, 3433, 3470, 3509, 3548, 3590, 3636};
|
|
};
|
|
|
|
#endif // BATTERY_H
|