You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

95 lines
4.0 KiB

#include <Arduino.h>
#include "settings.h"
#include "Log.h"
#include "Battery.h"
#include "Mqtt.h"
#include "Led.h"
#include "System.h"
constexpr uint16_t maxAnalogValue = 4095u; // Highest value given by analogRead(); don't change!
float warningLowVoltage = s_warningLowVoltage;
uint8_t voltageCheckInterval = s_voltageCheckInterval;
float voltageIndicatorLow = s_voltageIndicatorLow;
float voltageIndicatorHigh = s_voltageIndicatorHigh;
void Battery_Init() {
#ifdef MEASURE_BATTERY_VOLTAGE
// Get voltages from NVS for Neopixel
float vLowIndicator = gPrefsSettings.getFloat("vIndicatorLow", 999.99);
if (vLowIndicator <= 999) {
voltageIndicatorLow = vLowIndicator;
snprintf(Log_Buffer, Log_BufferLength, "%s: %.2f V", (char *) FPSTR(voltageIndicatorLowFromNVS), vLowIndicator);
Log_Println(Log_Buffer, LOGLEVEL_INFO);
} else { // preseed if not set
gPrefsSettings.putFloat("vIndicatorLow", voltageIndicatorLow);
}
float vHighIndicator = gPrefsSettings.getFloat("vIndicatorHigh", 999.99);
if (vHighIndicator <= 999) {
voltageIndicatorHigh = vHighIndicator;
snprintf(Log_Buffer, Log_BufferLength, "%s: %.2f V", (char *) FPSTR(voltageIndicatorHighFromNVS), vHighIndicator);
Log_Println(Log_Buffer, LOGLEVEL_INFO);
} else {
gPrefsSettings.putFloat("vIndicatorHigh", voltageIndicatorHigh);
}
float vLowWarning = gPrefsSettings.getFloat("wLowVoltage", 999.99);
if (vLowWarning <= 999) {
warningLowVoltage = vLowWarning;
snprintf(Log_Buffer, Log_BufferLength, "%s: %.2f V", (char *) FPSTR(warningLowVoltageFromNVS), vLowWarning);
Log_Println(Log_Buffer, LOGLEVEL_INFO);
} else {
gPrefsSettings.putFloat("wLowVoltage", warningLowVoltage);
}
uint32_t vInterval = gPrefsSettings.getUInt("vCheckIntv", 17777);
if (vInterval != 17777) {
voltageCheckInterval = vInterval;
snprintf(Log_Buffer, Log_BufferLength, "%s: %u Minuten", (char *) FPSTR(voltageCheckIntervalFromNVS), vInterval);
Log_Println(Log_Buffer, LOGLEVEL_INFO);
} else {
gPrefsSettings.putUInt("vCheckIntv", voltageCheckInterval);
}
#endif
}
// The average of several analog reads will be taken to reduce the noise (Note: One analog read takes ~10µs)
float Battery_GetVoltage(void) {
#ifdef MEASURE_BATTERY_VOLTAGE
float factor = 1 / ((float) rdiv2 / (rdiv2 + rdiv1));
float averagedAnalogValue = 0;
uint8_t i;
for (i = 0; i <= 19; i++) {
averagedAnalogValue += (float) analogRead(VOLTAGE_READ_PIN);
}
averagedAnalogValue /= 20.0;
return (averagedAnalogValue / maxAnalogValue) * referenceVoltage * factor + offsetVoltage;
#endif
}
// Measures voltage of a battery as per interval or after bootup (after allowing a few seconds to settle down)
void Battery_Cyclic(void) {
#ifdef MEASURE_BATTERY_VOLTAGE
static uint32_t lastVoltageCheckTimestamp = 0;
if ((millis() - lastVoltageCheckTimestamp >= voltageCheckInterval * 60000) || (!lastVoltageCheckTimestamp && millis() >= 10000)) {
float voltage = Battery_GetVoltage();
if (voltage <= warningLowVoltage) {
snprintf(Log_Buffer, Log_BufferLength, "%s: (%.2f V)", (char *) FPSTR(voltageTooLow), voltage);
Log_Println(Log_Buffer, LOGLEVEL_ERROR);
Led_Indicate(LedIndicatorType::VoltageWarning);
}
#ifdef MQTT_ENABLE
char vstr[6];
snprintf(vstr, 6, "%.2f", voltage);
publishMqtt((char *) FPSTR(topicBatteryVoltage), vstr, false);
#endif
snprintf(Log_Buffer, Log_BufferLength, "%s: %.2f V", (char *) FPSTR(currentVoltageMsg), voltage);
Log_Println(Log_Buffer, LOGLEVEL_INFO);
lastVoltageCheckTimestamp = millis();
}
#endif
}