|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
| 2 | +#pragma once |
| 3 | +#include <Arduino.h> |
| 4 | +#include <frozen/string.h> |
| 5 | +#include <TaskSchedulerDeclarations.h> |
| 6 | +#include "Statistic.h" |
| 7 | + |
| 8 | + |
| 9 | +class BatteryGuardClass { |
| 10 | + public: |
| 11 | + BatteryGuardClass() = default; |
| 12 | + ~BatteryGuardClass() = default; |
| 13 | + BatteryGuardClass(const BatteryGuardClass&) = delete; |
| 14 | + BatteryGuardClass& operator=(const BatteryGuardClass&) = delete; |
| 15 | + BatteryGuardClass(BatteryGuardClass&&) = delete; |
| 16 | + BatteryGuardClass& operator=(BatteryGuardClass&&) = delete; |
| 17 | + |
| 18 | + void init(Scheduler& scheduler); |
| 19 | + void updateSettings(void); |
| 20 | + void updateBatteryValues(float const nowVoltage, float const nowCurrent, uint32_t const millisStamp); |
| 21 | + std::optional<float> getOpenCircuitVoltage(void); |
| 22 | + std::optional<float> getInternalResistance(void) const; |
| 23 | + |
| 24 | + private: |
| 25 | + void loop(void); |
| 26 | + void slowLoop(void); |
| 27 | + |
| 28 | + Task _slowLoopTask; // Task |
| 29 | + Task _fastLoopTask; // Task |
| 30 | + bool _verboseLogging = false; // Logging On/Off |
| 31 | + bool _verboseReport = false; // Report On/Off |
| 32 | + bool _useBatteryGuard = false; // "Battery guard" On/Off |
| 33 | + bool _useLowVoltageLimiter = false; // "Low voltage power limiter" On/Off |
| 34 | + bool _useRechargeTheBattery = false; // "Periodically recharge the battery" On/Off |
| 35 | + uint32_t _lastUpdate = 0; // last update time stamp |
| 36 | + |
| 37 | + |
| 38 | + // used to calculate the "Open circuit voltage" |
| 39 | + enum class Text : uint8_t { Q_NODATA, Q_EXCELLENT, Q_GOOD, Q_BAD, T_HEAD }; |
| 40 | + |
| 41 | + bool calculateOpenCircuitVoltage(float const nowVoltage, float const nowCurrent); |
| 42 | + bool isDataValid() { return (millis() - _battMillis) < 30*1000; } |
| 43 | + void printOpenCircuitVoltageReport(void); |
| 44 | + bool isResolutionOK(void) const; |
| 45 | + frozen::string const& getText(Text tNr); |
| 46 | + |
| 47 | + float _battVoltage = 0.0f; // actual battery voltage [V] |
| 48 | + float _battCurrent = 0.0f; // actual battery current [A] |
| 49 | + uint32_t _battMillis = 0; // measurement time stamp [millis()] |
| 50 | + WeightedAVG<float> _battVoltageAVG {5}; // average battery voltage [V] |
| 51 | + WeightedAVG<float> _openCircuitVoltageAVG {5}; // average battery open circuit voltage [V] |
| 52 | + float _determinedResolutionV = 0; // determined resolution from the battery voltage [V] |
| 53 | + float _determinedResolutionI = 0; // determined resolution from the battery current [V] |
| 54 | + WeightedAVG<uint32_t> _determinedPeriod {20}; // determined measurement period [ms] |
| 55 | + size_t _notAvailableCounter = 0; // open circuit voltage not available counter |
| 56 | + |
| 57 | + |
| 58 | + // used to calculate the "Battery internal resistance" |
| 59 | + bool calculateInternalResistance(float const nowVoltage, float const nowCurrent); |
| 60 | + |
| 61 | + float _resistanceFromConfig = 0.0f; // configured battery resistance [Ohm] |
| 62 | + WeightedAVG<float> _resistanceFromCalcAVG {10}; // calculated battery resistance [Ohm] |
| 63 | + bool _firstOfTwoAvailable = false; // true after to got the first of two values |
| 64 | + bool _minMaxAvailable = false; // true if minimum and maximum values are available |
| 65 | + bool _triggerEvent = false; // true if we have sufficient current change |
| 66 | + std::pair<float,float> _pFirstVolt = {0.0f,0.0f}; // first of two voltages and related current [V,A] |
| 67 | + std::pair<float,float> _pMaxVolt = {0.0f,0.0f}; // maximum voltage and related current [V,A] |
| 68 | + std::pair<float,float> _pMinVolt = {0.0f,0.0f}; // minimum voltage and related current [V,A] |
| 69 | + uint32_t _lastTriggerMillis = 0; // last millis from the first min/max values [millis()] |
| 70 | + |
| 71 | +}; |
| 72 | + |
| 73 | +extern BatteryGuardClass BatteryGuard; |
0 commit comments