rasProject_01 / weSweetHome  R. 146 2026-09-26
process control       /     RasPi software         by   weinert-automation
Loading...
Searching...
No Matches
weBatt.h File Reference

Common types and values for buffer battery handling. More...

#include "basicTyCo.h"

Macros

#define BAT_BAL_STRT_PWM
 Start value for ballast loading (LiFePo4).
#define BAT_KEEP_PWM
 Battery keep alive PWM setting (LiFePo4).
#define BAT_LDBAL_STR_PWM
 PWM start value for ballast loading.
#define BAT_LDBAL_TIM
 Maximum time for battery loading as ballast.
#define BAT_LDMX_PWM
 Battery maximum load PWM setting (LiFePo4).
#define BAT_LOAD_PWM
 Value for permanent loading.
#define BAT_LOD_END_MAX_POW
 Battery controlled load end phase maximum power.
#define BAT_LOD_END_MIN_POW
 Battery controlled load end phase minimum power.
#define BAT_LOD_NRM_MAX_POW
 Battery controlled load maximum power.
#define BAT_LOD_NRM_MIN_POW
 Battery controlled load maximum power.
#define BAT_NOLD_PWM
 Battery no load no keep setting (LiFePo4).
#define BAT_SOC_UP_LIM_LOAD
 Upper SoC (state of charge float) limit to stop loading.
#define BAT_TNUM
 Battery type number.
#define BAT_TYPE
 Battery type.
#define BATkeepInhByCmd
 Inhibit battery keep loading after battery Off command.
#define BATkeepInhContLoad
 Inhibit battery keep loading after controlled loading.
#define BATkeepInhUnload
 Inhibit battery keep loading after unloading.
#define BATmaxUNLODtime
 Upper time limit to stop discharging (LiFePo4).
#define BATSOC_LO_LINT_UNLD
 SoC (state of charge integer) limit to start unload.
#define BATSOC_LO_STP_UNLD
 Lower SoC (state of charge integer) limit to stop discharging.
#define BATVOLT_LO_LIM_UNLD
 Voltage limit to start unload.
#define BATVOLT_LO_STP_UNLD
 Lower voltage limit to stop discharging.
#define BATVOLT_UP_LIM_LOAD
 Upper voltage limit to stop loading.
#define currSOC
 The actual state of charge (SoC).
#define ESP_U_CORR
 Correction factor for ESP battery voltmeter.
#define PDEL_MINP_UNL
 Minimum power from public electricity supplier to start discharging.
#define PDEL_STOP_UNL
 Minimum power from public electricity to stop discharging.
#define PINV_ON_CRIT
 Minimum discharge power to consider discharge inverter on.
#define SOCinvalid
 State of charge (SoC) is invalid.
#define SOCvalid
 State of charge (SoC) is valid.

Functions

unsigned int unldAllowed ()
 Is battery unload allowed by battery state.

Variables

uint16_t hundredsV
 The battery voltage in 0.01V units.
uint16_t tenPromSoC
 The battery state of charge or SOC in 0.01% units.

Detailed Description

Common types and values for buffer battery handling.

Copyright (c) 2018 2025 2026 Albrecht Weinert
weinert-automation.de a-weinert.de
/ / /\
/ /___ / \ |
\ /____\ /____\ | _|__
\ /\ / \ / \| |
\/ \/ \__/ \__/|_

Revision history

Rev. 148 8.10.2026
Rev. 159 04.07.2018 : new
Rev. 200 16.04.2019 : battery keep inhibit until low stress
Rev. 223 24.04.2020 : comment clarifications, voltage adjustments
Rev. 259 04.08.2022 : battery changed to ECO-WORTHY 12.8V 100Ah LiFePO4 accu
Rev. 268 15.10.2024 : ESP_U_CORR introduced to correct ESP voltmeter readings
Rev. 75 25.02.2025 : lead acid batteries (type 1) cancelled, search archive
Rev. 88 05.07.2025 : battery unload limit Ubat++, Psuppl++, etc
Rev. 89 21.07.2025 : typos, battery unload limit 11.9V,
26.07.2025 : ESP_U_CORR for 13,4 <-- 13,26 discrepancy
Rev. 91 10.08.2025 : values for new load module 0..24V 20A
Rev. 92 26.08.2025 : load unload values and SFCs
Rev. 94 24.09.2025 : charge module settings changed, hence pwm settings &c.
Rev. 96 12.10.2025 : BATVOLT_LO_STP_UNLD 12.49
Rev. 104 30.11.2025 : 3rd battery, has Bluetooth (not used), values adapted
Rev. 110 04.01.2026 : battery load and keep changed
Rev. 113 31.01.2026 : ESP_U_CORR corr for ESP * old 13,38 <-- 13,23 fluke
Rev. 114 2-8.2.2026 : tighter values: less dis/charge, BATVOLT_LO_LIM_UNLD400
Rev. 126+ 21+.07.26 : ESP_U_CORR corr ECOworthyBT, BATVOLT_LO_STP_UNLD 12.00
Rev. 128 16.07.2026 : BATVOLT_LO_STP_UNLD 12,82 to raise end SOC above 12%
Rev. 131 06.08.2026 : tenPromSoC
Rev. 136 15.08.2026 : BATVOLT_LO_STP_UNLD 12.92
Rev. 144 01.09.2026 : BAT_SOC_UP_LIM_LOAD 85, unldAllowed()
Rev. 148 08.10.2026 : BATSOC_LO_STP_UNLD from 28 to 33
#define BATVOLT_LO_STP_UNLD
Lower voltage limit to stop discharging.
Definition weBatt.h:360
#define BAT_SOC_UP_LIM_LOAD
Upper SoC (state of charge float) limit to stop loading.
Definition weBatt.h:447
#define BATSOC_LO_STP_UNLD
Lower SoC (state of charge integer) limit to stop discharging.
Definition weBatt.h:321
#define ESP_U_CORR
Correction factor for ESP battery voltmeter.
Definition weBatt.h:191
unsigned int unldAllowed()
Is battery unload allowed by battery state.
Definition sweetHome2.c:888
uint16_t tenPromSoC
The battery state of charge or SOC in 0.01% units.
Definition sweetHome2.c:313

In the smart home buffer batteries are used and managed since 2019.

Until August 2022, we had an array of parallel 12V (6 cell) lead acid batteries. The used batteries were donated to the project as becoming unfit for their former use in glider starting winches. Nominally, more than 200Ah should allow buffering 1 kWh. The usable capacity was far below, due to the batteries age and principal limits of lead acid accumulators as buffers.

Hence, all lead acid batteries were replaced by one 12,8V 100Ah ECO-WORTHY LiFePo4 accumulator. In consequence, all loading, keeping and unloading constants and procedures had to be changed. After good experiences with the type and reduction of prices, two more were added in February and November

  1. The three parallel 12V accumulators have an effective buffer capacity of 2.2 kWh with plenty reserve in both directions.

From start of the project battery voltage is measured at the battery clamps by a special ESP 32 based MQTT device (see also files mqttHome.h and sweetHome2.c). It uses WLAN and has a 12V supply and just "lives" directly on the batteries. Besides an own fuse it needs no extra hardware.

The idle voltage accuracy was more than sufficient, but the battery's (and fuse holder's) clamp voltage has significant variations due to current (range > +/-30A). Additionally there are delays from current to voltage changes. Getting a reliable value for SoC (state of charge) by idle Ubat is hardly feasible as 1% delta SoC is about 20mV delta U.

The battery management and protection system, of course, monitors internally every cell voltage and "knows" voltages, SoC and more accurately. Additionally, it will switch off loading or unloading in cases of over-current, over-voltage and under-voltage. Fortunately, the battery last purchased publishes all relevant and accurate internal values as well as the state of the load and unload protection switches by Bluetooth.
In August 2026 we made an M5Stamp ESP32S3 get those values and deliver them to the same MQTT server in a compatible (payload) format. If available the "Bluetooth" voltage and SoC take precedence over the ADU voltage and the SoC(U) look-up.

Macro Definition Documentation

◆ BAT_TNUM

#define BAT_TNUM

Battery type number.

The battery type as integer number corresponding to the text, see BAT_TYPE.
LiFePo4, 12.8V, has number 2 and LeadAcid, 12V, is type 1.
LeadAcid batteries were dumped as not fit for PV buffering. Hence, type 1 isn't implemented any more.

◆ PDEL_MINP_UNL

#define PDEL_MINP_UNL

Minimum power from public electricity supplier to start discharging.

If public power consumption is below this limit battery unloading shall not be started respectively inhibited. The current value is 300 W.
Rationale: Battery unload power is above 200 W and has no fine grained control. When exceeding the consumption unloading would be turned off. We won't use battery power to heat domestic hot water.
Used in: batUnloadStatChg

◆ PINV_ON_CRIT

#define PINV_ON_CRIT

Minimum discharge power to consider discharge inverter on.

As we use one DC input of a solar inverter (and a step up converter) for discharging the AC power flow to may start with up to 10 minutes delay. The measured discharge power > PINV_ON_CRIT is used as criterion for having started.

The delay is a special German feature: When a sleeping inverter is woken up by seeing DC power it must make long AV voltage and frequency considerations according to VDE-AR-N 4105 or similar standards. When changing the same inverter's setting from Germany to Poland (e.g.) the AC power delivery would start immediately. Consider the electric energy gain at every sunrise or tearing of clouds.

The current value is 53W (could be up to 200W).
Used in: batUnloadStatChg

◆ PDEL_STOP_UNL

#define PDEL_STOP_UNL

Minimum power from public electricity to stop discharging.

We inhibit all power delivery to the public grid. Especially we do not discharge the batteries when not consuming all battery power. As we can't control discharge power and re-starting discharge takes long (thanks to VDE-AR-N 4105, a German "unique selling point") we allow very low negative power hardly / not fully measured by Ferraris counters biased to start on minimal positive values.
Used in: batUnloadStatChg

See also
PDEL_MINP_UNL

◆ ESP_U_CORR

#define ESP_U_CORR

Correction factor for ESP battery voltmeter.

Due to tolerances the value delivered via MQTT is a bit too low. This factor is a good average correction and may be put into the ESP voltmeter code some day.
On the other hand changing this factor on Pi C Eclipse ... environment is loads more easy and less (hardware) error prone than handling an ESP.

◆ BAT_TYPE

#define BAT_TYPE

Battery type.

The battery type as text, like LiFePo4 or LeadAcid.
As C's macro handling is too stupid to compare strings we have a co-responding integer type number BAT_TNUM 2.

◆ BATmaxUNLODtime

#define BATmaxUNLODtime

Upper time limit to stop discharging (LiFePo4).

The normal discharge end condition in the unload SFC would be state of charge (SoC BATSOC_LO_STP_UNLD) battery or voltage (BATVOLT_LO_STP_UNLD). And there is this time limit of currently 10h.

With lead acid accumulators, it was much lower. Currently we have 3 * 100 aH * 12V LiFePo4 batteries. For currently 300 W discharging from 90 to 10% (SoC) 9h. 10h should be quite save if other end criteria fail.

Via Bluetooth one of the batteries gives precise SoC values an other experiments show the behaviour of the three parallel batteries being the same. Additionally all have a battery management and protection system with switches to turn off over and under charging. Hence, this end time feature

  • the live belt necessary for lead acid - is not critical nor really needed any more.
    Used in: batUnloadStatChg

◆ BATkeepInhUnload

#define BATkeepInhUnload

Inhibit battery keep loading after unloading.

Start battery keeping immediately after unloading would most probably be unnecessary charging as we are on the discharge curve. As we have ample reserve we may consider the base load 10..20W as mildly unloading. The current value is 3 hours.

Hint: The "inhibit keep timer" starts battery keeping (startBatteryKeep) when running out.

See also
batUnloadStatChg startBatteryKeep

◆ BATkeepInhContLoad

#define BATkeepInhContLoad

Inhibit battery keep loading after controlled loading.

The current value is 30 minutes.
Used in: batCntLodStatChg

See also
BATkeepInhUnload BATkeepInhByCmd batKeepInh

◆ BATkeepInhByCmd

#define BATkeepInhByCmd

Inhibit battery keep loading after battery Off command.

The current value is 10 minutes from now. If the inhibit timer is running already its end time will eventually be prolonged but not shortened.
Used in: stopBatteryOps

◆ BATVOLT_LO_LIM_UNLD

#define BATVOLT_LO_LIM_UNLD

Voltage limit to start unload.

This is the minimal voltage to allow starting an unload sequence.
Current value 13.120 V.
Used in: batUnloadStatChg and before starting unload in timers befRiseTimChg, sunsetTimChg and duskTimChg

See also
BATSOC_LO_LINT_UNLD BATSOC_LO_STP_UNLD BATVOLT_LO_STP_UNLD

◆ BATSOC_LO_LINT_UNLD

#define BATSOC_LO_LINT_UNLD

SoC (state of charge integer) limit to start unload.

This is the minimal SoC to allow starting an unload sequence.
Current value 34%.
Used in: batUnloadStatChg and before starting unload in timers befRiseTimChg, sunsetTimChg and duskTimChg

See also
BATSOC_LO_STP_UNLD BATVOLT_LO_STP_UNLD

◆ BATSOC_LO_STP_UNLD

#define BATSOC_LO_STP_UNLD

Lower SoC (state of charge integer) limit to stop discharging.

This is the minimal SoC to stop a running unload (SFC) for providing buffer capacity needed.

This is a critical value. Choosing a value too high reduces the usable buffer capacity (the battery's purpose in life). A value too low endangers the battery respectively if needed a minimal DC power reserve.

To allow for permanent loads without being forced to load within the next 24 hours we intend to stop in the range 30..20%.
The current value is 33%.
Note: 30% seemed too low after consecutive dark days. To avoid loading from public grid higher values seem indicated, best conditionally. Conditions may be past sunshine, weather forecast (no reliable dervice free of charge) or just time of the year.

For the Web interface and this limit ::valFilVal.by[11] is used as unsigned integer in the range of 0..100%; it is set to 120 (>100) to indicate that no valid ("young") value is available. In the case of invalid SoC only the voltage and its limits BATVOLT_LO_STP_UNLD and :: BATVOLT_LO_LIM_UNLD are used.

Used in: batCntBalStatChg batUnloadStatChg

See also
BATSOC_LO_LINT_UNLD BATVOLT_LO_LIM_UNLD BAT_KEEP_PWM BAT_SOC_UP_LIM_LOAD

◆ SOCvalid

#define SOCvalid

State of charge (SoC) is valid.

See also
SOCinvalid currSOC

◆ SOCinvalid

#define SOCinvalid

State of charge (SoC) is invalid.

See also
SOCvalid currSOC

◆ currSOC

#define currSOC

◆ BATVOLT_LO_STP_UNLD

#define BATVOLT_LO_STP_UNLD

Lower voltage limit to stop discharging.

This is the minimal voltage, measured under 5..10% cap unload, to stop a running unload sequence for providing buffer capacity needed.

This is a critical value. Choosing a value too high reduces the usable buffer capacity (the battery's purpose in life). A value too low endangers the battery.

To allow for permanent loads without being forced to load within the next 24 hours we intend to stop in the range 30..20%.
The current value is 12.00V under discharging load which then quickly recovers to our aim 12.31V (~10% on "book's" idle curve).

Used in: batCntBalStatChg batUnloadStatChg

See also
BATVOLT_LO_LIM_UNLD BAT_KEEP_PWM

◆ BAT_LDBAL_TIM

#define BAT_LDBAL_TIM

Maximum time for battery loading as ballast.

This time limit is the last resort to stop overloading as ballast for surplus power. The current value is 13 hours.
This feature is not necessary as the LiPoFe batteries protect themselves against over charging and the current loading module max. voltage of 14.75V (+ 0.4V for the Schottky diodes 15.15V) is within the limits.

Used in: batCntBalStatChg

See also
loadModUlookup

◆ BAT_LDBAL_STR_PWM

#define BAT_LDBAL_STR_PWM

PWM start value for ballast loading.

The current value is 135 (pwm = 13.88V) to have a quick start.

Used in: batCntBalStatChg

See also
loadModUlookup

◆ BAT_NOLD_PWM

#define BAT_NOLD_PWM

Battery no load no keep setting (LiFePo4).

This is the PWM setting for neither charging nor keeping. Until August 2024 it was 0 for the array of old lead acid starter batteries.

"LiFePO4 battery cells have a maximum discharge depth of 98% to 100%. This is longer than any other battery technology currently in the market. This means that you can safely discharge these batteries to their full capacity. However, most manufacturers recommend still using a 80% depth of discharge for these batteries to prolong their lifespan. Even if you occasionally use 100% of the battery capacity, the battery will not get harmed." cited from [https://ecotreelithium.co.uk/news/lifepo4-battery-depth-of-discharge/]

For neither keeping or loading we permanently back the battery with 12.5V (+0.4V on no current) to keep about 10%. The relation between BATVOLT_LO_STP_UNLD and BAT_NOLD_PWM shall not lead to start keeping immediately after unloading. Current value 37.

Used in: switchBatToStepUp changeBatLoadPWM

See also
BATVOLT_LO_STP_UNLD loadModUlookup batUnloadStatChg batCntBalStatChg batCntLodStatChg

◆ BATVOLT_UP_LIM_LOAD

#define BATVOLT_UP_LIM_LOAD

Upper voltage limit to stop loading.

The battery loading SFCs would stop when this voltage is reached.
Full loading would require 14.6 V and for safety reasons one should be more below, perhaps. 14.88V is over-charge protection and 14.4V is the cell equalising start voltage. On the other hand EcoWorth's LiFePo4 12V 100Ah has a built in battery management system (BSM), which would cut of at over-voltage.

See also
BAT_LDMX_PWM BAT_SOC_UP_LIM_LOAD

◆ BAT_SOC_UP_LIM_LOAD

#define BAT_SOC_UP_LIM_LOAD

Upper SoC (state of charge float) limit to stop loading.

The battery loading SFCs would stop when state of charge (SoC) by Bluetooth for one of the batteries is valid and if this upper limit reached. For the Web interface ::valFilVal.by[11] (or currSOC) is used as unsigned integer in the range of 0..100; it is set to 120% (>100) to indicate that no valid (not too old) value is available.

See also
tenPromSoC valFilVal BATVOLT_UP_LIM_LOAD currSOC SOCvalid BATSOC_LO_STP_UNLD

◆ BAT_KEEP_PWM

#define BAT_KEEP_PWM

Battery keep alive PWM setting (LiFePo4).

This is the PWM setting for the battery load module for permanently keeping the battery at live by preventing self discharge and by feeding the (low) permanent loads. The value is 45.

See also
loadModUlookup

◆ BAT_LDMX_PWM

#define BAT_LDMX_PWM

Battery maximum load PWM setting (LiFePo4).

N.b.: The value 14.6V is the value for full loading. Without load current the voltage will rise by the 0.4V drop of the (parallel) Schottky diodes. Hence monitoring BATVOLT_UP_LIM_LOAD and/or BAT_SOC_UP_LIM_LOAD is essential.
Current value 235 (= 14.6V).

◆ BAT_BAL_STRT_PWM

#define BAT_BAL_STRT_PWM

Start value for ballast loading (LiFePo4).

The value is 81 (= 13.37V).

◆ BAT_LOAD_PWM

#define BAT_LOAD_PWM

Value for permanent loading.

The value is 48.

See also
BAT_BAL_STRT_PWM BAT_LDBAL_STR_PWM BAT_NOLD_PWM BAT_KEEP_PWM BAT_LDMX_PWM

◆ BAT_LOD_NRM_MAX_POW

#define BAT_LOD_NRM_MAX_POW

Battery controlled load maximum power.

For controlled (resp. ordered unconditional) battery charging this value is the maximum power. If higher the output of the charging module will be reduced.
This condition can be checked when an actual charging power measurement is available. As water heating and battery charging use the same power meter heating would spoil the value; see batLoadPowValid.

The current value is 144.4 W.

See also
BAT_LOD_NRM_MIN_POW BAT_LOD_END_MAX_POW BAT_LOD_END_MIN_POW

◆ BAT_LOD_NRM_MIN_POW

#define BAT_LOD_NRM_MIN_POW

Battery controlled load maximum power.

For controlled (resp. ordered unconditional) battery charging this value is the minimum power; see BAT_LOD_NRM_MAX_POW.
The current value is 84.4 W.

◆ BAT_LOD_END_MAX_POW

#define BAT_LOD_END_MAX_POW

Battery controlled load end phase maximum power.

When the end criteria for controlled load are reached a low charging power end or keep fresh phase is entered.
Note: This feature is inherited from the quite complex handling of lead acid accumulator and may be removed.

The current value is 68.4 W.

See also
BAT_LOD_NRM_MAX_POW BAT_LOD_END_MIN_POW

◆ BAT_LOD_END_MIN_POW

#define BAT_LOD_END_MIN_POW

Battery controlled load end phase minimum power.

The current value is 31.4 W.

See also
BAT_LOD_END_MAX_POW

Function Documentation

◆ unldAllowed()

unsigned int unldAllowed ( )

Is battery unload allowed by battery state.

If state of charge or battery voltage prohibit discharging 0 (FALSE) will be returned.

Returns
0: not allowed; 1: allowed by SOC; 2: allowed by voltage, only

Variable Documentation

◆ hundredsV

uint16_t hundredsV
extern

The battery voltage in 0.01V units.

This is just an integer value consistent to the last valid battery voltage measurement valFilVal.batVolt. Contrary to valFilVal.batVolt which is set to -0.9 to indicate invalidity after 2.4s without new (MQTT) measurements, this integer value will be kept "forever".
It is preset with 1289 (12.89 V) to avoid "battery low" status before the first valid MQTT measurement / message.
Receiving a good MQTT message from the battery voltmeter will set valFilVal.batVolt, batVoltValid and this value.
Use

formFixed16(&textStart, hundredsV, 2)
uint16_t hundredsV
The battery voltage in 0.01V units.
Definition sweetHome2.c:311
char * formFixed16(char *target, uint8_t targetLen, uint16_t value, uint8_t dotPos)
Format 16 bit unsigned fixed point, right aligned.
Definition weUtil.c:252

to format as "12.89" without trailing zero.

See also
formFixed16 valFilVal batVoltValid tenPromSoC

◆ tenPromSoC

uint16_t tenPromSoC
extern

The battery state of charge or SOC in 0.01% units.

This the state of charge of (one of the) ECOworthy batteries in units of 0.01% or 10 per mille as published by Bluetooth. A value of 2468 would mean a SoC of 24.68% and for a 100Ah battery also a charge of 24.68Wh.

If no Bluetooth data of (at least) one of the three batteries connected in parallel are available the SoC will be looked up by SoC(U) table.

Use

formFixed16(&textStart, tenPromSoC, 2)

to format as "24.68" without trailing zero.

See also
formFixed16 valFilVal batVoltValid