I have custom board with nrf 52832. I am using SDK 12.3.0. and soft devices s132 V3.0.0 to transmit advertising packets with advertising interval 1s. I have written simple application that reads battery status and transmitted it in manufacturing data of advertising packets. The code of reading battery status as follows.
#define ADC_REF_VOLTAGE_IN_MILLIVOLTS 600 /**< Reference voltage (in milli volts) used by ADC while doing conversion. */
#define ADC_PRE_SCALING_COMPENSATION 6 /**< The ADC is configured to use VDD with 1/3 prescaling as input. And hence the result of conversion is to be multiplied by 3 to get the actual value of the battery voltage.*/
#define ADC_RES_10BIT 1024 /**< Maximum digital value for 10-bit ADC conversion. */
#define SAMPLES_IN_BUFFER 1
uint8_t percentage_batt_lvl;
static nrf_saadc_value_t m_buffer[SAMPLES_IN_BUFFER];
uint8_t GetBatPercentage(uint16_t adc_val)
{
uint16_t vbat_current_in_mv = (ADC_REF_VOLTAGE_IN_MILLIVOLTS * ADC_PRE_SCALING_COMPENSATION * adc_val) / 1024; //10 bit resolution =1024
uint8_t bat=(uint8_t) ((vbat_current_in_mv-2100)/9);
if(bat>100)
bat=100;
return bat;
}
void battery_level_get_callback(nrf_drv_saadc_evt_t const * p_event)
{
nrf_saadc_value_t adc_result;
// uint16_t batt_lvl_in_milli_volts;
if (p_event->type == NRF_DRV_SAADC_EVT_DONE)
{
ret_code_t err_code;
adc_result = p_event->data.done.p_buffer[0];
err_code = nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer, SAMPLES_IN_BUFFER);
APP_ERROR_CHECK(err_code);
//batt_lvl_in_milli_volts=ADC_RESULT_IN_MILLI_VOLTS(adc_result);// + DIODE_FWD_VOLT_DROP_MILLIVOLTS;
percentage_batt_lvl=GetBatPercentage(adc_result);
}
}
void saadc_init(void)
{
ret_code_t err_code;
//NRF_SAADC_INPUT_VDD
nrf_saadc_channel_config_t channel_config = NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_VDD);//SAADC_CH_PSELP_PSELP_VDD
err_code = nrf_drv_saadc_init(NULL, battery_level_get_callback);
APP_ERROR_CHECK(err_code);
err_code = nrf_drv_saadc_channel_init(0, &channel_config);
APP_ERROR_CHECK(err_code);
err_code = nrf_drv_saadc_buffer_convert(m_buffer, SAMPLES_IN_BUFFER);
APP_ERROR_CHECK(err_code);
}
//-------------------------- BATTERY LEVEL STATUS------------------------------------------------
void get_battery_status()
{
saadc_init();
nrf_drv_saadc_sample();
nrf_delay_us(200);
nrf_drv_saadc_uninit();
}
I have called get_battery_status() in update function. I am updating advertising packet in timer handler. Actual battery voltage is 2.96 v but it shows on nrfConnect application in between 85-92 %.