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:
  - platform: adc
    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 ?

https://diysolarforum.com/threads/lifepo4-voltage-chart.3156/

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:
  - platform: adc
    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 :confused:

again…

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

sensor:
  - platform: adc
    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: /