This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Calculating battery remaining capacity

Hi,

I am currently working on calculating a Li-ion battery;s remaining capacity. As far as I know, I should read the raw value via SAADC. then convert the value back to voltage and calculate with the battery's discharging settings. From the SAADC_LOW_POWER example, I have managed to successfully read values from VDD and print it to my terminal. However, the values that I was getting was quite different from the readings on my voltage meter.

After I plugged in my Li-ion battery to the board, I was getting between 880 to 900 from the adc. From the nRF52832 guide, page 353, the digital output from SAADC can be calculated back to voltage. Converting back to voltage will be 900* (1/6)/(0.6) * 2^10 = 3.16V (the voltage input n was disabled from my code). But my battery was outputting 3.9V measured from a voltage meter. I have also noticed that after I unplug my battery, the VDD value did not decreased to 0 but showing value 814(about 2.86V).

I am now confused of how to measure battery voltage from my nRF52 Development Kit. Is there anything I am missing or I am on a completely wrong track?

Here are some code from my program:

1. SAADC settings:

    saadc_config.low_power_mode = true;                                                   
    saadc_config.resolution = NRF_SAADC_RESOLUTION_10BIT;                             
    saadc_config.oversample = SAADC_OVERSAMPLE;                                       
    saadc_config.interrupt_priority = APP_IRQ_PRIORITY_LOW;                           
	
    //Initialize SAADC
    err_code = nrf_drv_saadc_init(&saadc_config, saadc_callback);                     
    APP_ERROR_CHECK(err_code);
		
    //Configure SAADC channel
    channel_config.reference = NRF_SAADC_REFERENCE_INTERNAL;                            
    channel_config.gain = NRF_SAADC_GAIN1_6;                                            
    channel_config.acq_time = NRF_SAADC_ACQTIME_10US;                                   
    channel_config.mode = NRF_SAADC_MODE_SINGLE_ENDED;                                  
    channel_config.pin_p = NRF_SAADC_INPUT_VDD;                                         
    channel_config.pin_n = NRF_SAADC_INPUT_DISABLED;                                    
    channel_config.resistor_p = NRF_SAADC_RESISTOR_DISABLED;                            
    channel_config.resistor_n = NRF_SAADC_RESISTOR_DISABLED;

2.  Code of converting ADC raw value to voltage:

int16_t raw_res = p_event->data.done.p_buffer[i];// Raw result from ADC
float true_voltage = raw_res * 3.6 / 1024;

  • Hi,

    You cannot supply a nRF52832 directly for a typical lithium battery, as the maximum voltage is too high (max supply voltage for the nRF52832 is 3.6 V). Therefor you need an external regulator, and because of that, the VDD voltage on the nRF32832 does not reflect the battery voltage. I recommend you refer to Measuring Lithium battery voltage with nRF52, which describes how you properly measure the voltage of a lithium battery.

  • Battery terminal voltage is a very poor indicator of remaining capacity for lithium batteries.

    Search the forum for the many times this has come up before!

    eg, https://devzone.nordicsemi.com/f/nordic-q-a/20389/battery-level-check/79486#79486 - with graphs to show you why.

  • Hi, thank you so much for the reply!
    I have followed the guide from the link you provided, but somehow I am still getting incorrect ADC values:

    The discharge curve of my Li-ion battery is from 4.2V (100%) to 3V (0%). I have used capacitor 2.2M and 0.82M to convert my input voltage. Which will be:

    Max. Voltage = 4.2V * (2.2/(2.2+0.82)) = 3.05928V
    Min. Voltage = 3V * (2.2/(2.2+0.82)) = 2.1852V

    then calculate to ADC value at both 4.2V and 3V:

    ADC value at 4.2V = 3V * (1/6)/0.6V * 2^10 = 853.33 
    ADC value at 3V = 2.18V * (1/6)/0.6V * 2^10 = 620.088
    =>So now the ADC value should be between 853 and 620

    I plugged in the wire to the VDD port on my nRF52 DK, and I got the value around 860 from the com port. Measuring the voltage of my battery with a voltage meter, I got 3.42V. I now calculate the voltage into ADC value:

    3.42V * (2.2/(2.2+0.82)) * (1/6)/0.6V * 2^10 = 708.58

    The ADC output should be around 708, but the output was very different from the actual result I got, which is around 860. While I was doing this measurement, my board was plugged in to my computer via Micro USB, and I access the board with Putty through COM connection. Is this because the VDD value was influenced by the USB power input?

  • Hi, thank you for the reply! 

    I am aware that calculating the remaining capacity of the battery using voltage is not the best way, but my project was very limited on hardware layouts. I am actually developing programs for an off-the-shelf Bluetooth tag device, which I planned to download the program to the chip via JLink. 

    The tag device was powered by a Li-ion battery pack, and since I am planning not to modify the hardware design of the tag, one easy method I found was to measure the voltage to calculate the remaining battery. Can you suggest other methods of calculating the remaining capacity of the battery without hardware modification? One alternate option I think I can do is to measure the power usage of my device and calculate the estimated hours, but this may also be inaccurate after hundreds of charging cycles.

  • Hi,

    Have you calibrated the SAADC?

    evanshwu said:
    Is this because the VDD value was influenced by the USB power input?

    That is possible, but it is difficult to say without knowing anything about your HW design.

Related