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;

Parents Reply Children
  • 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.

  • You really need to have the hardware (Coulomb Counter) to do it with any useful accuracy.

    If you don't have, and can't add, that hardware then it's probably best not to pretend that you can do it at all.

    Rather than try to predict remaining capacity, just do a "low battery" alert when the voltage falls right at the end of the battery life.

    You might want to feed this back to the device manufacturer ...

Related