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

Understanding SAADC

Hi all,

I am trying to use the SAADC to measure battery level. I have a rechargable lithium battery connected to my customed PCB with a NRF52832. The rechargable battery has a max voltage of about 4.2V when charged.

I also have a 3.3V voltage regulator connected to the battery and the 3.3V is used to power up the NRF52032.

I am using a voltage divider to measure the battery voltage. 4M ohm to battery and a 10M ohm to ground. The point between the 4M resistor and the 10M resistor is connected to AIN1. There is also a capacitor of 10nF across the 10M resistor.

My saadc init function is as follows:

void saadc_init(void)
{
    ret_code_t err_code;

    nrf_saadc_channel_config_t channel_config =
    NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN1);
    channel_config.reference = NRF_SAADC_REFERENCE_VDD4;
    err_code = nrf_drv_saadc_init(NULL, saadc_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_pool[0],SAMPLES_IN_BUFFER);
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_saadc_buffer_convert(m_buffer_pool[1],SAMPLES_IN_BUFFER);
    APP_ERROR_CHECK(err_code);
}

And the callback function is as follows:

void saadc_callback(nrf_drv_saadc_evt_t const * p_event)
{
   if (p_event->type == NRF_DRV_SAADC_EVT_DONE)
   {
      ret_code_t err_code;
      err_code = nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer, 
      SAMPLES_IN_BUFFER);
      APP_ERROR_CHECK(err_code);

  NRF_LOG_INFO("Conversion Result: %d\r\n", p_event->data.done.p_buffer[0]);

      nrf_drv_saadc_uninit();
      NRF_SAADC->INTENCLR = (SAADC_INTENCLR_END_Clear << SAADC_INTENCLR_END_Pos);
      NVIC_ClearPendingIRQ(SAADC_IRQn);
   }
}

I used a multimeter and measure a voltage if 2.09V at the output of the voltage divider and I am getting a measure value of about 550 for the ADC conversion.

How is this 550 value obtained? And is it the correct value? What is the reference voltage for the ADC? I am assuming it 0.6 x 6 = 3.6V?

If so, then (2.09/3.6) * 1023 = 593. This is slightly off from the measured value of 550.

Can anyone help?

Parents
  • Hi,

    In your code you are using the nRF52's VDD divided by 4 as reference voltage (NRF_SAADC_REFERENCE_VDD4) and a gain of 1/6. If we rearange the equation presentet here we can see that Vin is:

    Vin = ADCresult * Reference / (Resolution * Gain)

    In your case that should result in:

    Vin = 550 * (VDD/4) / (1024 * (1/6)) = 2.66.

    So something is wrong. Are you sure that VDD is 3.3V?

  • I'm not sure if I understand. It sounds like your measurements and ADC results are almost spot on (3.61V vs 3.598V)?

    Have you taken into account the accuracy of your resistors and the dropout voltage of your voltage regulator? Since you are using VDD as a reference voltage your ADC readings will be useless when/if the battery voltage gets so low that the regulator cannot produce 3.3V anymore.

Reply
  • I'm not sure if I understand. It sounds like your measurements and ADC results are almost spot on (3.61V vs 3.598V)?

    Have you taken into account the accuracy of your resistors and the dropout voltage of your voltage regulator? Since you are using VDD as a reference voltage your ADC readings will be useless when/if the battery voltage gets so low that the regulator cannot produce 3.3V anymore.

Children
No Data
Related