nPM1300 fuel gauge SoC

Hi

Setup: nPM1300, nRF54L15-based board, SDK 2.9.2

I am trying to figure out how to use the nPM1300.


So far, I have not succeeded. Quite frequently, after power cycling my device, the SoC read from the fuel gauge, after rebooting, is quite different (e.g. 20% difference) from the SoC before power down.


My code calls nrf_fuel_gauge_process() every 100 ms.

ret = read_sensors(charger, &voltage, &current, &temp, &chg_status);
:
soc = nrf_fuel_gauge_process(voltage, current, temp, delta, charging_active, NULL);


Some of the things I have tried…


ONE


Simple usage.

Provide no further information to the fuel gauge.

On power up, initialise the fuel gauge straight away.

ret = read_sensors(charger, &p.v0, &p.i0, &p.t0, &chg_status);
:
sensor_channel_get(charger, SENSOR_CHAN_GAUGE_DESIRED_CHARGING_CURRENT, &v);
:
nrf_fuel_gauge_init(&p, NULL);


TWO


Same as ONE, except wait 30 seconds before initialising


THREE


When the SoC reaches 100%, re-initialise the fuel gauge:


int ret = read_sensors(charger, &p.v0, &p.i0, &p.t0, &chg_status);
:
nrf_fuel_gauge_init(&p, NULL);

FOUR


After a few seconds after powering up, read the V,I,T


ret = read_sensors(charger, &p.v0, &p.i0, &p.t0, &chg_status);


then initialise the fuel gauge using these values


FIVE

Save V,I,T values to Flash on a regular basis, and on power-up, restore these  saved values and use them to initialise the fuel gauge.

SIX


Maintain an array of saved V,I,T values (e.g. size 120), and save the average of this circular array to Flash every so often (e.g. every 2 minutes for test purposes).
On power-up, restore these saved averages, and use them to initialise the fuel gauge.

FURTHER INFORMATION

In all cases, there is often quite a large drop or rise in the SoC after power cycling the device.

Here is a sample of the output while charging / discharging (from two separate logs).
One thing of note: the voltage and current fluctuate quite a bit during discharge.

Charging:

[00:13:31.976,257] : delta: 0.100000, V: 4.233, I: -0.019, T: 25.93, SoC: 98.59, TTE: nan, TTF: 2122, Chging 1, Conn 1, ChgSt 17
[00:13:32.076,293] : delta: 0.100000, V: 4.233, I: -0.017, T: 25.93, SoC: 98.59, TTE: nan, TTF: 2095, Chging 1, Conn 1, ChgSt 17
[00:13:32.176,239] : delta: 0.100000, V: 4.233, I: -0.018, T: 25.93, SoC: 98.59, TTE: nan, TTF: 2107, Chging 1, Conn 1, ChgSt 17
[00:13:32.276,275] : delta: 0.100000, V: 4.233, I: -0.017, T: 25.93, SoC: 98.59, TTE: nan, TTF: 2092, Chging 1, Conn 1, ChgSt 17
[00:13:32.376,312] : delta: 0.100000, V: 4.233, I: -0.017, T: 25.93, SoC: 98.59, TTE: nan, TTF: 2091, Chging 1, Conn 1, ChgSt 17
[00:13:32.476,379] : delta: 0.101000, V: 4.233, I: -0.019, T: 25.93, SoC: 98.59, TTE: nan, TTF: 2115, Chging 1, Conn 1, ChgSt 17
[00:13:32.576,293] : delta: 0.099000, V: 4.233, I: -0.018, T: 25.93, SoC: 98.59, TTE: nan, TTF: 2101, Chging 1, Conn 1, ChgSt 17
[00:13:32.676,300] : delta: 0.100000, V: 4.233, I: -0.017, T: 25.93, SoC: 98.59, TTE: nan, TTF: 2087, Chging 1, Conn 1, ChgSt 17
[00:13:32.776,367] : delta: 0.101000, V: 4.233, I: -0.017, T: 25.93, SoC: 98.59, TTE: nan, TTF: 2085, Chging 1, Conn 1, ChgSt 17
[00:13:32.876,312] : delta: 0.099000, V: 4.233, I: -0.019, T: 25.93, SoC: 98.59, TTE: nan, TTF: 2110, Chging 1, Conn 1, ChgSt 17
[00:13:32.976,348] : delta: 0.101000, V: 4.233, I: -0.018, T: 25.93, SoC: 98.59, TTE: nan, TTF: 2096, Chging 1, Conn 1, ChgSt 17
[00:13:33.076,385] : delta: 0.100000, V: 4.233, I: -0.017, T: 25.93, SoC: 98.59, TTE: nan, TTF: 2081, Chging 1, Conn 1, ChgSt 17
[00:13:33.176,330] : delta: 0.099000, V: 4.228, I: -0.018, T: 25.93, SoC: 98.59, TTE: nan, TTF: 2093, Chging 1, Conn 1, ChgSt 17
[00:13:33.276,336] : delta: 0.100000, V: 4.233, I: -0.017, T: 25.93, SoC: 98.59, TTE: nan, TTF: 2079, Chging 1, Conn 1, ChgSt 17
[00:13:33.376,403] : delta: 0.101000, V: 4.233, I: -0.019, T: 25.93, SoC: 98.59, TTE: nan, TTF: 2103, Chging 1, Conn 1, ChgSt 17
[00:13:33.476,348] : delta: 0.100000, V: 4.228, I: -0.018, T: 25.93, SoC: 98.59, TTE: nan, TTF: 2090, Chging 1, Conn 1, ChgSt 17
[00:13:33.576,354] : delta: 0.100000, V: 4.233, I: -0.018, T: 25.82, SoC: 98.59, TTE: nan, TTF: 2088, Chging 1, Conn 1, ChgSt 17
[00:13:33.676,452] : delta: 0.100000, V: 4.233, I: -0.019, T: 25.93, SoC: 98.59, TTE: nan, TTF: 2100, Chging 1, Conn 1, ChgSt 17
[00:13:33.776,367] : delta: 0.100000, V: 4.228, I: -0.018, T: 25.93, SoC: 98.59, TTE: nan, TTF: 2086, Chging 1, Conn 1, ChgSt 17
[00:13:33.876,342] : delta: 0.100000, V: 4.233, I: -0.016, T: 25.93, SoC: 98.59, TTE: nan, TTF: 2057, Chging 1, Conn 1, ChgSt 17
[00:13:33.976,470] : delta: 0.100000, V: 4.233, I: -0.019, T: 25.93, SoC: 98.59, TTE: nan, TTF: 2096, Chging 1, Conn 1, ChgSt 17
[00:13:34.076,354] : delta: 0.100000, V: 4.228, I: -0.018, T: 25.93, SoC: 98.60, TTE: nan, TTF: 2082, Chging 1, Conn 1, ChgSt 17
[00:13:34.176,361] : delta: 0.100000, V: 4.233, I: -0.018, T: 25.93, SoC: 98.60, TTE: nan, TTF: 2081, Chging 1, Conn 1, ChgSt 17
[00:13:34.276,428] : delta: 0.100000, V: 4.233, I: -0.018, T: 25.93, SoC: 98.60, TTE: nan, TTF: 2079, Chging 1, Conn 1, ChgSt 17
[00:13:34.376,373] : delta: 0.100000, V: 4.233, I: -0.017, T: 25.93, SoC: 98.60, TTE: nan, TTF: 2065, Chging 1, Conn 1, ChgSt 17
[00:13:34.476,379] : delta: 0.100000, V: 4.233, I: -0.018, T: 25.93, SoC: 98.60, TTE: nan, TTF: 2077, Chging 1, Conn 1, ChgSt 17

Discharging:

[00:14:18.076,660] : delta: 0.100000, V: 3.994, I: 0.011, T: 26.03, SoC: 96.79, TTE: 15040, TTF: nan, Chging 0, Conn 0, ChgSt 0
[00:14:18.176,727] : delta: 0.100000, V: 3.984, I: 0.023, T: 26.03, SoC: 96.79, TTE: 15039, TTF: nan, Chging 0, Conn 0, ChgSt 0
[00:14:18.276,794] : delta: 0.100000, V: 3.994, I: 0.023, T: 26.03, SoC: 96.79, TTE: 15039, TTF: nan, Chging 0, Conn 0, ChgSt 0
[00:14:18.376,678] : delta: 0.100000, V: 3.989, I: 0.067, T: 26.03, SoC: 96.79, TTE: 15039, TTF: nan, Chging 0, Conn 0, ChgSt 0
[00:14:18.476,745] : delta: 0.100000, V: 3.989, I: 0.019, T: 26.03, SoC: 96.78, TTE: 15039, TTF: nan, Chging 0, Conn 0, ChgSt 0
[00:14:18.576,812] : delta: 0.100000, V: 3.999, I: 0.021, T: 26.03, SoC: 96.78, TTE: 15038, TTF: nan, Chging 0, Conn 0, ChgSt 0
[00:14:18.676,696] : delta: 0.100000, V: 3.989, I: 0.023, T: 26.03, SoC: 96.78, TTE: 15038, TTF: nan, Chging 0, Conn 0, ChgSt 0
[00:14:18.776,763] : delta: 0.100000, V: 3.994, I: 0.019, T: 26.03, SoC: 96.78, TTE: 15038, TTF: nan, Chging 0, Conn 0, ChgSt 0
[00:14:18.876,922] : delta: 0.100000, V: 3.999, I: 0.039, T: 26.03, SoC: 96.78, TTE: 15038, TTF: nan, Chging 0, Conn 0, ChgSt 0
[00:14:18.976,715] : delta: 0.100000, V: 4.003, I: 0.043, T: 26.03, SoC: 96.78, TTE: 15037, TTF: nan, Chging 0, Conn 0, ChgSt 0
[00:14:19.076,782] : delta: 0.100000, V: 3.994, I: 0.011, T: 26.03, SoC: 96.78, TTE: 15037, TTF: nan, Chging 0, Conn 0, ChgSt 0
[00:14:19.176,940] : delta: 0.100000, V: 3.999, I: 0.067, T: 26.03, SoC: 96.78, TTE: 15037, TTF: nan, Chging 0, Conn 0, ChgSt 0
[00:14:19.276,733] : delta: 0.100000, V: 3.994, I: 0.023, T: 26.03, SoC: 96.78, TTE: 15037, TTF: nan, Chging 0, Conn 0, ChgSt 0
[00:14:19.376,800] : delta: 0.100000, V: 3.984, I: 0.022, T: 26.03, SoC: 96.78, TTE: 15036, TTF: nan, Chging 0, Conn 0, ChgSt 0
[00:14:19.476,959] : delta: 0.100000, V: 3.994, I: 0.035, T: 26.03, SoC: 96.78, TTE: 15036, TTF: nan, Chging 0, Conn 0, ChgSt 0
[00:14:19.576,812] : delta: 0.100000, V: 4.003, I: 0.022, T: 26.03, SoC: 96.78, TTE: 15036, TTF: nan, Chging 0, Conn 0, ChgSt 0
[00:14:19.676,788] : delta: 0.100000, V: 3.994, I: 0.019, T: 26.03, SoC: 96.78, TTE: 15035, TTF: nan, Chging 0, Conn 0, ChgSt 0
[00:14:19.776,947] : delta: 0.100000, V: 4.003, I: 0.021, T: 26.03, SoC: 96.78, TTE: 15035, TTF: nan, Chging 0, Conn 0, ChgSt 0
[00:14:19.876,861] : delta: 0.100000, V: 3.994, I: 0.021, T: 26.03, SoC: 96.78, TTE: 15035, TTF: nan, Chging 0, Conn 0, ChgSt 0
[00:14:19.976,837] : delta: 0.100000, V: 3.994, I: 0.009, T: 26.03, SoC: 96.77, TTE: 15035, TTF: nan, Chging 0, Conn 0, ChgSt 0
[00:14:20.076,995] : delta: 0.100000, V: 4.003, I: 0.039, T: 26.03, SoC: 96.77, TTE: 15035, TTF: nan, Chging 0, Conn 0, ChgSt 0
[00:14:20.176,879] : delta: 0.100000, V: 4.003, I: 0.020, T: 26.03, SoC: 96.77, TTE: 15034, TTF: nan, Chging 0, Conn 0, ChgSt 0
[00:14:20.276,855] : delta: 0.100000, V: 3.994, I: 0.019, T: 26.03, SoC: 96.77, TTE: 15034, TTF: nan, Chging 0, Conn 0, ChgSt 0
[00:14:20.377,014] : delta: 0.100000, V: 3.994, I: 0.021, T: 26.03, SoC: 96.77, TTE: 15034, TTF: nan, Chging 0, Conn 0, ChgSt 0
[00:14:20.477,020] : delta: 0.100000, V: 3.989, I: 0.019, T: 26.03, SoC: 96.77, TTE: 15034, TTF: nan, Chging 0, Conn 0, ChgSt 0
[00:14:20.576,843] : delta: 0.100000, V: 3.999, I: 0.019, T: 26.03, SoC: 96.77, TTE: 15033, TTF: nan, Chging 0, Conn 0, ChgSt 0
[00:14:20.677,032] : delta: 0.100000, V: 3.994, I: 0.039, T: 26.03, SoC: 96.77, TTE: 15033, TTF: nan, Chging 0, Conn 0, ChgSt 0
[00:14:20.776,885] : delta: 0.100000, V: 3.994, I: 0.011, T: 26.03, SoC: 96.77, TTE: 15033, TTF: nan, Chging 0, Conn 0, ChgSt 0
[00:14:20.876,922] : delta: 0.100000, V: 3.999, I: 0.021, T: 26.03, SoC: 96.77, TTE: 15033, TTF: nan, Chging 0, Conn 0, ChgSt 0
[00:14:20.977,050] : delta: 0.100000, V: 4.003, I: 0.019, T: 26.03, SoC: 96.77, TTE: 15032, TTF: nan, Chging 0, Conn 0, ChgSt 0
[00:14:21.076,934] : delta: 0.100000, V: 3.994, I: 0.039, T: 26.03, SoC: 96.77, TTE: 15032, TTF: nan, Chging 0, Conn 0, ChgSt 0
[00:14:21.176,940] : delta: 0.100000, V: 3.989, I: 0.019, T: 26.03, SoC: 96.77, TTE: 15032, TTF: nan, Chging 0, Conn 0, ChgSt 0
[00:14:21.277,069] : delta: 0.100000, V: 3.999, I: 0.019, T: 26.03, SoC: 96.77, TTE: 15032, TTF: nan, Chging 0, Conn 0, ChgSt 0
[00:14:21.377,075] : delta: 0.100000, V: 3.994, I: 0.019, T: 26.03, SoC: 96.77, TTE: 15032, TTF: nan, Chging 0, Conn 0, ChgSt 0
[00:14:21.476,959] : delta: 0.100000, V: 3.979, I: 0.043, T: 25.62, SoC: 96.77, TTE: 15031, TTF: nan, Chging 0, Conn 0, ChgSt 0
[00:14:21.577,087] : delta: 0.100000, V: 4.003, I: 0.019, T: 26.03, SoC: 96.77, TTE: 15031, TTF: nan, Chging 0, Conn 0, ChgSt 0
[00:14:21.677,062] : delta: 0.100000, V: 3.999, I: 0.022, T: 26.03, SoC: 96.77, TTE: 15031, TTF: nan, Chging 0, Conn 0, ChgSt 0
[00:14:21.776,947] : delta: 0.100000, V: 3.999, I: 0.009, T: 26.03, SoC: 96.76, TTE: 15031, TTF: nan, Chging 0, Conn 0, ChgSt 0

Question: Do you have any suggestions on how I could get more reliable SoC values from the chip?
Question: Is there a maximum interval between nrf_fuel_gauge_process() calls (i.e. a maximum delta) beyond which the update is not reliable (e.g. 500 ms?)
Question: Does the fuel gauge algorithm average its input over time?

Thanks

Parents
  • I compared SDK 2.9.2 to SDK 3.1.1, and I noticed that in nrf_fuel_gauge_init_parameters() there is a new addition:

    /** Optional state memory, previously retrieved using @ref nrf_fuel_gauge_state_get.
    * When used, the library resumes from this state and all other parameters are ignored.
    * Set to NULL when not used or when initializing the library for the first time.
    */
    const void *state;

    Is this used to save the SoC?
    If so, this would probably be useful.
    Unfortunately, it is not an option for us, right now, to upgrade out current project to use SDK 3.1.1.

Reply
  • I compared SDK 2.9.2 to SDK 3.1.1, and I noticed that in nrf_fuel_gauge_init_parameters() there is a new addition:

    /** Optional state memory, previously retrieved using @ref nrf_fuel_gauge_state_get.
    * When used, the library resumes from this state and all other parameters are ignored.
    * Set to NULL when not used or when initializing the library for the first time.
    */
    const void *state;

    Is this used to save the SoC?
    If so, this would probably be useful.
    Unfortunately, it is not an option for us, right now, to upgrade out current project to use SDK 3.1.1.

Children
  • Hi 

    Could you share the battery model file used and the project folder created during the profiling process? I can first have a look whether the battery model is correct.

    During discharge, the default recommended fuel gauge sampling rate is 1 second. The fuel gauge is designed for ultra-low-power operation when supplied from the battery.
    If you can provide the battery capacity and average application currents during discharge, we can suggest an optimized sampling rate.
    During charging, using a 100 ms interval is fine since USB power removes power constraints.

    Also, do you use the Battery Discharge Current Limit feature to limit discharge current and improve current measurement accuracy? Here the Low setting is recommended for better fuel gauge performance and stable current measurement.

    Fuel Gauge Initialization

    Initialize only when the battery is at rest and system activity is low. For example, initializing during charging is not recommended.The ideal moment is immediately after reboot, before enabling downstream peripherals or the charger. This ensures minimal load on the battery.

    The nrf_fuel_gauge_init() function uses the first measurement of voltage, current, and temperature.To ensure an accurate baseline, take this measurement when the battery is chemically stable (not charging and not under significant load).

    Some initialization error may still occur, but the algorithm corrects these gradually as the battery discharges.
    The fuel gauge library automatically reinitializes after a full-charge event, ensuring accurate SoC near 100% and preventing error accumulation.

    More info Fuel Guage initialization chapter in the fuel gauge app note for more info.


    Sleep Mode Considerations

    If the host enters sleep (RAM retained), do not reinitialize the fuel gauge upon wakeup. Instead, use nrf_fuel_gauge_idle_set() before sleep to notify the library of idle periods. Provide the expected average current during idle to improve estimation accuracy. When normal activity resumes, call nrf_fuel_gauge_process() to return to active tracking. This significantly accelerates ffuel gauge convergence after period of long inactivity.
    See Sleep Current Configuration and Fuel gauge RAM retention chapter in the fuel gauge app note for more info. 

    Hope this helps

    Regards 

    Tharaka




Related