# Battery mapping in range problem

Hi,
I have problem with battery percentage mapping in range (2.5 to 3.65) from 0 to 100%
with using a filter, calibrate_linear: ?

``````sensor:
pin: 34
attenuation: 0db
name: "SolarSoilSensorA Voltage Battery"
id: "VCC"
update_interval: 2s
filters:
- multiply : 5
- calibrate_linear:
- 0.0 -> 0.35
- 0.5 -> 0.79
- 1.0 -> 1.22
- 1.5 -> 1.65
- 2.0 -> 2.09
- 2.5 -> 2.52
- 3.0 -> 2.95
- 3.5 -> 3.38
- 4.0 -> 3.82

- platform: template
name: "SolarSoilSensorA Level Battery"
unit_of_measurement: '%'
accuracy_decimals: 2
id: \${device_name}_battery
update_interval: 10s
lambda: |-
return ((id(VCC).state /3.65) * 100.00); ?
#filters: ?
#- calibrate_linear: ?
# - 10 -> 100 ?
#- 20 -> 100 ?
``````

Capacity % Pack Voltage Cell Voltage
100% 14.60 3.65
99% 14.45 3.61
95% 13.87 3.46
90% 13.30 3.32
80% 13.25 3.31
70% 13.20 3.30
60% 13.17 3.29
50% 13.13 3.28
40% 13.10 3.27
30% 13.00 3.25
20% 12.90 3.22
17% 12.80 3.20
14% 12.50 3.12
9% 12.00 3.00
0% 10.00 2.50

% Level Battery has a non-linear course

What is your question?

I need to calibrate, map percentages LiFePo4 Battery as in the table above.
In platform: adc is filters - calibrate_linear: and it works fine.

how to map nonlinear this way in % ? in - platform: template

`````` return ((id(VCC).state /3.65) * 100.00);
``````

the line above is not giving the correct values:/

``````filters:
- calibrate_linear:
- 2.50 -> 0%
- 3.00 -> 9%
- 3.12 -> 14%
- 3.20 -> 17%
- 3.22 -> 20%
- 3.25 -> 30%
...... ?????
lambda: |-
return ((id(VCC).state /3.65) * 100.00); ?

id(VCC) to map value -> return % value ?``````

It’s still very difficult to understand what you want. Do you want to replace the calibration table with an equation?

I don’t want to replace it.

I want map voltage value to % value for LiFePo4 Battery.

`````` lambda: |-
return ((id(VCC).state /3.65) * 100.00);
``````

Now i have it and is not giving the correct values

I need get id(VCC).state ->> map to % value and return correct value to homeassistant (% level of battery)

You’re already converting voltage to % capacity in the calibrate linear table. Why do you need the equation?

It was just an example of how I would see it,
But it probably doesn’t work,

``````lambda: |-
return ((id(VCC).state /3.65) * 100.00); ?
``````

This is also not required, I just found such an example on the forum

Now I have this code

``````sensor:
pin: 34
attenuation: 0db
name: "SolarSoilSensorA Voltage Battery"
id: "VCC"
update_interval: 2s
filters:
- multiply : 5
- calibrate_linear:
- 0.0 -> 0.35
- 0.5 -> 0.79
- 1.0 -> 1.22
- 1.5 -> 1.65
- 2.0 -> 2.09
- 2.5 -> 2.52
- 3.0 -> 2.95
- 3.5 -> 3.38
- 4.0 -> 3.82

- platform: template
name: "SolarSoilSensorA Level Battery"
accuracy_decimals: 0
#id: \${device_name}_battery
id: "level_battery"
update_interval: 2s
#lambda: |-
#return ((id(VCC).state /3.65) * 100.00);
lambda: return (id(VCC).state);
filters:
- calibrate_linear:
- 2.50 -> 0.00
- 3.00 -> 9.00
- 3.12 -> 14.00
- 3.20 -> 17.00
- 3.22 -> 20.00
- 3.25 -> 30.00
- 3.27 -> 40.00
- 3.28 -> 50.00
- 3.29 -> 60.00
- 3.30 -> 70.00
- 3.31 -> 80.00
- 3.32 -> 90.00
- 3.46 -> 95.00
- 3.61 -> 99.00
- 3.65 -> 100.00

unit_of_measurement: '%'
``````

But the values are not correct:|
e.g.
2.50v = -30%
3.00v = 24%
3.30v = 57%
3.65v = 95%

Why is it not work?

1. I am really not sure why you are converting twice, surely it is simpler to go from voltage to %

2. It is not a linear relationship, so why use a linear filter?

I do not know how to do it .
What filter is correct for this?

I want to read the real level of battery Lifepo4 charge in 0 to 100%

Not work

again…

Here is the adc calibration, without it the readings are wrong!

``````sensor:
pin: 34
attenuation: 11db
name: "SolarSoilSensorA Voltage Battery"
id: "VCC"
update_interval: 2s
filters:
- multiply : 5
- calibrate_linear:
- 0.00 -> 0.60
- 0.10 -> 0.68
- 0.20 -> 0.75
- 0.30 -> 0.85
- 0.40 -> 0.94
- 0.50 -> 1.01
- 0.60 -> 1.09
- 0.70 -> 1.19
- 0.80 -> 1.27
- 0.90 -> 1.35
- 1.00 -> 1.45
- 1.50 -> 1.86
- 2.00 -> 2.29
- 2.10 -> 2.38
- 2.20 -> 2.46
- 2.30 -> 2.56
- 2.40 -> 2.63
- 2.50 -> 2.70
- 2.60 -> 2.78
- 2.70 -> 2.87
- 2.80 -> 2.95
- 2.90 -> 3.05
- 3.00 -> 3.14
- 3.50 -> 3.56
- 4.00 -> 3.98
``````

In the range of 0 - 4 volts the voltage is correct. For calibration, I use a laboratory power supply + true rms Multimeter.

Then I take the calibrated voltage and map / calibrate to percentages…

``````- platform: template
name: "SolarSoilSensorA Level Battery"
accuracy_decimals: 2
#id: \${device_name}_battery
id: "level_battery"
update_interval: 2s
#lambda: |-
#return ((id(VCC).state /3.65) * 100.00);
lambda: return (id(VCC).state);
filters:
- calibrate_linear:
- 2.50 -> 0.00
- 3.00 -> 9.00
- 3.12 -> 14.00
- 3.20 -> 17.00
- 3.22 -> 20.00
- 3.25 -> 30.00
- 3.27 -> 40.00
- 3.28 -> 50.00
- 3.29 -> 60.00
- 3.30 -> 70.00
- 3.31 -> 80.00
- 3.32 -> 90.00
- 3.46 -> 95.00
- 3.61 -> 99.00
- 3.65 -> 100.00

unit_of_measurement: '%'
``````

The values are correct for a lifepo4 battery but the values at the output of this filter are different … not correct…

I also experimentally did this calibration

``````    - calibrate_linear:
- 2.77 -> 0.00
- 2.86 -> 9.00
- 2.89 -> 14.00
- 2.935 -> 17.00
- 2.96 -> 20.00
- 3.06 -> 30.00
- 3.145 -> 40.00
- 3.24 -> 50.00
- 3.33 -> 60.00
- 3.42 -> 70.00
- 3.51 -> 80.00
- 3.60 -> 90.00
- 3.65 -> 95.00
- 3.69 -> 99.00
- 3.695 -> 100.00
``````

This calibration returns the correct values!
But this is not a scale for lifepo4: /